API Design & Integration
Use this skill for REST, GraphQL, and third-party integrations when you need stable contracts and operable behavior.
Priorities
- Clear contract
- Backward compatibility
- Validation and safety
- Observability
- Performance
Contract Rules
1. Design the contract before the handler
- Start from the consumer-facing shape: paths, fields, mutations, errors, pagination, auth, and compatibility rules.
- If the repo uses OpenAPI, schema files, generated clients, or GraphQL SDL, update the contract source first.
- Keep the contract smaller than the implementation would naturally drift toward.
2. Use resource-oriented shapes
For REST:
- prefer nouns over verbs
- use standard methods where semantics are clear
- keep nested resources shallow
For GraphQL:
- expose explicit object types and input types
- avoid catch-all fields that return overly generic blobs
- keep mutations specific and auditable
3. Preserve compatibility by default
- Additive changes are safer than breaking ones.
- Renaming, removing, or changing semantics requires an explicit migration plan.
- If a response field is optional, define when and why it may be absent.
- Do not overload one field with multiple meanings across versions or callers.
Request / Response Rules
4. Validate all external input
Validate:
- path params
- query params
- headers
- request bodies
- webhook payloads
- third-party responses before mapping them into domain models
Return validation failures in a stable, structured way.
5. Use a consistent error envelope
Errors should be:
- machine-readable
- safe to expose
- stable enough for clients to act on
Prefer a structure that includes:
- code
- user-safe message
- optional field/details metadata
- request or trace ID when available
Do not leak internal stack traces or provider-specific raw failures to clients.
6. Make success and async semantics explicit
- Use
200/201/204 deliberately for REST.
- Use idempotency for retry-prone create/side-effect operations when needed.
- For async work, make polling, callback, or event-driven completion explicit.
- Do not hide eventual consistency behind a synchronous-looking contract.
Collection Rules
7. Be explicit about pagination, filtering, and sorting
- Large collections should paginate by default.
- Prefer cursor pagination for unstable or large datasets.
- Keep filtering and sorting syntax consistent across related endpoints.
- Document default sort order and limits.
Auth / Safety Rules
8. Treat auth and authorization as part of the contract
- Define who can call the endpoint and under which conditions.
- Check authorization close to the business action, not only at the routing layer.
- Keep scopes/roles coarse enough to reason about, but not so coarse they become unsafe.
9. Protect the API operationally
- apply sensible timeouts
- rate-limit abuse-prone endpoints
- make retries safe before adding them
- log provider failures with enough context to debug
- add trace/request IDs where the stack supports them
Third-Party Integration Rules
10. Isolate external providers
- Wrap providers behind a local adapter or service boundary.
- Normalize provider-specific payloads before they reach the rest of the app.
- Define timeout, retry, and error-mapping policy explicitly.
- Circuit breakers and retry loops are useful only when the side effects are understood.
GraphQL-Specific Rules
- Avoid N+1 query patterns in resolvers.
- Separate read models from write inputs.
- Use explicit pagination types for list fields.
- Keep resolver logic thin; business rules belong in services/domain logic.
Review Heuristics
Look for:
- breaking contract changes without migration plan
- inconsistent error shapes
- missing validation at boundaries
- missing pagination on potentially large collections
- auth checks that are too early, too late, or missing
- unsafe retries on non-idempotent operations
- provider-specific details leaking into domain contracts
Anti-Patterns
Avoid:
- action-style REST paths when resources would be clearer
- one endpoint doing multiple unrelated operations
- stringly typed error handling
- undocumented optional behavior
- passing third-party payloads straight through to clients without normalization
- hiding expensive joins or fan-out calls behind innocent-looking fields
Quick Checklist
1---2name: api-design3description: Practical rules for designing, evolving, and integrating APIs safely.4license: See repository LICENSE5---67# API Design & Integration89Use this skill for REST, GraphQL, and third-party integrations when you need stable contracts and operable behavior.1011## Priorities12131. **Clear contract**142. **Backward compatibility**153. **Validation and safety**164. **Observability**175. **Performance**1819## Contract Rules2021### 1. Design the contract before the handler2223- Start from the consumer-facing shape: paths, fields, mutations, errors, pagination, auth, and compatibility rules.24- If the repo uses OpenAPI, schema files, generated clients, or GraphQL SDL, update the contract source first.25- Keep the contract smaller than the implementation would naturally drift toward.2627### 2. Use resource-oriented shapes2829For REST:3031- prefer nouns over verbs32- use standard methods where semantics are clear33- keep nested resources shallow3435For GraphQL:3637- expose explicit object types and input types38- avoid catch-all fields that return overly generic blobs39- keep mutations specific and auditable4041### 3. Preserve compatibility by default4243- Additive changes are safer than breaking ones.44- Renaming, removing, or changing semantics requires an explicit migration plan.45- If a response field is optional, define when and why it may be absent.46- Do not overload one field with multiple meanings across versions or callers.4748## Request / Response Rules4950### 4. Validate all external input5152Validate:5354- path params55- query params56- headers57- request bodies58- webhook payloads59- third-party responses before mapping them into domain models6061Return validation failures in a stable, structured way.6263### 5. Use a consistent error envelope6465Errors should be:6667- machine-readable68- safe to expose69- stable enough for clients to act on7071Prefer a structure that includes:7273- code74- user-safe message75- optional field/details metadata76- request or trace ID when available7778Do not leak internal stack traces or provider-specific raw failures to clients.7980### 6. Make success and async semantics explicit8182- Use `200/201/204` deliberately for REST.83- Use idempotency for retry-prone create/side-effect operations when needed.84- For async work, make polling, callback, or event-driven completion explicit.85- Do not hide eventual consistency behind a synchronous-looking contract.8687## Collection Rules8889### 7. Be explicit about pagination, filtering, and sorting9091- Large collections should paginate by default.92- Prefer cursor pagination for unstable or large datasets.93- Keep filtering and sorting syntax consistent across related endpoints.94- Document default sort order and limits.9596## Auth / Safety Rules9798### 8. Treat auth and authorization as part of the contract99100- Define who can call the endpoint and under which conditions.101- Check authorization close to the business action, not only at the routing layer.102- Keep scopes/roles coarse enough to reason about, but not so coarse they become unsafe.103104### 9. Protect the API operationally105106- apply sensible timeouts107- rate-limit abuse-prone endpoints108- make retries safe before adding them109- log provider failures with enough context to debug110- add trace/request IDs where the stack supports them111112## Third-Party Integration Rules113114### 10. Isolate external providers115116- Wrap providers behind a local adapter or service boundary.117- Normalize provider-specific payloads before they reach the rest of the app.118- Define timeout, retry, and error-mapping policy explicitly.119- Circuit breakers and retry loops are useful only when the side effects are understood.120121## GraphQL-Specific Rules122123- Avoid N+1 query patterns in resolvers.124- Separate read models from write inputs.125- Use explicit pagination types for list fields.126- Keep resolver logic thin; business rules belong in services/domain logic.127128## Review Heuristics129130Look for:131132- breaking contract changes without migration plan133- inconsistent error shapes134- missing validation at boundaries135- missing pagination on potentially large collections136- auth checks that are too early, too late, or missing137- unsafe retries on non-idempotent operations138- provider-specific details leaking into domain contracts139140## Anti-Patterns141142Avoid:143144- action-style REST paths when resources would be clearer145- one endpoint doing multiple unrelated operations146- stringly typed error handling147- undocumented optional behavior148- passing third-party payloads straight through to clients without normalization149- hiding expensive joins or fan-out calls behind innocent-looking fields150151## Quick Checklist152153- [ ] Contract shape is explicit and reviewable154- [ ] Compatibility impact is understood155- [ ] Inputs are validated at the boundary156- [ ] Error responses are structured and safe157- [ ] Pagination/filtering/sorting rules are defined where needed158- [ ] Auth and authorization are explicit159- [ ] Integration timeouts/retries/error mapping are defined160- [ ] Observability is good enough to debug production issues