Skip to content
Docs

Reference

How the Emailit API reports errors. Response body formats, HTTP status codes and what they mean, and fixes for the error messages you'll see most.

Updated Oct 1, 2026

The Emailit API uses HTTP status codes to tell you whether a request worked. Codes in the 2xx range mean success, 4xx codes mean something about the request needs to change, and 5xx codes mean something went wrong on our side. This page describes the error bodies, every status code the API returns and how to fix the most common errors.

Error response formats

Every error body is a JSON object with an error field. The exact shape depends on where the request failed. Write your error handling to read error, then message when it’s present, then any extra fields the endpoint documents.

Request errors

Authentication failures, permission errors, malformed JSON and other errors raised before an endpoint runs use the standard HTTP error format:

JSON
{
  "statusCode": 401,
  "error": "Unauthorized",
  "message": "API key required"
}
Field Description
statusCode The HTTP status code.
error The HTTP reason phrase, such as Unauthorized or Forbidden.
message What went wrong, in plain language.

Validation errors

When a query parameter or body field has the wrong type, is missing, or is out of range, the API rejects the request with 400 before it runs and lists each problem in details:

JSON
{
  "statusCode": 400,
  "error": "Bad Request",
  "message": "Validation error",
  "details": [
    {
      "instancePath": "/limit",
      "schemaPath": "#/properties/limit/maximum",
      "keyword": "maximum",
      "params": { "comparison": "<=", "limit": 100 },
      "message": "must be <= 100"
    }
  ]
}

instancePath points to the field (/limit, /to, /attachments/0/filename), and message describes the rule it broke. On a few endpoints, such as Send an email, these errors return only {"error": "Bad Request"}.

Resource errors

Errors raised by an endpoint, such as a missing object or a duplicate name, return error and often message:

JSON
{
  "error": "Email not found",
  "message": "Email with ID 'em_4KYof1ZzXndZE2VPi0DgULiekG8' not found in your workspace"
}

Some errors add fields that help you recover:

Field Returned with Contains
existing 409 when you create a duplicate domain, API key, audience, contact or subscriber The object that already exists, so you can use it instead.
usage 422 when a plan limit is reached used, limit and, for audiences, plan.
required_plan 403 with error: "plan_required" The lowest plan that includes the feature, such as pro.
code Some 403 and 422 errors A stable machine-readable code, such as unverified_workspace_recipient or events_offset_too_large.
missing 404 from Bulk update contacts The contact IDs that weren’t found.

Send validation errors

Send an email and Forward an email check the whole message at once and return every problem in validation_errors:

JSON
{
  "error": "Validation failed",
  "validation_errors": [
    "Missing required field: subject",
    "Invalid to email address at index 1: ada@example"
  ]
}

Field errors

Templates, campaigns and automations return validation problems grouped by field:

JSON
{
  "message": "Validation failed",
  "errors": {
    "alias": ["Alias must contain only lowercase letters (a-z), numbers (0-9), underscores (_), and hyphens (-)"]
  }
}

Rate limit errors

429 responses from the sending endpoints include the limit you hit and how long to wait. See Rate limits.

JSON
{
  "error": "Rate limit exceeded",
  "message": "Too many requests. Maximum 2 messages per second allowed.",
  "limit": 2,
  "current": 2,
  "retry_after": 1
}

HTTP status codes

Code Meaning Typical causes in the Emailit API
200 OK The request worked. Sends, updates, deletes and reads return 200.
201 Created A domain, API key, audience, subscriber, contact, template, webhook or other object was created.
202 Accepted A DMARC report upload was accepted for processing.
204 No Content A form was deleted. The response has no body.
400 Bad Request Invalid JSON, a missing required field, a value of the wrong type or out of range, an invalid Idempotency-Key, or no fields to update.
401 Unauthorized The API key is missing, invalid, deleted or regenerated, or an OAuth token expired. See Authentication.
402 Payment Required The workspace doesn’t have enough credits for the send, retry or verification.
403 Forbidden The key’s scope doesn’t allow the endpoint, a domain-restricted key sent from another domain, the workspace is suspended or not yet verified, the sending domain is paused, or the feature needs a higher plan.
404 Not Found The object doesn’t exist in this workspace, or a template alias has no published version.
409 Conflict An object with the same name or email already exists, or a request with the same Idempotency-Key is still running.
413 Payload Too Large The composed email is larger than 40 MB, or a DMARC report upload is larger than 10 MB.
422 Unprocessable Entity The request is valid but can’t be done right now: the from domain isn’t verified, an attachment couldn’t be fetched, the email’s status doesn’t allow cancel or retry, its content was already purged, or a plan limit was reached.
429 Too Many Requests The workspace hit its per-second or daily sending limit, or the hourly forward limit.
500 Internal Server Error Something failed on our side. Retry with backoff, and contact support if it persists.
503 Service Unavailable A temporary outage of a dependency, such as the idempotency store or the authentication database. Retry with backoff.

Common errors and how to fix them

Status error Cause Fix
400 Validation failed A send is missing from, to, subject or content, or has an invalid address or attachment. Fix each item listed in validation_errors.
400 Invalid JSON in request body (in message) The body isn’t valid JSON. Check quoting and trailing commas, and send Content-Type: application/json.
400 Invalid Idempotency-Key The key is longer than 256 characters or has characters other than letters, digits, - and _. Use a UUID or a similar safe value.
402 Insufficient credits Credits ran out. Each recipient costs one credit. Buy credits or turn on auto-refill.
403 Workspace not verified The workspace is in sandbox mode and a recipient isn’t a workspace member. Request production access.
403 Domain paused Sending from this domain is paused because of its sending health. Fix the bounce or complaint problem, then contact support.
403 Domain not authorized The API key is restricted to another sending domain. Send from the key’s domain or use another key.
403 plan_required The feature, such as DMARC reports or webhook filters, isn’t on your plan. Upgrade to the plan in required_plan.
403 mjml_alpha The request creates or changes MJML, or calls an MJML endpoint. MJML is in alpha and open to the Emailit team only. Use another editor or content type. See MJML editors and API.
404 Template not found The template ID doesn’t exist, or the alias has no published version. Publish a version of the template.
409 … already exists You created an object with a name or email that’s already taken. Use the object in existing, or pick another name.
409 Idempotency key in progress Another request with the same key hasn’t finished. Wait a moment and retry with the same key.
413 Message too large The email, including attachments, is over 40 MB. Send large files as links instead of attachments.
422 Domain not verified The from address isn’t on a verified sending domain of this workspace. Verify the domain or change from.
422 Attachment error An attachment url couldn’t be fetched within 30 seconds, isn’t reachable, or is larger than 25 MB. Check the URL is public and the file is small enough, or send content instead.
422 Cannot cancel email, Cannot retry email, Cannot update email The email’s status doesn’t allow the action, it’s within 3 minutes of its scheduled time, or its content was purged. Check the email’s status. See each endpoint for the rules.
422 Page is too deep You paged past offset 2,500 of List events. Narrow the results with type or created_at filters.
429 Rate limit exceeded, Daily limit exceeded The workspace hit its sending limit. Wait retry_after seconds. See Rate limits.

Retry safely

  • Retry 429, 500 and 503 responses after a delay. Use the retry-after header when it’s present, and exponential backoff otherwise. Rate limits has example code.
  • Don’t retry other 4xx errors unchanged. They fail the same way until you fix the request.
  • When you retry a send after a timeout or a 5xx error, reuse the same Idempotency-Key so the email isn’t sent twice.
Credentials, scopes and every authentication error.
Sending limits, headers and backoff.
Retry sends without sending twice.
See the request and response of every failed API call.

Was this page helpful?

Thanks for the feedback.

Thanks, we read every message.