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.

The same trust boundary as the console. The API uses the console’s verified-zone ownership check. A zone available to your console account is available to your API key; every other zone returns 403 forbidden_zone.
For a machine-readable endpoint catalogue, request 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.

Use the Authorization header only. Basic authentication and query-string tokens are not accepted. A token in a URL can leak through logs, referrer headers and browser history.

Each token carries scopes. A token with no configured scope receives dns:read by default. Write scope also permits reads.

ScopeGrants
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

HTTPError codeMeaning
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:

  1. 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.
  2. TXT verification — Used for a contested claim. Add the returned TXT value at _cnfdns-verify.<zone>, then call POST /v1/dns/zones/{zone}/verify.
  3. Legacy NS verification — Older pending claims may use verify_method: "ns". Verification compares the zone’s live NS answers with its expected nameserver set.
Why instant verification is safe. Records stored by c.nf are inert until the domain owner changes the authoritative NS delegation at the registrar. A first claim alone cannot make those records serve.
Reverse zones The same model applies to 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.

MethodPathScopePurpose
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.

MethodPathScopePurpose
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.

MethodPathScopePurpose
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.

MethodPathScopePurpose
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.

MethodPathScopePurpose
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.

MethodPathScopePurpose
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.

MethodPathScopePurpose
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.

MethodPathScopePurpose
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.

MethodPathScopePurpose
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.

MethodPathScopePurpose
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.

MethodPathScopePurpose
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.

MethodPathScopePurpose
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

FieldTypeRequirementNotes
zone string Required Apex zone, lowercased by the server. Reverse zones are accepted.

Create a DNS record

FieldTypeRequirementNotes
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

FieldTypeRequirementNotes
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.
Record type cannot be changed with 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/zones

Claim 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

  1. Create an API key with dns:write at Account → API keys, and copy it when it is shown.
  2. Store the token in a protected environment variable on your machine.
  3. Call GET /v1/account/me to confirm the token and its scopes.
  4. Claim a zone. The response says whether verification is instant, TXT-based or legacy NS-based.
  5. Complete the returned DNS proof when one is required, then call the verify endpoint.
  6. 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.