API Design
Use this skill to turn a vague integration idea, backend feature, or service boundary into a stable API contract that other skills can build on.
The job is not to generate pretty docs. The job is to:
- choose the right API style for the problem
- define resources, operations, inputs, outputs, and failure semantics
- make compatibility and versioning decisions explicit
- produce a contract artifact that implementation, testing, and documentation can share
- surface tradeoffs before the team hardens the wrong interface
Read references/contract-review-checklist.md and references/boundary-guide.md before handling unusual or high-risk API work.
If the user mainly needs:
- reference docs, tutorials, example-heavy guides, or doc portal setup → use
api-documentation
- auth implementation or token/session configuration → use
authentication-setup
- contract/integration test strategy → use
backend-testing
- schema/index/storage design → use
database-schema-design
When to use this skill
- Design a new REST API, GraphQL schema, or internal service contract
- Refactor an existing API without breaking clients unnecessarily
- Review naming, resource boundaries, status codes, pagination, filtering, idempotency, or error models
- Produce an OpenAPI or GraphQL SDL contract before implementation starts
- Evaluate versioning and backward-compatibility decisions
- Decide whether an API should stay REST, move to GraphQL, or expose both layers deliberately
- Prepare an implementation-ready contract packet for backend, frontend, QA, or partner teams
When not to use this skill
- The main task is building interactive docs, SDK docs, onboarding guides, or example portals → use
api-documentation
- The main task is writing server code, auth middleware, resolvers, or persistence logic
- The main task is database normalization, indexing, or storage-model optimization → use
database-schema-design
- The request is mainly test planning or contract-test coverage → use
backend-testing
- There is not enough clarity yet to define the API shape honestly; in that case define the open questions and a design spike instead of faking certainty
Instructions
Step 1: Frame the contract problem
Capture the design inputs before inventing endpoints.
Record:
- users or systems calling the API
- business action or job to be done
- domain entities and ownership boundaries
- existing clients or migrations that constrain compatibility
- sensitivity/security requirements
- expected scale patterns: reads, writes, fan-out, pagination, burstiness
- artifact format requested: OpenAPI, GraphQL SDL, endpoint table, or design memo
If the request is underspecified, state the missing assumptions explicitly inside the design packet.
Step 2: Choose the interface style deliberately
Do not default to a style out of habit.
Prefer REST when
- the workflow is resource-centric
- caching, predictable URLs, or simple CRUD-like operations matter
- external clients need stable, conventional HTTP semantics
- you want OpenAPI tooling, mocks, and broad ecosystem compatibility
Prefer GraphQL when
- clients need flexible field selection or combined graph traversal
- frontend teams need to reduce over-fetching/under-fetching across many screens
- the schema is a better shared contract than a fixed endpoint list
- you already have or expect schema-registry / breaking-change checks
Prefer a mixed approach only when
- the responsibilities are clearly different
- the team can explain who consumes which surface and why
- you can avoid duplicated ownership and drift
State the reason for the chosen style. “Because everyone uses it” is not enough.
Step 3: Model resources, operations, and boundaries
For REST:
- define the top-level resources and their ownership boundaries
- choose nouns, not verb endpoints, unless an action endpoint is genuinely clearer
- keep URL structure shallow unless nested resources carry clear parent-child meaning
- list standard operations plus domain-specific actions separately
For GraphQL:
- define the core types, relationships, queries, and mutations
- avoid one giant catch-all mutation surface
- note where pagination, filtering, and field-level authorization apply
- identify schema areas likely to change frequently
For either style:
- mark synchronous vs asynchronous behavior
- identify idempotent vs non-idempotent writes
- call out eventual-consistency or long-running-job behavior if relevant
Step 4: Define the request/response contract
Design the contract, not just the happy path.
Include:
- request shape and required fields
- response shape for success
- pagination or cursor rules
- filtering / sorting semantics
- nullability and defaults
- field naming conventions
- timestamps, IDs, and enum behavior
- partial update behavior
If the API supports both machine-to-machine and frontend clients, note where response shapes or expansion patterns differ.
Step 5: Design auth, errors, and compatibility rules
Capture the operational semantics clients depend on.
Define:
- auth model expectations at the contract level (for example: bearer token required, role checks, tenant scoping)
- common status codes / error categories
- machine-readable error codes
- retry / idempotency expectations
- deprecation and sunset behavior
- compatibility promises: additive-safe, breaking, version-gated, or migration-required
Do not fully implement auth here. Define the contract and hand off detailed setup to authentication-setup when needed.
Step 6: Produce the contract artifact
Pick the lightest artifact that still enables downstream work.
Recommended formats:
- OpenAPI outline for REST contracts and review-heavy environments
- GraphQL SDL sketch for schema-first GraphQL work
- endpoint / operation table for early architecture discussion
- design memo + risk list when the right shape is still being debated
Minimum contract packet:
- chosen style and why
- audience / consumers
- entity or type map
- operations and request/response summary
- auth/error/versioning notes
- open questions / risks
- downstream handoffs
Step 7: Review for breakage and handoff quality
Before finalizing, check:
- would an existing client break?
- are naming and semantics consistent?
- are pagination/filtering rules actually implementable?
- are error states and auth failures explicit enough for frontend/QA/docs work?
- did you accidentally mix contract design with tutorial-writing or server implementation?
Route next steps clearly:
api-documentation for published docs, tutorials, examples, and docs portal setup
backend-testing for contract-test and integration-test planning
authentication-setup for concrete auth implementation
database-schema-design when the storage model needs its own pass
Output format
## API Design Packet: [Name]
### Contract framing
- Style: [REST | GraphQL | mixed-with-justification]
- Consumers: [internal services / frontend app / partners / public developers]
- Primary job: [what the API enables]
### Resource or type model
- [resource/type]: [purpose]
- [resource/type]: [purpose]
### Operations
| Operation | Purpose | Input summary | Output summary | Notes |
|-----------|---------|---------------|----------------|-------|
| [GET/POST/query/mutation] | ... | ... | ... | ... |
### Contract rules
- Auth model: [...]
- Error model: [...]
- Pagination/filtering: [...]
- Versioning / compatibility: [...]
### Risks / open questions
- [...]
### Handoffs
- Documentation: [does `api-documentation` need to turn this into published docs?]
- Testing: [does `backend-testing` need contract/integration coverage?]
- Auth / data model: [adjacent handoffs]
Examples
Example 1: Public REST contract for partner integrations
Input: “Design a partner-facing order status API for ecommerce vendors. We need stable polling, webhook fallback later, and careful versioning.”
Good response shape:
- choose REST because external partners need predictable HTTP semantics
- define
orders and order-events clearly
- specify status transitions, pagination, filtering by updated time, and versioning/deprecation rules
- include machine-readable error codes and idempotent webhook registration expectations
- hand off to
api-documentation for partner docs and examples
Example 2: GraphQL schema for a dashboard client
Input: “We need a dashboard API for projects, deployments, incidents, and alerts. The UI has many views and keeps over-fetching in REST.”
Good response shape:
- justify GraphQL for flexible client reads
- define core types and query/mutation boundaries
- note pagination and authorization at field/query level
- flag likely schema hot spots and breaking-change review needs
- hand off to
backend-testing for contract checks and to api-documentation for example queries
Best practices
- Treat the API contract as a product boundary, not just a code convenience.
- Separate design decisions from documentation publishing.
- Record assumptions and open questions instead of pretending certainty.
- Prefer additive evolution and explicit deprecation over surprise breaking changes.
- Keep rationale visible when choosing REST vs GraphQL.
- Use the smallest artifact that lets downstream teams act.
- Hand off intentionally to adjacent skills instead of bloating this one.
References
1---2name: api-design3description: Design or refactor API contracts for REST and GraphQL systems.4license: Apache-2.05---6789101112131415161718# API Design1920Use this skill to turn a vague integration idea, backend feature, or service boundary into a stable API contract that other skills can build on.2122The job is not to generate pretty docs. The job is to:23- choose the right API style for the problem24- define resources, operations, inputs, outputs, and failure semantics25- make compatibility and versioning decisions explicit26- produce a contract artifact that implementation, testing, and documentation can share27- surface tradeoffs before the team hardens the wrong interface2829Read [references/contract-review-checklist.md](../api-design--references/contract-review-checklist.md) and [references/boundary-guide.md](../api-design--references/boundary-guide.md) before handling unusual or high-risk API work.3031If the user mainly needs:32- **reference docs, tutorials, example-heavy guides, or doc portal setup** → use `api-documentation`33- **auth implementation or token/session configuration** → use `authentication-setup`34- **contract/integration test strategy** → use `backend-testing`35- **schema/index/storage design** → use `database-schema-design`3637## When to use this skill38- Design a new REST API, GraphQL schema, or internal service contract39- Refactor an existing API without breaking clients unnecessarily40- Review naming, resource boundaries, status codes, pagination, filtering, idempotency, or error models41- Produce an OpenAPI or GraphQL SDL contract before implementation starts42- Evaluate versioning and backward-compatibility decisions43- Decide whether an API should stay REST, move to GraphQL, or expose both layers deliberately44- Prepare an implementation-ready contract packet for backend, frontend, QA, or partner teams4546## When not to use this skill47- The main task is building interactive docs, SDK docs, onboarding guides, or example portals → use `api-documentation`48- The main task is writing server code, auth middleware, resolvers, or persistence logic49- The main task is database normalization, indexing, or storage-model optimization → use `database-schema-design`50- The request is mainly test planning or contract-test coverage → use `backend-testing`51- There is not enough clarity yet to define the API shape honestly; in that case define the open questions and a design spike instead of faking certainty5253## Instructions5455### Step 1: Frame the contract problem56Capture the design inputs before inventing endpoints.5758Record:59- users or systems calling the API60- business action or job to be done61- domain entities and ownership boundaries62- existing clients or migrations that constrain compatibility63- sensitivity/security requirements64- expected scale patterns: reads, writes, fan-out, pagination, burstiness65- artifact format requested: OpenAPI, GraphQL SDL, endpoint table, or design memo6667If the request is underspecified, state the missing assumptions explicitly inside the design packet.6869### Step 2: Choose the interface style deliberately70Do not default to a style out of habit.7172#### Prefer REST when73- the workflow is resource-centric74- caching, predictable URLs, or simple CRUD-like operations matter75- external clients need stable, conventional HTTP semantics76- you want OpenAPI tooling, mocks, and broad ecosystem compatibility7778#### Prefer GraphQL when79- clients need flexible field selection or combined graph traversal80- frontend teams need to reduce over-fetching/under-fetching across many screens81- the schema is a better shared contract than a fixed endpoint list82- you already have or expect schema-registry / breaking-change checks8384#### Prefer a mixed approach only when85- the responsibilities are clearly different86- the team can explain who consumes which surface and why87- you can avoid duplicated ownership and drift8889State the reason for the chosen style. “Because everyone uses it” is not enough.9091### Step 3: Model resources, operations, and boundaries92For REST:93- define the top-level resources and their ownership boundaries94- choose nouns, not verb endpoints, unless an action endpoint is genuinely clearer95- keep URL structure shallow unless nested resources carry clear parent-child meaning96- list standard operations plus domain-specific actions separately9798For GraphQL:99- define the core types, relationships, queries, and mutations100- avoid one giant catch-all mutation surface101- note where pagination, filtering, and field-level authorization apply102- identify schema areas likely to change frequently103104For either style:105- mark synchronous vs asynchronous behavior106- identify idempotent vs non-idempotent writes107- call out eventual-consistency or long-running-job behavior if relevant108109### Step 4: Define the request/response contract110Design the contract, not just the happy path.111112Include:113- request shape and required fields114- response shape for success115- pagination or cursor rules116- filtering / sorting semantics117- nullability and defaults118- field naming conventions119- timestamps, IDs, and enum behavior120- partial update behavior121122If the API supports both machine-to-machine and frontend clients, note where response shapes or expansion patterns differ.123124### Step 5: Design auth, errors, and compatibility rules125Capture the operational semantics clients depend on.126127Define:128- auth model expectations at the contract level (for example: bearer token required, role checks, tenant scoping)129- common status codes / error categories130- machine-readable error codes131- retry / idempotency expectations132- deprecation and sunset behavior133- compatibility promises: additive-safe, breaking, version-gated, or migration-required134135Do not fully implement auth here. Define the contract and hand off detailed setup to `authentication-setup` when needed.136137### Step 6: Produce the contract artifact138Pick the lightest artifact that still enables downstream work.139140Recommended formats:141- **OpenAPI outline** for REST contracts and review-heavy environments142- **GraphQL SDL sketch** for schema-first GraphQL work143- **endpoint / operation table** for early architecture discussion144- **design memo + risk list** when the right shape is still being debated145146Minimum contract packet:147- chosen style and why148- audience / consumers149- entity or type map150- operations and request/response summary151- auth/error/versioning notes152- open questions / risks153- downstream handoffs154155### Step 7: Review for breakage and handoff quality156Before finalizing, check:157- would an existing client break?158- are naming and semantics consistent?159- are pagination/filtering rules actually implementable?160- are error states and auth failures explicit enough for frontend/QA/docs work?161- did you accidentally mix contract design with tutorial-writing or server implementation?162163Route next steps clearly:164- `api-documentation` for published docs, tutorials, examples, and docs portal setup165- `backend-testing` for contract-test and integration-test planning166- `authentication-setup` for concrete auth implementation167- `database-schema-design` when the storage model needs its own pass168169## Output format170171```markdown172## API Design Packet: [Name]173174### Contract framing175- Style: [REST | GraphQL | mixed-with-justification]176- Consumers: [internal services / frontend app / partners / public developers]177- Primary job: [what the API enables]178179### Resource or type model180- [resource/type]: [purpose]181- [resource/type]: [purpose]182183### Operations184| Operation | Purpose | Input summary | Output summary | Notes |185|-----------|---------|---------------|----------------|-------|186| [GET/POST/query/mutation] | ... | ... | ... | ... |187188### Contract rules189- Auth model: [...]190- Error model: [...]191- Pagination/filtering: [...]192- Versioning / compatibility: [...]193194### Risks / open questions195- [...]196197### Handoffs198- Documentation: [does `api-documentation` need to turn this into published docs?]199- Testing: [does `backend-testing` need contract/integration coverage?]200- Auth / data model: [adjacent handoffs]201```202203## Examples204205### Example 1: Public REST contract for partner integrations206**Input:** “Design a partner-facing order status API for ecommerce vendors. We need stable polling, webhook fallback later, and careful versioning.”207208**Good response shape:**209- choose REST because external partners need predictable HTTP semantics210- define `orders` and `order-events` clearly211- specify status transitions, pagination, filtering by updated time, and versioning/deprecation rules212- include machine-readable error codes and idempotent webhook registration expectations213- hand off to `api-documentation` for partner docs and examples214215### Example 2: GraphQL schema for a dashboard client216**Input:** “We need a dashboard API for projects, deployments, incidents, and alerts. The UI has many views and keeps over-fetching in REST.”217218**Good response shape:**219- justify GraphQL for flexible client reads220- define core types and query/mutation boundaries221- note pagination and authorization at field/query level222- flag likely schema hot spots and breaking-change review needs223- hand off to `backend-testing` for contract checks and to `api-documentation` for example queries224225## Best practices2261. Treat the API contract as a product boundary, not just a code convenience.2272. Separate design decisions from documentation publishing.2283. Record assumptions and open questions instead of pretending certainty.2294. Prefer additive evolution and explicit deprecation over surprise breaking changes.2305. Keep rationale visible when choosing REST vs GraphQL.2316. Use the smallest artifact that lets downstream teams act.2327. Hand off intentionally to adjacent skills instead of bloating this one.233234## References235- [OpenAPI Specification](https://swagger.io/specification/)236- [GraphQL Best Practices](https://graphql.org/learn/best-practices/)237- [Microsoft REST API Guidelines](https://github.com/microsoft/api-guidelines)238- [Zalando RESTful API Guidelines](https://opensource.zalando.com/restful-api-guidelines/)239- [Architectural Decision Records](https://adr.github.io/)