api-design · git:20261025.8aa06bd · 2026-10-25 · sha256 b9df47b913a3925b
api-design git:20261025.8aa06bdA
Immutable. This exact content never changes and is served at /api/v1/blob/b9df47b913a3925b.
---
name: api-design
description: API contract design and OpenAPI 3.1 specification skill. Enforces RFC 7807 problem details, idempotency headers, and consistent status codes.
---
# API Contract Design & OpenAPI 3.1 (`/api-design`)
> **Philosophy**: *APIs are permanent contracts. Design first. Standardize errors with RFC 7807. Enforce idempotency on state-changing operations. Paginate with cursors, never unbounded offsets.*
This skill establishes API contract standards, RESTful resource modeling, OpenAPI 3.1 specifications, uniform error semantics, and backward-compatibility rules.
---
## 1. RESTful Contract Architecture
```mermaid
flowchart LR
A["Client Request (+ Idempotency-Key)"] --> B["OpenAPI 3.1 Route Definition"]
B --> C["Strict Schema Parser (Fail-Fast)"]
C --> D{"Success?"}
D -- "Yes" --> E["200 OK / 201 Created (Envelope + Pagination)"]
D -- "No" --> F["RFC 7807 Problem Details (application/problem+json)"]
```
---
## 2. Core API Contract Standards
### 2.1 RFC 7807 Problem Details Error Envelope
Every error response must use Content-Type `application/problem+json`:
```json
{
"type": "https://api.example.com/errors/resource-not-found",
"title": "Resource Not Found",
"status": 404,
"detail": "User with ID 'usr_01HXYZ...' does not exist in the tenant workspace.",
"instance": "/v1/users/usr_01HXYZ...",
"code": "USER_NOT_FOUND",
"timestamp": "2026-10-25T14:00:00Z"
}
```
### 2.2 Cursor-Based Pagination Standard
Never implement unbounded queries or naive offset-based pagination (`OFFSET 10000`) for large collections. Use cursor pagination:
```json
{
"data": [
{ "id": "usr_01H1", "name": "Alice", "created_at": "2026-10-25T12:00:00Z" },
{ "id": "usr_01H2", "name": "Bob", "created_at": "2026-10-25T11:45:00Z" }
],
"pagination": {
"limit": 20,
"has_more": true,
"next_cursor": "ZXlKaGJHY2lPaUpTVXpVeE5pSXNJblI1Y0NJNklrcFhWQ0o5..."
}
}
```
- Query Parameters: `?limit=20&cursor=<opaque_base64_string>`
- Cursor encoding: Opaque Base64 of `(sort_value, id)` tuple to guarantee stable deterministic sorting across insertions.
### 2.3 Idempotency Key Specification
- Header: `Idempotency-Key: <UUIDv4>`
- Required on all payment, checkout, reservation, or email dispatch endpoints.
- Server validates that replayed requests with the same key and same payload return the identical cached response without re-executing side effects.
- If payload differs for the same key, return `422 Unprocessable Entity` (`ERR_IDEMPOTENCY_PAYLOAD_MISMATCH`).
### 2.4 Status Code Hierarchy
- `200 OK`: Successful read or update mutation.
- `201 Created`: Resource created. Must include `Location: /v1/resources/{id}`.
- `204 No Content`: Successful delete with empty body.
- `400 Bad Request`: Schema validation failure.
- `401 Unauthorized`: Missing or expired token.
- `403 Forbidden`: Authenticated caller lacks permissions.
- `404 Not Found`: Target resource does not exist.
- `409 Conflict`: Unique constraint violation or state collision.
- `422 Unprocessable Entity`: Business logic invariant violation.
- `429 Too Many Requests`: Rate limit exhausted. Must include `Retry-After: <seconds>`.
- `500 Internal Server Error`: Server exception. Never leak stack traces.
---
## 3. Deprecation & Sunset Standards
When deprecating an API endpoint or version:
1. Announce deprecation at least 90 days prior to removal.
2. Emit standard HTTP deprecation headers on every response:
- `Deprecation: @1735689600` (Unix timestamp of deprecation announcement)
- `Sunset: Wed, 11 Nov 2026 00:00:00 GMT` (Date of scheduled turn-off)
- `Link: <https://docs.example.com/migrations/v2>; rel="deprecation"`
3. Log usage metrics to identify clients still calling deprecated endpoints.
---
## 4. OpenAPI Specification Validator CLI
Validate OpenAPI 3.1 YAML/JSON specifications against contract rules:
```bash
python3 skills/api-design/scripts/validate_openapi_spec.py --spec openapi.yaml
```
Verifies:
- All routes have explicit `responses` with status codes.
- Error schemas reference RFC 7807 problem details structure.
- Mutation endpoints support `Idempotency-Key` headers where appropriate.
- Collections enforce pagination parameters.