From il
Guidance for RESTful API design, versioning, contracts, and error handling conventions
How this skill is triggered — by the user, by Claude, or both
Slash command
/il:api-designThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
Help the user design RESTful APIs with consistent patterns, clear contracts, and proper error handling.
Help the user design RESTful APIs with consistent patterns, clear contracts, and proper error handling.
All APIs at Imagine Learning follow REST conventions and must have an OpenAPI spec before implementation begins.
application/json for all request and response bodiescorrelationId for structured log correlationGET /api/v1/{resource} # List resources
POST /api/v1/{resource} # Create resource
GET /api/v1/{resource}/{id} # Get resource by ID
PUT /api/v1/{resource}/{id} # Replace resource
PATCH /api/v1/{resource}/{id} # Partial update
DELETE /api/v1/{resource}/{id} # Delete resource
/users, not /user)/learning-paths)/users/{id}/enrollments)Not all API operations should be handled in the request/response cycle. When designing endpoints, decide whether the operation should complete synchronously or be offloaded to async processing.
Synchronous (respond immediately):
Asynchronous (accept and process later):
For async operations, use 202 Accepted to acknowledge the request, then process the work via events:
POST /api/v1/sections/{sectionId}/export
→ 202 Accepted
→ { "exportId": "EXP-001", "status": "pending", "statusUrl": "/api/v1/exports/EXP-001" }
The caller can poll the status URL or receive a notification when processing completes.
If an operation triggers work that is a consequence of the primary action — and the caller doesn't need to wait for that work to finish — the API should persist the primary data synchronously and let downstream processing happen asynchronously via events. Refer to the eventing-architect agent for event flow design.
IL uses URL path versioning (/v1/resources, /v2/resources) as the standard. Explicit, discoverable in API docs, and easy to route.
| Strategy | Pros | Cons |
|---|---|---|
URL path (/v1/) | Explicit, easy to route | URL pollution |
Header (Accept-Version) | Clean URLs | Harder to test/discover |
Query param (?version=1) | Easy to add | Easily forgotten |
Increment version only for breaking changes: removing a field, changing a field type, altering behavior of an existing endpoint. Additive changes (new optional fields, new endpoints) do not require a version bump.
Use RFC 7807 Problem Details as the standard error response format:
Standard error:
{
"type": "https://api.imaginelearning.com/problems/resource-not-found",
"title": "Resource Not Found",
"status": 404,
"detail": "No user exists with ID '12345'",
"instance": "/v1/users/12345",
"traceId": "abc-123-def-456"
}
Validation error (multiple fields):
{
"type": "https://api.imaginelearning.com/problems/validation-error",
"title": "Validation Error",
"status": 400,
"detail": "Request body contains invalid fields",
"errors": [
{ "field": "email", "message": "Must be a valid email address" },
{ "field": "birthDate", "message": "Must not be in the future" }
],
"traceId": "abc-123-def-456"
}
| Code | Usage |
|---|---|
| 200 | Successful GET, PUT, PATCH |
| 201 | Successful POST (resource created) |
| 202 | Accepted — async operation queued for processing |
| 204 | Successful DELETE (no content) |
| 400 | Validation error, malformed request |
| 401 | Authentication required |
| 403 | Authenticated but not authorized |
| 404 | Resource not found |
| 409 | Conflict (duplicate, state conflict) |
| 422 | Semantically invalid request |
| 429 | Rate limit exceeded |
| 500 | Internal server error |
Standard Response Envelope:
{ "data": [...], "pagination": { ... } }Required Request Headers:
| Header | Value | Purpose |
|---|---|---|
Content-Type | application/json | Request body format |
Accept | application/json | Expected response format |
traceparent | W3C Trace Context | Distributed tracing propagation |
Tracing and Correlation:
traceparent, tracestate) or B3 headers on all outbound requestscorrelationId in structured logs for every requestobservability skill for full tracing and logging guidancePrefer cursor-based pagination for new APIs. Stable under concurrent writes, performs well at scale, avoids offset consistency issues. Use offset-based only when consumers need arbitrary page jumps (admin/reporting UIs over small, stable datasets).
Standard query parameters: cursor (opaque string), limit (default 25, max 100).
{
"data": [...],
"pagination": {
"nextCursor": "eyJpZCI6MTAwfQ==",
"hasMore": true
}
}
{
"data": [...],
"pagination": {
"offset": 0,
"limit": 25,
"total": 142
}
}
OpenAPI conventions:
components/schemas — avoid inline definitionsdescription on all operations, parameters, and schema propertiesDocumentation requirements:
Deprecation process:
deprecated: true in the OpenAPI specSunset header with the planned removal date on deprecated endpoints| Topic | Where to Go |
|---|---|
| Language and framework selection for backend | backend-architect agent |
| Caching and Cache-Control headers | caching skill |
| Logging, tracing, and SLOs | observability skill |
| DynamoDB data modeling for API-backed resources | dynamodb-table-design skill |
| Micro-frontend BFF patterns | mfe-architecture skill, frontend-architect agent |
| Service deployment and Kubernetes configuration | backend-architect agent |
Before publishing an API:
Sunset header and are marked in the OpenAPI specnpx claudepluginhub imaginelearning/dp-claude-plugin --plugin ilCreates bite-sized, testable implementation plans from specs or requirements, with file structure and task decomposition. Activates before coding multi-step tasks.