Docs/Reference/Error Handling

Error Handling

How to handle errors from the IvyMail API. Error response format, common error codes, and troubleshooting guide.

All IvyMail API responses use a consistent envelope format. When an error occurs, success is false and the error field contains a human-readable message.

Error response format

JSON
{
  "success": false,
  "error": "Description of what went wrong"
}

HTTP status codes

CodeMeaningCommon causes
400Bad RequestMissing required fields, invalid email format, empty to array
401UnauthorizedMissing or invalid x-api-key header
403ForbiddenAPI key doesn't have access to this workspace
404Not FoundDomain or resource doesn't exist
409ConflictDomain already exists in workspace
422UnprocessableValid JSON but semantically incorrect (e.g. unverified domain)
429Too Many RequestsRate limit exceeded
500Internal Server ErrorUnexpected server error. Retry with backoff

Common errors and solutions

"Invalid or missing API key"

Status: 401

Check that you're including the x-api-key header (not Authorization or Bearer).

Bash
# Correct
-H "x-api-key: ivym_sk_your_key"

# Wrong
-H "Authorization: Bearer ivym_sk_your_key"

"Domain not verified"

Status: 422

Your sending domain hasn't been verified yet. Go to Dashboard → Domains and check the verification status. See Domain Setup for DNS configuration.

"Recipient suppressed"

Status: 200 (logged as suppressed)

The recipient is on your suppression list due to a previous bounce or complaint. This is not an HTTP error. The API returns 200 with a suppressed status to indicate the send was intentionally blocked.

"Rate limit exceeded"

Status: 429

You've exceeded the request rate limit. Wait and retry with exponential backoff. See Rate Limits.

"Missing required field: to"

Status: 400

The to field must be a non-empty array of email address strings.

JSON
{
  "to": ["user@example.com"],
  "from_email": "you@yourdomain.com",
  "subject": "Hello",
  "text": "Hello!"
}

Retry strategy

For 429 and 5xx errors, implement exponential backoff:

python
import time
import requests

def send_with_retry(payload, api_key, max_retries=3):
    for attempt in range(max_retries):
        resp = requests.post(
            "https://api.ivymail.io/v1/send",
            headers={"x-api-key": api_key, "Content-Type": "application/json"},
            json=payload,
        )
        if resp.status_code == 429 or resp.status_code >= 500:
            wait = 2 ** attempt
            time.sleep(wait)
            continue
        return resp.json()
    return resp.json()

Validation errors

Request validation happens before any email processing. If your request is malformed, you'll get a 400 with details about what's wrong. Fix the request and retry immediately. No backoff needed.


For AI agents & LLMs

If you're an AI agent handling IvyMail errors, follow this decision tree:

  • 401 → API key is wrong or missing. Ask the user to provide their IVYMAIL_API_KEY.
  • 400 → Fix the request payload (check required fields: to, from_email, subject, and at least text or html).
  • 422 → Domain isn't verified. Tell the user to verify at ivymail.io/dashboard → Domains.
  • 429 → Rate limited. Wait and retry with exponential backoff (2^attempt seconds).
  • 5xx → Server error. Retry up to 3 times with backoff.

Always check the success field and error message in the response body for details.