Errors

One error shape for every endpoint, and the codes worth branching on.

Every error — validation, auth, not found, rate limit, or ours — comes back with the same body:

{
  "error": {
    "code": "CATALOG_PRODUCT_NOT_FOUND",
    "message": "The catalog product does not exist."
  }
}

Branch on code, never on message. The code is part of the contract and won't change under you. The message is a sentence for a human reading a log, and we reword it whenever a clearer one turns up.

Status codes

StatusWhat it means
400The request isn't valid — a bad parameter, a malformed body, a duplicate contact
401The key is missing, malformed, revoked or expired
404That resource doesn't exist in this organization. It may exist in another one; you get the same 404 either way
409Conflict with the current state of the resource
429Over the request limit — see Rate limits
5xxOurs. Retry with backoff; if it persists, write to support@trama.so

The codes

CodeStatusWhen
VALIDATION_FAILED400A parameter or field didn't pass validation. The message names the field: contacts.0.phone: Required
CRM_CUSTOMER_DUPLICATE_IDENTIFIER400Another customer already uses one of those contacts, or the same contact is repeated inside your payload
CRM_CUSTOMER_INVALID_PHONE400The contact's phone number isn't usable
API_KEY_MISSING401No Authorization and no x-api-key header
API_KEY_INVALID401The key doesn't validate
API_KEY_NOT_FOUND401The key was revoked, or never existed
CUSTOMER_NOT_FOUND404
OPPORTUNITY_NOT_FOUND404
CONVERSATION_NOT_FOUND404
QUOTE_NOT_FOUND404
CATALOG_PRODUCT_NOT_FOUND404
NOT_FOUND404The endpoint itself doesn't exist. Check the method and the path
API_KEY_RATE_LIMITED429See Rate limits

A code you don't recognize is still safe to handle. New codes get added as the API grows, so treat the list above as the ones worth branching on and everything else as "an error of this status". What won't happen is an existing code changing meaning.

Reading a validation error

VALIDATION_FAILED puts the offending field at the front of the message, as a dotted path into what you sent:

{ "error": { "code": "VALIDATION_FAILED", "message": "limit: Number must be less than or equal to 100" } }

That path is the useful part. The sentence after it comes from the schema and may be reworded.

What you won't get

  • No stack traces and no internal details. A 5xx says the request couldn't be completed and nothing else — on purpose.
  • No error text in Spanish. The dashboard is in Spanish and the domain code underneath it is too; the API translates at the boundary, so a caller never gets a message in a language they didn't ask for. If one ever slips through, that's a bug worth reporting.

On this page