Questions · Updated 2026-09-27

How do I get notified when domain verification breaks?

Get notified when domain verification breaks by subscribing to the domain.* events on POST /webhooks and by leaving the domain_verification_lost notification on in GET /notifications/preferences. When a verified domain stops verifying, the webhook fires and GET /notifications opens a row naming the domain and its new status.

Get notified when domain verification breaks in two ways. Subscribe to the domain.* events on POST /webhooks; its events array takes domain.created, domain.verified, domain.failed, domain.updated and domain.deleted. And leave the domain_verification_lost notification type on in GET /notifications/preferences, where it reaches you by email and in the console unless you turn it off. Domains and DNS describes the break: "A required record that is edited away later moves the domain out of verified and fires domain.failed." Sends from that domain then answer domain_not_verified, and the fix names POST /domains/{id}/verify.

What fires

A verified domain is re-checked on its own; the notification that opens on verification says "Checks continue every 6 hours in case a record is removed." When a check finds a required record gone, GET /domains/{id}/events gains "The DKIM record is no longer found." (or the return-path row's name) and "Domain is no longer verified.", and the domain's status changes.

The webhook event depends on the new status: domain.failed when it is failed, domain.updated when it is a partial state. Both carry name, region, status, reason and records in data, each record with its own status, so the handler knows which row to restore without a second call. Subscribe to domain.* rather than to domain.failed alone; the guide's advice is "Subscribe to the domain.* events so this reaches you before a customer does." A lookup that does not complete does not demote: a verified domain stays verified when the only miss on a required row is the resolver timing out, and the row's reason reads unreachable.

curl -sS -X POST https://api.agentisend.com/webhooks \
  -H "Authorization: Bearer $AGENTISEND_API_KEY" \
  -H "Idempotency-Key: $(uuidgen)"
201
{
  "created_at": "2026-09-04T09:14:00Z",
  "disabled": true,
  "events": [
    "email.delivered",
    "email.bounced"
  ],
  "id": "9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42",
  "last_delivery_status": "pending",
  "secret": "string",
  "svix_compat": true,
  "updated_at": "2026-09-04T09:14:00Z"
}
Response

The notification

GET /notifications is the account's own list. Its summary: "Conditions this account should know about. Open rows are live; resolved ones ended. One row per condition, counted, never one per re-fire." The type is domain_verification_lost. The row's title is the domain name followed by "stopped verifying", and its body names the new status and says "Sends from it are refused until its DNS records resolve again; the Domains screen lists the exact records to restore." console_path opens that domain in the console. When the domain verifies again, the row resolves and a domain_verified row opens in its place.

GET /notifications/preferences lists every type with email and in_app; its summary is "Which channels each notification type uses. A type with no stored row is on for both." PATCH /notifications/preferences changes them, and its summary is "Turn a notification type on or off per channel. The gate is the type — there is no severity to mute instead." How do I control account notifications? walks through the rest of the list.

When it fires

Open GET /domains/{id} and read the rows where required is true and status is not verified. reason not_found means the record is gone; mismatch means it answers with something else, and observed shows what. Restore the row at your DNS provider using the row's host and value, then call POST /domains/{id}/verify. Until it returns verified, POST /emails from that domain is refused with domain_not_verified, while a send to an address ending in @simulator.agentisend.com still works.

Next