Errors

The SpeyBooks API uses conventional HTTP status codes to indicate the outcome of a request. Codes in the 2xx range indicate success, codes in the 4xx range indicate a problem with the request, and codes in the 5xx range indicate an issue on our end.

Error response format

Every error response follows a consistent envelope. The code field is a machine-readable string you can match against in your code. The message field is a human-readable explanation suitable for logging — it should not be displayed directly to end users.

HTTP status codes

Status Meaning
200 Success — the request completed normally
201 Created — a new resource was created
204 No Content — the request succeeded with no response body
400 Bad Request — the request was malformed or contained invalid parameters
401 Unauthorized — no valid authentication credentials were provided
403 Forbidden — the credentials are valid but lack permission for this action
404 Not Found — the requested resource does not exist
409 Conflict — the request conflicts with the current state of a resource
422 Unprocessable Entity — the request was well-formed but failed business logic validation
429 Too Many Requests — you have exceeded the rate limit
500 Internal Server Error — something went wrong on our end

Error codes

Code Status Description
validation_error 400 One or more fields failed validation. Check the message for details.
invalid_id 400 The ID does not match the expected format. SpeyBooks uses prefixed IDs — for example, inv_42 for invoices, cont_3 for contacts.
not_found 404 The resource does not exist, or it belongs to a different organisation.
unauthorized 401 The request lacks valid authentication. Either the session has expired, the API key is missing, or the token is invalid.
forbidden 403 Authentication succeeded but the credentials lack the required scope.
insufficient_scope 403 The API key does not have the required scope for this endpoint. The message field indicates which scope is needed.
conflict 409 The action conflicts with the current state of the resource — for example, deleting a finalised invoice.
unprocessable_entity 422 The request is syntactically valid but violates a business rule — for example, declaring a dividend that exceeds retained profits.
rate_limited 429 Too many requests. Back off and retry after the period indicated in the Retry-After header.
internal_error 500 An unexpected error on our side. If this persists, contact support with the request timestamp and endpoint.

Idempotency errors

When using the Idempotency-Key header, two additional scenarios can occur. If you reuse a key with different request parameters, the API returns a 409 Conflict. If the original request failed with a 5xx error, the key is released and can be retried. Keys expire after 24 hours.

Handling errors

For robust integration, your client should:

  1. Always check the success field before accessing data.
  2. Match on the error.code string for programmatic handling, not the HTTP status code alone — multiple error codes can share the same status.
  3. Log the full error response including code and message for debugging.
  4. Implement exponential backoff for 429 and 5xx responses.
  5. Never display error.message directly to end users — it is intended for developers and may change between releases.