Skip to content
Browse the docs

Integrating · Published 2026-09-04 · Updated 2026-10-31 · AgentiSend

Domains and DNS

The records to publish, what verification checks, the US / EU region choice, TLS mode, and the customer return-path host.

Add, publish, verify

POST /domains with a name. GET /domains/{id} returns the records to publish. POST /domains/{id}/verify re-checks them. Verification is a DNS read, so it is only as fast as your registrar's propagation — minutes usually, longer if your TTLs are long.

First send before any DNS

Two ways to send before your records resolve:

  1. Simulator. Address the mail to an address ending in @simulator.agentisend.com. Nothing leaves the building, it costs nothing, and any well-formed From is accepted.
  2. Onboarding sender. from: onboarding@agentisend.com delivers real mail only to this account's members — the addresses they sign in with. 20 per UTC day, counted against the plan's inclusion. No cc, bcc, attachments, tracking, or extra headers. Anyone else is refused. The message may arrive from another of our addresses, such as onboarding@notify.agentisend.com; GET /account names it as onboarding_sender.delivered_from.
POST /emails
{
  "from": "onboarding@agentisend.com",
  "to": ["you@your-login.example"],
  "subject": "First send",
  "text": "It reached you without a sending domain of your own."
}

Region

region is optional and defaults to us; the other value is eu. It is recorded on the domain, returned on every domain response, and cannot be changed later. Today all mail, eu domains included, is sent from our US nodes in Oregon, and every account's data is stored in the US. EU sending is on the roadmap; eu domains move to it automatically when it ships, with nothing to change on your side. For this release the names us-east-1, sa-east-1 and ap-northeast-1 still map to us, and eu-west-1 maps to eu.

The records

For notify.example.com, GET /domains/{id} returns zone — the zone you edit at your DNS provider, example.com here — and every record with name (the full name), host (the name relative to that zone, which is what a DNS panel asks for), value_strings (TXT split at 255 characters), and required. GET /domains/{id}/setup is the one-shot sheet: a zone file, copy-paste commands, and the provider when nameservers name one. It reads your nameservers, so it also notices when notify.example.com is delegated as a zone of its own; its hosts are then relative to that zone.

RecordTypeHost in the `example.com` zoneValueSending
DKIMTXTas1._domainkey.notifyv=DKIM1; k=rsa; p=… (the key we generated). Paste every value_strings entry, or the quoted value_bind form.Required
Return pathMXsend.notifyfeedback.agentisend-dns.com (priority 10)Required
Return pathTXTsend.notifyv=spf1 include:_spf.agentisend-dns.com -allRequired
SPFTXTnotifyv=spf1 include:_spf.agentisend-dns.com ~allRecommended
DMARCTXT_dmarc.notifyv=DMARC1; p=none; rua=mailto:dmarc@reports.agentisend-dns.comRecommended
TrackingCNAMElinks.notifythe value GET /domains/{id} shows when tracking is availableOptional
Tracking CAACAAlinks.notifythe value GET /domains/{id} shows when tracking is availableOptional

Sending from the apex, example.com itself, the hosts lose the .notify: as1._domainkey, send, @ for SPF, _dmarc and links. Paste the host a response gives you rather than retyping one from this table: a panel appends the zone, so pasting a full name creates send.notify.example.com.example.com.

  • DKIM signs each message with a key only we hold, so receivers can prove the message was not altered and did come from you. Publish every string in value_strings; a key truncated at 255 bytes by a DNS editor is the commonest reason DKIM never resolves. Required.
  • Return path is a subdomain of *your* domain (send. by default; pass return_path_subdomain: "bounce" on POST /domains when send. already has an MX pointing elsewhere). The MX lets bounces come back to us; the TXT keeps SPF aligned with your domain. Required on a new domain. Until both records resolve, the envelope sender stays your From address. After they resolve, it becomes a signed address on send.notify.example.com.
  • SPF on the sending domain itself (notify.example.com; the apex only when you send from the apex) is spoofing cover once MAIL FROM is send.. Recommended, not required — a domain verifies and sends without it. The record we suggest ends ~all, so mail from a service the record does not name is marked, not bounced. If that name already has an SPF record, merge ours into it and keep the ending it already has; never publish a second one.
  • DMARC tells receivers what to do when authentication fails, and asks them to report. Start at p=none with a reporting address, read the reports for a week, then move to quarantine. Recommended, not required — a domain verifies and sends without it, and the record shows as recommended rather than failing.
  • Tracking is a host on *your* domain that opens and clicks are counted on (default links.notify.example.com). Optional; it never blocks verification, and both tracking switches stay off until you turn them on. The CNAME appears on GET /domains/{id} when tracking is available. Until then, and until the CNAME resolves, links go out as you wrote them. Tracking never uses a shared AgentiSend hostname.
  • Tracking CAA is a CAA record on that same host. Shown only if this domain already limits which authorities may issue certificates and that set does not already allow ours. Without a restriction, any authority can issue and this record is omitted. Verification checks it when it is published; it never blocks sending.

GET /domains list items omit the DNS records (use GET /domains/{id} for the sheet). The tracking subdomain can be changed with PATCH /domains/{id} (tracking_subdomain); it cannot be removed. Changing it regenerates the tracking records as pending and stops rewriting links until you verify again. Signed click URLs on the previous host keep redirecting for 30 days.

Name, region, and return-path cannot change on an existing domain — add a new domain instead.

TLS

tls_mode is opportunistic or enforced. Set it on POST /domains or PATCH /domains/{id}. update_domain takes the same field.

Opportunistic — try TLS, fall back to plain when the receiver has none (the default). Enforced — refuse to deliver to a receiver that cannot do TLS; mail to such receivers bounces.

Open tracking on a transactional send (receipts, resets, alerts) returns a warning explaining that inbox providers can mistake that mail for marketing. Broadcasts do not warn. The send is never blocked.

If you already have an SPF record

A name may carry exactly one SPF record; two invalidate both. So merge ours into the record that is already there rather than adding a second one. Either form verifies:

v=spf1 ip4:5.78.29.80 ip4:5.78.29.195 ip4:5.78.28.193 ip4:5.78.24.66 ip4:65.109.252.126 ip4:116.202.178.98 ip4:89.58.59.120 ip4:81.16.16.132 ip4:81.16.16.133 ip4:81.16.16.134 ip4:81.16.16.135 ip4:81.16.16.136 ip4:116.202.3.255 ip4:95.216.181.142 ip4:167.233.187.20 ip4:167.233.178.88 ip4:167.233.184.228 include:_spf.mailprovider.example -all
v=spf1 include:_spf.agentisend-dns.com include:_spf.mailprovider.example -all

Those two keep -all because the record already published ended that way. A record that ended ~all stays ~all. We do not loosen an ending you published, and we do not tighten one either. Verification accepts both.

_spf.agentisend-dns.com holds the same seventeen addresses, so the include form stays correct if we add an IP. include:_spf.agentisend.com still authorises us. Verification accepts either: all seventeen ip4: mechanisms present, or either include — and the include only when that name currently publishes every sending IP. An include that does not resolve does not authorise us.

The return-path MX we show is feedback.agentisend-dns.com. mta1.agentisend.com still verifies if that is what is already published.

The same merge rule applies on send. if that name already has an SPF record.

If the root has no SPF record but receives mail

When the root has no SPF record, we read its MX before suggesting one. If mail for the domain goes to Google Workspace, Microsoft 365, Fastmail or Proton Mail, the record we show names that provider as well as us, so mail your people send from those mailboxes keeps passing SPF:

v=spf1 include:_spf.google.com include:_spf.agentisend-dns.com ~all

The record ends in ~all either way. If the MX is a provider we cannot name, the setup sheet says which host to add. Add any other service that sends as your domain before you publish.

Use a subdomain for application mail

Send from mail.yourdomain.com or notifications.yourdomain.com rather than the apex. The reputation of your receipts and your password resets then cannot be damaged by anything else the company sends, and the reverse is also true.

What verification checks

POST /domains/{id}/verify reads DNS and rolls the answers up. A new domain is verified when DKIM and both return-path records resolve. Root SPF, DMARC, tracking, and Tracking CAA never move the domain's status in either direction. A wrong tracking CNAME is marked failed on that row, and sending still works. Return-path is used for the envelope sender only after both of its records resolve. The detail and the verify response list which records are missing and what each does. Domains verified under the previous rule (DKIM + root SPF) stay verified.

Click tracking and open tracking default to off. Open tracking is a one-pixel image: Apple Mail Privacy Protection loads it whether or not anyone read the message, and most other clients block it. Treat the number as a trend, never as a count. Leave it off for receipts and alerts.

Who may write to this domain

Receiving is a separate switch from sending. Once it is on, a block rule refuses a sender when either the envelope or the From header matches it, and an allow list stores the message when either address matches an allow rule. The calls are on Receiving and replying.

Verification can be lost

A required record that is edited away is checked again after 1, 2, 5 and 10 minutes. The domain stays verified, and sending stays open, until two of those checks at least 10 minutes apart both miss it. Mail already accepted waits up to 72 hours for the record to come back, then fails. When the domain becomes failed, domain.failed fires. When it becomes partially_failed, domain.updated fires. A new send is refused with domain_not_verified, whose fix names POST /domains/{id}/verify. After the domain leaves verified, checks continue every 30 minutes for 72 hours and then once a day, and a restored record verifies with no further call. Subscribe to the domain.* events so this reaches you before a customer does.

Hand DNS to a human

POST /domains/{id}/setup-link returns a page the person who owns DNS can open without signing in. It shows the same records as GET /domains/{id}/setup, a zone file, and a button that reads DNS again. The link lasts 7 days. A second request replaces it. DELETE /domains/{id}/setup-link withdraws it.

POST /domains/{id}/setup-link
{
  "url": "https://console.agentisend.com/setup/…",
  "expires_at": "2026-10-27T12:00:00.000Z"
}

The page reads GET /domains/setup/{token}. That answer is the setup sheet, each record's current result, and whether the domain is verified. An agent calls domains_setup_link and pastes url.

A public count of how AI companies publish SPF, DKIM and DMARC is How AI companies set up SPF, DKIM and DMARC.