Errors
Errors raised by the API come back as JSON in this shape.
message is the one to log. displayMessage is safe to show a user. Some errors also carry
debugMessage or a subErrors list when a request failed validation on specific fields.
A request that matches no route at all never reaches the API, so it comes back in the web layer’s own plainer shape. Match on the status code rather than on the body.
401 Unauthorized
The key was missing, unknown, revoked or expired.
Send it as X-Thera-API-Key. Not as a bearer token, and not in the query string.
403 Forbidden
The key is valid but is not allowed to do this.
A key is scoped to one company for its whole life. There is no way to widen it, so if you need another company’s data you need that company’s own key.
404 Not Found
Nothing exists at that ID within your company.
Worth ruling out first: a mistyped path. Routes are flat and have no /api prefix, so it is
/companies/{companyId}/teams, not /api/companies/{companyId}/teams.
429 Too Many Requests
You went over 600 requests a minute.
The response carries a Retry-After header with the number of seconds to wait, and the message
repeats it:
The limit counts each key separately, and 600 is the floor rather than a guarantee, so treat
Retry-After as the thing to obey rather than pacing against the number.
5xx
Something broke on our side, and retrying is reasonable. Retries still count against your rate limit, though, because a request is counted when it arrives rather than when it succeeds. Back off between attempts.
If one persists, send us the timestamp from the body at
support@getthera.com and we can find the request.

