CNF API · v1
One API for c.nf: DNS zones and records, personal files, packages, stored credentials, domain lookups, and a handful of public utilities that need no account at all. Every authenticated operation is restricted to the account whose key made the call.
Overview
Version 1 exposes DNS operations for zones you have claimed through DNS Management. Create and revoke tokens under Account → API keys.
403 forbidden_zone.GET /v1?format=json or send Accept: application/json to /v1.Base URL and versioning
https://api.c.nf/v1
All endpoints are below /v1. Breaking changes will use a new major-version path. Backwards-compatible fields and endpoints may be added to v1 and will be recorded in the changelog.
Authentication and scopes
Every request that reads or changes account data must include a Bearer token. Tokens begin with cnf_ followed by 32 hexadecimal characters.
curl https://api.c.nf/v1/dns/zones \
-H "Authorization: Bearer cnf_a1b2c3d4e5f60718293a4b5c6d7e8f90"
Tokens are stored as one-way hashes and the complete value is shown only when it is created. If a token is lost, revoke it and create another.
Each token carries scopes. A token with no configured scope receives dns:read by default. Write scope also permits reads.
| Scope | Grants |
|---|---|
dns:read |
List zones and records, and read individual records. |
dns:write |
Read, create, update and delete DNS records and zone claims. |
* |
All scopes. Use this only when it is genuinely required. |
A mismatch returns 403 forbidden_scope and includes both required_scopes and token_scopes for diagnosis.
Per-user isolation
A Bearer token resolves to exactly one user_id. Every zone handler checks that user’s verified claim before any read or write. There is no administrator override, impersonation path or cross-user bypass.
Even a token with * can act only on zones verified by its own user. Attempting to use another account’s zone returns 403 forbidden_zone.
Response envelope
Successful response
{
"success": true,
"data": { "zones": [] },
"request_id": "req_abc123def456abcd"
}
Error response
{
"success": false,
"error": "forbidden_zone",
"message": "zone not verified for this account (or does not exist)",
"request_id": "req_abc123def456abcd",
"zone": "example.com"
}
request_id appears on every response and is safe to record with client-side logs.
Error codes
| HTTP | Error code | Meaning |
|---|---|---|
| 400 | bad_request |
A required field is missing, the body is malformed or an input is invalid. |
| 401 | unauthorized |
The Bearer token is missing, invalid or revoked. |
| 403 | forbidden_scope |
The token does not have the required scope. |
| 403 | forbidden_zone |
The zone is not verified for this account, or it does not exist. |
| 404 | not_found |
The requested zone, record or user was not found. |
| 405 | method_not_allowed |
This endpoint does not support the HTTP method. |
| 502 | upstream_error |
The DNS provider returned an error. |
Zone verification
When POST /v1/dns/zones claims a zone, the server chooses one of these paths:
-
Instant verification (
method: "auto") — Used when no other account has claimed the zone. The claim is immediately verified. Records become authoritative only after the owner points the registrar’s NS delegation to the returned nameservers. -
TXT verification — Used for a contested claim. Add the returned TXT value at
_cnfdns-verify.<zone>, then callPOST /v1/dns/zones/{zone}/verify. -
Legacy NS verification — Older pending claims may use
verify_method: "ns". Verification compares the zone’s live NS answers with its expected nameserver set.
in-addr.arpa and ip6.arpa. Claim the zone, obtain expected_ns, and submit those delegation targets to the relevant registry.Verification is idempotent. Repeating it for a verified claim returns verified: true without changing the claim.
Record types and limits
Supported record types
A, AAAA, CNAME, MX, TXT, NS, SRV, CAA, PTR, SPF.
priority is required for MX and SRV and ignored for other types. ttl must be between 60 and 2,592,000 seconds.
Endpoints
Public utilities
Small dependable endpoints that need no account: time, address, country, exchange rates and hashes.
| Method | Path | Scope | Purpose |
|---|---|---|---|
| GET | /v1/public/time |
Public | The current UTC time in ISO 8601, RFC 2822 and Unix form. |
| GET | /v1/public/timestamp |
Public | The current Unix timestamp, in seconds and milliseconds. |
| GET | /v1/public/ip |
Public | The address this request came from. |
| GET | /v1/public/geo |
Public | The country this request came from, as resolved at the edge. |
| GET | /v1/public/fx |
Public | Exchange rates for a base currency, refreshed hourly. |
| GET | /v1/public/hash |
Public | Hash a string with SHA-256 or another supported algorithm. |
Account
Who a token belongs to, and what it is allowed to do.
| Method | Path | Scope | Purpose |
|---|---|---|---|
| GET | /v1/account/me |
Any token | The account behind the token, its scopes, and the endpoints they open. |
| GET | /v1/account/sessions |
account:read |
Every browser session currently signed in to this account. |
| POST | /v1/account/sessions/revoke |
account:write |
Sign one session out. |
| POST | /v1/account/sessions/revoke-all |
account:write |
Sign every session out. |
| POST | /v1/account/profile |
account:write |
Change your display name. |
DNS
Claim a domain, prove you control it, then manage its records.
| Method | Path | Scope | Purpose |
|---|---|---|---|
| GET | /v1/dns/zones |
dns:read |
Every zone this account has claimed. |
| POST | /v1/dns/zones |
dns:write |
Claim a zone. An uncontested claim is instant; a contested one gets a TXT challenge. |
| GET | /v1/dns/zones/{zone} |
dns:read |
One zone, with its verification instructions if it is still pending. |
| POST | /v1/dns/zones/{zone}/verify |
dns:write |
Run the verification lookup and mark the zone verified if it matches. |
| DELETE | /v1/dns/zones/{zone} |
dns:write |
Release a claim. The records themselves are left alone. |
| GET | /v1/dns/zones/{zone}/records |
dns:read |
Every record in a verified zone. |
| POST | /v1/dns/zones/{zone}/records |
dns:write |
Add a record to a verified zone. |
| GET | /v1/dns/zones/{zone}/records/{id} |
dns:read |
A single record. |
| PATCH | /v1/dns/zones/{zone}/records/{id} |
dns:write |
Change part of a record; whatever you omit keeps its value. |
| DELETE | /v1/dns/zones/{zone}/records/{id} |
dns:write |
Remove a record. |
Credentials
The private credential store behind the credentials tool.
| Method | Path | Scope | Purpose |
|---|---|---|---|
| GET | /v1/cred |
cred:read cred:write |
Stored credentials, optionally filtered by platform. |
| POST | /v1/cred |
cred:write |
Store a credential. |
Files
Personal file storage: list, upload, edit, share and delete.
| Method | Path | Scope | Purpose |
|---|---|---|---|
| GET | /v1/files |
files:read files:write |
Your stored files, newest first. |
| GET | /v1/files/{id} |
files:read files:write |
One file, including its share link if it has one. |
| GET | /v1/files/download |
files:read files:write |
Download a file. |
| POST | /v1/files/upload |
files:write |
Upload a file. |
| POST | /v1/files/update |
files:write |
Edit a file’s details, including whether it is shared. |
| POST | /v1/files/rename |
files:write |
Change the name a file downloads as. |
| POST | /v1/files/delete |
files:write |
Delete a file and its contents. |
| POST | /v1/files/upload-chunk |
files:write |
Send one part of a large upload. |
| POST | /v1/files/upload-finalize |
files:write |
Assemble the parts into a file. |
CDN
Edge caching and traffic for the files you share.
| Method | Path | Scope | Purpose |
|---|---|---|---|
| GET | /v1/cdn/stats |
cdn:read |
Cache settings and request counts for your shared files. |
| POST | /v1/cdn/config |
cdn:write |
Set how long the edge keeps a file, or stop serving it. |
| POST | /v1/cdn/purge |
cdn:write |
Drop a file from the edge cache now. |
SMS forwarder
Messages relayed from your phone, and the keys that let it in.
| Method | Path | Scope | Purpose |
|---|---|---|---|
| GET | /v1/sms/messages |
sms:read |
Messages forwarded to your account. |
| GET | /v1/sms/keys |
sms:read sms:write |
The forwarder keys your devices use. |
| POST | /v1/sms/keys |
sms:write |
Issue a forwarder key. Five at a time. |
| DELETE | /v1/sms/keys |
sms:write |
Revoke a forwarder key. |
Static sites
Upload a zip, serve a site.
| Method | Path | Scope | Purpose |
|---|---|---|---|
| GET | /v1/sites |
sites:read sites:write |
Your static sites, most recently deployed first. |
| POST | /v1/sites/deploy |
sites:write |
Deploy a zip as a site. |
| POST | /v1/sites/delete |
sites:write |
Delete a site and its files. |
Deployments
The form, webhook and shortlink endpoints you have deployed.
| Method | Path | Scope | Purpose |
|---|---|---|---|
| GET | /v1/deployments |
deploy:read deploy:write |
Your deployments and how often each has been used. |
| POST | /v1/deployments/toggle |
deploy:write |
Enable or disable a deployment. |
| POST | /v1/deployments/delete |
deploy:write |
Delete a deployment. |
Domains
Your domain portfolio and its registration data.
| Method | Path | Scope | Purpose |
|---|---|---|---|
| GET | /v1/domains |
domain:read domain:write |
Your domains, soonest to expire first. |
| POST | /v1/domains/whois-sync |
domain:write |
Refresh one domain from its registry record. |
Packages
Publish releases and read back their versions and download counts.
| Method | Path | Scope | Purpose |
|---|---|---|---|
| GET | /v1/packages |
packages:read packages:write |
Your packages, with version counts and download totals. |
| GET | /v1/packages/{slug} |
packages:read packages:write |
One package, with every version and artifact. |
| POST | /v1/packages/publish |
packages:write |
Publish a version, creating the package if it is new. |
| POST | /v1/packages/update |
packages:write |
Edit a package’s details. |
| POST | /v1/packages/delete |
packages:write |
Delete a package, every version and every artifact. |
WHOIS
Registration data for a domain, cached and shared with the domain tools.
| Method | Path | Scope | Purpose |
|---|---|---|---|
| GET | /v1/whois |
whois:read |
Registration details for a domain. |
For AI agents
Point an agent at /v1/ai for a brief written to be pasted straight into a prompt, or at /v1/ai?format=json for the same endpoints as tool definitions. /v1/openapi.json is the full OpenAPI 3.1 contract, and /llms.txt is the crawler map. All four are generated from the same route table as this page, so none of them can describe an endpoint that does not exist.
curl https://api.c.nf/v1/ai
curl https://api.c.nf/v1/ai?format=json
curl https://api.c.nf/v1/openapi.json
Request fields
Create a zone claim
| Field | Type | Requirement | Notes |
|---|---|---|---|
zone |
string |
Required | Apex zone, lowercased by the server. Reverse zones are accepted. |
Create a DNS record
| Field | Type | Requirement | Notes |
|---|---|---|---|
type |
string |
Required | One of A, AAAA, CNAME, MX, TXT, NS, SRV, CAA, PTR or SPF. |
host |
string |
Optional | Subdomain only. Use an empty string or @ for the apex. |
value |
string |
Required | Record content, such as an IP address, target name or text value. |
ttl |
integer |
Optional | Between 60 and 2,592,000 seconds. The default is 3,600. |
priority |
integer |
Optional | Required for MX and SRV; ignored for other types. |
Update a DNS record
| Field | Type | Requirement | Notes |
|---|---|---|---|
host |
string |
Optional | Replacement subdomain. |
value |
string |
Optional | Cannot be empty after merging with the current record. |
ttl |
integer |
Optional | Between 60 and 2,592,000 seconds. |
priority |
integer |
Optional | Used only for MX and SRV. |
PATCH. Delete the record and create another to change its type.Examples
List zones
curl -H "Authorization: Bearer $CNF_TOKEN" \
https://api.c.nf/v1/dns/zonesClaim a zone
curl -X POST https://api.c.nf/v1/dns/zones \
-H "Authorization: Bearer $CNF_TOKEN" \
-H "Content-Type: application/json" \
-d '{"zone":"example.com"}'Verify a zone
curl -X POST https://api.c.nf/v1/dns/zones/example.com/verify \
-H "Authorization: Bearer $CNF_TOKEN"Create a record
curl -X POST https://api.c.nf/v1/dns/zones/example.com/records \
-H "Authorization: Bearer $CNF_TOKEN" \
-H "Content-Type: application/json" \
-d '{"type":"A","host":"api","value":"192.0.2.10"}'Quick start
- Create an API key with
dns:writeat Account → API keys, and copy it when it is shown. - Store the token in a protected environment variable on your machine.
- Call
GET /v1/account/meto confirm the token and its scopes. - Claim a zone. The response says whether verification is instant, TXT-based or legacy NS-based.
- Complete the returned DNS proof when one is required, then call the verify endpoint.
- Create, read, update or delete records only after the claim is verified.
Changelog
v1.1.0 — zone management
- Added API-based zone claims, including instant and TXT verification paths.
- Added single-zone status and idempotent verification endpoints.
- Added claim revocation without implicit record deletion.
- Added verified, pending and all filters to the zone list.
v1.0.0 — initial release
- Added Bearer-token authentication and per-user zone isolation.
- Added read and write scopes.
- Added account, zone-list and record-management endpoints.
- Added a consistent response envelope with a request identifier.