Errors
Every error the API returns has the same shape, whatever went wrong:
{ "message": "Another of your workspaces already has this reference.", "code": "reference_taken", "doc_url": "https://docs.sendtruss.com/errors/#reference_taken", "request_id": "01JA2R7T5Y3W1V9X7Z5B3D1F9H"}messageis written for a person reading your logs. It can change, so never branch on it.codeis stable. Branch on it.errors, on a validation failure and a few refusals, holds the details by field.doc_urllinks to the code’s entry on this page.request_ididentifies the request. Every response carries it in theRequest-Idheader too, success or failure. Quote it when you ask us about a request.
New codes are not breaking changes, so treat a code you don’t know by its status: retry a 429 or 5xx later, and fix the request for any other 4xx.
Any request
Section titled “Any request”unauthenticated
Section titled “unauthenticated”401. The request carried no API key, or one that is wrong or revoked.
Send the key as Authorization: Bearer $SENDTRUSS_API_KEY. If it still fails, check the key in the console’s API keys screen; a revoked key stops working at once, so create a new one.
forbidden
Section titled “forbidden”403. The key isn’t allowed to do this.
Every key made in the console can call every operation, so this shouldn’t happen. Send us the request_id.
not_found
Section titled “not_found”404. Nothing exists at this path for your platform: the path is wrong, or the workspace, contact, event type, endpoint or webhook it names doesn’t exist or belongs to another platform.
Check the path against the API reference. A workspace or contact named by ref: must use your reference exactly as you set it. A deleted workspace answers 404 too.
rate_limited
Section titled “rate_limited”429. Your platform sent more requests than its limit allows.
Wait for the number of seconds in the Retry-After header, then send the request again unchanged.
validation_failed
Section titled “validation_failed”422. The request body doesn’t pass validation. errors lists each field at fault with its messages, keyed by the field’s path, such as recipient.email or fields.2.type.
Fix each field errors names and send it again. Saving a template can answer this too, with errors in the composition under composition naming their block.
bad_request
Section titled “bad_request”400. The request couldn’t be read, usually a body that isn’t valid JSON.
Check the body parses as JSON and is sent with Content-Type: application/json.
method_not_allowed
Section titled “method_not_allowed”405. The path exists but not with this method.
Check the method against the operation in the API reference.
unsupported_media_type
Section titled “unsupported_media_type”415. The body was sent in a format the API doesn’t take.
Send JSON with Content-Type: application/json.
http_error
Section titled “http_error”4xx. A client error none of the other codes covers. message says what it was.
Read the message and fix the request.
server_error
Section titled “server_error”5xx. Something failed on our side. Nothing you sent caused it.
Retry with backoff. An emit retried with the same idempotency key and body is safe: if the first one was recorded, you get its answer back. If it keeps failing, send us the request_id.
Too large
Section titled “Too large”A request body over 16 MB is refused with a bare 413 before it reaches the API, so it carries no code, doc_url or request_id. Send fewer or smaller attachments.
Workspaces
Section titled “Workspaces”reference_taken
Section titled “reference_taken”409. Another of your workspaces already has this reference.
References are unique per platform. If you meant that workspace, address it by ref: instead of creating it. Otherwise choose another reference.
workspace_ceiling_reached
Section titled “workspace_ceiling_reached”409. Your platform has as many workspaces as it is allowed.
Delete workspaces you no longer need, or contact us to raise the limit.
Contacts and attributes
Section titled “Contacts and attributes”email_taken
Section titled “email_taken”409. Another contact in this workspace already has this email address. contact names it, by ref: and its reference, or by its id when it has none.
One address belongs to one contact in a workspace. Update the contact contact names, or change or remove its address first.
consent_older_than_opt_out
Section titled “consent_older_than_opt_out”409. The marketing consent you sent was given before the person last left marketing, so it no longer stands.
Don’t resend it. Only a consent given after they left can subscribe them again; send that one, with the time it was given.
key_taken
Section titled “key_taken”409. An attribute definition with this key already exists.
Change the existing definition, or choose another key.
Event types and templates
Section titled “Event types and templates”schema_change_not_additive
Section titled “schema_change_not_additive”409. The change would remove a field or alter one in a way that could break emits already sent. errors names each field at fault by its path.
An event type’s schema can only grow: add new fields as optional. For a breaking change, register a new event type.
version_conflict
Section titled “version_conflict”409. The template moved on since the version you based your change on. errors says so under base_version.
Read the template again, apply your change to the current version, and save with its version as the base.
translations_outdated
Section titled “translations_outdated”422. Some translations were made from text that has changed since. errors lists each one by locale and field.
Send fresh translations, or send accept_outdated to keep them as they are.
Emitting events
Section titled “Emitting events”idempotency_key_reused
Section titled “idempotency_key_reused”409. This idempotency key was already used with a different body.
A key stands for one emit. Retry with the same body to get the first answer back, or use a new key for a different emit.
workspace_suspended
Section titled “workspace_suspended”409. The workspace is suspended, so it sends nothing.
Resume the workspace if it should send, then emit again with the same key.
domain_not_sendable
Section titled “domain_not_sendable”409. Your platform’s sending domain can’t send yet: it isn’t set up, or one of its DNS records isn’t verified.
Open the console’s domain screen and fix the records it marks. Until then you can emit to a simulator address.
recipient_rate_limited
Section titled “recipient_rate_limited”429. Too many emits went to this recipient in the last hour. Retry-After says how long to wait.
Check your code isn’t emitting in a loop. If the emit is wanted, send it again after Retry-After with the same idempotency key.
Webhook endpoints and secrets
Section titled “Webhook endpoints and secrets”url_invalid
Section titled “url_invalid”422. The URL couldn’t be read as an absolute URL.
Send a full URL, starting with https://.
url_too_long
Section titled “url_too_long”422. The URL is longer than 2,048 characters.
Use a shorter URL.
url_not_https
Section titled “url_not_https”422. The URL doesn’t use HTTPS.
Serve your endpoint over HTTPS and send its https:// URL.
url_port_not_allowed
Section titled “url_port_not_allowed”422. The URL names a port other than 443.
Serve your endpoint on port 443 and leave the port out of the URL.
url_ip_literal
Section titled “url_ip_literal”422. The URL names an IP address instead of a host.
Give your endpoint a host name.
url_has_credentials
Section titled “url_has_credentials”422. The URL carries a user name or password.
Remove them. Every webhook is signed, so verify the signature instead.
url_has_email_address
Section titled “url_has_email_address”422. The URL contains an email address.
Remove it from the URL.
url_unresolvable
Section titled “url_unresolvable”422. The URL’s host doesn’t resolve.
Check the host name, and that its DNS record exists.
url_address_refused
Section titled “url_address_refused”422. The URL’s host resolves to an address webhooks are never sent to, such as a private, loopback or link-local one.
Use a host that resolves only to public addresses. To try webhooks before your own endpoint is public, use a request-inspection service’s URL.
unknown_type
Section titled “unknown_type”422. The endpoint asks for a webhook type that doesn’t exist.
Check the type against the webhooks reference.
endpoint_ceiling_reached
Section titled “endpoint_ceiling_reached”409. Your platform has as many webhook endpoints as it is allowed.
Delete an endpoint before adding another. One endpoint can take every type.
secret_ceiling_reached
Section titled “secret_ceiling_reached”409. Your platform has as many live signing secrets as it is allowed.
Revoke one before creating another.
last_secret_in_use
Section titled “last_secret_in_use”409. This is your last live signing secret and your endpoints still need it.
Create a new secret first, deploy it, then revoke this one.
endpoint_deleted
Section titled “endpoint_deleted”409. The webhook’s endpoint has been deleted, so it can’t be sent again.
Nothing to redeliver. If you still need it, read its body with Get a webhook.