Errors and rate limits
How the Coassemble API signals failures, the status codes you should plan for, and how to handle rate limits.
Error envelope
Failed requests respond with a JSON body containing a human-readable message and a structured error object. The error object carries a stable code and the HTTP status.
{
"message": "Course not found",
"error": {
"code": "NOT_FOUND",
"status": 404
}
} Prefer error.code for application logic and the HTTP status for transport-level handling.
Common status codes
| Status | Code | Meaning |
|---|---|---|
400 | BAD_REQUEST | Your request body, query, or path was invalid — for example a missing required field, an unknown enum value, or an unparseable date. |
401 | UNAUTHORIZED | The Authorization header was missing, malformed, or did not match an active workspace API key. Send the full COASSEMBLE:<workspaceId>:<secret> value without a Bearer prefix. |
403 | FORBIDDEN | Your workspace or key does not have the access required by this endpoint (e.g. authoring, analytics, advanced, or SCORM). Check the response message and the endpoint's requirements. The setup guide uses your workspace's current access. |
404 | NOT_FOUND | The resource ID does not exist, or does not belong to your workspace. |
429 | TOO_MANY_REQUESTS | You have exceeded the request rate limit. See below. |
500 | INTERNAL_SERVER_ERROR | Something went wrong on our side. Retry idempotent requests with exponential backoff. |
Rate limits
Authenticated requests to /api/v1/headless share a budget of 100 requests per minute per API key, in fixed one-minute windows. Requests without a valid workspace key use an IP-based budget.
When you exceed the budget, the API responds with 429 Too Many Requests and a Retry-After header set to the number of seconds until the window resets:
HTTP/1.1 429 Too Many Requests
Retry-After: 23
X-RateLimit-Limit: 100
X-RateLimit-Remaining: 0
Content-Type: application/json
{
"message": "Over the limit of 100 requests per minute — Retry-After says how long to wait.",
"error": {
"code": "TOO_MANY_REQUESTS",
"status": 429
}
} Respect Retry-After rather than retrying immediately. X-RateLimit-Limit gives the current budget, X-RateLimit-Remaining the requests left, and X-RateLimit-Reset the reset time as a Unix timestamp in seconds.