Designs REST APIs, GraphQL schemas, OpenAPI specs, webhook systems, and API versioning strategies. Use when a founder or team needs to design or document an API before building it, create an OpenAPI/Swagger spec, design a webhook system, plan API versioning, or build developer-facing APIs. Trigger for "design an API", "API spec", "OpenAPI", "REST vs GraphQL", "webhook design", "API versioning", "developer API", or "document my endpoints". Part of the Founder OS suite — the API contract layer that connects frontend and backend.
Great APIs are designed before they are built. The contract between frontend and backend — and between your product and other developers — should be explicit, versioned, and stable.
# Resources are nouns, never verbs
GET /api/v1/users ✓
GET /api/v1/getUsers ✗
# Nested resources show relationships
GET /api/v1/users/:id/posts ✓
GET /api/v1/getUserPosts ✗
# Actions that don't fit CRUD use sub-resources
POST /api/v1/users/:id/activate ✓
POST /api/v1/activateUser ✗
| Method | Action | Success Code | Body |
|---|---|---|---|
| GET | Fetch resource(s) | 200 | Response data |
| POST | Create resource | 201 |
| Created resource |
| PUT | Replace resource | 200 | Updated resource |
| PATCH | Update fields | 200 | Updated resource |
| DELETE | Remove resource | 204 | Empty |
// Always use this shape — never break it
interface ApiResponse<T> {
success: boolean;
data?: T;
error?: {
code: string; // Machine-readable: "USER_NOT_FOUND"
message: string; // Human-readable: "No user with that ID exists"
field?: string; // For validation errors: "email"
};
meta?: {
total: number; // For paginated lists
page: number;
limit: number;
hasMore: boolean;
};
}
// Success example
{ "success": true, "data": { "id": "123", "name": "Alice" } }
// Error example
{ "success": false, "error": { "code": "VALIDATION_ERROR", "message": "Email is invalid", "field": "email" } }
// Paginated list
{ "success": true, "data": [...], "meta": { "total": 500, "page": 2, "limit": 20, "hasMore": true } }
HTTP 400 — Bad Request → Validation errors, malformed input
HTTP 401 — Unauthorized → Not authenticated (no/invalid token)
HTTP 403 — Forbidden → Authenticated but not permitted
HTTP 404 — Not Found → Resource doesn't exist
HTTP 409 — Conflict → Duplicate, state conflict
HTTP 422 — Unprocessable → Semantically invalid (valid JSON, bad business logic)
HTTP 429 — Too Many Requests → Rate limit hit
HTTP 500 — Internal Error → Something broke on server side