uk.app

API documentation

Manage names and DNS through the REST API described below. Account security and some billing actions use the panel. API requests use bearer tokens and JSON responses.

Base URL     https://api.uk.app/v1
Auth         Authorization: Bearer <token>
Spec         https://api.uk.app/v1/openapi.json
DDNS         https://ddns.uk.app/nic/update
MCP          https://mcp.uk.app/

Overview

A uk.app name is a third-level name such as petersblog.uk.app. It lives in a zone served by our own authoritative DNS (PowerDNS on three authoritative nameservers: ns1.uk.app, ns2.uk.app and ns3.uk.app, DNSSEC-signed). You manage records beneath it, subject to record limits and validation: www, api, *, _acme-challenge, anything. Changes publish within seconds; resolver caches follow the TTL you set (default 300 s).

A name goes through these states:

StatusMeaning
pendingReserved for 48 hours, not yet paid. Not in DNS.
parkedPaid, no records of your own yet — shows the parking page.
activePaid and pointing somewhere.
graceRenewal failed; keeps working for 30 days.
holdStopped resolving; restorable by paying.
suspendedTaken down for abuse. Serves a suspension page.

Authentication

Create tokens at my.uk.app/tokens. Each token carries scopes; requests without the required scope get 403.

ScopeAllows
readList names and records, verify, WHOIS, account info.
write:recordsAdd, change, delete records; apply presets. ACME adapters use this scope; the dyndns2 endpoint uses a separate per-name DDNS token.
write:namesRegister (including payment from available balance), release, restore and permanently delete names.

Tokens are shown once. Revoking a token takes effect immediately. Keep tokens out of git; for CI use a token with write:records only.

Conventions & errors

  • Names can be passed as petersblog or petersblog.uk.app; both work everywhere.
  • Request bodies: JSON (Content-Type: application/json) or form-encoded. Responses are JSON unless noted.
  • Validation problems return 422 with {"message": "...", "errors": {"field": ["..."]}}.
  • Rate limit: 600 requests per minute per token. Headers X-RateLimit-Remaining and Retry-After tell you where you stand.
  • Timestamps are ISO 8601 in UTC.
CodeWhen
401Missing or invalid token.
402Insufficient balance for an explicitly requested balance payment; the response includes payment links.
403Token lacks the scope.
404Name or record not found, or not yours.
422Invalid input, name unavailable, limit reached, name not active yet.
429Rate limited.

Quick start

export TOKEN=ukapp_...

# 1. check availability and the quoted annual price
curl "https://api.uk.app/v1/names/check?name=petersblog"
# {"name":"petersblog.uk.app","available":true,"price_gbp":4.99,"billing":"yearly, auto-renew"}

# 2. reserve it (returns a checkout URL; the name activates after payment)
curl -H "Authorization: Bearer $TOKEN" -X POST https://api.uk.app/v1/names -d name=petersblog -d pay=checkout

# 3. once active, point it at your server
curl -H "Authorization: Bearer $TOKEN" -X POST https://api.uk.app/v1/names/petersblog/records \
     -d host=@ -d type=A -d content=203.0.113.7

# 4. or use a preset
curl -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" -X POST https://api.uk.app/v1/names/petersblog/presets/vercel \
     -d '{"params":{"target":"YOUR-PROJECT.vercel-dns-017.com"}}'

# 5. confirm DNS + HTTPS
curl -H "Authorization: Bearer $TOKEN" -X POST https://api.uk.app/v1/names/petersblog/verify

Check availability

GET /v1/names/check?name=label public
{"name":"petersblog.uk.app","available":true,"reason":null,"price_gbp":4.99,"billing":"yearly, auto-renew"}
{"name":"paypal-login.uk.app","available":false,"reason":"Names containing protected brands need manual review. Contact support@uk.app."}

Standard names use 3–63 characters, a-z 0-9 -, with no leading/trailing hyphen. Selected shorter names may be explicitly released for premium registration; other short names remain reserved. Punycode-style labels, system names and blocked names are unavailable. Search returns the current availability, applicable annual price and any restriction; a premium offer does not grant trademark rights.

WHOIS

GET /v1/whois/label public · JSON or text

Registered or available, dates, status, name servers. Owner details are never returned. Add ?format=json or send Accept: application/json; otherwise you get classic whois text, handy for curl.

$ curl https://uk.app/whois/petersblog
Domain Name: petersblog.uk.app
Registry: uk.app (third-level registry, powered by PowerDNS + DNSSEC)
Status: available
Price: £4.99/year, renews automatically
Register: https://my.uk.app/dashboard?claim=petersblog
Name Servers: ns1.uk.app, ns2.uk.app, ns3.uk.app
DNSSEC: signed

List, register, release

GET /v1/names read
[{"name":"petersblog.uk.app","label":"petersblog","status":"active","records":4,"claimed_at":"2026-09-10T09:00:00Z","expires_at":"2027-09-10T09:00:00Z"}]
POST /v1/names write:names

Body: {"name": "petersblog", "pay": "checkout"}. Explicit pay=checkout reserves the label for 48 hours and returns 201 with a checkout_url; activation follows confirmed payment. Use the price returned by availability checking, including premium pricing.

With pay=balance, the API charges the available balance and activates the name. If pay is omitted, balance payment is the default when the balance covers the annual price; otherwise a checkout link is returned. An explicit balance request with insufficient funds returns 402 and payment links. Authorise automated spending before using this route without pay=checkout. MCP reservations are different: they return a payment link and do not spend balance.

{"name":"petersblog.uk.app","status":"pending","checkout_url":"https://my.uk.app/names/42/checkout", ...}
GET /v1/names/label read
DELETE /v1/names/label write:names

Moves the name to the bin and removes its records from published DNS. Stored records are retained for restoration. This does not cancel a linked card subscription: cancel future card renewals separately in billing. Paid names normally remain quarantined for 30 days unless permanently deleted sooner; see bin and restoration.

GET /v1/me read

Your email, limits, current standard price and token scopes. Use the individual name or availability response for its applicable annual price.

Verify DNS & HTTPS

POST /v1/names/label/verify read

Checks DNS and probes one resolved public address for HTTPS and a valid certificate for the hostname. HTTP status is reported separately; redirects are not followed. Results may be reused for one minute. This does not verify every address, application functionality or a game server.

{"name":"petersblog.uk.app",
 "dns":[{"host":"petersblog.uk.app","type":"A","ip":"76.76.21.21","ttl":300}],
 "https":{"ok":true,"issuer":"Let's Encrypt","expires":"2026-12-09T08:33:00+00:00"},
 "hsts_preloaded":true,"note":"Live."}

Records

GET /v1/names/label/records read
POST /v1/names/label/records write:records
PUT /v1/names/label/records/id write:records
DELETE /v1/names/label/records/id write:records
FieldTypeNotes
hoststring@ for the name itself (default), www, *, _acme-challenge, mc.eu (nested is fine).
typeenumSee record types.
contentstringIP, hostname, text, or the type-specific format below. No trailing dot needed.
ttlint60–86400 seconds, default 300.
priointMX and SRV priority, default 0.
curl -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
     -X POST https://api.uk.app/v1/names/petersblog/records \
     -d '{"host":"_minecraft._tcp","type":"SRV","content":"5 25565 petersblog.uk.app","prio":0}'
# 201 {"id":91,"host":"_minecraft._tcp","type":"SRV","content":"5 25565 petersblog.uk.app","ttl":300,"prio":0,"source":"api"}

Every write is transactional: if the DNS server rejects a record, nothing is stored and you get a 422 with the reason. Adding a real record on @ automatically removes the parking record.

Record types

TypeContent formatExample
AIPv4203.0.113.7
AAAAIPv62001:db8::7
CNAMEhostname; cannot share a host with other recordscname.vercel-dns.com
TXTtext, up to 4000 chars (quoted automatically)v=spf1 -all
MXmail hostname, priority in priomail.protonmail.ch / prio 10
SRVweight port target, priority in prio5 25565 petersblog.uk.app
CAAflags tag "value"0 issue "letsencrypt.org"
NShostname — delegate a sub-host to another DNS providerns1.example-dns.com

Presets

POST /v1/names/label/presets/preset write:records

Replaces routing records only at the affected hosts, preserving mail, TXT and unrelated records. Conflicts return 422 without changing DNS. Delegated names must first switch to managed DNS. Parameters go in params.

Add the exact hostname to your hosting project first. For Vercel, Netlify and Pages, optional params.host selects @ (default) or www; only that hostname changes. A CNAME cannot coexist with MX or TXT at the same hostname: choose www to retain mail at @. Provider verification records must stay within your registered name.

PresetParamsRecords created
verceltargetCNAME to the exact target shown in the project's Domains settings
netlifysiteCNAME to your full site hostname, e.g. your-site.netlify.app
cf-pagesprojectCNAME to your full your-project.pages.dev hostname; add it in Pages first to avoid error 522
github-pagesuser4 × @ A 185.199.108-111.153, www CNAME user.github.io
cf-tunnelUnavailableReturns 422: Tunnel requires DNS records in the same Cloudflare account
minecraftip, port@ A ip, _minecraft._tcp SRV 5 port name
serverip@ A ip, www CNAME name
parking—back to our parking page
curl -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
     -X POST https://api.uk.app/v1/names/petersblog/presets/minecraft \
     -d '{"params":{"ip":"203.0.113.7","port":"25565"}}'

Own nameservers (delegation)

PUT /v1/names/label/nameservers write:records

Body: {"nameservers": ["ns1.example-dns.com", "ns2.example-dns.com"]} (2–6 hosts, must resolve, must not be inside the name itself). Replaces every record with NS records so petersblog.uk.app and everything under it is served by a provider that accepts this exact zone, or your own authoritative DNS server. Create and verify the zone petersblog.uk.app there first. NS delegation does not guarantee acceptance as an independent Cloudflare zone. Export existing records before switching; delegation replaces the managed records.

DELETE /v1/names/label/nameservers write:records

Back to managed DNS on ns1/ns2/ns3.uk.app (parks the name; add records again).

Import / export

GET /v1/names/label/export read · text/plain
POST /v1/names/label/import write:records

One record per line, host type content [ttl] [prio]; lines starting with ; or # are ignored. Send as zone field or as the raw request body. Import appends, so export → edit → delete → import gives you a full replace.

curl -H "Authorization: Bearer $TOKEN" https://api.uk.app/v1/names/petersblog/export
; petersblog.uk.app — exported 2026-09-10T10:00:00Z
; host type content ttl [prio]
@ A 203.0.113.7 300
www CNAME petersblog.uk.app 300
@ MX mail.example.com 3600 10
@ TXT "v=spf1 -all" 300

Bin (released names)

DELETE /v1/names/{label} moves a name to the bin and removes published DNS records; cached answers may remain until their TTL expires. Stored records are normally retained for 30 days. A linked card subscription is not cancelled by this action; cancel future card renewals in billing. Balance-funded names are not renewed while in the bin. Neither action automatically refunds a payment.

GET /v1/bin read
POST /v1/bin/label/restore write:names

Restores stored DNS records while the name remains in the bin, its paid term has not expired and no other registration or suspension restriction prevents restoration. An expired name cannot be restored from the bin just because fewer than 30 days have passed.

DELETE /v1/bin/label write:names

Permanently removes stored records after confirming cancellation of a linked card subscription. Cancellation errors prevent completion. Successful deletion can make an otherwise eligible name available before the normal quarantine ends; reserved and blocked names remain restricted. This cannot be undone. Scheduled processing normally attempts permanent deletion after 30 days in the bin.

Dynamic DNS

GET https://ddns.uk.app/nic/update?hostname=host&myip=ip Basic auth

Uses the dyndns2 protocol. Configure a client that accepts a custom HTTPS update server, such as ddclient. Router and NAS support depends on the model and firmware; a built-in DDNS menu alone does not guarantee compatibility. Username is the name (petersblog.uk.app), password is the DDNS token from the domain page → Dynamic DNS (scoped to that name only). Create or replace it there; copy it immediately because it is shown only once. Revoke it to stop updates without deleting DNS records. DDNS requires managed DNS and an active, parked or grace-period name. Omit myip to use the caller's address; IPv6 addresses create AAAA records. Responses: good ip, nochg ip, badauth, nohost.

# /etc/ddclient.conf
protocol=dyndns2
ssl=yes
use=web
server=ddns.uk.app
login=petersblog.uk.app
password=YOUR_DDNS_TOKEN
home.petersblog.uk.app

# or from cron
curl -u "petersblog.uk.app:YOUR_DDNS_TOKEN" "https://ddns.uk.app/nic/update?hostname=home.petersblog.uk.app"

ACME DNS-01 (wildcard certificates)

Use the adapters in the ACME setup guide with a write:records token. They create challenge TXT records and remove only the records they created, preserving unrelated or concurrent challenges. API support alone does not mean a certificate client has a native uk.app provider. Follow the client-specific setup and renewal instructions.

A custom acme.sh hook, lego exec adapter and Python CLI are available in the integration download. DNS-01 staging issuance was verified with acme.sh 3.1.5 and lego 5.4.1 on 13 September 2026. Follow the ACME setup guide. These integrations are provided here; no native uk.app provider has been merged upstream. Certificate-authority limits and domain grouping still apply; check the authority's current policy before relying on high-volume issuance.

MCP for AI agents

Connect a Streamable HTTP client to https://mcp.uk.app/. OAuth discovery redirects you to your existing uk.app login and an explicit authorization screen; PKCE S256 is required. Clients using API tokens can send Authorization: Bearer <token> instead. Existing token scopes remain enforced.

The registry tool accepts an action: check_name, list_names, get_balance, list_records, verify_domain, reserve_name, add_record or delete_record. Include name except for list_names/get_balance. Record writes use the same host/type/content/ttl/prio fields as the API; deletion requires the record ID.

OAuth approval authorizes account reads, DNS changes and reservations. Reservations return a checkout link for a person to pay; no MCP action charges a card or spends account balance. Revoke OAuth access from MCP connections. Supported registration callbacks are HTTPS under claude.ai or chatgpt.com, or local loopback callbacks; other clients require an explicit callback configuration. The download also includes the local stdio adapter.

Balance payments

Balance top-ups and name payments are separate transactions. The REST registration route can spend sufficient balance automatically unless pay=checkout is supplied; MCP reservations do not. Balance-funded live names attempt annual renewal from available funds, including retries during grace. Card subscriptions renew through Stripe. See payment and cancellation terms and the billing panel before funding automated use.

Limits & billing

PriceStandard: £4.99/year. New premium registrations: £99.00/year. Existing premium registrations retain their agreed annual price. Check the quoted price and final checkout total; see pricing.
Names per account100 (ask support@uk.app for more).
Records per name100.
Reservation48 hours unpaid, then the label is released.
LapseNormally: 30 days grace → 30 days hold without published DNS → bin with 30-day quarantine. Scheduled processing, early permanent deletion and registration restrictions affect reuse; see terms.
RefundRequest within 14 days of the first registration payment if the name has not been used. This service offer does not limit statutory rights. See refund details.
API rate600 requests/minute per token; DDNS 60/minute per name.

HTTPS & HSTS

The .app TLD is on the HSTS preload list of Chrome, Firefox, Safari and Edge. Browsers refuse plain HTTP for any .app hostname, so a uk.app site without a valid certificate does not load at all — there is no "proceed anyway". Supported hosting providers and configured servers can automate certificate issuance after hostname verification and their other requirements are met. HTTP-01 also needs the challenge to be reachable over public port 80; a DNS record alone is insufficient. Certificate-authority limits apply, including shared registered-domain limits while uk.app is not independently listed in the PSL. See Let’s Encrypt rate limits. Use verify to confirm the certificate is in place.

OpenAPI

The machine-readable spec is at https://api.uk.app/v1/openapi.json (OpenAPI 3.1). Generate a client with openapi-generator, or paste the URL into Postman, Insomnia or Bruno.

A name for your next idea

Give your website, home server or next project a memorable address: yourname.uk.app. Choose your name and check availability before registering.

Find your name