Docs

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.

Example 404 response
{
  "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

StatusCodeMeaning
400BAD_REQUESTYour request body, query, or path was invalid — for example a missing required field, an unknown enum value, or an unparseable date.
401UNAUTHORIZEDThe 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.
403FORBIDDENYour 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.
404NOT_FOUNDThe resource ID does not exist, or does not belong to your workspace.
429TOO_MANY_REQUESTSYou have exceeded the request rate limit. See below.
500INTERNAL_SERVER_ERRORSomething 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:

Example 429 response
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.