Adding and verifying a domain
To send from hello@acme.com you prove you own acme.com by publishing DNS records. Verification sets up DKIM signing (so receivers know the mail is really yours) and a custom return path (so SPF and DMARC align with your domain).
-
Add the domain
add-domain.ts import { SpacePost } from "@spacepost/node";const spacepost = new SpacePost(process.env.SPACEPOST_API_KEY);const { data: domain, error } = await spacepost.domains.create({ name: "acme.com" });if (error) throw new Error(`${error.name}: ${error.message}`);console.log(domain.id, domain.status); // "not_started" or "pending"for (const r of domain.records ?? []) {console.log(`${r.type.padEnd(5)} ${r.name} -> ${r.value}${r.priority ? ` (priority ${r.priority})` : ""}`);}Terminal window curl -X POST https://api.spacepost.dev/domains \-H "Authorization: Bearer $SPACEPOST_API_KEY" \-H "Content-Type: application/json" \-d '{ "name": "acme.com" }'r = requests.post("https://api.spacepost.dev/domains",headers={"Authorization": f"Bearer {os.environ['SPACEPOST_API_KEY']}"},json={"name": "acme.com"},)for rec in r.json()["records"]:print(rec["type"], rec["name"], rec["value"])You can also use the dashboard or
spacepost domains add acme.com. -
Create the DNS records
The response contains a
recordsarray and arecommended_recordsarray (DMARC):Response (abridged) {"object": "domain","id": "0192e1c4-0000-7000-8000-000000000001","name": "acme.com","status": "not_started","region": "eu-central-1","open_tracking": false,"click_tracking": false,"records": [{ "record": "DKIM", "name": "a1b2c3d4e5f6._domainkey", "type": "CNAME", "ttl": "Auto", "status": "not_started", "value": "a1b2c3d4e5f6.dkim.amazonses.com" },{ "record": "DKIM", "name": "g7h8i9j0k1l2._domainkey", "type": "CNAME", "ttl": "Auto", "status": "not_started", "value": "g7h8i9j0k1l2.dkim.amazonses.com" },{ "record": "DKIM", "name": "m3n4o5p6q7r8._domainkey", "type": "CNAME", "ttl": "Auto", "status": "not_started", "value": "m3n4o5p6q7r8.dkim.amazonses.com" },{ "record": "SPF", "name": "send", "type": "MX", "ttl": "Auto", "status": "not_started", "value": "feedback-smtp.eu-central-1.amazonses.com", "priority": 10 },{ "record": "SPF", "name": "send", "type": "TXT", "ttl": "Auto", "status": "not_started", "value": "\"v=spf1 include:amazonses.com ~all\"" }],"recommended_records": [{ "record": "DMARC", "name": "_dmarc", "type": "TXT", "ttl": "Auto", "status": "not_started", "value": "\"v=DMARC1; p=none;\"" }]}Add them at your DNS provider. See the records explained below and the provider guides.
-
Verify
DNS changes can take a few minutes (rarely hours). SpacePost rechecks pending domains automatically, and you can trigger a check at any time:
verify-domain.ts import { SpacePost } from "@spacepost/node";const spacepost = new SpacePost(process.env.SPACEPOST_API_KEY);const id = "0192e1c4-0000-7000-8000-000000000001";const { error } = await spacepost.domains.verify(id); // asks SpacePost to re-check DNS nowif (error) throw new Error(error.message);const { data: domain } = await spacepost.domains.get(id);console.log(domain?.status); // "verified" once DKIM is confirmedTerminal window curl -X POST https://api.spacepost.dev/domains/$DOMAIN_ID/verify -H "Authorization: Bearer $SPACEPOST_API_KEY"curl https://api.spacepost.dev/domains/$DOMAIN_ID -H "Authorization: Bearer $SPACEPOST_API_KEY"Terminal window spacepost domains verify acme.comspacepost domains doctor acme.com # looks up each record live and tells you what is missing or wrong
The records explained
Section titled “The records explained”Record names in the API are relative to your domain (send, _dmarc, a1b2c3d4e5f6._domainkey). Some DNS providers want the full name (send.acme.com); the provider guides say which.
| Record | Type | Name | Value | Purpose |
|---|---|---|---|---|
| DKIM (x3) | CNAME | <token>._domainkey |
<token>.dkim.amazonses.com |
Publishes the public keys Amazon SES rotates for you (“Easy DKIM”). Receivers use them to verify that each message was signed by your domain and not altered. Required: verification depends on all three. |
| Return path | MX | send |
feedback-smtp.<region>.amazonses.com, priority 10 |
Receives bounce and complaint notifications addressed to send.acme.com. Together with the TXT below it forms a custom MAIL FROM domain. |
| Return path | TXT | send |
v=spf1 include:amazonses.com ~all |
SPF for the return-path subdomain. Because the envelope sender is on your domain, SPF aligns with your From address, which DMARC needs. |
| DMARC (recommended) | TXT | _dmarc |
v=DMARC1; p=none; |
Tells receivers what to do with mail that fails authentication, and is required by Gmail and Yahoo for bulk senders. See DMARC. |
Statuses
Section titled “Statuses”| Status | Meaning |
|---|---|
not_started |
Domain added, DNS not yet seen. |
pending |
SpacePost is checking DNS. |
verified |
DKIM is confirmed. You can send from this domain. |
temporary_failure |
A lookup failed temporarily. It is retried automatically. |
failed |
DNS was not found within 72 hours, or a record is wrong. Fix the records and call verify again. |
The domain is verified as soon as DKIM passes. If only the return-path records are missing, mail still sends but SPF alignment falls back to Amazon’s domain, which weakens DMARC alignment. Fix it for best deliverability.
Each record in records has its own status with the same values, so you can see exactly which one is missing.
Sending from subdomains
Section titled “Sending from subdomains”If acme.com is verified you can send from any subdomain (news@mail.acme.com). Verifying the subdomain itself (mail.acme.com) is better practice for marketing mail because it keeps reputation separate from your transactional domain.
Limits
Section titled “Limits”| Plan | Domains |
|---|---|
| Free | 3 |
| Pro | 10 |
| Scale | 1,000 |
Adding a domain that another team already registered returns 422 validation_error (“Domain already registered”).
DNS provider guides
Section titled “DNS provider guides”Stuck? See Troubleshooting.