Errors and Rate Limits
The Crewsum customer API uses HTTP status codes to show whether a request succeeded. Error responses have a JSON body with a message that describes the problem.
Status codes
Section titled “Status codes”| Status | Meaning |
|---|---|
200 OK | The request succeeded. |
201 Created | The request succeeded. Some create endpoints use this status. Each endpoint page gives its success status. |
400 Bad Request | The request is not correct, for example a required value is missing, or the body is not valid JSON. |
404 Not Found | The record does not exist, or the URL does not match an endpoint. |
409 Conflict | The request conflicts with the current data. Only some endpoints use this status. |
429 Too Many Requests | You sent too many requests. See Rate limits. |
500 Internal Server Error | Authentication failed, or the request could not be completed. Read the message. |
Each endpoint page lists the errors that the endpoint returns.
Error response bodies
Section titled “Error response bodies”Error responses use one of two JSON shapes.
Endpoint errors
Section titled “Endpoint errors”Errors from an endpoint have a message:
{ "message": "Client not found: client-doesnotexist"}Some error responses also include an internalError field. It is for Crewsum diagnostics. Do not rely on its contents.
Request and authentication errors
Section titled “Request and authentication errors”Errors that the API server returns outside an endpoint have statusCode, error, and message. Authentication errors, rate limit errors, request body parse errors, unknown URLs, and unexpected server errors use this shape:
{ "statusCode": 500, "error": "Internal Server Error", "message": "Insufficient scopes, this endpoint requires the following scopes: projects:read"}Some of these errors also include a code, such as FST_ERR_CTP_INVALID_JSON_BODY.
To handle both shapes, check the HTTP status, and then read message.
Authentication and scope errors
Section titled “Authentication and scope errors”All of these errors currently return status 500 with the request error shape.
message | Cause | What to do |
|---|---|---|
The x-api-key header missing or in an incorrect format | The x-api-key header is missing. | Send the key in the x-api-key header. A Bearer token in Authorization is not accepted. |
The provided api key was not found | The key does not exist, was deleted, or is not complete. | Check that you send the full key. If the key was deleted, generate a new one. |
The provided api key could not be validated | The key has a valid format but the secret part is wrong. | Check that you copied the full key correctly. |
Insufficient scopes, this endpoint requires the following scopes: <scope> | The key does not have the scope that the endpoint requires. | Generate a key that has this scope. See Scopes. |
An internal error has occurred. please try again later | Crewsum could not check the key or the subscription. | Retry later. If it continues, contact Crewsum. |
Subscription errors
Section titled “Subscription errors”The API requires an active Crewsum subscription. A trial counts as active.
message | Cause |
|---|---|
An active Crewsum subscription was not found. | Your Crewsum account has no subscription. |
Your subscription is currently inactive, please resume your subscription to use this api. | Your Crewsum subscription is inactive. |
Both return status 500. A Tenant Admin can manage the subscription in the Crewsum app.
Request body errors
Section titled “Request body errors”| Status | Body | Cause |
|---|---|---|
400 | {"statusCode": 400, "code": "FST_ERR_CTP_INVALID_JSON_BODY", "error": "Bad Request", "message": "Body is not valid JSON but content-type is set to 'application/json'"} | The body is not valid JSON. |
400 | {"statusCode": 400, "code": "FST_ERR_CTP_EMPTY_JSON_BODY", "error": "Bad Request", "message": "Body cannot be empty when content-type is set to 'application/json'"} | Content-Type: application/json is set, but the body is empty. |
400 | {"message": "Error parsing body"} | The body does not match the schema. Only the contacts endpoints check the body schema. |
500 | Varies | A required field is missing or has the wrong type, or the Content-Type header is missing. |
Most endpoints do not check the request body against a schema before they process it. A missing or wrong field often returns 500 instead of 400, and an unexpected value can be saved as sent. Send the fields and types shown on each endpoint page, and always set Content-Type: application/json.
Rate limits
Section titled “Rate limits”The API allows 1,000 requests per minute for each IP address. The limit applies to all endpoints together.
Responses to requests that pass authentication include these headers:
| Header | Description |
|---|---|
x-ratelimit-limit | The number of requests allowed in each one-minute window (1000). |
x-ratelimit-remaining | The number of requests left in the current window. |
x-ratelimit-reset | The number of seconds until the window resets. |
When you go over the limit, the API returns 429 and a retry-after header with the number of seconds to wait:
HTTP/1.1 429 Too Many Requestsx-ratelimit-limit: 1000x-ratelimit-remaining: 0x-ratelimit-reset: 23retry-after: 23content-type: application/json; charset=utf-8
{"statusCode":429,"error":"Too Many Requests","message":"Rate limit exceeded, retry in 23 seconds"}Handle errors in your integration
Section titled “Handle errors in your integration”429: wait for the number of seconds inretry-after, and then send the request again.500with an authentication, scope, or subscription message: do not retry. Fix the key, its scopes, or the subscription first.- Other
500errors: a retry can succeed. Before you retry aPOST, check whether the first request created the record, so that you do not create it twice. 400and404: do not retry without changing the request.- Log the status and
messageof each failed request. They help Crewsum support find the problem.