Reviews REST + gRPC contracts for stability, versioning, completeness, backwards compatibility. References rest-api-architect / protobuf-architect / grpc-architect for rules; runs `buf breaking` / `openapi-diff`. Severity-keyed findings. Use when reviewing a new endpoint, proto change, or before a breaking-change release.
Scanned 9/23/2026
Install to Claude Code
npx -y skills add ralvarezdev/ralvaskills --skill api-contract-reviewer --agent claude-codeInstalls into .claude/skills of the current project.
Are you the author of Api Contract Reviewer?
Add the live security badge to your README — it updates automatically with every re-scan.
[](https://www.skillsdirectory.com/skills/ralvarezdev-api-contract-reviewer)More formats (shields.io, HTML) on the badges page.
---
name: api-contract-reviewer
version: 1.0.0
description: Reviews REST + gRPC contracts for stability, versioning, completeness, backwards compatibility. References rest-api-architect / protobuf-architect / grpc-architect for rules; runs `buf breaking` / `openapi-diff`. Severity-keyed findings. Use when reviewing a new endpoint, proto change, or before a breaking-change release.
---
# API Contract Reviewer
Reviews **contracts** — REST OpenAPI specs and protobuf `.proto` files — for stability, versioning hygiene, and completeness. Catches the contract issues architects encoded rules against before they ship to clients.
## 1. When to invoke
- A PR changes `.proto` files, OpenAPI YAML, or any handler that affects the wire contract.
- Before publishing a new major version of an API.
- Before deprecating a field or method.
- Periodic audit of an existing API for drift between spec and implementation.
## 2. Output format
Same shape as [security-reviewer §2](../security-reviewer/SKILL.md#2-output-format) — findings table with severity, then a one-line summary.
```markdown
| Severity | Rule | Location | Evidence | Fix |
|---|---|---|---|---|
| Critical | Breaking change to v1 | `proto/orders/v1/order.proto:23` | Field `status` type changed `string` → `int32` | Revert; introduce `status_v2` as a new field in v1, deprecate `status`, or bump to v2 |
| High | Versioning mismatch | `openapi.yaml` | Endpoint `/orders` lacks `/v1/` prefix | Add `/v1/` prefix per rest-api-architect §4 |
| Medium | Missing OpenAPI example | `openapi.yaml:42` | `CreateOrderRequest` has no `example:` | Add a realistic example — drives SDK gen + docs |
| Low | Inconsistent error shape | `openapi.yaml` | 404 returns `{detail: ...}` while 422 returns RFC 7807 | Standardize on RFC 7807 per rest-api-architect §7 |
```
Severity guide:
- **Critical** — wire-breaking change in a stable version (clients break on deploy).
- **High** — convention violation that's expensive to fix later (versioning, error shape).
- **Medium** — completeness gap that hurts client experience (missing examples, undocumented errors).
- **Low** — polish (inconsistent casing, missing descriptions).
## 3. Review approach
1. **Mechanical pass** (REST: `openapi-diff`; gRPC: `buf breaking`) — surfaces wire-breaking changes.
2. **Convention pass** — read the spec / proto files against the architect rules in §4.
3. **Completeness pass** — every endpoint, every model, every error has the metadata clients need (examples, descriptions, types).
## 4. What to check — by category
### Versioning
Per [rest-api-architect §4](../../protocols/rest-api-architect/SKILL.md#4-versioning--url-prefix) and [protobuf-architect §4](../../encoding/protobuf-architect/SKILL.md#4-versioning):
- **REST:** every endpoint under `/v1/`, `/v2/`, etc. Not in headers, not in query params.
- **gRPC / proto:** version is part of the package path (`acme.shop.orders.v1`), never appended to message names (`OrderV1` is wrong).
- **Additive changes don't bump the version** — new optional field, new endpoint, new enum value, new RPC method. Stay in the existing version.
- **Breaking changes always bump the major version** — field removal, type change, semantic change, required-field tightening. New `vN` package + run side-by-side.
- **Deprecate before remove** — add `[deprecated = true]` (proto) or `deprecated: true` (OpenAPI), set `Deprecation` / `Sunset` headers (RFC 9745 / 8594) for REST.
### Field & method hygiene (proto)
Per [protobuf-architect §3](../../encoding/protobuf-architect/SKILL.md#3-field-numbering--reservation-discipline):
- **Field numbers never reused.** Removed field → `reserved N;` + `reserved "name";`.
- **Field type never changed.** `int32 → string` is wire-breaking even if the runtime value fits both.
- **Field numbers 1–15** reserved for fields read on every request (1-byte wire encoding).
- **Enum: `*_UNSPECIFIED = 0` mandatory.** Enum value names `UPPER_SNAKE_CASE` prefixed with the enum name.
- **No primitive wrappers** (`StringValue`, `Int32Value`) — use `optional` instead.
### Error contracts
Per [rest-api-architect §7](../../protocols/rest-api-architect/SKILL.md#7-error-contracts--rfc-7807-problem-details) for REST and [grpc-architect §2](../../protocols/grpc-architect/SKILL.md#2-error-handling--statuserror-with-codes) for gRPC:
- **REST: every error returns `application/problem+json`** (RFC 7807) — `type`, `title`, `status`, `detail`, `instance`, `correlation_id`. Never `{"detail": "..."}` and `{"errors": [...]}` mixed in one API.
- **gRPC: `status.Error` with a standard code.** Domain-error → code mapping is centralized; no handler invents its own.
- **`type` URLs are stable** once published — clients switch on them.
- **422 validation errors include the structured field list** per rest-api-architect §7.
- **5xx responses always include `correlation_id`** ties to server logs.
### Idempotency and concurrency
Per [rest-api-architect §8](../../protocols/rest-api-architect/SKILL.md#8-idempotency--idempotency-key-mandatory) and [§9](../../protocols/rest-api-architect/SKILL.md#9-concurrency-control--etag--if-match-mandatory):
- **`Idempotency-Key` mandatory on POST/PATCH.** Missing → `400`. Documented in OpenAPI as a required header.
- **`ETag` + `If-Match` mandatory on PUT/PATCH.** Stale → `412`. Documented.
- **Cursor pagination, not offset.** Documented `next_cursor` and `limit` in response.
### JSON shape & encoding
Per [rest-api-architect §12](../../protocols/rest-api-architect/SKILL.md#12-content-negotiation--encoding):
- **`snake_case` JSON field names.**
- **ISO 8601 timestamps**, string-encoded with timezone.
- **Money as strings** (`"99.99"`), never JSON numbers.
- **UUIDs as canonical hex with dashes**, UUID v7 preferred.
- **`null` ≠ missing** — both are documented behaviors in PATCH.
### OpenAPI completeness (REST)
- **Tag, summary, description on every operation.** They drive docs and SDK code-gen.
- **`responses:` documents non-default codes** (`401`, `403`, `404`, `409`, `412`, `422`).
- **`examples:` on every request / response model.** SDKs render them; integration tests use them.
- **`requestBody.required: true`** when the body is mandatory — default is `false`, easy to miss.
- **`securitySchemes` declared** (Bearer / OAuth2) and referenced per-endpoint.
- **`servers:` and `info.contact` set** — these aren't FastAPI defaults but matter for published specs.
- **`info.version` matches the API major version** (`1.0.0`, not `0.1.7`).
### gRPC service hygiene
Per [grpc-architect §1](../../protocols/grpc-architect/SKILL.md#1-service-definition):
- **One service per file.**
- **Every RPC takes a `<Verb><Noun>Request` and returns `<Verb><Noun>Response`.** Never `google.protobuf.Empty` as input.
- **`ListXRequest`/`ListXResponse` use cursor pagination** matching REST conventions.
- **`google.protobuf.Empty`** only for fire-and-forget responses with no useful return.
- **Streaming pattern justified** in proto comments (server-stream vs client-stream vs bidi).
### Documentation drift
The spec is the contract; drift between code and spec is a contract failure:
- **OpenAPI generated from code, not hand-written.** Per [rest-api-architect §15](../../protocols/rest-api-architect/SKILL.md#15-openapi-as-the-source-of-truth).
- **Snapshot test in CI:** the spec is asserted against a committed snapshot file. Any change is reviewed.
- **gRPC equivalent:** generated code is committed under `gen/` per [protobuf-architect §6](../../encoding/protobuf-architect/SKILL.md#6-code-generation--buf-generate--bufgenyaml). PR shows the generated diff alongside the proto diff.
## 5. Tooling
Run these on the diff before the read pass; their output goes into the report.
| Tool | Catches |
|---|---|
| `buf breaking --against '.git#branch=main,subdir=proto'` | Wire-breaking changes in `.proto` files |
| `buf lint` | proto3 style + Buf-style package naming |
| `openapi-diff <old> <new>` | Wire-breaking changes in OpenAPI specs (additions, removals, type changes) |
| `swagger-cli validate openapi.yaml` (or `redocly lint`) | OpenAPI 3.1 validity + completeness rules |
| Snapshot diff in CI | `assert(app.openapi() == snapshot)` per [fastapi-architect §10](../../frameworks/fastapi-architect/SKILL.md#10-testing) |
These run in CI per [rest-api-architect §15](../../protocols/rest-api-architect/SKILL.md#15-openapi-as-the-source-of-truth) and [protobuf-architect §8](../../encoding/protobuf-architect/SKILL.md#8-breaking-change-detection--buf-breaking-in-ci) — review they're actually wired and failing builds on findings.
## 6. What this skill does NOT do
- **Performance review.** Slow queries, blocking I/O — see [performance-reviewer](../performance-reviewer/SKILL.md).
- **Security review.** Auth, injection, secrets — see [security-reviewer](../security-reviewer/SKILL.md).
- **Architecture review.** Whether the API surface is shaped right at the boundary level — see [improve-codebase-architecture](../../refactoring/improve-codebase-architecture/SKILL.md).
This skill is about whether the contract is *stable and complete*, not whether the underlying implementation is fast or safe.
## 7. Cross-skill ties
- [rest-api-architect](../../protocols/rest-api-architect/SKILL.md) — REST rules this skill verifies.
- [protobuf-architect](../../encoding/protobuf-architect/SKILL.md) — proto rules + `buf breaking` / `buf lint`.
- [grpc-architect](../../protocols/grpc-architect/SKILL.md) — gRPC service-definition conventions + error codes.
- [fastapi-architect](../../frameworks/fastapi-architect/SKILL.md) / [gin-architect](../../frameworks/gin-architect/SKILL.md) / [nethttp-architect](../../frameworks/nethttp-architect/SKILL.md) — implementation skills; reviewer confirms code matches the contract.
- [security-reviewer](../security-reviewer/SKILL.md) — when contract issues are also security issues (tokens in query params, sensitive data in URLs), promote severity.
- [commit-author](../../workflows/commit-author/SKILL.md) — breaking changes get the `BREAKING CHANGE:` footer in the commit.
Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.
No comments yet. Be the first to comment!