A domain is the identity your mail is signed with. Add it, publish its DNS records, verify it, and it can send.
The records
POST /domains answers with a records array. Publish the entries for what you use, exactly as given, at your DNS provider. Names are relative to your DNS zone: the table shows them for a domain at the root of its zone, and for send.acme.example each one carries .send — rasket._domainkey.send, send.send, links.send.
The DNS records a domain needs
Record
Type
Name
Value
DKIM
TXT
rasket._domainkey
A bare p=… value. The key is 2048-bit, so the value is published as two quoted strings — most providers do that for you when you paste it.
MAIL FROM
CNAME
send
<code>.rasket.net for the domain's region — us1.rasket.net for us-east-1. This is what makes bounces come back to us instead of to your own mail server, and what your SPF check passes on. Publish it DNS only, never proxied. Some domains are given an MX and a TXT at send instead; publish whichever records returns — both work.
Receiving
MX
@
Our inbound mail host for your region, priority 10, at receiving_host (@ by default). Only in us-east-1 and eu-west-1, and only needed once you turn receiving on.
Tracking
CNAME
links
links1.rasket-dns.com. Only needed if you turn on open or click tracking, and never proxied.
The first two are what sending needs. The Receiving and Tracking rows are in the array from the start, whatever the toggles say, but only have to verify once you turn receiving, or open or click tracking, on — a domain verifies for sending without them. The tracking guide covers it. No CAA record is required for any of them.
Send from a subdomain — send.acme.example rather than acme.example. A subdomain keeps your transactional reputation separate from whatever else your root domain does, and it means these records never collide with the ones your mail provider already publishes.
Publishing them for you
POST /domains/{domain_id}/autoconfigure writes the records through your DNS provider. Cloudflare is the only provider we can configure today. It takes an API token created from the Zone → DNS → Edit template and scoped to this domain's zone; a token covering more than one zone is refused, and a global API key is refused outright.
Only the records for capabilities you have enabled are published. Turn tracking on first if you want its record written too.
We never delete a record and never overwrite one we did not create. Anything already sitting at one of our names comes back in conflicts for you to resolve.
The token is deleted as soon as the records are written unless you pass keep_token. DELETE /domains/{domain_id}/autoconfigure/credential removes a kept one — that stops us using it, not anyone else, so revoke it at Cloudflare too.
Regions
region selects where your mail is signed and relayed from. It is a deliverability and latency choice, not a data residency one: it does not decide where your data is stored. A domain's region is fixed once it is created.
Verification
POST /domains/{domain_id}/verify checks now and returns the domain with each record's status. A second call within 15 seconds returns the current state without checking again.
We also re-check every domain on a schedule, so a record you publish will verify on its own without you polling.
A record that verified and later stops resolving is reported as drifted rather than silently ignored.
A record's status is about DNS only. A Receiving MX can read verified while capabilities.receiving is disabled: the record is in place, and receiving is off until you turn it on.
Claiming a domain someone else verified
A domain can be verified on one team at a time, so adding one another team already holds answers 409 resource_locked. POST /domains/claim is how you take it over, and the only way: prove you control the name in DNS.
The claim comes back with a TXT record to publish at the root of the domain. Its value always starts rasket-domain-verification=:
When the record resolves, the domain moves to your team and the previous owner's copy is switched off. There is no other route — no support ticket and no override.
The transfer waits if the current owner verified the domain in the last 72 hours, sent from it in the last 24 hours, or has mail scheduled from it. blocked_reason says which, and we re-check every hour.
A claim expires after 7 days. The domain arrives with fresh DKIM records of its own — the previous owner's values are never reusable — so publish those and verify as normal.
TLS
tls is opportunistic by default: we use TLS to the receiving server when it offers it. Setting it to enforced changes what happens when it does not — messages to mail servers that do not support TLS will not be sent and will appear as email.failed. That is the trade: no plaintext delivery, at the cost of some mail not arriving.
DMARC
DMARC is not required to verify a domain and we do not publish one for you. It is worth adding, starting at p=none and tightening once the reports look right:
If your domain already publishes _dmarc with p=reject and the MAIL FROM records above are not yet verified, mail you send through us may be rejected outright until alignment is in place. Publish the records first, verify, then send.
Rewrite the body to add a tracking pixel. Off by default.
click_trackingboolean
Rewrite links so clicks are recorded. Off by default.
tracking_subdomainstring
The label tracking links are served from. Defaults to links.
custom_return_pathstring
The label the sending records are published at. Leave it out and we pick the first label no other email service uses at your domain: rasket, then rasketmail, rk, rasket1, rasket2. A label that already holds another service's records answers 422 invalid_parameter with details.reasonreturn_path_in_use and a free details.suggestion.
receiving_hoststring
Where the domain receives mail: @ by default (anything@<name>), or a label such as inbound for anything@inbound.<name>. An MX at @ takes the domain's mail from its current mailbox provider.
confirm_replace_mxboolean
Only with receiving enabled. If the receiving name's MX already delivers to another mailbox provider, the request is refused with 409 receiving_mx_in_use unless this is true. Use a receiving_host label instead to leave that mail where it is.
tlsstring
opportunistic (the default) or enforced. Enforced refuses to deliver without TLS.
capabilitiesobject
{ sending, receiving }, each enabled or disabled. Defaults to sending on, receiving off; at least one must be on. Receiving in a region without it is 400 validation_error.
Publish the records for each capability you turned on (DKIM and the SPF CNAME for sending), then call verify. Nothing sends until the domain is verified.
records lists every group whatever the toggles say — Tracking, and in us-east-1 and eu-west-1 a Receiving MX at receiving_host — so you can see what turning one on would need. Record names are relative to your DNS zone: for send.acme.example in acme.example, the return-path CNAME sits at rasket.send.
region is where your mail is sent from, not where your data is stored.
A name another team has already verified answers 409 resource_locked.
custom_return_path in the response is the label we chose when you named none.
Change tracking, TLS, the tracking subdomain, the return path or where the domain receives mail.
Path parameters
domain_idstringRequired
The domain's ID.
Body
open_trackingboolean
Turn the tracking pixel on or off.
click_trackingboolean
Turn link rewriting on or off.
7 more fields (tls, tracking_subdomain, receiving_host, custom_return_path, confirm_replace_mx, capabilities, region)
tlsstring
opportunistic or enforced.
tracking_subdomainstring
Changing this publishes a new record and re-verifies tracking.
receiving_hoststring
A label or @. Changing it moves the Receiving MX to the new name and re-verifies receiving; mail is accepted at the new address once that MX verifies.
custom_return_pathstring
Changing it moves the sending records to the new label: publish them there and keep the old ones until the new ones verify. The domain keeps sending meanwhile. A label that already holds another service's records answers 422 invalid_parameter.
confirm_replace_mxboolean
Turning receiving on, or moving receiving_host, at a name whose MX already delivers to another mailbox provider is 409 receiving_mx_in_use unless this is true.
capabilitiesobject
{ sending, receiving }, each enabled or disabled; name one or both. At least one must stay on.
regionstring
Fixed at creation. Sending it is 422 invalid_parameter.
The check runs immediately and the call waits up to 10 seconds for it.
A second call within 15 seconds returns the current state without checking again. So does a call while a check is already running, or one whose check does not finish in time; the scheduled check then finishes it.
We also re-check every domain on a schedule, so a published record verifies on its own within the hour.
Verification reads DNS. A record published seconds ago may still be cached as absent by the resolver.
Publish the DKIM record's new value before your next send. The old key stops signing immediately, and the domain is not verified for sending again until we see the new record.
One call per minute per domain. Verifying the domain within that minute also counts.
Publish the returned TXT record at the root of the domain. We check it on a schedule; when it resolves, the domain moves to your team and the previous owner's copy is switched off.
The transfer waits if the current owner verified the domain in the last 72 hours, sent from it in the last 24 hours, or has scheduled mail from it. blocked_reason says which, and we re-check every hour.
A claim expires after 7 days. Calling this again while a claim is open returns that claim unchanged with 200 rather than starting a second one.
The domain arrives with new DKIM records of its own: the previous owner's values are never reusable. Publish them and verify the domain as normal.
Poll this to follow a claim: pending while we look for the record, blocked with a reason while the current owner is still active, completed once the domain is yours.
Only records for capabilities you have enabled are published. Turning on receiving or tracking first, then running this, is what publishes those records.
We never delete a record, and never overwrite one we did not create. Anything already sitting at one of our names comes back in conflicts for you to resolve.
The token is encrypted at rest and only ever used for this domain's zone. Revoke it at Cloudflare when you are done — deleting it here stops us using it, not anyone else.
One call per minute per domain. Verifying the domain within that minute also counts.
Store an SVG as this domain's brand logo and get the URL it is served at.
Path parameters
domain_idstringRequired
The domain's ID.
Body
svgstringRequired
The logo, as SVG source. It has to be a square SVG Tiny Portable/Secure file: a <title>, baseProfile="tiny-ps", version="1.2", a square viewBox, and none of <script>, <image>, <use>, <a>, animation, event handlers or references to anything outside the file.
Nothing is repaired or stripped. A file that breaks any of the rules is refused with one sentence per rule it breaks, and no logo is stored.
The URL carries the digest of the bytes it serves, so uploading a new logo gives you a new URL. Publish the default._bimi record again after you do.
The logo is at most 32 KB, and one per domain — uploading again replaces the one that is there.
Whether a recipient sees it is up to their mail app. Most show a self-asserted logo only once your DMARC policy is at quarantine or reject, and some show one only with a paid certificate.
state is none, awaiting_certificate, active, logo_changed or expired. Only active is published.
logo_changed means the logo was replaced after the certificate was issued. Nothing is thrown away: put the previous logo back, or ask your authority to re-issue for the new one.
The private key never leaves us and is in no response.
{
"object": "domain_brand_certificate",
"domain_id": "d91a7b60-1a5f-4a2e-9d1b-0d9f2c7a1e34",
"state": "awaiting_certificate",
"csr_pem": "-----BEGIN CERTIFICATE REQUEST-----\nMIICrTCC…\n-----END CERTIFICATE REQUEST-----\n",
"subject": {
"common_name": "mail.example.com",
"organization": "Acme Corporation",
"organizational_unit": null,
"locality": "Portland",
"state": "Oregon",
"country": "US"
},
"requested_at": "2026-09-09T09:30:00.000Z",
"url": null,
"bytes": null,
"sha256": null,
"issuer": null,
"expires_at": null,
"installed_at": null,
"published": false,
"reason": "Take the request below to a certificate authority. When they issue your certificate, paste it here."
}
This needs a paid plan, and the domain needs a brand logo: a certificate is issued for the logo it will be published with.
You buy the certificate from the authority. We charge nothing for it and never see the transaction.
Calling this again while a request is open returns the same request, because that one may already be with the authority. Delete the certificate first to start over.
The chain is accepted only if its first certificate carries the public key of this domain's request, it is inside its validity window, and each certificate is signed by the one after it.
Publish the default._bimi record again afterwards: its value has changed.