Skip to main content

Troubleshooting: EMAIL_TEST_RECIPIENT_NOT_VERIFIED

When your organization has no verified sending domain of its own, outbound email rides the platform’s shared sender. To keep that shared sender’s reputation intact, the send pipeline gates each recipient against an allowlist before dispatch: the recipient must be a saved contact on your audience, a verified member of your organization, or an address on the legacy verified-recipient list. A recipient in none of those buckets rejects with 422 EMAIL_TEST_RECIPIENT_NOT_VERIFIED — this is the test-mode gate. Verify your own sending domain and the gate steps aside for that sender entirely. Definitions live in the Error Code Reference; this page owns the recovery ladder.

Symptom

A send attempt returns 422 with code: EMAIL_TEST_RECIPIENT_NOT_VERIFIED per recipient. Replaying the same send produces the same reject — the gate is deterministic: nothing changed between attempts, so the same recipient fails identically every time. On a campaign or batch fan-out, each unverified recipient fails its own send while the verified rest of the batch proceeds.

Where the gate fires

The gate runs on the send’s admission path, before anything reaches the email provider, and only while the send resolves to the shared sender — the platform-default posture for an organization that has not verified its own sending domain. Three independent checks run there, in order:
  1. Suspension — a support-imposed halt (403 FORBIDDEN, “Email sending is suspended for this organization”). Unconditional: no allowlist or cap state overrides it.
  2. Daily cap — the shared sender enforces a per-organization daily ceiling; exhaustion rejects with 429 RATE_LIMIT_EXCEEDED rather than this code.
  3. Recipient allowlist — the gate this page covers. The allowlist is the union of (a) your saved contacts, (b) verified organization members, and (c) any addresses on the legacy verified-recipient list from the retired OTP-verify surface (still honored where present).
This is a deterministic refusal, distinct from the transient and the retryable classes in the rate-limit and cooldown taxonomy: retrying an unchanged send never clears it. It also differs from a production posture: once you send from a domain whose DNS you have verified, the send rides your own sender reputation and the recipient allowlist no longer applies to that sender — though the suspension flag and the daily ceiling remain.

Recovery ladder

Pick the step that matches why the recipient is missing:
  1. Save the recipient as a contact. If the recipient is a customer or lead you deliberately target, save them under Audience → Contacts and retry. This is the normal fix — the gate admits recipients your address book already claims.
  2. Invite them as an organization member. If the recipient is a teammate you are testing with, add them under Settings → Team; a member whose email is verified joins the allowlist automatically.
  3. Verify your own sending domain. Complete the DNS records under Email → Senders (see Domain Setup). A send from a verified domain skips the recipient allowlist entirely — this is the production posture, the right long-term answer for real traffic, and the moment test-mode scoping stops applying to that sender at all.
The legacy OTP-verified list needs no action: entries verified before the OTP surface retired keep passing.

Bulk path — campaigns and batch sends

The campaign executor aggregates per-recipient rejections: an audience with unverified recipients fails those rows with EMAIL_TEST_RECIPIENT_NOT_VERIFIED and completes the rest. Do not re-fire the whole campaign and read the failures one at a time. Instead sample first:
  1. Run a small slice of the audience through Messages → Batch (or POST /messages/batch) — the per-recipient receipt names each address that hits the gate, same as the bulk-review shape on messaging pre-send gates.
  2. Fix the list — save the failing addresses as contacts, or drop them from the audience.
  3. Then re-fire the campaign.
If the campaign’s whole recipient list should be reachable without per-recipient allowlisting, step 3 of the recovery ladder (a verified sending domain) is the correct escalation, not more retries.

What not to do

Do not loop retries. A deterministic 422 fails identically every time — a retry against an unchanged recipient list only burns your daily send ceiling and floods your own logs. Fix the recipient’s state first, then send exactly once.

When to escalate

The gate persisting after the recipient is saved as a contact (or verified as a member) is abnormal. Escalate to support with:
  1. Your organization ID — Settings → Organization, or from GET /api/v1/me.
  2. The exact code and meta.request_id from the rejected envelope.
  3. The recipient address and which allowlist step you completed (contact save, member invite, or domain verification).

See also