<!-- https://docs.elchi.dev/emx-errors | EMX | Elchi Docs -->

# EMX error codes

Every error is

```json
{"error": {"code": "not_permitted", "message": "…", "requestId": "…", "docs": "https://docs.elchi.dev/emx-errors#not-permitted"}}
```

`code` is stable and what your program should switch on. `message` is
for a person and may change. `requestId` is what to quote when you write
to us; it is also in the `X-Request-Id` header of every answer.

## Requests

### bad_request

`400`. The body could not be read, a field is missing or malformed, an
ID is not a UUID, a name is not allowed. The message says which.

### not_found

`404`. No such thing, or one you may not see: whether it exists is
private, so both answer the same.

### too_large

`413`. A message, attachment or upload beyond the limit; `limits.maxMessageBytes`
in `/api/me` says what it is.

### rate_limited

`429`. More than 600 requests in a minute with one token. `Retry-After`
says how long to wait.

### server_error

`500`. Our fault. The request id is in the answer; the error is in our
log with it.

### unavailable

`503`, sometimes `501`. A part is not configured on this server: sending,
live updates, billing, DNS checks. Not a retry case.

## Authentication and rights

### bad_token

`401`. The token is unknown, revoked or expired. Make a new one.

### signed_out

`401`. The session ended or was revoked; the web client signs in again.

### scope

`403`. The token lacks the scope the call needs.

### forbidden

`403`. Allowed in principle, not for you: an administrator's call by a
member, an operator's call by an administrator.

### session_only

`403`. Tokens, app passwords, profiles and sessions are managed in the
web client, not with a token.

### cross_origin

`403`. A browser request from another site. Programs send a bearer
token and are never affected.

### no_identity_provider

`503`. Sign-in through EAuth is not configured on this server.

## Mail

### reload

`410` on `/changes`. The changes since that state are no longer known;
load the mailbox again and continue from the `modseq` you get.

### sealed

`409`. The mailbox is sealed: this part or body is ciphertext the browser
opens, not the server.

### not_sealed

`404`. Sealed-mailbox calls on a mailbox that is not sealed.

### name_taken

`409`. A folder with that name exists at that place.

## Sending

### not_permitted

`403`. `from` is not one of your `sendFrom` addresses, or the right to
send as it was removed.

### unknown_recipient

`400`. A recipient at one of our domains does not exist. Mail to other
domains is accepted and bounces later if need be.

### refused

`400`. The message was refused for what it is: a malformed address, a
header that cannot be sent, too many recipients. The message says which.

### daily_limit

`429`. Your recipients for today are used up; the count resets at
midnight Swiss time. The plan sets the limit: 200 on Private, 1,000 on
Team.

### monthly_limit

`429`. The organisation's recipients for this month are used up. The
plan says how many; Team can raise it.

### try_later

`503`. The queue could not take the message right now. Try again in a
minute; with the same `Idempotency-Key`, a retry cannot send twice.

## Webhooks

### too_many

`409`. Twenty webhooks on the account already.

## Administration

### taken

`409`. The address belongs to somebody already.

### signed_in

`409`. The person has signed in already; an invitation cannot be made
for them again.

### last_owner

`409`. An organisation keeps at least one owner.

### plan_limit

`402`. The plan does not allow another mailbox, domain or person.
Change the plan under billing.

### not_verified

`409`. The domain's `_emx-challenge` record was not found. DNS can take
a few minutes.

### no_subscription

`404`. The organisation has no subscription yet; checkout comes first.

### billing_error

`502`. Stripe did not answer. Try again in a moment.

### bad_signature

`400` or `401`. A signed request (Stripe's webhook, the Elchi console's
internal API) did not verify. Check the secret and the clock.
