Error Handling
Our API uses standard HTTP status codes to signal errors. Here are the most common ones you'll run into.
Error Codes Overview
| Code | Description |
|---|---|
| 400 | Bad Request - The server cannot process the request due to a client error, such as malformed syntax or invalid parameters. |
| 401 | Unauthorized - The request requires authentication, but the client has not provided valid credentials. |
| 403 | Forbidden - The client does not have permission to access the requested resource. |
| 404 | The server could not find the requested resource. |
| 409 | Conflict - The request conflicts with the current state of the resource, e.g. a duplicate invite or member. |
| 422 | Unprocessable Entity - The request was well-formed but could not be processed due to semantic errors. |
| 429 | Too Many Requests - The client has sent too many requests in a given amount of time (rate limiting). |
| 500 | Internal Server Error - The server encountered an unexpected condition preventing it from fulfilling the request. |
| 501 | Not Implemented - The server does not support the functionality required to fulfill the request. |
| 502 | Bad Gateway - The server received an invalid response from an upstream server while trying to fulfill the request. |
| 503 | Service Unavailable - The server is currently unable to handle the request due to temporary overloading or maintenance. |
| 504 | Gateway Timeout - The server did not receive a timely response from an upstream server or proxy. |
429 Too Many Requests
Rate limiting happens at the infrastructure/ingress layer in front of our API. Treat a 429 as a signal to back off and retry with backoff, but don't rely on specific limits unless we document them separately.
When you encounter an error, the response body includes a detailed explanation. The status code is exposed under a status field. See the 401/403 examples below.
400 Bad Request
You sent a request with a missing or invalid payload. Check the response body for the exact error details.
Examples
Invalid Request with missing property workspaceName:
{
"status": 400,
"instancePath": "",
"schemaPath": "#/required",
"keyword": "required",
"params": {
"missingProperty": "workspaceName"
},
"message": "must have required property 'workspaceName'"
}Invalid request with disallowed additional property myAdditionalProperty:
{
"status": 400,
"instancePath": "",
"schemaPath": "#/additionalProperties",
"keyword": "additionalProperties",
"params": {
"additionalProperty": "myAdditionalProperty"
},
"message": "must NOT have additional properties"
}Requests that pass schema validation but are rejected by business-rule checks use a different, flatter shape. For example, creating a workspace with an invalid workspaceKey:
{
"status": 400,
"message": "WorkspaceKey {workspaceKey} is invalid",
"params": {
"workspaceKey": "invalid key!"
},
"path": "workspaceKey",
"expected": "valid workspaceKey"
}401 Unauthorized
The request requires authentication, or the credentials you provided were rejected.
The response includes the status code under a status field:
{
"status": 401,
"message": "Unauthorized"
}403 Forbidden
The server understood the request but refuses to fulfill it. Re-authenticating won't change that.
The response includes the status code under a status field:
{
"status": 403,
"message": "Forbidden"
}404 Not Found
This typically occurs when the requested URL is invalid, or the resource doesn't exist.
Eventually Consistent Read Models
Our event sourced architecture employs eventually consistent read models. As a result, a POST, PUT, PATCH, or DELETE request may return 200 or 201 right away, but the read models can take a moment to catch up. This delay might cause a subsequent GET request, executed immediately after the mutating request, to encounter an error like 404 or 403.
Example
{
"status": 404,
"message": "Not found"
}500 Internal Server Error
This is a generic error, used when nothing more specific applies.
Example
{
"status": 500,
"message": "Internal Server Error"
}502 Bad Gateway
Our API gateway returns this status when an internal backend service fails in a way that prevents it from fulfilling your request. It covers any unexpected error that doesn't fall under Service Unavailable (503) or Gateway Timeout (504).
Example
{
"status": 502,
"message": "Bad Gateway"
}503 Service Unavailable
Our backend service for this endpoint is (temporarily) unavailable.
Asynchronous Request Processing
Our system uses asynchronous handlers to process requests. Therefore, even if you encounter this error, your request may still be executed asynchronously at a later time.
Example
{
"status": 503,
"message": "Service Unavailable"
}504 Gateway Timeout
Our backend service was unable to handle your request due to a timeout.
Asynchronous Request Processing
Our system uses asynchronous handlers to process requests. Therefore, even if you encounter this error, your request may still be executed asynchronously at a later time.
Example
{
"status": 504,
"message": "Gateway Timeout"
}