Skip to main content
Read the current domain and required DNS records, save an operation ID, then set or validate the domain. These settings use the configured SendGrid account and are shared across live/test data modes. Staging can use the same provider account as production; a test credential does not isolate DNS operations.

Read domain and DNS state

Use a verified personal MCP credential or signed-in Firebase user. Team API/OAuth keys cannot impersonate their creator. Current unblocked members can read state; writes and operation recovery require a current team or billing administrator. Inspect data.domain.configured, data.domain.valid, data.domain.dns_setup and data.active_operation. A configured domain may still need DNS changes. Each DNS entry includes host, type, data and valid. Install the supplied records through your DNS administrator. The historical full_domain display value uses subdomain@domain; it is not a website URL.

Set a domain with a saved operation ID

Generate a UUID v4 and save it before sending the change:
The server normalizes DNS names to lowercase/IDNA and validates labels. Domain and subdomain each allow at most 253 characters; labels allow 1–63 letters, digits or hyphens, without leading/trailing hyphens. The domain must include a dot. Do not submit an email address, URL or provider key. A repeated operation ID with the identical action/body returns the same operation. Different input under that ID returns a conflict. Replacing a configured domain retains the old provider domain; result.previous_provider_domain_retained reports this. completed means setup completed, not that DNS is valid.

Validate or remove the current domain

After installing DNS, send POST /teams/{id}/email-domain/validate with a new saved operation_id. Inspect result.domain.valid and individual DNS records. To remove the current configuration, send DELETE /teams/{id}/email-domain with a new operation_id. The server removes the exact stored provider domain and clears local state only after confirmation. It does not sweep previously retained provider domains.

Ownership verification

data.ownership_status is verified or migration_required. Unverified legacy configuration remains readable with can_manage:false. Mutations and provider reconciliation return HTTP409 domain_migration_required until an operator verifies ownership independently of historical client-writable IDs. Do not clear or rewrite team fields to bypass this state. Provider bindings and locks now live in server-only records; browser-visible team fields are read mirrors.

Recover an interrupted operation

Read GET /teams/{id}/email-domain/operations/{operationId} after a timeout. A failed or outcome_unknown operation is unsuccessful even if HTTP status is 200; preserve the response for recovery. Times are milliseconds. Send POST /operations/{operationId}/reconcile under the email-domain base with {} to check exact local/provider evidence. This does not repeat a provider write. An optional observation describes current state with attempt_confirmed: false; it cannot prove that the original validation happened. A lost creation response is not confirmed by finding a same-name domain. An uncertain operation holds a team lock shared by the API and dashboard. After ten minutes, a current administrator can explicitly send {"acknowledge_unconfirmed_effects":true} to POST /operations/{operationId}/resolve. This releases the lock for a new operation, preserves the old unknown result, and does not undo remote effects. Never resolve and retry automatically. 401 requires personal authentication; 403 requires current authority. For 409 domain_migration_required, request operator ownership verification; waiting or retrying does not resolve it. Other 409 responses can require inspecting the existing operation or waiting until recovery is eligible. These routes have offline coverage; live provider validation remains subject to the actual authorized environment and effects.