# Porkbun > Porkbun is a domain registrar with a developer-friendly REST API for programmatic domain registration, transfers, DNS management, SSL certificates, and related operations. The API is built for AI agents and automation: machine-readable error codes, idempotency keys on writes, request IDs, version signalling, header auth, GET on all reads, signed outbound webhooks, and an official MCP server. The OpenAPI spec is at https://porkbun.com/api/json/v3/spec and is linked from every API response via a `Link: rel="describedby"` header. Documentation home (all formats): https://porkbun.com/api/json/v3/documentation — interactive reference at https://porkbun.com/api/json/v3/documentation/interactive Note: unlike some registrars, Porkbun API keys work regardless of whether account two-factor authentication is enabled — you never have to weaken account security to automate. ## What you can do with the Porkbun API - Check domain availability and pricing across hundreds of TLDs (no auth required) - Register, renew, and transfer-in domain names programmatically - Get a single domain or list/filter all domains in an account (by TLD, expiry window, auto-renew, API-access) - Create, read, update, and delete DNS records (A, AAAA, CNAME, MX, TXT, NS, SRV, CAA, TLSA, SSHFP, ALIAS, HTTPS, SVCB) - Manage DNSSEC records, URL forwarding, and glue records - Retrieve free SSL certificate bundles for registered domains - Read account credit balance and API spend-control settings - Browse the domain marketplace with server-side filters (query, TLD, SLD length, sort) - Set auto-renewal across a portfolio; detect caller IP for dynamic DNS - Subscribe to outbound webhooks for real-time, signed event notifications (registrations, renewals, transfers, upcoming expirations, DNS changes) instead of polling ## Agent-safety features (why this API is good for autonomous use) - **Dry run / validate-only** — pass `dryRun: true` to rehearse a write without performing it. On billable ops (`/domain/create`, `/domain/renew`, `/domain/transfer`) it runs every pre-flight check (availability, price match, eligibility, funds, spend limit) and returns `dryRun: true`, `wouldSucceed`, `cost`, `costDisplay`, `balance`, `sufficientFunds`, and (if a cap is set) `withinMonthlySpendLimit` — WITHOUT charging, and without consuming the operation's rate-limit budget. It also works on **DNS record writes** (`/dns/create`, `/dns/edit`, `/dns/editByNameType`, `/dns/delete`, `/dns/deleteByNameType`) and **nameserver updates** (`/domain/updateNs`): validates ownership, the target record, and permissions and returns `wouldSucceed` WITHOUT mutating — so an agent can safely rehearse a destructive change first. - **Idempotency keys** — send `Idempotency-Key: ` on any POST; retries within 24h replay the original response instead of re-charging or double-registering. Reused key with a different body returns 409 `IDEMPOTENCY_KEY_MISMATCH`; an in-flight duplicate returns 409 `IDEMPOTENCY_KEY_IN_USE`. - **Request IDs** — every response carries an `X-Request-Id` header and a `requestId` body field (UUIDv7) for retry-dedup, log correlation, and support tickets. - **Registration requirements as JSON Schema** — `GET /domain/getRegistrationRequirements/{tld}` tells you upfront whether a TLD is API-registerable and returns the `/domain/create` body as a JSON Schema, plus (for TLDs with registry eligibility rules like .us/.ca) a schema of the required fields + allowed values. Validate a registration before attempting it instead of discovering requirements via a failed call. - **Version signalling** — every response carries `X-API-Version` (e.g. `3.4`). The URL path stays `/api/json/v3/`; minor bumps are always backward-compatible, so you can pin `v3` and watch the header / Changelog for additions. - **Outbound webhooks** — register HTTPS endpoints and Porkbun POSTs a signed JSON payload when events occur, so an agent reacts to state changes instead of polling. Events: `domain.registered`, `domain.renewed`, `domain.transfer.completed`, `domain.expiring`, `dns.record.created|updated|deleted`. Each delivery carries `X-Porkbun-Signature` = `sha256=` + `HMAC-SHA256(secret, "{timestamp}.{rawBody}")` (timestamp from `X-Porkbun-Webhook-Timestamp`); verify it with a constant-time compare and reject stale timestamps. Failed deliveries retry with exponential backoff (6 attempts) and a ~30-day delivery log is queryable (`/webhook/deliveries`, `/webhook/delivery/{id}`) with manual replay via `/webhook/resend` (reuses the original event id). Manage via the `/webhook/*` endpoints or the MCP `*_webhook` tools. - **Machine-readable error codes** — every error has `status: "ERROR"`, a human `message`, and a stable `code`. - **Actionable errors** — most errors also carry a `next_action` object (`{type, hint, url?}`) telling you how to recover (re-quote the price, enable API access, add funds, register on the website, etc.). `type` is a small stable vocabulary (`fix_request`, `authenticate`, `enable_setting`, `add_funds`, `wait_and_retry`, `use_website`, …) — branch on it instead of string-matching messages. - **Rate-limit headers** — `X-RateLimit-Limit`, `X-RateLimit-Remaining`, `X-RateLimit-Reset` on rate-limited endpoints. - **Spec self-discovery** — `Link: <...spec>; rel="describedby"` on every response. - **Per-key scoping** — each API key can be restricted to specific source IPs (CIDR supported) and/or specific domains; out-of-policy calls return 403 `IP_NOT_ALLOWED` / `DOMAIN_NOT_ALLOWED`. Hand an agent a key that can only touch the domains you intend, from the network you expect. - **Spend controls** — per-account monthly API spend limit, low-balance alerts, and auto top-up, enforced on registrations/renewals/transfers. ## Official MCP server Porkbun ships a first-party Model Context Protocol server exposing the whole API as native tools (Claude Desktop, Cursor, Cline, etc.). Write tools auto-attach an Idempotency-Key. One server covers both **live operations** and **documentation grounding** — alongside the domain/DNS/SSL/webhook tools it includes `list_doc_topics`, `read_doc`, and `search_docs`, so an agent can search and read these docs in-session without leaving the conversation (no separate docs server to install). ``` npx -y @porkbunllc/mcp-server ``` Repo: https://github.com/oborseth/Porkbun-MCP — configure with `PORKBUN_API_KEY` / `PORKBUN_SECRET_API_KEY`. ## Quickstart (agentic domain registration) 1. Check availability + price: `POST https://api.porkbun.com/api/json/v3/domain/checkDomain/{domain}` 2. Register: `POST /domain/create/{domain}` with `cost` (price in pennies as integer, must match the quote), `agreeToTerms: "yes"`, and an `Idempotency-Key` header 3. Add DNS: `POST /dns/create/{domain}` with `type`, `content`, optional `ttl` ## Authentication Pass `apikey` and `secretapikey` in the JSON body, or use `X-API-Key` / `X-Secret-API-Key` request headers (preferred for GET and agent frameworks). A short-lived bearer token is also available via `/auth/getToken` (`Authorization: Bearer `). Create keys at https://porkbun.com/account/api ## Key endpoints - `GET/POST /ping` — verify credentials, get caller IP - `GET/POST /ip` — caller IP, no auth - `GET/POST /pricing/get` — pricing across all TLDs (no auth) - `POST /domain/checkDomain/{domain}` — availability + price (registration, renewal, transfer) - `GET /domain/getRegistrationRequirements/{tld}` — is the TLD API-registerable + the create-request body as JSON Schema + any registry eligibility fields (e.g. .us nexus, .ca legal type). Call before create to validate eligibility/payload - `POST /domain/create/{domain}` — register - `POST /domain/renew/{domain}` — renew - `POST /domain/transfer/{domain}` — initiate inbound transfer (needs `authCode`) - `GET /domain/getTransfer/{domain}` , `GET /domain/listTransfers` — transfer status - `GET /domain/get/{domain}` — single domain detail - `GET/POST /domain/listAll` — list/filter domains (`?tlds[]=`, `?expiringWithinDays=`, `?autoRenew=`, `?apiAccess=`, `?nameContains=`, `?sortName=`, `?start=`) - `GET/POST /dns/retrieve/{domain}` — get DNS records - `POST /dns/create/{domain}` , `POST /dns/edit/{domain}/{id}` , `POST /dns/delete/{domain}/{id}` — manage DNS - `GET/POST /ssl/retrieve/{domain}` — SSL bundle - `GET /account/balance` — account credit balance - `GET /account/apiSettings` — spend-control settings + current month spend - `POST /marketplace/getAll` — marketplace listings with filters - `GET /webhook/eventTypes` — subscribable event-type catalog - `GET /webhook/list` , `GET /webhook/get/{id}` — list / fetch webhook endpoints - `POST /webhook/create` — register an HTTPS endpoint (returns the signing secret) - `POST /webhook/update` — change url/events/status (ACTIVE|DISABLED) - `POST /webhook/rotateSecret` , `POST /webhook/test` , `POST /webhook/delete` — rotate secret, send a test event, delete - `GET /webhook/deliveries` , `GET /webhook/delivery/{id}` — recent delivery log (~30 days) + single delivery with full payload - `POST /webhook/resend` — re-queue a past delivery (reuses the original event id) ## Error codes (selection) - `INVALID_API_KEYS_001` — the public `apikey` is invalid/unknown - `INVALID_API_KEYS_002` — the public key is valid but the `secretapikey` doesn't match - `MISSING_SECRETAPIKEY` — no secret supplied (common cause: the field was named `secretkey` instead of `secretapikey`) - `IP_NOT_ALLOWED` / `DOMAIN_NOT_ALLOWED` — request outside this key's allowlist - `IDEMPOTENCY_KEY_MISMATCH` / `IDEMPOTENCY_KEY_IN_USE` — idempotency conflicts - `RATE_LIMIT_EXCEEDED` — see `ttlRemaining` and `X-RateLimit-Reset` - `MONTHLY_SPEND_LIMIT_EXCEEDED` — would exceed the account's API spend cap - `INSUFFICIENT_FUNDS` — not enough account credit - `DOMAIN_NOT_FOUND` / `INVALID_DOMAIN` — domain not in your account / invalid - `INVALID_TYPE` — unsupported DNS record type ## API specification - OpenAPI 3.0 spec: https://porkbun.com/api/json/v3/spec - Full Markdown reference (no JS): https://porkbun.com/llms-full.txt - Per-topic Markdown docs (index): https://porkbun.com/llms (e.g. /llms/dns, /llms/webhooks) - Guides (task-oriented how-tos): https://porkbun.com/llms/guides (getting-started, register-a-domain, dynamic-dns, verify-a-webhook) - Documentation home (all formats): https://porkbun.com/api/json/v3/documentation - Interactive reference: https://porkbun.com/api/json/v3/documentation/interactive - Base URL: https://api.porkbun.com/api/json/v3 - IPv4-only base URL: https://api-ipv4.porkbun.com/api/json/v3 (force IPv4 from an IPv6 network) ## Links - Homepage: https://porkbun.com - Domain pricing: https://porkbun.com/tlds - Create API keys: https://porkbun.com/account/api - MCP server: https://github.com/oborseth/Porkbun-MCP - Support: https://porkbun.com/support