422 Unprocessable Content
Some errors add fields of their own:
errors for a validation error, problems for a campaign that is not ready, data for a transactional e-mail that was logged but not sent.
The HTTP statuses
Validation errors
422 validation_error, with the detail field by field:
subscribers.14.email is the 15th line of a batch.
An address nothing would arrive at
Adding someone new checks the address first:POST /v1/lists/{list}/subscribers, and POST /v1/automations/{automation}/trigger for a person not on the list yet. A throwaway mailbox, or a domain with no mail server, answers 422 undeliverable_address with two more fields:
Show
suggestion to the person and let them choose: never swap it in on your own. In a batch, the same address is a line with "outcome": "failed" and its message; in an import, a line in error.
Retry or not
- Retry on
429rate_limited, on5xxand on network errors, with a growing delay and the sameIdempotency-Key. - Read first a
502from a transactional e-mail:data.failure_reasonsays whether sending again can work. - Do not retry any other
4xx: the same call gives the same answer. Fix it first. One exception:409idempotency_key_in_use, the same idempotent call still running; try again a moment later.
Every code
Grouped by where they come from. Each one has its anchor:/errors#rate_limited.
Any route
unauthenticated
401. No Authorization header, a malformed token, or a revoked one. Check that the whole token follows Bearer . See Authentication.
missing_ability
403. A Read token called a route that writes. Create a Read and write token for this application.
role_not_allowed
403. The token’s owner may not do this in the team: a viewer writing, a writer sending a campaign. A token acts with its owner’s role, checked on every call. See The roles.
team_suspended
403. The team is suspended: every call is refused until whoever runs the service lifts it. Contact support.
team_access_lost
403. The token’s owner is no longer a member of the team the token was made in. Create a token from an account that is.
two_factor_required
403. The team requires two-factor authentication, and the token’s owner has neither a second factor nor a passkey. Once they set one up, the token works again. See Rules of the team.
no_team
403. The account is in no team at all. It happens to someone removed from every team.
forbidden
403. Refused for a reason that has no code of its own. message says which.
not_found
404. No route at this address, or no resource of this id in the token’s team. A resource of another team is not found either, by design.
method_not_allowed
405. The route exists, with another method: GET instead of POST, say.
conflict
409. The state of the resource does not allow it. message says why.
bad_request
400. The request could not be read.
payload_too_large
413. The body is larger than the server accepts. Send fewer lines per batch, or a smaller file.
validation_error
422. A field is missing or invalid. errors lists them, field by field. See Validation errors.
invalid_request
422. Refused for a reason that has no code of its own. message says which.
rate_limited
429. The token made more than its calls of the minute (120 by default). Wait the Retry-After seconds; X-RateLimit-Remaining says, on every answer, how many calls are left.
server_error
500. Lekalao’s fault. Try again later with the same Idempotency-Key; if it lasts, tell support the time of the call.
service_unavailable
503. The installation is in maintenance. Try again in a few minutes.
Idempotency
idempotency_key_too_long
400. The Idempotency-Key is longer than 255 characters.
idempotency_key_in_use
409. A call with the same key is still running. Try again a moment later: you will get its answer.
idempotency_key_reused
422. The key was already used for another route or another body. Give each operation its own key.
idempotency_key_expired
422. The key is more than 24 hours old. Send a new one. See Idempotency.
Test keys
sandbox_cannot_send
403. A test key called a route that exists to write to real people: sending a campaign, putting someone into an automation, sending a confirmation e-mail again. Use a live key.
Contacts
undeliverable_address
422. The address cannot receive e-mail: a throwaway mailbox, or a domain without a mail server. See An address nothing would arrive at.
address_suppressed
422. The address is on the team’s suppression list: it bounced for good, complained, or was blocked by hand. It cannot be subscribed again by the API.
subscriber_limit_reached
422. The plan holds no more subscribers. Move up a plan, or clean the lists. See Plans.
confirmation_not_needed
422. resend-confirmation for someone who has nothing to confirm: already subscribed, or on a list without double opt-in.
batch_rejected
422. Not one line of the batch could be saved. data gives the reason of each line, meta the counts.
contact_not_found
404. A conversion for an address that is on none of the team’s lists.
event_count_out_of_range
422. POST /v1/events takes one event, or between 1 and 1,000 under events.
Sending
sender_not_allowed
422. The sender address is not on a verified sending domain of the team, where the installation requires one. The message names the domain. See Sending domains.
template_error
422. The template does not render: a tag left open, an unknown filter. The message says where.
content_missing
422. A transactional e-mail with neither template nor html.
recipient_missing
422. A transactional e-mail with no to, from a template that has no default recipients either.
too_many_recipients
422. More than 50 addresses in one transactional e-mail, to, cc and bcc together. A transactional e-mail is written to someone: send one each.
recipients_suppressed
422. Every address in to is on the suppression list. The e-mail is logged as failed, under data. Sending it again fails the same way.
monthly_quota_exceeded
429. The plan’s e-mails of the month are used up; each recipient of an e-mail counts, copies included. The e-mail is logged as failed, under data. Wait for the next month, or move up a plan. A campaign test refused for this reason answers test_refused.
sending_paused
422. The team may not send: its paid period ended without a payment. The e-mail is logged as failed, under data. See Billing.
provider_error
502. The provider refused the transactional e-mail on every try, for six hours, or a test key wrote to failed@sink.lekalao.dev. data.failure_reason holds the provider’s last word.
queue_unavailable
502. The e-mail was logged, but the queue could not take it. Try again in a moment with the same Idempotency-Key: a 502 is not kept, so the e-mail is not counted twice.
mail_not_kept
409. A resend of a transactional e-mail whose template keeps neither the content nor the variables (one-time codes, sign-in links). Send a new e-mail.
campaign_not_ready
422. The campaign cannot leave yet. problems lists what is missing, as the interface does. See Ready or not.
campaign_is_sending
409. A campaign being sent cannot be deleted. Pause it in the interface first.
test_refused
422. A campaign test that may not leave: the sender’s domain is not verified (where the installation requires it), every address given is on the suppression list, the team has sent 100 test e-mails this hour, or the month’s allowance is used up. message says which.
automation_not_running
409. The automation is not active, or has no list. Switch it on in the interface.
already_in_automation
409. The person is already travelling through this automation. The answer also carries "started": false.
Licences
licence_invalid
422. POST /v1/licences/check: the key cannot be read, or is not signed by Lekalao. The answer also carries "valid": false, "reason": "invalid".
licence_revoked
403. The licence has been revoked. The answer also carries "valid": false, "reason": "revoked".
A transactional e-mail that failed
A transactional e-mail keeps why it failed infailure_code, with the same words as the codes above: recipients_suppressed, monthly_quota_exceeded, sending_paused, provider_error, queue_unavailable. One more is never an answer to a call, since it happens later: lost, an e-mail still pending seven hours after the call because its job was lost. Send it again. See Transactional e-mails.