Skip to content

Errors

A request that fails is answered with an error status and a single error object:

{
"error": {
"type": "invalid_request_error",
"code": "not_found",
"message": "No customer in this project is identified by `stripe:cus_QX7bN2kLp4Rt9v`."
}
}
  • type is the class of failure.
  • code says what went wrong, and is stable enough to branch on.
  • message explains it in a sentence that is safe to show a person.
  • param names the input at fault, when the failure is about one. It is absent otherwise.

Statuses

Status Type When
400 invalid_request_error An input is missing, has a value it cannot take, or is not one the endpoint takes. param names it.
401 authentication_error The request carries no API key, or one that is mistyped or revoked.
403 permission_error The key may not do this: its role is too low, or a scope header names another project.
404 invalid_request_error The path does not exist, or what it or an input names does not exist in the project.
409 invalid_request_error Another write to the same record got there at the same moment.
429 rate_limit_error A rate limit was reached. See Rate limits.
500 api_error Something went wrong on our side. Retry later.

A 409 with the code conflict can happen on any write. Nothing was saved, and the same request can simply be sent again.

Any request can fail in these ways, so an endpoint’s page does not list them again. What an endpoint requires — which source may change a field, say — is in its description and its fields’, and a request that does not follow it is refused.

More than one problem

When more than one thing was wrong, such as two invalid fields in one body, every one of them is listed in error.errors, each with its own type, code, message and param. The fields of error itself are the first of them, so a client that reads only those still reads a real error:

{
"error": {
"type": "invalid_request_error",
"code": "invalid",
"message": "`maintainer` is not one of `viewer`, `writer`, `admin`, `owner`",
"param": "project_role",
"errors": [
{"type": "invalid_request_error", "code": "invalid", "message": "`maintainer` is not one of `viewer`, `writer`, `admin`, `owner`", "param": "project_role"},
{"type": "invalid_request_error", "code": "required", "message": "`name` is required.", "param": "name"}
]
}
}

Codes

The codes an integration most often has reason to branch on:

  • not_found (404): what the path or an input names does not exist in the project.
  • conflict (409): another write got there first. Send the request again.
  • not_the_owner (400): the record lives in another source. See Sources and ownership.
  • required, invalid and unknown_parameter (400): an input is missing, has a value it cannot take, or is not one the endpoint takes.
  • invalid_api_key (401): the key is mistyped or has been revoked.
  • outside_key_scope (403): a scope header names a project or an organization other than the key’s.
  • forbidden (403): the key’s role does not allow this.
  • requests_per_second, analytics_requests_per_minute and concurrent_analytics_requests (429): the rate limit reached.