PadiMail Docs

Errors

Every error code the API returns, what causes it and how to fix it.

Every error has the same shape. Branch on code in your code; message is for people and may change.

{
  "error": {
    "type": "validation_error",
    "code": "invalid_from_address",
    "message": "The from address can't be used. Use a verified domain, one of your sender handles, or the sandbox.",
    "fields": {
      "from": "Domain not verified"
    },
    "doc_url": "https://padimail.dev/errors#invalid_from_address",
    "request_id": "req_01JBX7Q3F6ZK0Q9W1Y2R3T4V5S"
  }
}
  • fields appears on validation errors, naming each field with its problem. Batch validation adds errors: one { index, code, message } per invalid email.
  • Quote request_id (also in the X-Request-Id header) when you contact support.
  • Retry 429, 500 and 503 with backoff, waiting for Retry-After when it's sent. Don't retry other 4xx errors unchanged. The Node SDK retries for you.
  • The Resend-compatible API returns Resend's error shape instead, with our code in pm_code. See Switch from Resend.

400: the request isn't valid

validation_failed

400 · validation_error

Some fields aren't valid. Check the fields listed and try again.

Cause. One or more fields are missing or in the wrong format. The fields object names each one with the problem.

Fix. Correct the fields listed in fields and send the request again.

invalid_from_address

400 · validation_error

The from address can't be used. Use a verified domain, one of your sender handles, or the sandbox.

Cause. The from address isn't one you can send from: its domain isn't added or verified, or the sender handle isn't yours.

Fix. Use an address on a verified domain, one of your sender handles, or onboarding@sandbox.padimail.app. If the domain is new, add the DNS records shown on its page and check again.

too_many_recipients

400 · validation_error

An email can have at most 50 recipients across to, cc and bcc.

Cause. to, cc and bcc together have more than 50 addresses.

Fix. Split the email into several, or use POST /v1/emails/batch to send one email per recipient.

missing_body

400 · validation_error

Add html, text or a template.

Cause. The email has no html, text or template.

Fix. Add html and/or text, or a template with its variables.

attachment_too_large

400 · validation_error

The email is larger than 40 MB with its attachments.

Cause. The whole message, with attachments encoded, is over 40 MB.

Fix. Make the attachments smaller, or link to the files instead of attaching them.

invalid_scheduled_at

400 · validation_error

scheduled_at must be between 1 minute and 30 days from now.

Cause. scheduled_at is less than 1 minute or more than 30 days away, or isn't an ISO 8601 time.

Fix. Send a time such as 2026-10-28T09:00:00+01:00 between 1 minute and 30 days from now.

template_variables_missing

400 · validation_error

Some required template variables are missing.

Cause. The template declares required variables that the request didn't include.

Fix. Pass every required variable in template.variables. POST /v1/templates/{id}/render lists what's missing.

handle_not_allowed

400 · validation_error

That handle can't be used.

Cause. The sender handle matches a protected brand, a reserved word or our blocklist.

Fix. Choose a handle that's clearly your own organisation's name.

missing_org

400 · validation_error

Choose an organisation (send the X-PM-Org header).

Cause. A dashboard request didn't say which organisation it was for.

Fix. This only affects the dashboard. Reload the page and choose an organisation.

401: the API key is missing or wrong

missing_api_key

401 · authentication_error

Send your API key in the Authorization header: Bearer pm_live_…

Cause. The request had no Authorization header.

Fix. Send Authorization: Bearer pm_live_… (or pm_test_…). Keys in the query string are refused.

invalid_api_key

401 · authentication_error

That API key isn't valid.

Cause. The key doesn't exist, or is mistyped.

Fix. Copy the key again, or create a new one under API keys in the dashboard. Keys are shown only once.

revoked_api_key

401 · authentication_error

That API key has been revoked. Create a new one in the dashboard.

Cause. Someone in your organisation revoked this key.

Fix. Create a new key under API keys and update your server's environment.

not_signed_in

401 · authentication_error

Sign in to continue.

Cause. A dashboard request was made without a signed-in session.

Fix. Sign in again.

402: payment needed

insufficient_credits

402 · payment_required

You don't have enough credits for this email.

Cause. Your credit balance can't cover this email, and you asked for quota_behavior: "reject".

Fix. Buy credits under Billing, or leave out quota_behavior so the email waits until credits arrive.

plan_limit_reached

402 · payment_required

Your plan's limit has been reached.

Cause. Your plan's limit is used up, and you asked for quota_behavior: "reject".

Fix. Upgrade your plan, wait for the limit to reset, or let the email wait instead of rejecting it.

403: not allowed

forbidden

403 · permission_error

You don't have permission to do this.

Cause. The key or member doesn't have permission for this. A sending-only key can only send, read and cancel emails.

Fix. Use a full-access key, or ask an owner or admin to change your role.

phone_verification_required

403 · permission_error

Verify your phone number before sending with a live key. Test keys work now.

Cause. Live keys work only after the organisation owner verifies a phone number.

Fix. Verify your phone under Verification. Test keys (pm_test_…) work in the meantime.

sandbox_recipient_not_verified

403 · permission_error

In the sandbox you can only send to your organisation's verified addresses. Verify your identity to send to anyone.

Cause. In the sandbox (Tier 0) you can only send to your organisation's own verified email addresses.

Fix. Send to a member's address, or verify your identity (Tier 1) to send to anyone.

tier_required

403 · permission_error

Your verification tier doesn't allow this yet.

Cause. This needs a higher verification tier than your organisation has.

Fix. Complete the next verification step under Verification. The error message says which tier is needed.

account_suspended

403 · permission_error

This organisation is suspended.

Cause. Our trust and safety team suspended the organisation.

Fix. Check your email for our message, or contact support with the request ID.

account_paused

403 · permission_error

Sending is paused for this organisation.

Cause. Sending is paused, by an automatic brake (high bounces or complaints) or by a member.

Fix. Open the dashboard: the banner explains why and what to do before sending resumes.

sender_not_allowed

403 · permission_error

This key can't send from that address.

Cause. The API key is restricted to one domain, and the from address uses another.

Fix. Send from the key's domain, or use a key without a domain restriction.

not_a_member

403 · permission_error

You aren't a member of this organisation.

Cause. You aren't a member of the organisation the request was for.

Fix. Switch to an organisation you belong to, or ask an owner for an invitation.

email_not_verified

403 · permission_error

Verify your email address first. We sent a code to it when you signed up.

Cause. The signed-in dashboard user hasn't verified their email address yet. Until they do, they can't create or join an organisation or act in one.

Fix. Enter the code from the verification email (or ask for a new one on the verification page), then try again.

404: not found

not_found

404 · not_found

We couldn't find that.

Cause. Nothing with that ID exists in this organisation and mode.

Fix. Check the ID, and that you're using a key from the right organisation. Test keys only see test data.

email_not_found

404 · not_found

We couldn't find that email.

Cause. No email with that ID exists in this organisation, or it's older than 90 days.

Fix. Check the ID and the key. Live and test emails are separate: a pm_test_ key can't see live emails.

domain_not_found

404 · not_found

We couldn't find that domain.

Cause. No domain with that ID exists in this organisation.

Fix. List your domains with GET /v1/domains to find the right ID.

template_not_found

404 · not_found

We couldn't find that template.

Cause. No template with that ID or alias exists in this organisation.

Fix. Check the ID or alias with GET /v1/templates.

webhook_not_found

404 · not_found

We couldn't find that webhook.

Cause. No webhook endpoint with that ID exists in this organisation.

Fix. List your endpoints with GET /v1/webhooks.

suppression_not_found

404 · not_found

We couldn't find that suppression.

Cause. No suppression with that ID exists, or it has already been removed.

Fix. Search with GET /v1/suppressions?address=….

api_key_not_found

404 · not_found

We couldn't find that API key.

Cause. No API key with that ID exists, or it's already revoked.

Fix. List your keys with GET /v1/api-keys.

invitation_not_found

404 · not_found

We couldn't find that invitation.

Cause. The invitation link is wrong, or the invitation was withdrawn.

Fix. Ask the person who invited you to send a new invitation.

organization_not_found

404 · not_found

We couldn't find that organisation.

Cause. That organisation doesn't exist, or you can't see it.

Fix. Choose an organisation from the switcher in the dashboard.

409: conflict

idempotency_conflict

409 · conflict

This Idempotency-Key was already used with a different request body.

Cause. The Idempotency-Key was used in the last 24 hours with a different request body.

Fix. Use a new key for a different request. Reuse a key only to retry exactly the same request.

domain_already_exists

409 · conflict

You've already added this domain.

Cause. Your organisation has already added this domain.

Fix. Open the existing domain instead of adding it again.

handle_taken

409 · conflict

That handle is taken.

Cause. Another organisation already uses this sender handle, or released it less than 90 days ago.

Fix. Choose a different handle.

email_already_sent

409 · conflict

This email has already been sent.

Cause. You tried to change or cancel an email that has already been handed over for delivery.

Fix. Only scheduled, waiting or held emails can be changed or canceled.

alias_taken

409 · conflict

Another template already uses that alias.

Cause. Another template in your organisation already uses this alias.

Fix. Pick a different alias, or change the other template's alias first.

already_member

409 · conflict

This person is already a member.

Cause. That person is already a member of the organisation.

Fix. Change their role on the Team page instead of inviting them again.

last_owner

409 · conflict

An organisation needs at least one owner. Make someone else an owner first.

Cause. This change would leave the organisation without an owner.

Fix. Make another member an owner first.

invalid_state

409 · conflict

This can't be done in the current state.

Cause. The resource isn't in a state that allows this, for example rescheduling an email that isn't scheduled.

Fix. Fetch the resource to see its current status, then try an action that fits it.

410: gone

content_expired

410 · gone

This email's content was deleted after your plan's retention period.

Cause. The email's content was deleted after your plan's retention period. Its status and events are still kept.

Fix. Keep your own copy of content you need for longer, or move to a plan with longer retention.

invitation_expired

410 · gone

This invitation has expired. Ask for a new one.

Cause. The invitation link is past its expiry date.

Fix. Ask for a new invitation.

422: content blocked

content_blocked

422 · unprocessable

This content can't be sent under our acceptable use policy.

Cause. Content scanning blocked the email under our acceptable use policy. The message says why in general terms.

Fix. Change the content. If you think it's a mistake, contact support with the request ID.

429: too many requests or over a limit

rate_limited

429 · rate_limit_error

Too many requests. Slow down and retry after the time in Retry-After.

Cause. Too many requests from this key in a short time (10 a second, bursts to 20, by default).

Fix. Wait for the time in Retry-After and try again. The Node SDK does this for you. Use batch sending for many emails.

daily_quota_exceeded

429 · rate_limit_error

You've reached today's sending limit.

Cause. Today's sending limit is used up, and you asked for quota_behavior: "reject".

Fix. Wait for the limit to reset at midnight in your organisation's time zone, or let the email wait instead of rejecting it.

monthly_quota_exceeded

429 · rate_limit_error

You've reached this month's sending limit.

Cause. This month's sending limit is used up, and you asked for quota_behavior: "reject".

Fix. Upgrade your plan or buy credits, or let the email wait.

warmup_limit_reached

429 · rate_limit_error

This sender's warm-up allowance for today is used up.

Cause. A new sender handle sends a little more each day while it warms up, and today's allowance is used.

Fix. Let the email wait for tomorrow's allowance, or send from a verified custom domain.

sandbox_limit_reached

429 · rate_limit_error

You've reached the sandbox limit of 50 emails today.

Cause. The sandbox allows 50 emails a day, and you asked for quota_behavior: "reject".

Fix. Verify your identity (Tier 1) for higher limits, or let the email wait until tomorrow.

deferred_queue_full

429 · rate_limit_error

Too many emails are already waiting for your limit. Cancel some or raise your limit.

Cause. So many emails are already waiting for your limit that no more can be added.

Fix. Cancel waiting emails you no longer need, or raise your limit by upgrading or verifying.

500: server error

internal_error

500 · api_error

Something went wrong on our side. Retry with backoff; quote the request ID if it keeps happening.

Cause. Something failed on our side.

Fix. Retry with backoff (the Node SDK does). If it keeps happening, contact support with the request ID.

501: not available yet

not_implemented

501 · not_implemented

This endpoint isn't available yet.

Cause. This endpoint isn't available yet.

Fix. Check the docs for the endpoint's status. The error links to the closest working alternative where there is one.

503: service unavailable

service_unavailable

503 · api_error

The service is busy. Retry with backoff.

Cause. The API is busy or in maintenance.

Fix. Retry with backoff. Check the status page if it lasts more than a few minutes.

Was this page helpful?

On this page