Skip to Content
Errors

Errors

Every failure uses one envelope:

{ "error": { "code": "contact_already_exists", "message": "A contact with this email already exists in this audience", "param": "email", "request_id": "req_8fk2..." } }
  • code is the contract. Branch on it. Never parse message.
  • message is for humans and may change at any time.
  • param names the offending input field, when one is at fault.
  • request_id is always present. Include it when reporting a problem to day3 support.

Codes

StatusCodeMeaning
400invalid_requestMalformed body, or a value that failed validation.
400invalid_emailThe address is not a valid email.
400invalid_filterA stored segment filter no longer parses, so its members cannot be listed. A filter rejected on write is invalid_request.
400batch_too_largeMore than 1,000 items in one batch.
400email_suppressedOn POST /emails: the address hard-bounced, complained, or was suppressed by the provider.
401invalid_api_keyMissing, malformed, or unknown key.
401revoked_api_keyThe key was revoked.
403plan_limit_reachedOut of subscriber headroom, or out of monthly send allowance.
403sending_disabledSending is turned off for this account.
403domain_not_verifiedThe from domain is not a verified sending domain.
403sandbox_recipient_not_allowedFree plan, and the recipient is not a member of your organization.
403insufficient_scopeThe key lacks campaigns:send, automations:enroll or webhooks:manage.
403test_keys_not_supportedA day3_test_ key was used.
403forbiddenThe action is not allowed for this key or account state.
404not_foundNo such object. Also returned for another organization’s ids.
409contact_already_existsCreating a contact whose email is already in the audience, without ?upsert=true.
409email_suppressedOn contact writes: the address is on the account’s suppression list.
409idempotency_conflictSame Idempotency-Key, different body. Or the same key is already in flight.
409invalid_requestThe action conflicts with the object’s state: editing a campaign that has left draft, or enrolling into an unpublished automation.
422immutable_fieldChanging something that cannot change, such as a field’s key.
429rate_limit_exceededOver the request limit. Carries Retry-After.
500internal_errorOur fault. Retry, and send us the request_id.

What to retry

CodeRetry?
rate_limit_exceededYes, after Retry-After seconds.
internal_errorYes, with backoff.
idempotency_conflict meaning “already in progress”Yes, in a moment.
plan_limit_reachedNo. Tell the user to upgrade.
domain_not_verifiedNo. Verify the domain first.
email_suppressedNever. The address bounced or complained. Retrying it damages your sending reputation.
sandbox_recipient_not_allowedNo. Upgrade, or send to an organization member.
insufficient_scopeNo. Mint a key that has the scope.
invalid_request, invalid_emailNo. Fix the payload. param names the field.
invalid_filterNo. Rewrite the segment’s filter in the app or over the API.

Why email_suppressed appears twice

The same code shows up with two statuses, on purpose:

  • 400 on POST /emails. You asked to send to an address that must not be mailed.
  • 409 on contact writes. You asked to create a contact that conflicts with account-wide suppression state.

Both mean the address is unmailable. Neither should be retried.

Last updated on