Domains
Add a sending domain, publish its DNS records and verify it.
You can only send from a domain that belongs to your project and is verified. Verification proves you own the domain and sets up SPF, DKIM and DMARC so receiving servers trust your mail.
All endpoints on this page accept an email API key (or a Helipod API key with the Email API enabled) and act on the key's project.
Domain object
Prop
Type
DNS records
Each entry of dnsRecords is one record to create:
Prop
Type
A fully provisioned domain returns:
| Purpose | Type | Host |
|---|---|---|
| Domain ownership verification | TXT | a verification name under your domain |
| SPF | TXT | your domain |
| DMARC | TXT | _dmarc. + your domain |
| DKIM signing keys (one record per key, usually three) | CNAME | <selector>._domainkey. + your domain |
| Custom MAIL FROM (bounce path), listed until it is verified | MX and TXT | the MAIL FROM domain (bounce. + your domain) |
| Receiving, only when receiving is enabled | MX | the receiving host |
Always copy host and value exactly as the API (or the dashboard) returns them. DKIM selectors and the verification value are unique to your domain. Do not reuse records from another domain or from an example.
If the DKIM records are missing, publish the ownership record first and call verify: DKIM records can appear only after ownership is confirmed. The MAIL FROM records leave the list once that domain is verified, so keep them published.
If your domain already has an SPF record, merge the mechanism from the returned SPF value into your existing record instead of adding a second SPF record: a domain may have only one.
List domains
/domainscurl https://mail.helipod.io/api/email/domains \
-H "Authorization: Bearer your_email_api_key"Returns data as an array of domain objects.
Add a domain
/domainsProp
Type
curl -X POST https://mail.helipod.io/api/email/domains \
-H "Authorization: Bearer your_email_api_key" \
-H "Content-Type: application/json" \
-d '{"domain":"example.com"}'Response 202: the domain object (status pending) plus a jobId. The dnsRecords in this response are not complete yet: the verification value and the DKIM records appear once the job has finished. Poll GET /jobs/{jobId} until it completes, then read GET /domains/{id}.
{
"success": true,
"data": {
"id": "3f2a9c4e-1b7d-4e0a-9c55-2d8f6b1a7e10",
"domain": "example.com",
"status": "pending",
"dkimStatus": "pending",
"spfValid": false,
"dkimValid": false,
"dmarcValid": false,
"mailFromDomain": null,
"mailFromStatus": null,
"inboundEnabled": false,
"inboundHost": null,
"inboundMxValid": false,
"inboundEnabledAt": null,
"dnsRecords": ["..."],
"verifiedAt": null,
"createdAt": "2026-10-16T09:14:03.221Z",
"jobId": "eml_8f21c0a94d7b4c2e9a1f"
}
}Errors: 400 INVALID_DOMAIN, 409 DOMAIN_EXISTS, 402 DOMAIN_LIMIT_REACHED.
Get a domain
/domains/{id}curl https://mail.helipod.io/api/email/domains/3f2a9c4e-1b7d-4e0a-9c55-2d8f6b1a7e10 \
-H "Authorization: Bearer your_email_api_key"{
"success": true,
"data": {
"id": "3f2a9c4e-1b7d-4e0a-9c55-2d8f6b1a7e10",
"domain": "example.com",
"status": "pending",
"dkimValid": false,
"spfValid": false,
"dmarcValid": false,
"dnsRecords": [
{ "type": "TXT", "host": "<verification host from the API>", "value": "<verification value from the API>", "purpose": "Domain ownership verification (TXT)" },
{ "type": "TXT", "host": "example.com", "value": "<SPF value from the API>", "purpose": "..." },
{ "type": "TXT", "host": "_dmarc.example.com", "value": "v=DMARC1; p=none", "purpose": "..." },
{ "type": "CNAME", "host": "<selector1>._domainkey.example.com", "value": "<DKIM target from the API>", "purpose": "DKIM signing key 1 of 3" },
{ "type": "CNAME", "host": "<selector2>._domainkey.example.com", "value": "<DKIM target from the API>", "purpose": "DKIM signing key 2 of 3" },
{ "type": "CNAME", "host": "<selector3>._domainkey.example.com", "value": "<DKIM target from the API>", "purpose": "DKIM signing key 3 of 3" }
]
}
}The example is abridged and uses placeholders; your response contains the real values to publish. The suggested DMARC policy is p=none; tighten it to quarantine or reject once your mail is passing.
Returns 404 DOMAIN_NOT_FOUND for an unknown id.
Verify a domain
/domains/{id}/verifyCall this after publishing the records. DNS changes can take from minutes to hours to propagate; it is safe to call again.
curl -X POST https://mail.helipod.io/api/email/domains/3f2a9c4e-1b7d-4e0a-9c55-2d8f6b1a7e10/verify \
-H "Authorization: Bearer your_email_api_key"{ "success": true, "data": { "alreadyVerified": false, "jobId": "eml_1c2d3e4f5a6b7c8d9e0f" } }alreadyVerified is true when the domain was already fully green before this check (verified, with SPF, DKIM and DMARC valid). A check is queued either way. When the job completes, read GET /domains/{id}: status becomes verified once ownership and DKIM pass, and spfValid and dmarcValid reflect live DNS lookups.
Remove a domain
/domains/{id}curl -X DELETE https://mail.helipod.io/api/email/domains/3f2a9c4e-1b7d-4e0a-9c55-2d8f6b1a7e10 \
-H "Authorization: Bearer your_email_api_key"{ "success": true, "data": { "jobId": "eml_9e8d7c6b5a4f3e2d1c0b", "domain": "example.com" } }The domain stays in the list until the job completes. After that, sends from it return 403 DOMAIN_NOT_FOUND.