HTTP status codes, the error response format, and how to handle failures.
Truss uses conventional HTTP response codes to indicate the success or failure of an API request. In general:
- Codes in the
2xxrange indicate success. - Codes in the
4xxrange indicate an error that failed given the information provided. For example, a missing required parameter, a record that doesn't exist, or a key that isn't authorized. - Codes in the
5xxrange indicate an error with the Truss servers. These are rare.
Error response format
Every error response has a JSON body with a single key describing what went wrong.
{ "errors": "Not found" }
The value of errors is a string for most failures. When a request fails validation, it is an array of human-readable messages, one per problem:
{
"errors": [
"Invoice tasks require a connected Stripe account. Set one up in Truss under Payments.",
"amount_due is only valid on invoice tasks"
]
}
File and drive-folder endpoints use the singular error key with a string value. Handle both keys when you parse errors generically.
{ "error": "File red-book-of-westmarch.pdf is empty. Please upload a valid file." }
Messages are written for people and may change. Branch on the HTTP status code, not on the text.
HTTP status codes
| Code | Meaning |
|---|---|
200 OK | The request succeeded. |
201 Created | A resource was created. Notes and comments return this; most other create endpoints return 200 with the created object. |
400 Bad Request | A required parameter is missing or malformed, a referenced user or page doesn't exist, or a URL you asked Truss to download couldn't be fetched. |
401 Unauthorized | The bearer token has a shape that can't be an API key. See Authentication. |
403 Forbidden | No key was provided, the key is invalid, or the key's user isn't allowed to do this. Permission restrictions on a user in Truss apply to their API key in the same way. |
404 Not Found | The resource doesn't exist, or it exists but isn't visible to the key's user. Truss doesn't distinguish the two. |
409 Conflict | The request collides with an existing record, such as creating a contact whose email already belongs to a contact in the firm. |
422 Unprocessable Content | The request was well formed but failed validation. The body lists each problem. |
501 Not Implemented | The endpoint exists in the API but isn't available. |
500 Internal Server Error | Something went wrong on our side. The body is always { "errors": "Internal server error" }; the details are logged and reviewed by Truss. |
Rate limits
Truss does not currently enforce a published request-rate limit on the API. Treat the service with the care you would give any shared system: run bulk work at a steady pace rather than in bursts, cache reference data such as project statuses and document categories, and use webhooks instead of polling to learn about changes.
Handling errors
A few patterns cover almost everything:
- Retry
5xxresponses with an exponential backoff. Don't retry4xxresponses without changing the request. - Treat
403withAuthentication failedas a configuration problem, not a transient one. The usual cause is that someone generated a new API key, which invalidates the old one. - On
422, show the messages to whoever can fix the input. They are written to be read. - Log the full response body along with the status code. The message usually names the field or record at fault.