Default API style is RESTful HTTP with a custom JSON envelope and OpenAPI documentation.
Path-based versioning is used:
/api/v1- Resource names are plural.
- URL segments use kebab-case.
Examples:
/users
/projects
/chat-sessions
/payment-methodsGET: list/detailPOST: create/action with side effectPATCH: partial updatePUT: full replacement onlyDELETE: delete
Single resource:
{
"data": {
"id": "usr_123",
"email": "ali@example.com",
"displayName": "Ali"
},
"meta": {
"requestId": "req_123"
}
}Collection:
{
"data": [],
"pagination": {
"limit": 20,
"nextCursor": null,
"hasNextPage": false
},
"meta": {
"requestId": "req_123"
}
}{
"error": {
"code": "VALIDATION_ERROR",
"message": "Validation failed.",
"details": [
{
"field": "email",
"message": "Email must be valid.",
"code": "INVALID_EMAIL"
}
],
"requestId": "req_123"
}
}400: malformed/structural request401: missing/invalid authentication403: authenticated but not authorized404: not found, or cross-tenant existence hiding409: conflict412: optimistic concurrency mismatch415: unsupported media type422: semantic/domain validation failure429: rate limited500: internal error502: external provider failure503: service unavailable504: upstream timeout
- PATCH is the default partial update method.
- Omitted field means no change.
nullclears value only if nullable.- Empty PATCH body returns
400 EMPTY_UPDATE. - Unknown fields return
400. - Known but disallowed fields return
422. - Successful PATCH returns
200plus updated resource by default.
Cursor pagination is preferred:
GET /api/v1/users?limit=20&cursor=cursor_123&sort=-createdAtCollection endpoints must document supported filters, sorting and search parameters.
Side-effect-producing POST endpoints should support Idempotency-Key, especially for payment, subscription, external API side effects, email/SMS sending and billing-relevant AI generation.
- OpenAPI documentation is generated code-first from Zod schemas and route metadata.
- The OpenAPI version is selected per project based on current stable version and tooling compatibility.
- Main output:
docs/openapi/openapi.yaml - Optional JSON output:
docs/openapi/openapi.json - Protected endpoints must document security definitions.
- Generated OpenAPI must not be stale in CI.