Skip to main content

DNS records API endpoints

These endpoints manage the DNS records of a custom domain whose nameservers point to Cloider. A record says what a name under the domain resolves to: an A record for an IPv4 address, MX for mail, TXT for verification strings, and so on. Cloider's nameservers answer with your records shortly after you save them.

All paths are relative to https://cloider.com/api. Records are created under their domain (/domains/example.com/dns-records) and then addressed by their numeric id (/dns-records/1042). See DNS records for what each type is for.

At a glance​

MethodPathAccess
GET/domains/:domain_name/dns-recordsRead
POST/domains/:domain_name/dns-recordsWrite
GET/dns-records/:record_idRead
PUT/dns-records/:record_idWrite
DELETE/dns-records/:record_idWrite

Records can only be added to custom domains. A free subdomain such as blog.cloider.app is managed by Cloider, and adding a record to it answers 400 Can't add records on subdomains.

The record object​

{
"id": 1042,
"domain_name": "example.com",
"record_type": "A",
"record_name": "www",
"record_value": "203.0.113.10\n203.0.113.11",
"ttl": 300,
"internal": false,
"created_at": "2026-10-02T08:15:27.300421Z",
"updated_at": "2026-10-02T08:15:27.300421Z"
}
FieldTypeDescription
idintegerThe record's id
domain_namestringThe domain it belongs to
record_typestringA, AAAA, CNAME, ALIAS, MX, TXT, NS, CAA, HTTPS, SPF, SRV or PTR
record_namestringThe name relative to the domain: www for www.example.com, _dmarc, * for a wildcard, or empty for the domain itself (shown as @ in the dashboard). @ is saved as empty
record_valuestringOne or more values, one per line (\n). Each line becomes one answer
ttlintegerTime to live in seconds, 60 to 172800
internalbooleantrue for records Cloider manages for your targets. They are hidden by default and can't be changed through these endpoints
created_at, updated_atstringWhen the record was created and last changed

One record per name and type​

A domain has at most one record of each type for each name. To give www two IPv4 addresses, put both in one A record, on separate lines, rather than creating two records. Creating a second one answers A record already exists for 'www'. Instead of creating separate records, edit the existing record and add multiple values on separate lines.

Several names can use the same address: an A record for www and one for the domain itself can both hold 203.0.113.10.

One exception to these rules: while the ALIAS record a custom domain was added with still points at Cloider (cloider.app or a name under it), creating an A, AAAA or ALIAS record with an empty record_name deletes it and creates the new record in its place, rather than refusing it.

Values per type​

TypeValue formatExample
AA public IPv4 address. Private addresses are refused203.0.113.10
AAAAAn IPv6 address2001:db8::1
CNAMEOne fully qualified host name. Not allowed on the domain itself, and not next to other records of the same nameshop.myshopify.com
ALIASOne fully qualified host name. Answered as the target's A and AAAA records, allowed on the domain itself, not next to A, AAAA or CNAME records of the same namemyapp.herokuapp.com
MXpriority hostname10 mx1.mail.example.net
TXTText. Long values can be split over several linesv=spf1 include:_spf.example.net ~all
NSA nameserver host name, ideally ending with a dotns1.example.net.
CAAflags tag "value", tag issue, issuewild or iodef0 issue "letsencrypt.org"
HTTPSpriority target [params]1 . alpn="h2,h3"
SPFMust start with v=spf1v=spf1 include:_spf.example.net ~all
SRVpriority weight port target10 5 5060 sip.example.com
PTRA host namehost.example.com

List a domain's records​

GET /domains/:domain_name/dns-records

Returns the records of one domain, sorted by type and name.

Access: any token.

Query parameterRequiredDescription
internalNofalse (default) for your own records, true for the records Cloider manages for targets, all for both
curl https://cloider.com/api/domains/example.com/dns-records \
-H "Authorization: Bearer $CLOIDER_TOKEN"
Response
[
{"id": 1042, "domain_name": "example.com", "record_type": "A", "record_name": "www", "record_value": "203.0.113.10\n203.0.113.11", "ttl": 300, "internal": false, "created_at": "2026-10-02T08:15:27.300421Z", "updated_at": "2026-10-02T08:15:27.300421Z"},
{"id": 1043, "domain_name": "example.com", "record_type": "MX", "record_name": "", "record_value": "10 mx1.mail.example.net\n20 mx2.mail.example.net", "ttl": 3600, "internal": false, "created_at": "2026-10-02T08:16:02.118823Z", "updated_at": "2026-10-02T08:16:02.118823Z"}
]

A domain that doesn't exist or belongs to another account answers with an empty list rather than an error.

Create a record​

POST /domains/:domain_name/dns-records

Creates a record and publishes it on Cloider's nameservers.

Access: Read & Write token.

FieldTypeRequiredDescription
record_typestringYesOne of the types above
record_namestringNoThe name relative to the domain. Empty for the domain itself
record_valuestringYesOne or more values separated by \n. Blank lines and surrounding spaces are removed
ttlintegerYes60 to 172800 seconds. There is no default: 0 is refused
curl -X POST https://cloider.com/api/domains/example.com/dns-records \
-H "Authorization: Bearer $CLOIDER_TOKEN" \
-H "Content-Type: application/json" \
-d '{"record_type": "A", "record_name": "www", "record_value": "203.0.113.10\n203.0.113.11", "ttl": 300}'

The response is the new record object. More examples:

# Mail for the domain itself
curl -X POST https://cloider.com/api/domains/example.com/dns-records \
-H "Authorization: Bearer $CLOIDER_TOKEN" -H "Content-Type: application/json" \
-d '{"record_type": "MX", "record_name": "", "record_value": "10 mx1.mail.example.net\n20 mx2.mail.example.net", "ttl": 3600}'

# DMARC policy
curl -X POST https://cloider.com/api/domains/example.com/dns-records \
-H "Authorization: Bearer $CLOIDER_TOKEN" -H "Content-Type: application/json" \
-d '{"record_type": "TXT", "record_name": "_dmarc", "record_value": "v=DMARC1; p=quarantine; rua=mailto:dmarc@example.com", "ttl": 3600}'

# Only Let's Encrypt may issue certificates
curl -X POST https://cloider.com/api/domains/example.com/dns-records \
-H "Authorization: Bearer $CLOIDER_TOKEN" -H "Content-Type: application/json" \
-d '{"record_type": "CAA", "record_name": "", "record_value": "0 issue \"letsencrypt.org\"", "ttl": 3600}'

Email DNS records covers MX, SPF, DKIM and DMARC in detail.

Errors​

Validation messages name the value they are about, so they can be shown as they are:

StatusFieldExample messages
400record_typeRecord type is required
400ttlTTL must be between 60 and 172800 seconds
400record_valueRecord value cannot be empty, Duplicate value found: 203.0.113.10
400record_valueInvalid IPv4 address: 203.0.113. Expected format: 192.168.1.1, Private IP address detected: 10.0.0.5. Consider if this is intended for public DNS, IPv6 address detected: 2001:db8::1. Use AAAA record type for IPv6 addresses
400record_valueCNAME records can only have one target. Remove additional values, IP address detected: 203.0.113.10. Use A record type for IPv4 addresses, not CNAME
400record_valueMX record missing priority or hostname: mx1.mail.example.net. Expected format: '10 mail.example.com', MX record with priority 10 already exists for www
400record_valueSPF record must start with 'v=spf1': include:_spf.example.net, CAA record incomplete: 0 issue. Expected format: '0 issue "letsencrypt.org"', SRV record must have exactly 4 parts: ...
400record_valueDuplicate record already exists with the same type, name, and value, A record already exists for 'www'. ...
400record_nameCNAME records cannot be used for the root domain (record name cannot be empty), CNAME record cannot coexist with other record types for the same name: www, Cannot create A record: CNAME already exists for name: www
400_Can't add records on subdomains., Operation failed, couldn't create the DNS record!
403_This API token is read only!
404Not Found (plain text), the domain isn't the account's

Get a record​

GET /dns-records/:record_id

Returns one record. Internal records and records of other accounts answer 404 Not Found (plain text).

Access: any token.

curl https://cloider.com/api/dns-records/1042 \
-H "Authorization: Bearer $CLOIDER_TOKEN"

Update a record​

PUT /dns-records/:record_id

Replaces a record's type, name, value and TTL. Send all four fields, even the ones that don't change. The same validation as for creating applies, and the record keeps its id.

Access: Read & Write token.

curl -X PUT https://cloider.com/api/dns-records/1042 \
-H "Authorization: Bearer $CLOIDER_TOKEN" \
-H "Content-Type: application/json" \
-d '{"record_type": "A", "record_name": "www", "record_value": "203.0.113.10\n203.0.113.12", "ttl": 3600}'

The response is the updated record. Operation failed, couldn't update the DNS record! means it wasn't saved.

Delete a record​

DELETE /dns-records/:record_id

Deletes a record from Cloider's nameservers.

Access: Read & Write token.

curl -X DELETE https://cloider.com/api/dns-records/1042 \
-H "Authorization: Bearer $CLOIDER_TOKEN"
Response
{"message": "DNS record deleted successfully"}

400 Operation failed, couldn't delete the DNS record! means nothing was deleted. 404 Not Found for an unknown, internal or foreign record.

Check a record​

Records are served by ns1.cloider.com to ns4.cloider.com. Ask one of them directly to see a change without waiting for caches:

dig @ns1.cloider.com www.example.com A +short
Output
203.0.113.10
203.0.113.12

Resolvers that cached the old answer keep it until its TTL runs out. Lower the TTL before a planned change.