How the Open API reports errors — HTTP status codes and the JSON error shapes.
The Open API uses conventional HTTP status codes to signal success or failure, and returns errors in a small, predictable set of JSON shapes. A 2xx means success, a 4xx means the request was rejected (something you can fix — bad input, auth, or a business rule), and a 5xx means something went wrong on our side.
Status codes
| Code | Meaning |
|---|---|
200 OK | The request succeeded. |
201 Created | A resource was created (e.g. a payment method or setup intent). |
204 No Content | The request succeeded with no response body (e.g. a delete). |
400 Bad Request | Validation failed, or a business rule rejected the request. |
401 Unauthorized | No authentication token was provided on a protected endpoint. |
403 Forbidden | The token is invalid, expired, or blacklisted. |
404 Not Found | The resource does not exist — or a business rule rejected the request (several endpoints use 404 for domain errors). |
429 Too Many Requests | The request was throttled (e.g. repeated passwordless or login attempts). |
500 Internal Server Error | An unexpected error occurred on our side. |
Error response shapes
Validation errors (400)
400)When one or more fields fail validation, the response contains an errors object keyed by field name, each with an array of messages:
{
"errors": {
"plan_id": ["Plan ID is required"],
"email": ["The email must be a valid email address."]
}
}Application errors (400 / 404)
400 / 404)Business-rule rejections return a single error object with a status and a human-readable message:
{
"error": {
"report_id": null,
"status": 404,
"message": "Invalid plan provided"
}
}Authentication errors (401 / 403)
401 / 403)A protected endpoint called without a token returns 401:
{ "error": { "message": "Token not provided" } }A token that is present but invalid, expired, or blacklisted returns 403:
{
"error": {
"status": 403,
"message": "Authentication token is invalid, please try again"
}
}Server errors (500)
500)Unexpected errors include a report_id you can quote to support so we can trace the incident:
{
"error": {
"report_id": "9b2c1e7a-4f3d-6a2b-8c1d-0e5f7a9b3c2d",
"status": 500,
"message": "Sorry, something went wrong with your request. We are working to resolve this incident as quickly as possible."
}
}
Quotingreport_idWhen you contact support about a
500, include thereport_idfrom the response — it lets us find the exact request in our logs.
Not-found bodiesA few endpoints return an empty body alongside a
404(e.g. a single resource that doesn't exist). Always branch on the status code, not on the presence of a body.

