Domain verification & DNS
Verify ownership of your sending domain using the TXT records generated for your account.
1. Check before adding
Adding a domain requires an active package and an available node. max_domains is a hard package limit, not technically unlimited domains. Multiple domains share the current account package’s sending quota. Use an ASCII FQDN and investigate conflicts, limits or node failures before submitting again.
curl -X POST "${SMTPDOG_API_ORIGIN}/domains" \
-H "Authorization: Bearer ${SMTPDOG_SESSION_TOKEN}" \
-H "Content-Type: application/json" \
--data '{"domain_name":"example.com"}'2. Use the real TXT records
The creation response or GET /domains/{id} can return dns_records with type, name and value. Use the actual DKIM selector, public key and SPF include values. No publishable demo TXT is provided here. DNS providers may require a relative host name. Review merging an existing SPF record instead of blindly replacing it or publishing several SPF records.
| Field / setting | Type / status | Description |
|---|---|---|
| type | string | Currently TXT |
| name | string | Use the returned full record name; check provider relative Host rules |
| value | string | Use the returned DKIM key / SPF value, not demo data |
type: TXT
name: <use the actual dns_records[].name>
value: <use the actual dns_records[].value>3. Add the records on your DNS provider
Every sending domain gets its own DKIM selector, public key and SPF record in your account. Add them as TXT records at your DNS provider, then run verification in the console.
- STEP 01 · Get your recordsAdd the domain in the console
Add your domain (or a subdomain) in the console. It returns your own dns_records list with type, name and value.
- STEP 02 · Add TXT recordsCreate them at your DNS provider
Sign in to your DNS provider and add each record as TXT. Pay attention to whether the host field expects a relative name.
- STEP 03 · VerifyConfirm all_passed
Wait for the records to propagate, then click Verify in the console. You can send once the SPF and DKIM checks pass (all_passed is true).
Step-by-step by DNS provider
Providers differ in whether they append your root domain to the host field. Pick yours:
1. Where to go
Cloudflare dashboard → select your domain → DNS → Records → Add record.
2. What to enter as Host / Name
In Name, enter @ for a root-domain record such as SPF, or the subdomain prefix such as mail. For DKIM enter the relative part, <selector>._domainkey. Cloudflare also accepts the full name and normalises it.
3. Record type and value
Set Type to TXT and paste the exact value from the console into Content, without extra spaces at either end.
4. TTL and timing
Leave TTL on Auto. TXT records are never proxied. Changes usually appear quickly, but allow a few minutes.
1. Where to go
Alibaba Cloud console → Alibaba Cloud DNS → Public Zone → your domain → Settings → Add Record.
2. What to enter as Host / Name
Important: the Host field takes the relative name only; the console appends your domain automatically. Enter @ for example.com, mail for mail.example.com, and <selector>._domainkey for the DKIM record.
3. Record type and value
Set Record Type to TXT and paste the full SPF or DKIM string into Record Value.
4. TTL and timing
Keep the line on Default. A TTL of 10 minutes (600 s) works well; wait a few minutes before verifying.
1. Where to go
DNSPod console → My Domains → open your domain → Add Record.
2. What to enter as Host / Name
Same rule as Alibaba Cloud: enter only the relative name — @ for the root, or the prefix for a subdomain or DKIM. Do not type your domain again, otherwise the record becomes example.com.example.com and verification fails.
3. Record type and value
Choose TXT and paste the value as shown in the console. Do not add your own quotation marks.
4. TTL and timing
Set Line to Default and keep the default TTL of 600 s, then run verification in the console.
1. Where to go
Route 53 console → Hosted zones → your domain → Create record.
2. What to enter as Host / Name
Check whether the Record name box already ends with your domain. If it does, enter only the relative part (leave it empty for the root domain). Create the SPF and DKIM values as separate TXT records.
3. Record type and value
Choose TXT and paste the value. If the host already has an SPF record, merge the include into that single v=spf1 record. A single text string is limited to 255 characters, so if the provider rejects the long DKIM value, split it into several quoted strings of up to 255 characters inside the same record.
4. TTL and timing
A TTL of 300 s (5 minutes) is a good starting point; verify once your provider has propagated the change.
Provider consoles change their layout from time to time. If a label differs, apply the same rules: relative host, type TXT, exact value.
Host name conversion reference
When your provider appends your root domain automatically, convert the full name returned by the console into a relative host:
| Scenario | Name returned by the console | Host to enter | Notes |
|---|---|---|---|
| Root domain SPF | example.com | @ | @ means the root domain. If an SPF record already exists, merge into it instead of adding a second one. |
| Subdomain SPF | mail.example.com | Drop the trailing .example.com and keep only the subdomain prefix. | |
| Root domain DKIM | <selector>._domainkey.example.com | <selector>._domainkey | Use the selector the console returned and drop the root domain. |
| Subdomain DKIM | <selector>._domainkey.mail.example.com | <selector>._domainkey.mail | Keep the subdomain part (.mail) and drop only the trailing .example.com. |
Common pitfalls
1. One SPF record per host: a host cannot have several v=spf1 TXT records. If you already use SPF for another mail service, merge the include from the console into it rather than adding a second record.
2. Long DKIM values: the DKIM public key is longer than 255 characters. Most providers split it for you; if yours does not, split it into several quoted strings of up to 255 characters inside one TXT record.
3. HTTP 200 from the verify endpoint only means the check ran. Look for all_passed = true, and compare expected_value with found_values in checks[] when something fails.
4. Verify and inspect the result
POST /domains/{id}/verify needs no body. all_passed may still be false with HTTP 200. Inspect each check’s passed, expected_value, found_values and lookup_error. Require all checks to pass. DNS verification does not prove node deployment is complete and is not a promise of continuous monitoring.
| Field / setting | Type / status | Description |
|---|---|---|
| all_passed / status | bool / string | Overall pass and current status |
| checks[].name | string | dkim / spf |
| record_name / expected_value / passed | string / bool | Expected record values and pass result |
| found_values / lookup_error | string[] / string | Optional DNS troubleshooting context |
curl -X GET "${SMTPDOG_API_ORIGIN}/domains/${SMTPDOG_DOMAIN_ID}" \
-H "Authorization: Bearer ${SMTPDOG_SESSION_TOKEN}"
curl -X POST "${SMTPDOG_API_ORIGIN}/domains/${SMTPDOG_DOMAIN_ID}/verify" \
-H "Authorization: Bearer ${SMTPDOG_SESSION_TOKEN}"5. Troubleshoot and unbind
For a TXT mismatch, check the full name/value, propagation and provider host format. There is no DMARC verification endpoint. DELETE /domains/{id} disables a domain while retaining history; immediate rebinding or account transfer is not guaranteed. Contact support for partial creation failures instead of retrying indefinitely.