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" }
StatusCodeWhen
400BAD_REQUESTThe body is not valid JSON, is over 4KB, is missing "ip", or the address does not parse
401UNAUTHORIZEDThe Authorization header is missing or malformed, or the key is unknown or revoked
403FORBIDDENThe IP is in a private or reserved range, which requires a Business plan
404NOT_FOUNDNo hostname with this id belongs to your account
409CONFLICTThe hostname was released; released names cannot come back
429RATE_LIMITEDThe account is at its 25 active-hostname cap
500INTERNAL_ERRORUnexpected 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.

StatusCodeWhen
400BAD_REQUESTThe body is not valid JSON, is over 4KB, is missing "ip", or the address does not parse
401UNAUTHORIZEDThe Authorization header is missing or malformed, or the key is unknown or revoked
403FORBIDDENThe IP is in a private or reserved range, which requires a Business plan
403FORBIDDENA custom label was requested and the account is not on Pro or Business
400BAD_REQUESTThe custom label is malformed, or is not available (blocklist)
409CONFLICTThe custom label is taken or retired on this domain
429RATE_LIMITEDThe account already has 25 active hostnames
500INTERNAL_ERRORUnexpected 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.

StatusCodeWhen
401UNAUTHORIZEDThe Authorization header is missing or malformed, or the key is unknown or revoked
500INTERNAL_ERRORUnexpected 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.

StatusCodeWhen
401UNAUTHORIZEDThe Authorization header is missing or malformed, or the key is unknown or revoked
404NOT_FOUNDNo hostname with this id belongs to your account
500INTERNAL_ERRORUnexpected 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.

StatusCodeWhen
400BAD_REQUESTThe body is not valid JSON, is over 4KB, is missing "ip", or the address does not parse
401UNAUTHORIZEDThe Authorization header is missing or malformed, or the key is unknown or revoked
403FORBIDDENThe IP is in a private or reserved range, which requires a Business plan
404NOT_FOUNDNo hostname with this id belongs to your account
409CONFLICTThe hostname was released; released names cannot come back
500INTERNAL_ERRORUnexpected 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.

StatusCodeWhen
401UNAUTHORIZEDThe Authorization header is missing or malformed, or the key is unknown or revoked
404NOT_FOUNDNo hostname with this id belongs to your account
409CONFLICTThe hostname was released; released names cannot come back
500INTERNAL_ERRORUnexpected 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.

StatusCodeWhen
401UNAUTHORIZEDThe Authorization header is missing or malformed, or the key is unknown or revoked
404NOT_FOUNDNo hostname with this id belongs to your account
500INTERNAL_ERRORUnexpected 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.