From api-first
Use when deciding if an API change requires a minor version bump or a new major version file, or when a backward compatibility check fails
How this skill is triggered — by the user, by Claude, or both
Slash command
/api-first:api-versioningThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
> With a sufficient number of users of an API, it does not matter what you promise in the contract: all observable behaviors of your system will be depended upon by somebody.
With a sufficient number of users of an API, it does not matter what you promise in the contract: all observable behaviors of your system will be depended upon by somebody.
This is why backward compatibility is enforced mechanically (oasdiff), not by intention. Even "internal" details — response field ordering, timing, error message wording — become implicit contracts once consumers depend on them. Assume every observable behavior has a consumer.
Implication: changes that feel safe ("just reformatting the response", "just changing the error message") can break consumers. Run oasdiff and check usage metrics regardless.
| Tier | File | Behaviour |
|---|---|---|
v0 / experimental | v0.yaml | Breaking changes allowed; document in info.description; skip oasdiff enforcement |
v1+ / stable | v1.yaml, v2.yaml, ... | Backward compat enforced by oasdiff in CI |
| deprecated | any | deprecated: true on operations; Sunset header; planned removal date |
Is the API still experimental (v0)?
├─ Yes → edit v0.yaml; breaking changes fine; no compat check required
└─ No ↓
Is the change backward compatible?
├─ Yes → bump info.version in vN.yaml; commit
└─ No → try expand-contract first
├─ Expand-contract works → stay on vN.yaml; bump minor
└─ Cannot avoid breaking change → create v(N+1).yaml
Three phases, spread across multiple releases:
This avoids creating a new major version file in most cases. Start here.
When expand-contract does NOT apply:
In these cases, your options are:
api/
myservice/
v1.yaml # served at /v1/...
v2.yaml # served at /v2/...
Each version serves its own openapi.json:
GET /v1/openapi.json → the v1 specGET /v2/openapi.json → the v2 specThe version prefix is part of the path, not a header. Generate separate clients per version.
deprecated: true to the affected operations in the spec.Sunset header (RFC 8594) to responses, with the planned removal date.info.description.410 Gone (not 404) — consumers can distinguish deliberate removal from "resource never existed".docs/agent-integration.md — not just in the spec. Agents reading only the spec might miss the intent to deprecate.410 Gone after removal is not optional — returning 404 silently lies to the agent about what was possible.Sunset header404 after removing an endpoint (use 410 Gone)Searches MemPalace before answering questions about past work, people, projects, or prior decisions. Returns verbatim stored content instead of guessing from model memory.
Guides Payload CMS config (payload.config.ts), collections, fields, hooks, access control, APIs. Debugs validation errors, security, relationships, queries, transactions, hook behavior.
Implements vector databases with Pinecone, Weaviate, Qdrant, Milvus, pgvector for semantic search, RAG, recommendations, and similarity systems. Optimizes embeddings, indexing, and hybrid search.
npx claudepluginhub u-abramchuk/skills --plugin api-first