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