Domains API
Manage sending domains and their DKIM verification status.
Every request needs a bearer token and goes to a path under https://api.anypost.com/v1. See API conventions for the shared request, error, and pagination rules.
List domains
GET /v1/domains
Returns the authenticated team's domains, newest-first, with cursor pagination.
Parameters
limitintegerin query[optional]Number of items to return.
afterstringin query[optional]Opaque cursor from a previous response's
next_cursor. Do not parse.
Example request
curl https://api.anypost.com/v1/domains \
-H "Authorization: Bearer $ANYPOST_API_KEY"Response body
On success (200), the response body is:
dataarray of Domainhas_morebooleannext_cursorstringMay be null.
{
"data": [
{
"id": "domain_550e8400-e29b-41d4-a716-446655440000",
"name": "example.com",
"status": "pending",
"dns_records": [
{
"type": "CNAME",
"name": "anypost",
"value": "dxyz12345.c.anypost.email",
"purpose": "verification"
}
],
"verification_failure": {
"code": "string",
"message": "string"
},
"tracking": {
"opens_enabled": true,
"clicks_enabled": true,
"subdomain": "track",
"dns_records": [
{
"type": "CNAME",
"name": "anypost",
"value": "dxyz12345.c.anypost.email",
"purpose": "verification"
}
],
"status": "disabled",
"verification_failure": {
"code": "string",
"message": "string"
},
"verified_at": "string"
},
"created_at": "string",
"verified_at": "string"
}
],
"has_more": true,
"next_cursor": "string"
}Responses
| Status | Description |
|---|---|
200 | Paginated list of domains. |
401 | Missing or invalid credentials. |
Create a domain
POST /v1/domains
Adds a new sending domain for the authenticated team and
generates its DKIM keys. Anypost publishes the authoritative
DKIM/SPF/MX records in its own DNS; the customer only needs to
publish the CNAME records returned in the response's
dns_records array, then call POST /domains/{id}/verify.
If Anypost cannot publish the domain's records, the create is
rolled back atomically and a 503 is returned — no
half-created domain is left behind. Safe to retry.
Request body
Send as JSON with Content-Type: application/json.
namestring[required]
Example request
curl https://api.anypost.com/v1/domains \
-X POST \
-H "Authorization: Bearer $ANYPOST_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"name": "example.com"
}'Response body
On success (201), the response body is:
idstringnamestringstatusstringpendinguntil the customer's CNAMEs resolve to our authoritative records; flips toverifiedafter a successful verify call. Reflects mail-flow verification only — tracking-CNAME issues are reported separately viatracking.statusand never affect this field.One of:
pending,verified.dns_recordsarray of DnsRecordThe mail-flow DNS records the customer should publish at their provider to verify the domain and route DKIM/SPF/MX through us. Iterate and publish each record verbatim. Always one verification CNAME plus one CNAME per active DKIM selector (typically two). Tracking-related records are surfaced separately under
tracking.dns_records.verification_failureVerificationFailure or nullMost recent mail-flow verification failure, or null when the domain is verified or has never been checked.
codeis one ofapex_cname_missing,apex_cname_mismatch,dkim_cname_missing,dkim_cname_mismatch,dkim_mismatch,chain_broken,mx_missing,spf_missing.trackingDomainTrackingBranded open / click tracking configuration for a domain. Tracking is opt-in and entirely independent of mail-flow verification — failures here never affect
Domain.statusor interrupt sending.created_atstring (date-time)verified_atstring (date-time)When the domain most recently transitioned to
verified.May be null.
{
"id": "domain_550e8400-e29b-41d4-a716-446655440000",
"name": "example.com",
"status": "pending",
"dns_records": [
{
"type": "CNAME",
"name": "anypost",
"value": "dxyz12345.c.anypost.email",
"purpose": "verification"
}
],
"verification_failure": {
"code": "string",
"message": "string"
},
"tracking": {
"opens_enabled": true,
"clicks_enabled": true,
"subdomain": "track",
"dns_records": [
{
"type": "CNAME",
"name": "anypost",
"value": "dxyz12345.c.anypost.email",
"purpose": "verification"
}
],
"status": "disabled",
"verification_failure": {
"code": "string",
"message": "string"
},
"verified_at": "string"
},
"created_at": "string",
"verified_at": "string"
}Responses
| Status | Description |
|---|---|
201 | Domain created. Status is pending until verified. |
401 | Missing or invalid credentials. |
413 | Request body exceeded the 5 MB gateway limit. Rejected at the transport layer before authentication or validation, so the response uses a shorter error shape than application-layer errors. The connection is closed after the response. |
422 | Request validation failed. |
503 | Anypost could not publish the domain's authoritative records. The domain was rolled back, so it is safe to retry. Persistent failures are an operational issue on Anypost's side. |
Retrieve a domain
GET /v1/domains/{id}
Returns metadata for a single domain, including the CNAMEs the customer must publish, the active DKIM selectors, the most recent verification failure category (if any), and the current tracking configuration and status.
Parameters
idstringin path[required]
Example request
curl https://api.anypost.com/v1/domains/domain_550e8400-e29b-41d4-a716-446655440000 \
-H "Authorization: Bearer $ANYPOST_API_KEY"Response body
On success (200), the response body is:
idstringnamestringstatusstringpendinguntil the customer's CNAMEs resolve to our authoritative records; flips toverifiedafter a successful verify call. Reflects mail-flow verification only — tracking-CNAME issues are reported separately viatracking.statusand never affect this field.One of:
pending,verified.dns_recordsarray of DnsRecordThe mail-flow DNS records the customer should publish at their provider to verify the domain and route DKIM/SPF/MX through us. Iterate and publish each record verbatim. Always one verification CNAME plus one CNAME per active DKIM selector (typically two). Tracking-related records are surfaced separately under
tracking.dns_records.verification_failureVerificationFailure or nullMost recent mail-flow verification failure, or null when the domain is verified or has never been checked.
codeis one ofapex_cname_missing,apex_cname_mismatch,dkim_cname_missing,dkim_cname_mismatch,dkim_mismatch,chain_broken,mx_missing,spf_missing.trackingDomainTrackingBranded open / click tracking configuration for a domain. Tracking is opt-in and entirely independent of mail-flow verification — failures here never affect
Domain.statusor interrupt sending.created_atstring (date-time)verified_atstring (date-time)When the domain most recently transitioned to
verified.May be null.
{
"id": "domain_550e8400-e29b-41d4-a716-446655440000",
"name": "example.com",
"status": "pending",
"dns_records": [
{
"type": "CNAME",
"name": "anypost",
"value": "dxyz12345.c.anypost.email",
"purpose": "verification"
}
],
"verification_failure": {
"code": "string",
"message": "string"
},
"tracking": {
"opens_enabled": true,
"clicks_enabled": true,
"subdomain": "track",
"dns_records": [
{
"type": "CNAME",
"name": "anypost",
"value": "dxyz12345.c.anypost.email",
"purpose": "verification"
}
],
"status": "disabled",
"verification_failure": {
"code": "string",
"message": "string"
},
"verified_at": "string"
},
"created_at": "string",
"verified_at": "string"
}Responses
| Status | Description |
|---|---|
200 | The domain. |
404 | Resource not found. |
Update a domain
PATCH /v1/domains/{id}
Updates the domain's tracking configuration. The domain name
is immutable through this endpoint — only the fields under
tracking may be changed.
When either tracking flag is enabled, tracking.subdomain is
required. The server composes the full tracking host as
{subdomain}.{Domain.name}, which is what the customer
publishes as a CNAME and what we look up to verify. Tracking
hosts are unique within a team. Toggling a flag or changing
the subdomain clears any previous tracking verification — the
customer must re-publish the CNAME shown in
tracking.dns_records and call POST /domains/{id}/verify
again. Mail-flow verification is unaffected.
Parameters
idstringin path[required]
Request body
Send as JSON with Content-Type: application/json.
trackingobject[required]Tracking config patch. Any of the inner fields may be omitted — only supplied keys are updated.
Example request
curl https://api.anypost.com/v1/domains/domain_550e8400-e29b-41d4-a716-446655440000 \
-X PATCH \
-H "Authorization: Bearer $ANYPOST_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"tracking": {}
}'Response body
On success (200), the response body is:
idstringnamestringstatusstringpendinguntil the customer's CNAMEs resolve to our authoritative records; flips toverifiedafter a successful verify call. Reflects mail-flow verification only — tracking-CNAME issues are reported separately viatracking.statusand never affect this field.One of:
pending,verified.dns_recordsarray of DnsRecordThe mail-flow DNS records the customer should publish at their provider to verify the domain and route DKIM/SPF/MX through us. Iterate and publish each record verbatim. Always one verification CNAME plus one CNAME per active DKIM selector (typically two). Tracking-related records are surfaced separately under
tracking.dns_records.verification_failureVerificationFailure or nullMost recent mail-flow verification failure, or null when the domain is verified or has never been checked.
codeis one ofapex_cname_missing,apex_cname_mismatch,dkim_cname_missing,dkim_cname_mismatch,dkim_mismatch,chain_broken,mx_missing,spf_missing.trackingDomainTrackingBranded open / click tracking configuration for a domain. Tracking is opt-in and entirely independent of mail-flow verification — failures here never affect
Domain.statusor interrupt sending.created_atstring (date-time)verified_atstring (date-time)When the domain most recently transitioned to
verified.May be null.
{
"id": "domain_550e8400-e29b-41d4-a716-446655440000",
"name": "example.com",
"status": "pending",
"dns_records": [
{
"type": "CNAME",
"name": "anypost",
"value": "dxyz12345.c.anypost.email",
"purpose": "verification"
}
],
"verification_failure": {
"code": "string",
"message": "string"
},
"tracking": {
"opens_enabled": true,
"clicks_enabled": true,
"subdomain": "track",
"dns_records": [
{
"type": "CNAME",
"name": "anypost",
"value": "dxyz12345.c.anypost.email",
"purpose": "verification"
}
],
"status": "disabled",
"verification_failure": {
"code": "string",
"message": "string"
},
"verified_at": "string"
},
"created_at": "string",
"verified_at": "string"
}Responses
| Status | Description |
|---|---|
200 | The updated domain. |
401 | Missing or invalid credentials. |
404 | Resource not found. |
413 | Request body exceeded the 5 MB gateway limit. Rejected at the transport layer before authentication or validation, so the response uses a shorter error shape than application-layer errors. The connection is closed after the response. |
422 | Request validation failed. |
Delete a domain
DELETE /v1/domains/{id}
Permanently deletes the domain and its DKIM keys. Anypost removes the authoritative records it published in its own DNS asynchronously — the response returns immediately and any leftover records are cleaned up shortly after.
Parameters
idstringin path[required]
Example request
curl https://api.anypost.com/v1/domains/domain_550e8400-e29b-41d4-a716-446655440000 \
-X DELETE \
-H "Authorization: Bearer $ANYPOST_API_KEY"Responses
| Status | Description |
|---|---|
204 | Deleted. |
404 | Resource not found. |
Verify a domain
POST /v1/domains/{id}/verify
Resolves the customer's published CNAMEs through to our authoritative
DKIM/SPF/MX records and, on success, persists status = verified. The
response always returns 200 with the current domain — read status
(pending vs verified) and verification_failure to learn the
outcome. DNS propagation can lag; callers may poll this endpoint until
the status flips.
If the domain has tracking configured, this endpoint also
re-checks the branded tracking CNAME (the host named in
tracking.dns_records) and updates tracking.status /
tracking.verification_failure independently. A failed
tracking check never flips the mail-flow status to
pending and never disrupts sending.
Parameters
idstringin path[required]
Example request
curl https://api.anypost.com/v1/domains/domain_550e8400-e29b-41d4-a716-446655440000/verify \
-X POST \
-H "Authorization: Bearer $ANYPOST_API_KEY"Response body
On success (200), the response body is:
idstringnamestringstatusstringpendinguntil the customer's CNAMEs resolve to our authoritative records; flips toverifiedafter a successful verify call. Reflects mail-flow verification only — tracking-CNAME issues are reported separately viatracking.statusand never affect this field.One of:
pending,verified.dns_recordsarray of DnsRecordThe mail-flow DNS records the customer should publish at their provider to verify the domain and route DKIM/SPF/MX through us. Iterate and publish each record verbatim. Always one verification CNAME plus one CNAME per active DKIM selector (typically two). Tracking-related records are surfaced separately under
tracking.dns_records.verification_failureVerificationFailure or nullMost recent mail-flow verification failure, or null when the domain is verified or has never been checked.
codeis one ofapex_cname_missing,apex_cname_mismatch,dkim_cname_missing,dkim_cname_mismatch,dkim_mismatch,chain_broken,mx_missing,spf_missing.trackingDomainTrackingBranded open / click tracking configuration for a domain. Tracking is opt-in and entirely independent of mail-flow verification — failures here never affect
Domain.statusor interrupt sending.created_atstring (date-time)verified_atstring (date-time)When the domain most recently transitioned to
verified.May be null.
{
"id": "domain_550e8400-e29b-41d4-a716-446655440000",
"name": "example.com",
"status": "pending",
"dns_records": [
{
"type": "CNAME",
"name": "anypost",
"value": "dxyz12345.c.anypost.email",
"purpose": "verification"
}
],
"verification_failure": {
"code": "string",
"message": "string"
},
"tracking": {
"opens_enabled": true,
"clicks_enabled": true,
"subdomain": "track",
"dns_records": [
{
"type": "CNAME",
"name": "anypost",
"value": "dxyz12345.c.anypost.email",
"purpose": "verification"
}
],
"status": "disabled",
"verification_failure": {
"code": "string",
"message": "string"
},
"verified_at": "string"
},
"created_at": "string",
"verified_at": "string"
}Responses
| Status | Description |
|---|---|
200 | The domain after the verification attempt. |
404 | Resource not found. |