API

API and access keys

Everything a client does in the account is available through the API — except six actions that always need a human.

A key is a set of policies

Rights and resources are different axes: “edit DNS” and “in which domains” don’t merge into one. Conditions (IP, expiry, spend limit) apply to the whole key.

Key
 ├─ environment: live · test
 ├─ policy: right [dns.edit] on resources [domains tagged “client A”]
 ├─ policy: right [domain.renew] on resources [example.com.ua]
 └─ limits: IP 203.0.113.0/24 · until 2026-12-26 · spend ≤ 2 000 ₴/mo

Four danger classes

The class sets the key’s lifetime, whether an IP restriction is mandatory, and who confirms the operation.

Danger classes of API rights
ClassNameExampleConfirmation
0Readdomain list, DNS records, certificate statusordinary sign-in
1Reversible changea DNS record, a monitoring check, a webhookordinary sign-in
2Moneyrenewal, registration, top-upsign-in + notice to owners
3Ownership and irreversiblelift the transfer lock, change nameserversa second owner or a 24-hour activation delay

Rights catalogue (excerpt)

The full catalogue is in the docs; here are the most common rights with their danger class on the right.

domain.read
domain list, expiry dates, statuses
0
domain.renew
renew a domain — this is a spend
2
domain.nameservers
change nameservers; on a live domain this breaks the site and mail for the TTL window
3
dns.edit
create, change, delete DNS records through a checked plan
1
dns.acme_challenge
only a TXT record under _acme-challenge.<name> — for certbot and similar
1
cert.issue
a free Let’s Encrypt certificate
1
monitor.read
checks, history, monitoring reports
0
billing.topup
top up the balance from a saved card
2

The dns.acme_challenge right is deliberately narrow: a compromised web server with this key can only reissue a certificate for its own domain, not rewrite MX and steal the mail.

What a key never gets

  • A domain transfer code — only to a human in the account, after re-authentication.
  • Changing the domain owner (registrant).
  • Managing an organisation’s people and keys.
  • The payment method, turning off two-factor checks, deleting the account.

Sample request

Every write call requires an Idempotency-Key: a repeat returns the same result, not a new operation.

GET /v1/domains/kava.com.ua HTTP/1.1
Authorization: Bearer zr_live_…
Idempotency-Key: 8f14e45f-…

200 OK
{ "domain": "kava.com.ua", "status": ["ok"],
  "expires_at": "2027-09-12", "auto_renew": true }

An error is a machine code plus a human-readable message and suggested actions:

{ "error": {
  "code": "domain_taken",
  "message": { "uk": "kava.com.ua зайнятий до 2027-09-12.",
               "en": "kava.com.ua is registered until 2027-09-12." },
  "actions": [ { "type": "check_alternatives", "href": "/v1/search?q=kava" } ] } }

Where to issue a key

Keys are issued in the account: a rights template → domains → conditions → a plain-language summary. The public read-only MCP is available without a key.

FAQ

What is the public MCP?

A read-only tool for assistants (models), no key required: domain check, certificate status. It never writes to an account.

Can we test an integration without spending money?

Yes, a test key zr_test_… runs against the sandbox: registrations and charges look real but aren’t.

Can we get a domain transfer code through the API?

No. It’s one of six actions available only to a human in the account after re-authentication — even with domain.lock in the key.