API reference
The base URL is https://dnsmint.com/api/v1. Requests and responses are JSON, and request bodies are capped at 4KB. New here? The quickstart walks the whole loop from key to certificate.
Authentication
Every endpoint requires an API key in the Authorization header:
Authorization: Bearer dnsm_<keyId>_<secret>Keys are created in the dashboard, which also lists and revokes them. The secret appears once, in the creation response, and is stored only as a hash after that. An account can hold up to 20 keys. A missing, malformed, or revoked key gets:
{ "error": "Missing or invalid API key", "code": "UNAUTHORIZED" }Errors
Every non-2xx response has the same shape: an error string for humans and a stable code for programs.
{ "error": "Hostname not found", "code": "NOT_FOUND" }| Status | Code | When |
|---|---|---|
| 400 | BAD_REQUEST | The body is not valid JSON, is over 4KB, is missing "ip", or the address does not parse |
| 401 | UNAUTHORIZED | The Authorization header is missing or malformed, or the key is unknown or revoked |
| 403 | FORBIDDEN | The IP is in a private or reserved range, which requires a Business plan |
| 404 | NOT_FOUND | No hostname with this id belongs to your account |
| 409 | CONFLICT | The hostname was released; released names cannot come back |
| 429 | RATE_LIMITED | The account is at its 25 active-hostname cap |
| 500 | INTERNAL_ERROR | Unexpected server error |
POST /v1/hostnames
Registers a public IP address and mints a new hostname with an opaque label on a pool domain.
Parameters
ip(body, required) A public IPv4 or IPv6 address as a string. The record type follows the address: A for IPv4, AAAA for IPv6.label(body, optional) A custom hostname label (Pro/Business). 3-63 lowercase letters, digits, and hyphens; no leading or trailing hyphen. Impersonating or reserved terms are rejected.
$ curl -X POST https://dnsmint.com/api/v1/hostnames \
-H "Authorization: Bearer $DNSMINT_KEY" \
-H "Content-Type: application/json" \
-d '{"ip": "34.120.50.10"}'201 with the new hostname:
{
"id": "68ad3a1e9c4b2f0d5e6a7b8c",
"hostname": "q7k4m2.pool-3.mintzone.net",
"ip": "34.120.50.10",
"record_type": "A",
"status": "live",
"expires_at": "2026-09-02T08:30:00.000Z",
"created_at": "2026-08-26T08:30:00.000Z"
}The name starts live with expires_at set 7 days out. New registrations may briefly return "pending"; poll GET until "live".
Free accounts can hold 25 active hostnames; registration past the cap returns 429.
| Status | Code | When |
|---|---|---|
| 400 | BAD_REQUEST | The body is not valid JSON, is over 4KB, is missing "ip", or the address does not parse |
| 401 | UNAUTHORIZED | The Authorization header is missing or malformed, or the key is unknown or revoked |
| 403 | FORBIDDEN | The IP is in a private or reserved range, which requires a Business plan |
| 403 | FORBIDDEN | A custom label was requested and the account is not on Pro or Business |
| 400 | BAD_REQUEST | The custom label is malformed, or is not available (blocklist) |
| 409 | CONFLICT | The custom label is taken or retired on this domain |
| 429 | RATE_LIMITED | The account already has 25 active hostnames |
| 500 | INTERNAL_ERROR | Unexpected server error |
GET /v1/hostnames
Lists the account's hostnames, newest first, excluding released ones.
Parameters
limit(query, optional) Maximum results to return. Default 100; values are clamped to the 1 to 500 range.skip(query, optional) Results to skip, for pagination. Default 0.
$ curl "https://dnsmint.com/api/v1/hostnames?limit=100&skip=0" \
-H "Authorization: Bearer $DNSMINT_KEY"200 with a hostnames envelope:
{
"hostnames": [
{
"id": "68ad3a1e9c4b2f0d5e6a7b8c",
"hostname": "q7k4m2.pool-3.mintzone.net",
"ip": "34.120.50.10",
"record_type": "A",
"status": "live",
"expires_at": "2026-09-02T08:30:00.000Z",
"created_at": "2026-08-26T08:30:00.000Z"
}
]
}Expired names appear with status "expired". Released names never appear.
Listing is a read of the collection, not of any one hostname, so it renews nothing.
| Status | Code | When |
|---|---|---|
| 401 | UNAUTHORIZED | The Authorization header is missing or malformed, or the key is unknown or revoked |
| 500 | INTERNAL_ERROR | Unexpected server error |
GET /v1/hostnames/{id}
Reads one hostname by id.
Parameters
id(path, required) The hostname id returned at creation.
$ curl https://dnsmint.com/api/v1/hostnames/68ad3a1e9c4b2f0d5e6a7b8c \
-H "Authorization: Bearer $DNSMINT_KEY"200 with the hostname:
{
"id": "68ad3a1e9c4b2f0d5e6a7b8c",
"hostname": "q7k4m2.pool-3.mintzone.net",
"ip": "34.120.50.10",
"record_type": "A",
"status": "live",
"expires_at": "2026-09-02T08:30:00.000Z",
"created_at": "2026-08-26T08:30:00.000Z"
}Reading a live hostname counts as use: the response already carries an expires_at 7 days out. New registrations may briefly return "pending"; poll GET until "live".
A hostname already marked expired is returned as expired; bring it back with the renew endpoint.
| Status | Code | When |
|---|---|---|
| 401 | UNAUTHORIZED | The Authorization header is missing or malformed, or the key is unknown or revoked |
| 404 | NOT_FOUND | No hostname with this id belongs to your account |
| 500 | INTERNAL_ERROR | Unexpected server error |
PUT /v1/hostnames/{id}
Points the hostname at a new IP. The name and its certificates carry over untouched.
Parameters
id(path, required) The hostname id returned at creation.ip(body, required) The new public IPv4 or IPv6 address. The record type follows the address, so a name can move between A and AAAA.
$ curl -X PUT https://dnsmint.com/api/v1/hostnames/68ad3a1e9c4b2f0d5e6a7b8c \
-H "Authorization: Bearer $DNSMINT_KEY" \
-H "Content-Type: application/json" \
-d '{"ip": "34.120.51.22"}'200 with the updated hostname:
{
"id": "68ad3a1e9c4b2f0d5e6a7b8c",
"hostname": "q7k4m2.pool-3.mintzone.net",
"ip": "34.120.51.22",
"record_type": "A",
"status": "live",
"expires_at": "2026-09-02T10:00:00.000Z",
"created_at": "2026-08-26T08:30:00.000Z"
}An update counts as use: the name comes back live with expires_at 7 days out, even if it had expired.
| Status | Code | When |
|---|---|---|
| 400 | BAD_REQUEST | The body is not valid JSON, is over 4KB, is missing "ip", or the address does not parse |
| 401 | UNAUTHORIZED | The Authorization header is missing or malformed, or the key is unknown or revoked |
| 403 | FORBIDDEN | The IP is in a private or reserved range, which requires a Business plan |
| 404 | NOT_FOUND | No hostname with this id belongs to your account |
| 409 | CONFLICT | The hostname was released; released names cannot come back |
| 500 | INTERNAL_ERROR | Unexpected server error |
POST /v1/hostnames/{id}/renew
Heartbeat with no request body. Slides the idle expiry to 7 days from now.
Parameters
id(path, required) The hostname id returned at creation.
$ curl -X POST https://dnsmint.com/api/v1/hostnames/68ad3a1e9c4b2f0d5e6a7b8c/renew \
-H "Authorization: Bearer $DNSMINT_KEY"200 with the renewed hostname:
{
"id": "68ad3a1e9c4b2f0d5e6a7b8c",
"hostname": "q7k4m2.pool-3.mintzone.net",
"ip": "34.120.50.10",
"record_type": "A",
"status": "live",
"expires_at": "2026-09-02T11:45:00.000Z",
"created_at": "2026-08-26T08:30:00.000Z"
}Renew also revives an expired name: the label was reserved for your account all along, so it comes back live.
Released names cannot be renewed; that returns 409.
| Status | Code | When |
|---|---|---|
| 401 | UNAUTHORIZED | The Authorization header is missing or malformed, or the key is unknown or revoked |
| 404 | NOT_FOUND | No hostname with this id belongs to your account |
| 409 | CONFLICT | The hostname was released; released names cannot come back |
| 500 | INTERNAL_ERROR | Unexpected server error |
DELETE /v1/hostnames/{id}
Releases the hostname permanently. The label is never reused, by you or anyone else.
Parameters
id(path, required) The hostname id returned at creation.
$ curl -X DELETE https://dnsmint.com/api/v1/hostnames/68ad3a1e9c4b2f0d5e6a7b8c \
-H "Authorization: Bearer $DNSMINT_KEY"200 with a confirmation:
{
"released": true
}The DNS record stops being served and the name cannot come back. Releasing an already released hostname returns the same 200.
| Status | Code | When |
|---|---|---|
| 401 | UNAUTHORIZED | The Authorization header is missing or malformed, or the key is unknown or revoked |
| 404 | NOT_FOUND | No hostname with this id belongs to your account |
| 500 | INTERNAL_ERROR | Unexpected server error |
DNS-01 certificate API
An acme-dns-compatible API publishes _acme-challenge TXT records for a hostname, which enables wildcard certificates and certificates for machines on private networks. Credentials are scoped: one credential can publish challenges for exactly one hostname.
POST /api/v1/hostnames/:id/acme-credential
Mints a credential for the hostname (API-key auth, same as other v1 endpoints). The password appears in this response exactly once. At most 5 credentials per hostname.
curl -X POST https://dnsmint.com/api/v1/hostnames/HOST_ID/acme-credential \
-H "Authorization: Bearer $DNSMINT_KEY"
{
"username": "2f1e6a9c-8b3d-4e5f-9a1b-6c7d8e9f0a1b",
"password": "f3a9...",
"fulldomain": "_acme-challenge.q7k4m2.pool-1.example",
"subdomain": "2f1e6a9c-8b3d-4e5f-9a1b-6c7d8e9f0a1b",
"server_url": "https://dnsmint.com/api/acme",
"allowfrom": []
}POST /api/acme/update
The acme-dns wire protocol, spoken by certbot, Caddy, Traefik, lego, and cert-manager. Authentication is the credential, sent as X-Api-User and X-Api-Key headers. subdomain must be the credential's username; txt is the 43-character challenge value. The two newest values per name are served, which covers Let's Encrypt's apex plus wildcard double validation. Credentials for released or expired hostnames stop working.
curl -X POST https://dnsmint.com/api/acme/update \
-H "X-Api-User: 2f1e6a9c-8b3d-4e5f-9a1b-6c7d8e9f0a1b" \
-H "X-Api-Key: f3a9..." \
-d '{"subdomain": "2f1e6a9c-8b3d-4e5f-9a1b-6c7d8e9f0a1b", "txt": "CHALLENGE_VALUE_43_CHARS"}'
{"txt": "CHALLENGE_VALUE_43_CHARS"}CAA records
Pool domains can publish CAA records so a CA of your choosing is the only one allowed to issue for names on that domain. This is an admin-only setting: PATCH /api/admin/domains/:id with { "caa": ["0 issue \"letsencrypt.org\""] }, one presentation string per entry (flags 0–255, tag issue, issuewild, or iodef, value in quotes). An empty array clears the records. Names without CAA still return empty NOERROR, which means any CA may issue.
Machine-readable formats
This reference is also published as an OpenAPI 3.1 document at /openapi.json and as a single plain-text file for LLMs at /llms-full.txt.