At some point your application will need to handle errors returned from the API. Below are the details of how we structure our error responses and the conventions we use. We have tried to provide a simple set of errors that can be handled easily whilst allowing some endpoints to also specify more granular error codes. These enable applications to handle different error cases gracefully depending on context to provide the best user experience possible in each case.

HTTP Codes

The API will return one of the below HTTP status codes along with the JSON error response. Your app should detect these and act accordingly.

  • 200 - Request was successful
  • 400 - Request failed due to client error, e.g. validation failed or User not found
  • 429 - Rate limit reached or service overloaded see Rate Limits
  • 500 - Our servers encountered an internal error, try again
  • 503 - Our servers are currently unavailable, try again later. This is normally due to planned or emergency maintenance.

We suggest that your client treats anything that is >= 400 as an error.

Note: If you receive a 500 error it is reasonable for your client to retry that request for a maximum of three retires. We allow for a certain amount of failure within our cluster so retrying is expected.

JSON Error Format

In addition to the HTTP status, the response body will also contain a JSON error structure giving more details about the error.

JSON Error Keys

  • error - The error type
  • error_description - The error message. You should NOT parse this as it may change, use error or error_code for conditional logic within your app
  • error_details - (Optional) For validation errors, this will be a key/value map containing error information for each field
  • error_code - (Optional) An additional endpoint specific error code

Example Error

    "error": "invalid_request",
    "error_description": "Request field validation failed.",
    "error_details": {
        "username": "username is required"

Error Types

The error key in the JSON error will be one of the following strings.

  • invalid_request - General error
  • unauthorized - Access denied to endpoint or one of its resources
  • unverified_account - Email address must be verified to access endpoint
  • server_error - Server error, try again later
  • version_error - The requested version does not exist

Note: some older endpoints do use additional error strings, these will be deprecated and slowly replaced over time. You can find more information about any differences on the specific endpoints documentation.

Additional Error Codes

Some endpoints may provide additional error codes so your application can provide fine grained handling of the error states. Each endpoint will define any additional codes in its documentation, all codes start from zero and are specific to that particular endpoint.

Example Error With Additional Code

  "error": "invalid_request",
  "error_description": "User not found",
  "error_code": 0

403 Errors

If you recieve 403 errors that contain an HTML response rather than JSON, please ensure your client is sending a User Agent header and using HTTP compression for the request, we reject any requests not meeting this requirement.

Rate Limits

Currently we do not operate a fixed request limit for a client, instead we have adaptive rate limiting, allowing short bursts of activity but preventing clients from making requests at a rate that will affect other users or our API's stability.

When a client triggers the adaptive rate limit we will return a 429 HTTP status. The client should handle this error and treat it as a request to slow down its request rate. You may also recieve rate errors if our backend systems are overloaded and cannot accept anymore requests, again when this happens clients should back off their requests for a period.

The client must choose how to handle rate errors, it may be appropriate to show an error message to the user suggesting that the service is temporarily unavailable.

In general, regardless of whether the client automatically retries requests or relies on user re-trying the action, the client should keep track of these failures and implement an exponential backoff. For example, you might retry after 1 second. If that still returns 429, then you should wait 2 seconds before the next request and then 4 etc. If the client keeps on issuing requests at the same or even a lower fixed rate, it's likely that it will take much longer to get back to a state where your requests are not limited.


If your client does not include the major version (E.g. /v1/) in the URI of the endpoint, your client will be automatically locked to V1.0 and the API will return legacy (pre versioning May 2014) errors. These errors will be marked as deprecated in the documentation for the endpoint.