AUTH4D-200 Sending domain without a domains provider
AUTH4D-200 changes what the sending-domain routes (AUTH4D-168) do when the deployment has no
RESEND_DOMAINS_API_KEY. No contract or migration changes.
Behaviour
| Request (no domains provider) | Status | error.code |
|---|---|---|
POST /management/tenants/{tenantId}/sending-domain |
503 | sending_domains_unavailable |
POST …/sending-domain/verify or DELETE …/sending-domain, row |
503 | sending_domains_unavailable |
POST …/verify or DELETE, no row |
404 | not_found |
GET …/sending-domain |
200 | stored state, no refresh |
The add check runs after role, body validation and the request body check, and before the
per-project add budget, so it costs no budget. Nothing is stored, no audit event is written and no
request reaches Resend. Responses carry Cache-Control: no-store. Verification emails keep the
auth4.dev sender, because only a verified row changes it.
503 temporarily_unavailable keeps its meaning: a provider is configured but could not be reached.
Why
Before AUTH4D-200 the API fell back to the sending key RESEND_API_KEY when
RESEND_DOMAINS_API_KEY was unset. On staging, where RESEND_API_KEY is a sending-only key, saving a
domain reached Resend and answered 409 domain_unavailable, so the console said the domain “may
already be used by another project”. Nothing was stored, but the notice was wrong, and the outcome
depended on how Resend worded its refusal.
Console
Settings → Sending domain maps sending_domains_unavailable to its own notice: “Sending domains
aren’t available on this deployment yet. Verification emails keep coming from the auth4.dev
address.” The server’s message is never shown.
Tests
tests/integration/auth4d-200.sending-domain-unconfigured.test.ts: staging-like bindings (sending key set, no Domains API key). It checks the code, no outbound request, no row, no audit event, the auth4.dev sender, and verify and remove on an existing row. It fails without the fix.tests/e2e/auth4d-200.sending-domain-unconfigured.spec.ts(tests/e2e/auth4d-200.playwright.config.ts, port 5200): the console notice at 1280 and 320 px, with the server message hidden and axe clean.
Source: docs/api-spec/auth4d-200.md