{"openapi":"3.0.0","info":{"title":"Porkbun API v3","version":"3.7","description":"The Porkbun API enables programmatic domain registration, DNS management, SSL certificate retrieval, and related operations. It is fully usable by AI agents, automation scripts, and developer tools.\n## Quickstart\n\n**1. Get your API keys** \u2014 visit https:\/\/porkbun.com\/account\/api\n\n**2. Test connectivity**\n```bash\ncurl https:\/\/api.porkbun.com\/api\/json\/v3\/ip\n```\nReturns your public IP. No credentials required.\n\n**3. Check domain availability** (also verifies your credentials)\n```bash\ncurl -X POST https:\/\/api.porkbun.com\/api\/json\/v3\/domain\/checkDomain\/example.com \\\n  -H \"Content-Type: application\/json\" \\\n  -d '{\"apikey\":\"your_api_key\",\"secretapikey\":\"your_secret_key\"}'\n```\nReturns `avail: \"yes\"\/\"no\"` and `price` in USD. Returns an error if credentials are invalid.\n\n**4. Register the domain** \u2014 convert `price` to pennies (e.g. $9.73 \u2192 973) for `cost`\n```bash\ncurl -X POST https:\/\/api.porkbun.com\/api\/json\/v3\/domain\/create\/example.com \\\n  -H \"Content-Type: application\/json\" \\\n  -d '{\"apikey\":\"your_api_key\",\"secretapikey\":\"your_secret_key\",\"cost\":973,\"agreeToTerms\":\"yes\"}'\n```\n\n**5. Add a DNS record**\n```bash\ncurl -X POST https:\/\/api.porkbun.com\/api\/json\/v3\/dns\/create\/example.com \\\n  -H \"Content-Type: application\/json\" \\\n  -d '{\"apikey\":\"your_api_key\",\"secretapikey\":\"your_secret_key\",\"type\":\"A\",\"content\":\"1.2.3.4\",\"ttl\":\"600\"}'\n```\n\n## AI agents (MCP)\n\nIf you're building with Claude Desktop, Cursor, Cline, or another [Model Context Protocol](https:\/\/modelcontextprotocol.io) client, install our official Porkbun MCP server \u2014 no integration code required, your AI client gets domain registration, DNS, SSL, marketplace, and account-management tools natively.\n\n```bash\nnpx -y @porkbunllc\/mcp-server\n```\n\nRepo and Claude Desktop config: [github.com\/oborseth\/Porkbun-MCP](https:\/\/github.com\/oborseth\/Porkbun-MCP). It covers everything documented below, plus documentation-search tools that work without credentials. See the repo README for the current tool list. All write operations automatically attach an `Idempotency-Key` so agent retries don't double-charge.\n\n## What you can build\n\n- **Agentic domain registration** \u2014 Search availability and pricing across hundreds of TLDs, then register domains on behalf of users with a single API call\n- **Automated DNS management** \u2014 Provision, update, and tear down DNS records as part of infrastructure automation or app deployment pipelines\n- **Dynamic DNS clients** \u2014 Use `\/ping` or `\/ip` to detect IP address changes, then update A\/AAAA records automatically\n- **Domain portfolio tools** \u2014 List, monitor expiry, and configure auto-renewal settings across all domains in an account\n- **SSL automation** \u2014 Retrieve free SSL certificate bundles for domains registered at Porkbun\n- **Domain availability search** \u2014 Check availability and real-time pricing across all supported TLDs\n\n## Agent-friendly design\n\n- **Machine-readable error codes** \u2014 Every error response includes a `code` field (e.g. `INVALID_DOMAIN`, `INSUFFICIENT_FUNDS`) for programmatic branching\n- **Header authentication** \u2014 Pass `X-API-Key` \/ `X-Secret-API-Key` as request headers; no JSON body required for read operations\n- **GET support on read endpoints** \u2014 All read-only endpoints accept `GET` requests, making safe\/idempotent operations distinguishable by HTTP method\n- **Rate limit headers** \u2014 `X-RateLimit-Limit`, `X-RateLimit-Remaining`, and `X-RateLimit-Reset` on rate-limited endpoints enable intelligent backoff\n- **Spec discovery** \u2014 Every API response includes `Link: <https:\/\/porkbun.com\/api\/json\/v3\/spec>; rel=\"describedby\"` so clients can self-discover this spec\n- **Idempotency keys** \u2014 Send `Idempotency-Key: <unique-string>` on POST endpoints; retries within 24h return the cached response so a network blip can't double-charge\n- **Official MCP server** \u2014 `npx -y @porkbunllc\/mcp-server` exposes this entire API as native tools for Claude Desktop, Cursor, and other Model Context Protocol clients\n- **Request IDs** \u2014 every response carries an `X-Request-Id` header and a `requestId` field in the JSON body; reference these in support tickets, retry-deduplication logic, or log correlation\n- **Version signalling** \u2014 every response carries an `X-API-Version` header (matching this spec's `info.version`). The URL path stays at `\/api\/json\/v3\/` across all minor versions; minor bumps are always backward-compatible, so you can pin to `v3` and watch the header (or the Changelog below) to know what's available\n- **Per-key scoping** \u2014 restrict each API key to specific source IPs (with CIDR support) and\/or specific target domains. Lets you hand an agent a key that can only operate on the domains you intend, from the network you expect\n- **Plain-text docs for LLMs** \u2014 a short overview at [\/llms.txt](https:\/\/porkbun.com\/llms.txt) and the full reference as flat Markdown at [\/llms-full.txt](https:\/\/porkbun.com\/llms-full.txt), and per-topic pages at [\/llms](https:\/\/porkbun.com\/llms) (no JavaScript required, generated from this spec)\n- **Per-TLD registration requirements (JSON Schema)** \u2014 `GET \/domain\/getRegistrationRequirements\/{tld}` returns whether a TLD is registerable via the API, the `\/domain\/create` body as a JSON Schema, and (for TLDs with registry eligibility rules like `.us`\/`.ca`) a second JSON Schema of the required fields and allowed values. Assemble and validate a registration payload before sending it, instead of discovering requirements through failed attempts.\n- **Dry run \/ validate-only** \u2014 pass `dryRun: true` to rehearse a write without performing it. On the billable ops (`\/domain\/create`, `\/domain\/renew`, `\/domain\/transfer`) it runs every pre-flight check and returns the would-be cost, balance, and `wouldSucceed` WITHOUT charging. 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, returns `wouldSucceed` WITHOUT mutating anything \u2014 so an agent can safely rehearse a destructive change before applying it\n\n## Intended use\n\nThe Porkbun API is not a reseller service as defined under ICANN\u2019s Registrar Accreditation Agreement (RAA). All domain registrations are processed directly by Porkbun as the registrar of record. The API is intended for managing domains within your own account or on behalf of clients, and does not establish a reseller relationship.\n\n## Authentication\n\n**1. JSON body (primary)** \u2014 Include `apikey` and `secretapikey` in the JSON request body. This is the standard method.\n\n**2. Request headers** \u2014 Pass `X-API-Key: <apikey>` and `X-Secret-API-Key: <secretapikey>` as headers instead of in the body. Header auth takes effect only when no body credentials are present.\n\n## HTTP status codes\n\n- **400** \u2014 Request error (see `code` and `message` in response body)\n- **403** \u2014 Additional authentication required (e.g. two-factor code)\n- **429** \u2014 Rate limit exceeded (see `X-RateLimit-Reset` header for retry time)\n\n## Error codes\n\nEvery error response includes a `code` string field alongside `status: \"ERROR\"` and `message`. Use `code` for programmatic error handling; use `message` for display to users.\n\n**Authentication and protocol**\n\n| Code | Meaning |\n|------|---------|\n| `INVALID_PROTOCOL` | Request was not made over HTTPS |\n| `METHOD_NOT_ALLOWED` | HTTP method not allowed for this endpoint |\n| `INVALID_OR_EMPTY_JSON` | Request body is missing or not valid JSON |\n| `API_KEY_REQUIRED` | No API key or token was provided |\n| `INVALID_API_KEYS_001` | API key and secret combination is invalid |\n| `INVALID_TOKEN` | Bearer token is invalid or expired |\n| `INVALID_USER` | Account associated with the API key was not found or is not active |\n| `IP_NOT_ALLOWED` | This API key has an IP allowlist configured and the request source IP is not in it. HTTP 403. |\n| `DOMAIN_NOT_ALLOWED` | This API key has a domain allowlist configured and the target domain is not in it. HTTP 403. |\n\n**Rate limiting**\n\n| Code | Meaning |\n|------|---------|\n| `RATE_LIMIT_EXCEEDED` | Request rate limit reached; see `ttlRemaining` field and `X-RateLimit-Reset` header for reset time |\n\n**Domain operations**\n\n| Code | Meaning |\n|------|---------|\n| `INVALID_DOMAIN` | Domain parameter is invalid or not in your account |\n| `DOMAIN_NOT_AVAILABLE` | Domain is not available for registration |\n| `INSUFFICIENT_FUNDS` | Account credit is insufficient to complete the purchase |\n\n**DNS operations**\n\n| Code | Meaning |\n|------|---------|\n| `INVALID_TYPE` | DNS record type is not supported |\n| `INVALID_RECORD_ID` | DNS record ID was not found or is not owned by your account |\n\nAdditional endpoint-specific codes may be returned; always check `message` for details.\n\n## API key scoping (IP &amp; domain restrictions)\n\nEach API key can optionally be restricted to specific source IPs and\/or specific target domains. Both restrictions are configured per key at [porkbun.com\/account\/api](https:\/\/porkbun.com\/account\/api) (click the gear icon next to any key). Empty\/unset = no restriction.\n\n**Source IP allowlist.** When set, requests from any other IP fail immediately with HTTP 403 `IP_NOT_ALLOWED`, before any other endpoint logic runs. Supports IPv4 and IPv6, both bare addresses and CIDR ranges. One entry per line in the UI. Examples:\n\n```\n203.0.113.10\n198.51.100.0\/24\n2001:db8::\/32\n```\n\n**Target domain allowlist.** When set, any operation against a domain not in the list fails with HTTP 403 `DOMAIN_NOT_ALLOWED`. Exact match only \u2014 `example.com` does not implicitly include `foo.example.com`, because each registered domain is independent. (Subdomains inside DNS records are scoped under the parent domain, which is what gets checked.) Example:\n\n```\nexample.com\nmyothersite.io\n```\n\n**Recommended pattern for AI agents.** Hand the agent its own dedicated API key, restricted to the domains it actually needs to manage and (if you know the agent's egress IP) restricted to that IP. The blast radius of an accidentally-leaked key drops to `operations on these domains from this IP` instead of `anything on the account`.\n\n## Idempotency\n\nAll v3 POST endpoints (excluding partner-only routes) accept an optional `Idempotency-Key` request header. When present, the API stores the response for 24 hours and replays it for any retry of the same request \u2014 so an agent that retries after a network blip will not double-charge or double-register.\n\n**Key format:** any non-empty string up to 255 characters. UUIDs work well; agents can also use their own internal request IDs.\n\n**Behavior on retry:**\n\n- **Same key, same request body** within 24h \u2192 returns the original response with header `Idempotent-Replayed: true`\n- **Same key, different request body** \u2192 returns 409 with `code: IDEMPOTENCY_KEY_MISMATCH` (catches accidental key reuse)\n- **Same key, original request still in flight** \u2192 returns 409 with `code: IDEMPOTENCY_KEY_IN_USE` (retry shortly)\n- **No header sent** \u2192 behavior is unchanged from before; no caching happens\n\n```bash\ncurl -X POST https:\/\/api.porkbun.com\/api\/json\/v3\/domain\/create\/example.com \\\n  -H \"Idempotency-Key: a1b2c3d4-e5f6-7890-abcd-ef1234567890\" \\\n  -H \"X-API-Key: pk1_...\" -H \"X-Secret-API-Key: sk1_...\" \\\n  -d '{\"cost\":973,\"agreeToTerms\":\"yes\"}'\n```\n\n## Rate limiting\n\nSome endpoints are rate limited. When exceeded, the API returns HTTP 429 with a `RateLimitExceeded` response body. Fixed-limit endpoints (`\/apikey\/request`, `\/apikey\/retrieve`) also return `X-RateLimit-Limit`, `X-RateLimit-Remaining`, and `X-RateLimit-Reset` headers on every call.\n\n## Webhooks\n\nSubscribe HTTPS endpoints to account events and Porkbun will `POST` a signed JSON payload to them as those events happen \u2014 no polling required. Manage endpoints with the **Webhooks** endpoints in this reference, the MCP tools (`create_webhook`, `list_webhooks`, \u2026), or the web UI at `porkbun.com\/account\/api`.\n\n**Event types:** `domain.registered`, `domain.renewed`, `domain.transfer.completed`, `domain.expiring` (fires at 60\/30\/5 days before expiry), `dns.record.created`, `dns.record.updated`, `dns.record.deleted`. Subscribe to specific types, to a prefix wildcard like `dns.*`, or to `*` for everything (recommended \u2014 you'll receive new event types automatically). Call `GET \/webhook\/eventTypes` for the live catalog.\n\n**Payload envelope** \u2014 every delivery has the same outer shape:\n\n```json\n{\n  \"event\": \"domain.registered\",\n  \"id\": \"018f9c2a-7b3e-7c41-9b8a-2f1e6d4c5a90\",\n  \"createdAt\": \"2026-06-17T18:30:00Z\",\n  \"data\": { \"domain\": \"example.com\", \"tld\": \"com\", \"expireDate\": \"2027-06-17 18:30:00\" }\n}\n```\n\n`id` is a UUIDv7 (time-ordered) and is also sent as the `X-Porkbun-Webhook-Id` header; use it to dedupe, since an endpoint may occasionally receive the same event more than once. The `data` object is event-specific.\n\n**Delivery headers:**\n\n- `X-Porkbun-Event` \u2014 the event type (e.g. `domain.renewed`).\n- `X-Porkbun-Webhook-Id` \u2014 the event UUID (matches `id` in the body).\n- `X-Porkbun-Webhook-Timestamp` \u2014 Unix seconds when the request was signed.\n- `X-Porkbun-Signature` \u2014 `sha256=` + the signature (see below).\n\n**Verify the signature.** The signature is `HMAC-SHA256(secret, \"{timestamp}.{rawBody}\")` where `secret` is the endpoint's signing secret, `{timestamp}` is the `X-Porkbun-Webhook-Timestamp` header value, and `{rawBody}` is the exact bytes of the request body (verify before parsing). Compare using a constant-time equality check, and reject timestamps that are too old (e.g. >5 minutes) to blunt replay attacks.\n\n```php\n$timestamp = $_SERVER['HTTP_X_PORKBUN_WEBHOOK_TIMESTAMP'];\n$signature = $_SERVER['HTTP_X_PORKBUN_SIGNATURE']; \/\/ \"sha256=...\"\n$body      = file_get_contents('php:\/\/input');\n$expected  = 'sha256=' . hash_hmac('sha256', $timestamp . '.' . $body, $endpointSecret);\nif (!hash_equals($expected, $signature) || abs(time() - (int)$timestamp) > 300) {\n    http_response_code(400); exit;\n}\n\/\/ signature OK \u2014 now json_decode($body) and process\n```\n\n```javascript\nimport crypto from 'node:crypto';\nconst ts  = req.header('X-Porkbun-Webhook-Timestamp');\nconst sig = req.header('X-Porkbun-Signature');\nconst expected = 'sha256=' + crypto.createHmac('sha256', endpointSecret)\n  .update(`${ts}.${rawBody}`).digest('hex');\nconst ok = crypto.timingSafeEqual(Buffer.from(expected), Buffer.from(sig))\n  && Math.abs(Date.now()\/1000 - Number(ts)) < 300;\n```\n\n**Delivery log & manual resend.** Every attempt is recorded \u2014 list recent deliveries with `GET \/webhook\/deliveries` (filter by `endpointId` or `status`, newest first) and fetch one with its full payload via `GET \/webhook\/delivery\/{id}`. History is retained ~30 days. To replay a delivery (e.g. after fixing a bug on your side), call `POST \/webhook\/resend` with the delivery `id`; it re-queues a fresh attempt reusing the **original event id**, so a consumer that dedupes on `X-Porkbun-Webhook-Id` treats it as the same event. The target endpoint must still exist and be ACTIVE.\n\n**Responding & retries.** Return any `2xx` status to acknowledge. Non-2xx responses, timeouts, or connection errors are retried with exponential backoff (~1m, 5m, 30m, 2h, 6h) up to 6 attempts. An endpoint that racks up 20 consecutive failures is automatically disabled and the account owner emailed; re-enable it (which resets the failure counter) via `POST \/webhook\/update` with `status: \"ACTIVE\"`. Use `POST \/webhook\/test` to send a `webhook.test` event and confirm your verifier works end-to-end.\n\n## Changelog\n\nThe API URL path stays at `\/api\/json\/v3\/`. The version below (`major.minor`, also on the `X-API-Version` response header) tracks backward-compatible additions \u2014 new endpoints, new optional fields, new error codes, relaxed limits. Existing integrations are never broken by a minor bump; only a breaking change would introduce a new major version (and a new URL path).\n\n### v3.7\n\n- **Clearer auth errors** \u2014 a request with a valid API key but a missing or misnamed secret now returns `MISSING_SECRETAPIKEY` with an explicit message (the field is `secretapikey`, not `secretkey`) instead of the generic `INVALID_API_KEYS_002`. A genuinely wrong secret still returns the deliberately-vague `INVALID_API_KEYS_002`, and auth errors now carry `next_action` hints.\n\n### v3.6\n\n- **Validate-only writes** \u2014 `dryRun: true` now works beyond the billable endpoints: DNS record writes (`\/dns\/create`, `\/dns\/edit`, `\/dns\/editByNameType`, `\/dns\/delete`, `\/dns\/deleteByNameType`) and nameserver updates (`\/domain\/updateNs`) validate and return `wouldSucceed` without mutating anything. Rehearse a destructive change before applying it.\n\n### v3.5\n\n- **Actionable errors** \u2014 most error responses now include a `next_action` object (`{type, hint, url?}`) telling an agent how to recover (e.g. re-quote the price, enable API access, add funds, register on the website). `type` is a small stable vocabulary; branch on it instead of string-matching messages.\n\n### v3.4\n\n- **TLD registration requirements as JSON Schema** \u2014 `GET \/domain\/getRegistrationRequirements\/{tld}` returns whether a TLD is API-registerable, the `\/domain\/create` body as a JSON Schema, and (for TLDs with registry eligibility rules like .us\/.ca) a second schema enumerating the required fields and allowed values. Lets an agent validate a registration before attempting it.\n\n### v3.3\n\n- **Outbound webhooks** \u2014 register HTTPS endpoints that Porkbun POSTs signed JSON to when lifecycle events occur (`domain.registered`, `domain.renewed`, `domain.transfer.completed`, `domain.expiring`, `dns.record.created|updated|deleted`). Manage them under the **Webhooks** endpoints below or at `porkbun.com\/account\/api`. Each delivery is signed with HMAC-SHA256 \u2014 see the **Webhooks** section above.\n\n### v3.2\n\n- **Dry run** \u2014 `dryRun: true` on register\/renew\/transfer previews availability, cost, balance, and `wouldSucceed` without charging or creating anything.\n- **LLM-readable docs** \u2014 full API reference as flat Markdown at `\/llms-full.txt`, plus per-topic pages indexed at `\/llms`, generated from this spec; refreshed `\/llms.txt` index; non-JavaScript fallback on the docs page so agents can read it.\n\n### v3.1\n\n- **Idempotency** \u2014 `Idempotency-Key` request header on POST endpoints; retries within 24h replay the original response instead of re-charging.\n- **Request IDs** \u2014 `X-Request-Id` response header and `requestId` body field on every response.\n- **Version signalling** \u2014 `X-API-Version` response header.\n- **Domain transfers** \u2014 `transfer`, `getTransfer`, and `listTransfers` endpoints for inbound transfers via API.\n- **Single-domain lookup** \u2014 `GET \/domain\/get\/{domain}` plus new filters on `listAll` (`domain`, `nameContains`, `tlds`, `expiringWithinDays`, `autoRenew`, `apiAccess`, `sortName`, `sortDirection`).\n- **Marketplace filtering** \u2014 server-side `query`, `tlds`, `sldLengthMin`\/`Max`, and sort parameters on `marketplace\/getAll`.\n- **Account endpoints** \u2014 `GET \/account\/balance` and `GET \/account\/apiSettings`.\n- **Spend controls** \u2014 per-account monthly spend limit, low-balance alert, and auto top-up, enforced on registrations\/renewals\/transfers.\n- **Per-key restrictions** \u2014 each API key can be scoped to specific source IPs (with CIDR support) and\/or specific target domains (`IP_NOT_ALLOWED` \/ `DOMAIN_NOT_ALLOWED`).\n- **DNS record types** \u2014 `HTTPS`, `SVCB`, and `SSHFP` documented as supported types.\n- **Machine-readable error codes** \u2014 every error response includes a `code` field.","contact":{"name":"Porkbun Support","url":"https:\/\/porkbun.com\/support"},"x-logo":{"url":"https:\/\/porkbun.com\/img\/logo.png"}},"servers":[{"url":"https:\/\/api.porkbun.com\/api\/json\/v3","description":"Production"},{"url":"https:\/\/api-ipv4.porkbun.com\/api\/json\/v3","description":"Production (IPv4 only \u2014 use this if your client is on an IPv6 network and needs to reach the API over IPv4)"}],"paths":{"\/ping":{"post":{"tags":["Utility"],"summary":"Test credentials and get caller IP","description":"Returns the caller's public IP address. Optionally validates API credentials.\n\n- **No credentials supplied** \u2014 returns IP only.\n- **Valid credentials supplied** \u2014 returns IP with `credentialsValid: true`.\n- **Invalid credentials supplied** \u2014 returns an error.\n\nUseful for agents and clients to verify their API key is working before making other calls.","operationId":"ping","requestBody":{"required":false,"content":{"application\/json":{"schema":{"type":"object","properties":{"apikey":{"type":"string","description":"Your API key (optional)"},"secretapikey":{"type":"string","description":"Your secret API key (optional, required if apikey is supplied)"}}}}}},"responses":{"200":{"description":"Success \u2014 IP returned, credentials validated if supplied","content":{"application\/json":{"schema":{"allOf":[{"$ref":"#\/components\/schemas\/IpResponse"},{"type":"object","properties":{"credentialsValid":{"type":"boolean","description":"Present and true when valid credentials were supplied"}}}]}}}},"400":{"description":"Invalid credentials","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/ErrorResponse"}}}}},"security":[],"x-codeSamples":[{"lang":"curl","label":"curl","source":"curl -X POST https:\/\/api.porkbun.com\/api\/json\/v3\/ping \\\n  -H 'Content-Type: application\/json' \\\n  -d '[]'"}]},"get":{"tags":["Utility"],"summary":"Test credentials and get caller IP","description":"Returns the caller's public IP address. Optionally validates API credentials.\n\n- **No credentials supplied** \u2014 returns IP only.\n- **Valid credentials supplied** \u2014 returns IP with `credentialsValid: true`.\n- **Invalid credentials supplied** \u2014 returns an error.\n\nUseful for agents and clients to verify their API key is working before making other calls.","operationId":"pingGet","parameters":[{"name":"X-API-Key","in":"header","required":false,"schema":{"type":"string"},"description":"API key header auth (use with X-Secret-API-Key)"},{"name":"X-Secret-API-Key","in":"header","required":false,"schema":{"type":"string"},"description":"Secret API key header auth (use with X-API-Key)"}],"responses":{"200":{"description":"Success \u2014 IP returned, credentials validated if supplied","content":{"application\/json":{"schema":{"allOf":[{"$ref":"#\/components\/schemas\/IpResponse"},{"type":"object","properties":{"credentialsValid":{"type":"boolean","description":"Present and true when valid credentials were supplied"}}}]}}}},"400":{"description":"Invalid credentials","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/ErrorResponse"}}}}},"security":[],"x-codeSamples":[{"lang":"curl","label":"curl","source":"curl 'https:\/\/api.porkbun.com\/api\/json\/v3\/ping'"}]}},"\/ip":{"post":{"tags":["Utility"],"summary":"Get caller IP address","description":"Returns the caller's public IP address. No credentials required. Use the `api-ipv4.porkbun.com` hostname if you need to force an IPv4 address.","operationId":"ipPost","requestBody":{"required":false,"content":{"application\/json":{"schema":{"type":"object"}}}},"responses":{"200":{"description":"Caller IP address","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/IpResponse"}}}}},"security":[],"x-codeSamples":[{"lang":"curl","label":"curl","source":"curl -X POST https:\/\/api.porkbun.com\/api\/json\/v3\/ip \\\n  -H 'Content-Type: application\/json' \\\n  -d '[]'"}]},"get":{"tags":["Utility"],"summary":"Get caller IP address","description":"Returns the caller's public IP address. No credentials required. Use the `api-ipv4.porkbun.com` hostname if you need to force an IPv4 address.","operationId":"getIp","parameters":[],"responses":{"200":{"description":"Caller IP address","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/IpResponse"}}}}},"security":[],"x-codeSamples":[{"lang":"curl","label":"curl","source":"curl 'https:\/\/api.porkbun.com\/api\/json\/v3\/ip'"}]}},"\/pricing\/get":{"post":{"tags":["Pricing"],"summary":"Retrieve domain pricing (public)","description":"Retrieve default domain pricing information for all supported TLDs. Does not require authentication. Prices are in US dollars.","operationId":"getPricing","requestBody":{"required":false,"content":{"application\/json":{"schema":{"type":"object","properties":{"tlds":{"type":"array","items":{"type":"string"},"description":"Optional array of TLDs to filter results. If omitted, all supported TLDs are returned."}}}}}},"responses":{"200":{"description":"Pricing data","content":{"application\/json":{"schema":{"type":"object","properties":{"status":{"type":"string","example":"SUCCESS"},"pricing":{"type":"object","description":"Object keyed by TLD string","additionalProperties":{"type":"object","properties":{"registration":{"type":"string","example":"9.73"},"renewal":{"type":"string","example":"9.73"},"transfer":{"type":"string","example":"9.73"},"specialType":{"type":"string","description":"Present only for special TLDs (e.g. 'handshake')"},"coupons":{"type":"object","description":"Active coupon codes for this TLD, keyed by product type","additionalProperties":{"type":"object","properties":{"code":{"type":"string"},"max_per_user":{"type":"integer"},"first_year_only":{"type":"string","enum":["yes","no"]},"type":{"type":"string"},"amount":{"type":"number"}}}}}}}}}}}}},"security":[],"x-codeSamples":[{"lang":"curl","label":"curl","source":"curl -X POST https:\/\/api.porkbun.com\/api\/json\/v3\/pricing\/get \\\n  -H 'Content-Type: application\/json' \\\n  -d '{\"tlds\":[]}'"}]},"get":{"tags":["Pricing"],"summary":"Retrieve domain pricing (public)","description":"Retrieve default domain pricing information for all supported TLDs. Does not require authentication. Prices are in US dollars.\n\nThis GET form returns pricing for all TLDs. To filter by specific TLDs, use `POST \/pricing\/get` with a `tlds` array in the request body.","operationId":"getPricingGet","parameters":[],"responses":{"200":{"description":"Pricing data","content":{"application\/json":{"schema":{"type":"object","properties":{"status":{"type":"string","example":"SUCCESS"},"pricing":{"type":"object","description":"Object keyed by TLD string","additionalProperties":{"type":"object","properties":{"registration":{"type":"string","example":"9.73"},"renewal":{"type":"string","example":"9.73"},"transfer":{"type":"string","example":"9.73"},"specialType":{"type":"string","description":"Present only for special TLDs (e.g. 'handshake')"},"coupons":{"type":"object","description":"Active coupon codes for this TLD, keyed by product type","additionalProperties":{"type":"object","properties":{"code":{"type":"string"},"max_per_user":{"type":"integer"},"first_year_only":{"type":"string","enum":["yes","no"]},"type":{"type":"string"},"amount":{"type":"number"}}}}}}}}}}}}},"security":[],"x-codeSamples":[{"lang":"curl","label":"curl","source":"curl 'https:\/\/api.porkbun.com\/api\/json\/v3\/pricing\/get'"}]}},"\/apikey\/request":{"post":{"tags":["API Key Management"],"summary":"Initiate an API key authorization request","description":"Initiate an API key authorization flow. No credentials are required. Returns a `requestToken` and `authUrl` that the account holder must visit to approve the request. After approval, the application should poll `\/apikey\/retrieve` to get the public API key. The secret API key is shown only in the user's browser and must be pasted into the application manually.\n\n**Rate limit:** 20 requests per IP per 3600 seconds.","operationId":"apikeyRequest","x-ratelimit":{"requests":20,"window":3600,"windowUnit":"seconds","scope":"ip","note":"Counted per originating IP address. The Redis key is API:apikeyRequest:{ip}."},"requestBody":{"required":false,"content":{"application\/json":{"schema":{"type":"object","properties":{"name":{"type":"string","maxLength":255,"description":"Optional human-readable name for the application requesting access."}}}}}},"responses":{"200":{"description":"Authorization request created","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Maximum requests allowed in the window (20)"},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Remaining requests in the current window"},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"Unix timestamp when the window resets"}},"content":{"application\/json":{"schema":{"type":"object","required":["requestToken"],"properties":{"status":{"type":"string","example":"SUCCESS"},"requestToken":{"type":"string","description":"Token used to poll `\/apikey\/retrieve` to check approval status."},"authUrl":{"type":"string","description":"URL the account holder must visit to approve the request","example":"https:\/\/porkbun.com\/account\/apiKeyApproval\/abc123..."},"expiration":{"type":"string","description":"ISO datetime when this request expires (10 minutes from creation)","example":"2026-03-30 14:30:00"},"message":{"type":"string","description":"Human-readable instructions"}}}}}},"400":{"description":"Validation error (e.g. app name too long)","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/RateLimitExceeded"}}}},"500":{"description":"Internal error","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/ErrorResponse"}}}}},"security":[],"x-codeSamples":[{"lang":"curl","label":"curl","source":"curl -X POST https:\/\/api.porkbun.com\/api\/json\/v3\/apikey\/request \\\n  -H 'Content-Type: application\/json' \\\n  -d '[]'"}]}},"\/apikey\/retrieve":{"post":{"tags":["API Key Management"],"summary":"Poll for API key approval","description":"Poll to check whether the account holder has approved an API key authorization request. Returns `status: PENDING` while awaiting approval. On approval, returns the public API key. The secret API key is never transmitted via this endpoint \u2014 it is displayed in the user's browser and must be pasted into the application.\n\n**Rate limit:** 120 requests per IP per 3600 seconds.","operationId":"apikeyRetrieve","x-ratelimit":{"requests":120,"window":3600,"windowUnit":"seconds","scope":"ip","note":"Counted per originating IP address. The Redis key is API:apikeyRetrieve:{ip}."},"requestBody":{"required":true,"content":{"application\/json":{"schema":{"type":"object","required":["requestToken"],"properties":{"requestToken":{"type":"string","description":"The token returned by \/apikey\/request. Must be a 64-character lowercase hex string.","pattern":"^[a-f0-9]{64}$"}}}}}},"responses":{"200":{"description":"Approval status. `status` may be `SUCCESS` (approved), `PENDING` (awaiting user action), or `ERROR` (expired\/denied\/invalid).","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Maximum requests allowed in the window (120)"},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Remaining requests in the current window"},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"Unix timestamp when the window resets"}},"content":{"application\/json":{"schema":{"type":"object","properties":{"status":{"type":"string","enum":["SUCCESS","PENDING","ERROR"],"example":"SUCCESS"},"apikey":{"type":"string","description":"The approved public API key. Present only when status is SUCCESS."},"message":{"type":"string"},"code":{"type":"string","description":"Machine-readable error code. Present when status is ERROR."}}}}}},"400":{"description":"Validation error or expired\/denied token","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/ErrorResponse"}}}},"403":{"description":"Request was denied by the account holder","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/RateLimitExceeded"}}}}},"security":[],"x-codeSamples":[{"lang":"curl","label":"curl","source":"curl -X POST https:\/\/api.porkbun.com\/api\/json\/v3\/apikey\/retrieve \\\n  -H 'Content-Type: application\/json' \\\n  -d '[]'"}]}},"\/domain\/checkDomain\/{domain}":{"post":{"tags":["Domain"],"summary":"Check domain availability","description":"Check if a domain is available for registration and retrieve current pricing. Includes registration, renewal, and transfer prices.\n\n**Rate limit:** Configurable per API key. Default is 1 check per 10 seconds per account. Rate limit usage is returned in the `limits` field of the response.","operationId":"domainCheckDomain","x-ratelimit":{"requests":1,"window":10,"windowUnit":"seconds","scope":"account","note":"Default values. The actual limit and window are configurable per API key (api.checkLimit \/ api.checkTTL). The Redis key is API:checkSingleDomain:{accountId}."},"parameters":[{"name":"domain","in":"path","required":true,"schema":{"type":"string"},"example":"example.com"}],"requestBody":{"required":true,"content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/AuthRequest"}}}},"responses":{"200":{"description":"Availability and pricing","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/CheckDomainResponse"}}}},"400":{"description":"Rate limit exceeded (returned as 200 body with status ERROR) or other error. See also 429.","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/RateLimitExceeded"}}}}},"x-codeSamples":[{"lang":"curl","label":"curl","source":"curl -X POST https:\/\/api.porkbun.com\/api\/json\/v3\/domain\/checkDomain\/{domain} \\\n  -H 'Content-Type: application\/json' \\\n  -d '{\"apikey\":\"pk1_...\",\"secretapikey\":\"sk1_...\"}'"}]}},"\/domain\/create\/{domain}":{"post":{"tags":["Domain"],"summary":"Register a domain","description":"Register a domain using account credit. Requirements:\n- Account email and phone must be verified\n- Account must have sufficient credit\n- `agreeToTerms` must be `'yes'` or `'1'`\n- `cost` must equal the current price for the domain's minimum registration duration (in pennies)\n- Account must have placed at least one previous domain registration\n- Premium domains cannot be registered via API\n\nRegistrations are always for the registry-minimum duration (usually 1 year).\n\n**WHOIS privacy.** WHOIS privacy is automatically enabled on new registrations (when the TLD supports it). Pass the optional `whoisPrivacy` field to override this on a per-registration basis, or change the account-level default under Account Security Settings on porkbun.com\/account.\n\n**Rate limits (both apply):**\n- Attempt limit (default: 1 attempt per 10 seconds per account)\n- Success limit (default: 50 successful registrations per 86400 seconds per account)\n\nBoth limits are configurable per API key and their current values are returned in the `limits` field of the response.\n\n## Dry run\n\nAdd `dryRun: true` to validate everything and preview the cost WITHOUT registering or charging \u2014 nothing is created. Example response:\n\n```json\n{\n  \"status\": \"SUCCESS\",\n  \"dryRun\": true,\n  \"wouldSucceed\": true,\n  \"operation\": \"registration\",\n  \"domain\": \"example.com\",\n  \"tld\": \"com\",\n  \"available\": \"available\",\n  \"premium\": false,\n  \"duration\": 1,\n  \"cost\": 973,\n  \"costDisplay\": \"$9.73\",\n  \"balance\": 5000,\n  \"sufficientFunds\": true,\n  \"message\": \"Dry run: this registration would succeed and cost $9.73. No order was created and no charge was made.\",\n  \"requestId\": \"019e04fa-258d-7d11-aa86-4d5795c3fe8f\"\n}\n```","operationId":"domainCreate","x-ratelimit":{"requests":null,"window":null,"windowUnit":"seconds","scope":"account","note":"Two separate limits apply. Attempt limit: default 1 attempt per 10s (api.createLimit \/ api.createTTL). Success limit: default 50 successes per 86400s (api.createSuccessLimit \/ api.createSuccessTTL). Both are configurable per API key. Redis keys: API:createSingleDomain:{accountId} and API:createSuccessSingleDomain:2:{accountId}."},"parameters":[{"name":"domain","in":"path","required":true,"schema":{"type":"string"},"example":"example.com"}],"requestBody":{"required":true,"content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/CreateDomainRequest"}}}},"responses":{"200":{"description":"Domain registered successfully","content":{"application\/json":{"schema":{"oneOf":[{"$ref":"#\/components\/schemas\/CreateDomainResponse"},{"$ref":"#\/components\/schemas\/DryRunPreviewResponse"}]},"examples":{"registered":{"summary":"Live registration (domain registered, charged)","value":{"status":"SUCCESS","domain":"example.com","cost":973,"orderId":12345678,"limits":{"attempts":{"TTL":1,"limit":1,"used":1,"naturalLanguage":"1 out of 1 create attempts within 1 seconds used."},"success":{"TTL":86400,"limit":50,"used":1,"naturalLanguage":"1 out of 50 successful creates within 86400 seconds used."}},"balance":4027,"ttlRemaining":86400,"requestId":"019e04fa-258d-7d11-aa86-4d5795c3fe8f"}},"dryRun":{"summary":"Dry run (dryRun:true \u2014 nothing registered or charged)","value":{"status":"SUCCESS","dryRun":true,"wouldSucceed":true,"operation":"registration","domain":"example.com","tld":"com","available":"available","premium":false,"duration":1,"cost":973,"costDisplay":"$9.73","balance":5000,"sufficientFunds":true,"message":"Dry run: this registration would succeed and cost $9.73. No order was created and no charge was made.","requestId":"019e04fa-258d-7d11-aa86-4d5795c3fe8f"}}}}}},"400":{"description":"Validation, fraud, or rate-limit error","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/RateLimitExceeded"}}}}},"x-codeSamples":[{"lang":"curl","label":"curl","source":"curl -X POST https:\/\/api.porkbun.com\/api\/json\/v3\/domain\/create\/{domain} \\\n  -H 'Content-Type: application\/json' \\\n  -d '{\"apikey\":\"pk1_...\",\"secretapikey\":\"sk1_...\",\"cost\":0,\"agreeToTerms\":\"yes\"}'"}]}},"\/domain\/renew\/{domain}":{"post":{"tags":["Domain"],"summary":"Renew a domain","description":"Renew a domain using account credit. Requirements:\n- Domain must be in your account and active\n- Domain must be opted in to API access\n- Account email and phone must be verified\n- Account must have sufficient credit\n- `cost` must equal the current renewal price for the domain's minimum renewal duration (in pennies)\n- Domain must have been registered more than 30 days ago (checked against the domain's creation date)\n- Domain must not have been successfully renewed within the last 30 days\n- Premium renewals are not currently supported via API\n\nRenewals are always for the registry-minimum duration (usually 1 year). Use `\/domain\/checkDomain\/{domain}` with `priceType=renewal` to get the current price before renewing.\n\n**Rate limits (both apply):**\n- Attempt limit (default: 1 attempt per 10 seconds per account)\n- Success limit (default: 50 successful renewals per 86400 seconds per account)\n\nBoth limits are configurable per API key and their current values are returned in the `limits` field of the response.\n\n## Dry run\n\nAdd `dryRun: true` to validate everything and preview the cost WITHOUT renewing or charging \u2014 nothing is created. Example response:\n\n```json\n{\n  \"status\": \"SUCCESS\",\n  \"dryRun\": true,\n  \"wouldSucceed\": true,\n  \"operation\": \"renewal\",\n  \"domain\": \"example.com\",\n  \"tld\": \"com\",\n  \"available\": \"unavailable\",\n  \"premium\": false,\n  \"duration\": 1,\n  \"cost\": 1099,\n  \"costDisplay\": \"$10.99\",\n  \"balance\": 5000,\n  \"sufficientFunds\": true,\n  \"message\": \"Dry run: this renewal would succeed and cost $10.99. No order was created and no charge was made.\",\n  \"requestId\": \"019e04fa-3c11-7a02-9bd2-1f7c0e4a8b55\"\n}\n```","operationId":"domainRenew","x-ratelimit":{"requests":null,"window":null,"windowUnit":"seconds","scope":"account","note":"Two separate limits apply. Attempt limit: default 1 attempt per 10s (api.createLimit \/ api.createTTL). Success limit: default 50 successes per 86400s (api.createSuccessLimit \/ api.createSuccessTTL). Both are configurable per API key. Redis keys: API:renewSingleDomain:{accountId} and API:renewSuccessSingleDomain:{accountId}."},"parameters":[{"name":"domain","in":"path","required":true,"schema":{"type":"string"},"example":"example.com"}],"requestBody":{"required":true,"content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/RenewDomainRequest"}}}},"responses":{"200":{"description":"Domain renewed successfully","content":{"application\/json":{"schema":{"oneOf":[{"$ref":"#\/components\/schemas\/RenewDomainResponse"},{"$ref":"#\/components\/schemas\/DryRunPreviewResponse"}]},"examples":{"renewed":{"summary":"Live renewal (domain renewed, charged)","value":{"status":"SUCCESS","domain":"example.com","expirationDate":"2027-04-21","cost":1099,"orderId":12345679,"balance":3928,"ttlRemaining":86400,"requestId":"019e04fa-3c11-7a02-9bd2-1f7c0e4a8b55"}},"dryRun":{"summary":"Dry run (dryRun:true \u2014 nothing renewed or charged)","value":{"status":"SUCCESS","dryRun":true,"wouldSucceed":true,"operation":"renewal","domain":"example.com","tld":"com","available":"unavailable","premium":false,"duration":1,"cost":1099,"costDisplay":"$10.99","balance":5000,"sufficientFunds":true,"message":"Dry run: this renewal would succeed and cost $10.99. No order was created and no charge was made.","requestId":"019e04fa-3c11-7a02-9bd2-1f7c0e4a8b55"}}}}}},"400":{"description":"Validation or rate-limit error","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/RateLimitExceeded"}}}}},"x-codeSamples":[{"lang":"curl","label":"curl","source":"curl -X POST https:\/\/api.porkbun.com\/api\/json\/v3\/domain\/renew\/{domain} \\\n  -H 'Content-Type: application\/json' \\\n  -d '{\"apikey\":\"pk1_...\",\"secretapikey\":\"sk1_...\",\"cost\":0}'"}]}},"\/domain\/transfer\/{domain}":{"post":{"summary":"Initiate a domain transfer","description":"Initiates an inbound domain transfer to Porkbun using account credit. The transfer is processed asynchronously and typically takes 5\u20137 days to complete.\n\n**Requirements:**\n- Account email and phone must be verified.\n- Sufficient account credit to cover the transfer cost.\n- Domain must not already be in your account.\n- No other active transfer for the same domain.\n- `.uk` and manage-only TLDs are not supported via API.\n- Premium domain transfers are not supported via API.\n\n## Dry run\n\nAdd `dryRun: true` to validate everything and preview the cost WITHOUT initiating the transfer or charging \u2014 nothing is created. Example response:\n\n```json\n{\n  \"status\": \"SUCCESS\",\n  \"dryRun\": true,\n  \"wouldSucceed\": true,\n  \"operation\": \"transfer\",\n  \"domain\": \"example.com\",\n  \"tld\": \"com\",\n  \"available\": \"unavailable\",\n  \"premium\": false,\n  \"duration\": 1,\n  \"cost\": 999,\n  \"costDisplay\": \"$9.99\",\n  \"balance\": 5000,\n  \"sufficientFunds\": true,\n  \"message\": \"Dry run: this transfer would succeed and cost $9.99. No order was created and no charge was made.\",\n  \"requestId\": \"019e04fa-5f22-7c93-8a41-2e9d0b3f6c77\"\n}\n```","operationId":"transferDomain","tags":["Domain"],"parameters":[{"name":"domain","in":"path","required":true,"schema":{"type":"string"},"description":"The domain name to transfer (e.g. `example.com`)."}],"requestBody":{"required":true,"content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/TransferDomainRequest"}}}},"responses":{"200":{"description":"Transfer initiated, dry-run preview, or error.","content":{"application\/json":{"schema":{"oneOf":[{"$ref":"#\/components\/schemas\/TransferDomainResponse"},{"$ref":"#\/components\/schemas\/DryRunPreviewResponse"}]},"examples":{"initiated":{"summary":"Live transfer initiated (charged)","value":{"status":"SUCCESS","domain":"example.com","orderId":12345680,"transferId":98765,"message":"Transfer initiated. The domain transfer process has begun and typically takes 5-7 days to complete.","balance":2829,"ttlRemaining":86400,"requestId":"019e04fa-5f22-7c93-8a41-2e9d0b3f6c77"}},"dryRun":{"summary":"Dry run (dryRun:true \u2014 nothing transferred or charged)","value":{"status":"SUCCESS","dryRun":true,"wouldSucceed":true,"operation":"transfer","domain":"example.com","tld":"com","available":"unavailable","premium":false,"duration":1,"cost":999,"costDisplay":"$9.99","balance":5000,"sufficientFunds":true,"message":"Dry run: this transfer would succeed and cost $9.99. No order was created and no charge was made.","requestId":"019e04fa-5f22-7c93-8a41-2e9d0b3f6c77"}}}}}}},"x-codeSamples":[{"lang":"curl","label":"curl","source":"curl 'https:\/\/api.porkbun.com\/api\/json\/v3\/domain\/transfer\/example.com' \\\n  -H 'Content-Type: application\/json' \\\n  -d '{\n    \"apikey\": \"pk1_...\",\n    \"secretapikey\": \"sk1_...\",\n    \"authCode\": \"abc123\",\n    \"cost\": 899\n  }'"}]}},"\/domain\/getTransfer\/{domain}":{"get":{"tags":["Domain"],"summary":"Get transfer status","description":"Returns the most recent transfer record for the specified domain in your account. Authenticate using `X-API-Key` and `X-Secret-API-Key` headers, or `Authorization: Bearer <token>`.","operationId":"getTransferGet","parameters":[{"name":"X-API-Key","in":"header","required":false,"schema":{"type":"string"},"description":"API key header auth (use with X-Secret-API-Key)"},{"name":"X-Secret-API-Key","in":"header","required":false,"schema":{"type":"string"},"description":"Secret API key header auth (use with X-API-Key)"},{"name":"domain","in":"path","required":true,"schema":{"type":"string"},"description":"The domain name (e.g. `example.com`)."}],"responses":{"200":{"description":"Transfer record or error.","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/GetTransferResponse"}}}}},"x-codeSamples":[{"lang":"curl","label":"curl","source":"curl 'https:\/\/api.porkbun.com\/api\/json\/v3\/domain\/getTransfer\/example.com' \\\n  -H 'X-API-Key: pk1_...' \\\n  -H 'X-Secret-API-Key: sk1_...'"}]}},"\/domain\/listTransfers":{"get":{"tags":["Domain"],"summary":"List active transfers","description":"Returns all active inbound domain transfers for your account (excludes completed and canceled transfers). Authenticate using `X-API-Key` and `X-Secret-API-Key` headers, or `Authorization: Bearer <token>`.","operationId":"listTransfersGet","parameters":[{"name":"X-API-Key","in":"header","required":false,"schema":{"type":"string"},"description":"API key header auth (use with X-Secret-API-Key)"},{"name":"X-Secret-API-Key","in":"header","required":false,"schema":{"type":"string"},"description":"Secret API key header auth (use with X-API-Key)"}],"responses":{"200":{"description":"List of active transfers.","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/ListTransfersResponse"}}}}},"x-codeSamples":[{"lang":"curl","label":"curl","source":"curl 'https:\/\/api.porkbun.com\/api\/json\/v3\/domain\/listTransfers' \\\n  -H 'X-API-Key: pk1_...' \\\n  -H 'X-Secret-API-Key: sk1_...'"}]}},"\/domain\/listAll":{"post":{"tags":["Domain"],"summary":"List all domains","description":"Retrieve domains in the authenticated account. Results are returned in chunks of up to 1000 domains. Use `start` to paginate.\n\n**Filtering:** all filter parameters are optional. Combine them freely.\n\n- `domain` \u2014 exact match (returns 0 or 1)\n- `nameContains` \u2014 substring search\n- `tlds` \u2014 limit to these TLDs\n- `expiringWithinDays` \u2014 only domains expiring within N days\n- `autoRenew` \u2014 `yes` \/ `no`\n- `apiAccess` \u2014 `yes` \/ `no` (filter to domains the API key can operate on)\n- `sortName` \u2014 `domain` \/ `tld` \/ `create_date` \/ `expire_date`\n- `sortDirection` \u2014 `asc` \/ `desc`\n\nSupports both GET (with header auth) and POST (with body or header auth). For multi-value `tlds` on GET, use bracket syntax: `?tlds[]=com&tlds[]=io`.","operationId":"listDomains","requestBody":{"required":true,"content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/ListAllRequest"}}}},"responses":{"200":{"description":"Domain list","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/DomainListAllResponse"}}}},"400":{"description":"Authentication error","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/ErrorResponse"}}}}},"x-codeSamples":[{"lang":"curl","label":"curl","source":"curl -X POST https:\/\/api.porkbun.com\/api\/json\/v3\/domain\/listAll \\\n  -H 'Content-Type: application\/json' \\\n  -d '{\"apikey\":\"pk1_...\",\"secretapikey\":\"sk1_...\",\"start\":0,\"includeLabels\":\"yes\"}'"}]},"get":{"tags":["Domain"],"summary":"List all domains","description":"Retrieve domains in the authenticated account. Results are returned in chunks of up to 1000 domains. Use `start` to paginate.\n\n**Filtering:** all filter parameters are optional. Combine them freely.\n\n- `domain` \u2014 exact match (returns 0 or 1)\n- `nameContains` \u2014 substring search\n- `tlds` \u2014 limit to these TLDs\n- `expiringWithinDays` \u2014 only domains expiring within N days\n- `autoRenew` \u2014 `yes` \/ `no`\n- `apiAccess` \u2014 `yes` \/ `no` (filter to domains the API key can operate on)\n- `sortName` \u2014 `domain` \/ `tld` \/ `create_date` \/ `expire_date`\n- `sortDirection` \u2014 `asc` \/ `desc`\n\nSupports both GET (with header auth) and POST (with body or header auth). For multi-value `tlds` on GET, use bracket syntax: `?tlds[]=com&tlds[]=io`.","operationId":"getDomains","responses":{"200":{"description":"Domain list","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/DomainListAllResponse"}}}},"400":{"description":"Authentication error","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/ErrorResponse"}}}}},"parameters":[{"name":"X-API-Key","in":"header","required":false,"schema":{"type":"string"},"description":"API key header auth (use with X-Secret-API-Key)"},{"name":"X-Secret-API-Key","in":"header","required":false,"schema":{"type":"string"},"description":"Secret API key header auth (use with X-API-Key)"},{"name":"start","in":"query","required":false,"schema":{"type":"integer","default":0},"description":"Zero-based offset for pagination. Returns up to 1000 domains per call."},{"name":"includeLabels","in":"query","required":false,"schema":{"type":"string","enum":["yes","no"]},"description":"Return label metadata for each domain. Defaults to no."},{"name":"domain","in":"query","required":false,"schema":{"type":"string"},"description":"Exact domain name match. Returns 0 or 1 result."},{"name":"nameContains","in":"query","required":false,"schema":{"type":"string"},"description":"Substring match against the full domain name. Case-insensitive."},{"name":"expiringWithinDays","in":"query","required":false,"schema":{"type":"integer"},"description":"Filter to domains expiring within this many days."},{"name":"tlds","in":"query","required":false,"schema":{"type":"array","items":{"type":"string"}},"style":"form","explode":true,"description":"Limit to these TLDs (no leading dot). Use bracket form: `?tlds[]=com&tlds[]=io`."},{"name":"autoRenew","in":"query","required":false,"schema":{"type":"string","enum":["yes","no"]},"description":"Filter to domains with auto-renew on or off."},{"name":"apiAccess","in":"query","required":false,"schema":{"type":"string","enum":["yes","no"]},"description":"Filter to domains opted in to API access."},{"name":"sortName","in":"query","required":false,"schema":{"type":"string","enum":["domain","tld","create_date","expire_date"]},"description":"Field to sort by. Default: `expire_date` ascending."},{"name":"sortDirection","in":"query","required":false,"schema":{"type":"string","enum":["asc","desc"]},"description":"Sort direction. Default: asc."}],"x-codeSamples":[{"lang":"curl","label":"curl","source":"curl 'https:\/\/api.porkbun.com\/api\/json\/v3\/domain\/listAll?tlds[]=com&expiringWithinDays=30&autoRenew=no' \\\n  -H 'X-API-Key: pk1_...' \\\n  -H 'X-Secret-API-Key: sk1_...'"}]}},"\/domain\/get\/{domain}":{"get":{"tags":["Domain"],"summary":"Get a single domain","description":"Get the metadata for a single domain in the authenticated account. Returns the same per-domain shape as `listAll` items but as a single object. Returns HTTP 404 with code `DOMAIN_NOT_FOUND` if the domain isn't in the account.","operationId":"getDomain","parameters":[{"name":"domain","in":"path","required":true,"schema":{"type":"string"},"description":"Fully qualified domain name in the authenticated account.","example":"example.com"},{"name":"X-API-Key","in":"header","required":false,"schema":{"type":"string"},"description":"API key header auth (use with X-Secret-API-Key)"},{"name":"X-Secret-API-Key","in":"header","required":false,"schema":{"type":"string"},"description":"Secret API key header auth (use with X-API-Key)"},{"name":"includeLabels","in":"query","required":false,"schema":{"type":"string","enum":["yes","no"]},"description":"Return label metadata. Defaults to no."}],"responses":{"200":{"description":"Domain metadata","content":{"application\/json":{"schema":{"type":"object","properties":{"status":{"type":"string","example":"SUCCESS"},"domain":{"type":"object","properties":{"domain":{"type":"string","example":"example.com"},"status":{"type":"string","example":"ACTIVE"},"tld":{"type":"string","example":"com"},"createDate":{"type":"string"},"expireDate":{"type":"string"},"securityLock":{"type":"integer"},"whoisPrivacy":{"type":"integer"},"autoRenew":{"type":"integer"},"apiAccess":{"type":"integer"},"notLocal":{"type":"integer"}}}}}}}},"404":{"description":"Domain not found in the authenticated account.","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/ErrorResponse"}}}}},"x-codeSamples":[{"lang":"curl","label":"curl","source":"curl 'https:\/\/api.porkbun.com\/api\/json\/v3\/domain\/get\/example.com' \\\n  -H 'X-API-Key: pk1_...' \\\n  -H 'X-Secret-API-Key: sk1_...'"}]}},"\/domain\/updateAutoRenew\/{domain}":{"post":{"tags":["Domain"],"summary":"Update auto-renew setting","description":"Update the auto-renew setting for one or more domains. The domain can be passed in the URL path or in the `domains` array in the request body (or both). Both are combined and deduplicated.","operationId":"domainUpdateAutoRenew","parameters":[{"name":"domain","in":"path","required":false,"description":"Optional single domain in URL. Omit or use `\/domain\/updateAutoRenew\/` (without trailing domain) when using the `domains` body array instead.","schema":{"type":"string"},"example":"example.com"}],"requestBody":{"required":true,"content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/UpdateAutoRenewRequest"}}}},"responses":{"200":{"description":"Per-domain results","content":{"application\/json":{"schema":{"type":"object","properties":{"status":{"type":"string","example":"SUCCESS"},"results":{"type":"object","description":"Object keyed by domain name","additionalProperties":{"type":"object","properties":{"status":{"type":"string"},"message":{"type":"string"}}}}}}}}},"400":{"description":"Validation error","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/ErrorResponse"}}}}},"x-codeSamples":[{"lang":"curl","label":"curl","source":"curl -X POST https:\/\/api.porkbun.com\/api\/json\/v3\/domain\/updateAutoRenew\/{domain} \\\n  -H 'Content-Type: application\/json' \\\n  -d '{\"apikey\":\"pk1_...\",\"secretapikey\":\"sk1_...\",\"status\":\"on\",\"domains\":[]}'"}]}},"\/domain\/getNs\/{domain}":{"post":{"tags":["Domain"],"summary":"Get nameservers","description":"Retrieve the authoritative nameservers listed at the registry for the domain. Supports both GET (with header auth) and POST (with body or header auth).","operationId":"domainGetNs","parameters":[{"name":"domain","in":"path","required":true,"schema":{"type":"string"},"example":"example.com"}],"requestBody":{"required":true,"content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/AuthRequest"}}}},"responses":{"200":{"description":"Nameserver list","content":{"application\/json":{"schema":{"type":"object","properties":{"status":{"type":"string","example":"SUCCESS"},"ns":{"type":"array","items":{"type":"string"},"example":["ns1.porkbun.com","ns2.porkbun.com"]}}}}}},"400":{"description":"Error","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/ErrorResponse"}}}}},"x-codeSamples":[{"lang":"curl","label":"curl","source":"curl -X POST https:\/\/api.porkbun.com\/api\/json\/v3\/domain\/getNs\/{domain} \\\n  -H 'Content-Type: application\/json' \\\n  -d '{\"apikey\":\"pk1_...\",\"secretapikey\":\"sk1_...\"}'"}]},"get":{"tags":["Domain"],"summary":"Get nameservers","description":"Retrieve the authoritative nameservers listed at the registry for the domain. Supports both GET (with header auth) and POST (with body or header auth).","operationId":"getDomainNs","parameters":[{"name":"domain","in":"path","required":true,"schema":{"type":"string"},"example":"example.com"},{"name":"X-API-Key","in":"header","required":false,"schema":{"type":"string"},"description":"API key header auth (use with X-Secret-API-Key)"},{"name":"X-Secret-API-Key","in":"header","required":false,"schema":{"type":"string"},"description":"Secret API key header auth (use with X-API-Key)"}],"responses":{"200":{"description":"Nameserver list","content":{"application\/json":{"schema":{"type":"object","properties":{"status":{"type":"string","example":"SUCCESS"},"ns":{"type":"array","items":{"type":"string"},"example":["ns1.porkbun.com","ns2.porkbun.com"]}}}}}},"400":{"description":"Error","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/ErrorResponse"}}}}},"x-codeSamples":[{"lang":"curl","label":"curl","source":"curl 'https:\/\/api.porkbun.com\/api\/json\/v3\/domain\/getNs\/{domain}' \\\n  -H 'X-API-Key: pk1_...' \\\n  -H 'X-Secret-API-Key: sk1_...'"}]}},"\/domain\/updateNs\/{domain}":{"post":{"tags":["Domain"],"summary":"Update nameservers","description":"Update the nameservers for the domain at the registry.","operationId":"domainUpdateNs","parameters":[{"name":"domain","in":"path","required":true,"schema":{"type":"string"},"example":"example.com"}],"requestBody":{"required":true,"content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/UpdateNsRequest"}}}},"responses":{"200":{"description":"Update result","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/BasicResponse"}}}},"400":{"description":"Error","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/ErrorResponse"}}}}},"x-codeSamples":[{"lang":"curl","label":"curl","source":"curl -X POST https:\/\/api.porkbun.com\/api\/json\/v3\/domain\/updateNs\/{domain} \\\n  -H 'Content-Type: application\/json' \\\n  -d '{\"apikey\":\"pk1_...\",\"secretapikey\":\"sk1_...\",\"ns\":[\"ns1.example.com\",\"ns2.example.com\"]}'"}]}},"\/domain\/getGlue\/{domain}":{"post":{"tags":["Domain"],"summary":"Get glue records","description":"Retrieve all glue records (host objects) registered under the domain. Supports both GET (with header auth) and POST (with body or header auth).","operationId":"domainGetGlue","parameters":[{"name":"domain","in":"path","required":true,"schema":{"type":"string"},"example":"example.com"}],"requestBody":{"required":true,"content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/AuthRequest"}}}},"responses":{"200":{"description":"Glue records","content":{"application\/json":{"schema":{"type":"object","properties":{"status":{"type":"string","example":"SUCCESS"},"hosts":{"type":"array","description":"Array of [hostname, ipAddresses] tuples. Each element is a two-item array: index 0 is the full hostname (string), index 1 is an object with `v4` (array of IPv4 strings) and `v6` (array of IPv6 strings). Example: `[\"ns1.example.com\", {\"v4\": [\"1.2.3.4\"], \"v6\": []}]`","items":{"type":"array","description":"Two-element array: [0] full hostname string, [1] IP addresses object","prefixItems":[{"type":"string","description":"Full hostname (e.g. 'ns1.example.com')"},{"type":"object","description":"IP address object","properties":{"v4":{"type":"array","items":{"type":"string"},"description":"Array of IPv4 address strings"},"v6":{"type":"array","items":{"type":"string"},"description":"Array of IPv6 address strings"}}}]}}}}}}},"400":{"description":"Error","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/ErrorResponse"}}}}},"x-codeSamples":[{"lang":"curl","label":"curl","source":"curl -X POST https:\/\/api.porkbun.com\/api\/json\/v3\/domain\/getGlue\/{domain} \\\n  -H 'Content-Type: application\/json' \\\n  -d '{\"apikey\":\"pk1_...\",\"secretapikey\":\"sk1_...\"}'"}]},"get":{"tags":["Domain"],"summary":"Get glue records","description":"Retrieve all glue records (host objects) registered under the domain. Supports both GET (with header auth) and POST (with body or header auth).","operationId":"getDomainGlue","parameters":[{"name":"domain","in":"path","required":true,"schema":{"type":"string"},"example":"example.com"},{"name":"X-API-Key","in":"header","required":false,"schema":{"type":"string"},"description":"API key header auth (use with X-Secret-API-Key)"},{"name":"X-Secret-API-Key","in":"header","required":false,"schema":{"type":"string"},"description":"Secret API key header auth (use with X-API-Key)"}],"responses":{"200":{"description":"Glue records","content":{"application\/json":{"schema":{"type":"object","properties":{"status":{"type":"string","example":"SUCCESS"},"hosts":{"type":"array","description":"Array of [hostname, ipAddresses] tuples. Each element is a two-item array: index 0 is the full hostname (string), index 1 is an object with `v4` (array of IPv4 strings) and `v6` (array of IPv6 strings). Example: `[\"ns1.example.com\", {\"v4\": [\"1.2.3.4\"], \"v6\": []}]`","items":{"type":"array","description":"Two-element array: [0] full hostname string, [1] IP addresses object","prefixItems":[{"type":"string","description":"Full hostname (e.g. 'ns1.example.com')"},{"type":"object","description":"IP address object","properties":{"v4":{"type":"array","items":{"type":"string"},"description":"Array of IPv4 address strings"},"v6":{"type":"array","items":{"type":"string"},"description":"Array of IPv6 address strings"}}}]}}}}}}},"400":{"description":"Error","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/ErrorResponse"}}}}},"x-codeSamples":[{"lang":"curl","label":"curl","source":"curl 'https:\/\/api.porkbun.com\/api\/json\/v3\/domain\/getGlue\/{domain}' \\\n  -H 'X-API-Key: pk1_...' \\\n  -H 'X-Secret-API-Key: sk1_...'"}]}},"\/domain\/createGlue\/{domain}\/{subdomain}":{"post":{"tags":["Domain"],"summary":"Create glue record","description":"Create a glue record (host object) for a nameserver hostname under the domain. Use this when you want to host a nameserver at a subdomain of the domain itself (e.g. ns1.example.com).","operationId":"domainCreateGlue","parameters":[{"name":"domain","in":"path","required":true,"schema":{"type":"string"},"example":"example.com"},{"name":"subdomain","in":"path","required":true,"schema":{"type":"string"},"description":"The subdomain portion only (e.g. 'ns1' for ns1.example.com)","example":"ns1"}],"requestBody":{"required":true,"content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/GlueRecordRequest"}}}},"responses":{"200":{"description":"Created","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/BasicResponse"}}}},"400":{"description":"Error","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/ErrorResponse"}}}}},"x-codeSamples":[{"lang":"curl","label":"curl","source":"curl -X POST https:\/\/api.porkbun.com\/api\/json\/v3\/domain\/createGlue\/{domain}\/{subdomain} \\\n  -H 'Content-Type: application\/json' \\\n  -d '{\"apikey\":\"pk1_...\",\"secretapikey\":\"sk1_...\",\"ips\":[\"1.2.3.4\",\"2001:db8::1\"]}'"}]}},"\/domain\/updateGlue\/{domain}\/{subdomain}":{"post":{"tags":["Domain"],"summary":"Update glue record","description":"Update the IP addresses of a glue record. All existing IP addresses are replaced with the supplied list.","operationId":"domainUpdateGlue","parameters":[{"name":"domain","in":"path","required":true,"schema":{"type":"string"},"example":"example.com"},{"name":"subdomain","in":"path","required":true,"schema":{"type":"string"},"example":"ns1"}],"requestBody":{"required":true,"content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/GlueRecordRequest"}}}},"responses":{"200":{"description":"Updated","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/BasicResponse"}}}},"400":{"description":"Error","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/ErrorResponse"}}}}},"x-codeSamples":[{"lang":"curl","label":"curl","source":"curl -X POST https:\/\/api.porkbun.com\/api\/json\/v3\/domain\/updateGlue\/{domain}\/{subdomain} \\\n  -H 'Content-Type: application\/json' \\\n  -d '{\"apikey\":\"pk1_...\",\"secretapikey\":\"sk1_...\",\"ips\":[\"1.2.3.4\",\"2001:db8::1\"]}'"}]}},"\/domain\/deleteGlue\/{domain}\/{subdomain}":{"post":{"tags":["Domain"],"summary":"Delete glue record","description":"Delete a glue record (host object) for a subdomain.","operationId":"domainDeleteGlue","parameters":[{"name":"domain","in":"path","required":true,"schema":{"type":"string"},"example":"example.com"},{"name":"subdomain","in":"path","required":true,"schema":{"type":"string"},"example":"ns1"}],"requestBody":{"required":true,"content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/AuthRequest"}}}},"responses":{"200":{"description":"Deleted","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/BasicResponse"}}}},"400":{"description":"Error","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/ErrorResponse"}}}}},"x-codeSamples":[{"lang":"curl","label":"curl","source":"curl -X POST https:\/\/api.porkbun.com\/api\/json\/v3\/domain\/deleteGlue\/{domain}\/{subdomain} \\\n  -H 'Content-Type: application\/json' \\\n  -d '{\"apikey\":\"pk1_...\",\"secretapikey\":\"sk1_...\"}'"}]}},"\/domain\/getUrlForwarding\/{domain}":{"post":{"tags":["Domain"],"summary":"List URL forwards","description":"Retrieve all active URL forwards for a domain. Supports both GET (with header auth) and POST (with body or header auth).","operationId":"domainGetUrlForwarding","parameters":[{"name":"domain","in":"path","required":true,"schema":{"type":"string"},"example":"example.com"}],"requestBody":{"required":true,"content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/AuthRequest"}}}},"responses":{"200":{"description":"URL forward list","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/GetUrlForwardingResponse"}}}},"400":{"description":"Error","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/ErrorResponse"}}}}},"x-codeSamples":[{"lang":"curl","label":"curl","source":"curl -X POST https:\/\/api.porkbun.com\/api\/json\/v3\/domain\/getUrlForwarding\/{domain} \\\n  -H 'Content-Type: application\/json' \\\n  -d '{\"apikey\":\"pk1_...\",\"secretapikey\":\"sk1_...\"}'"}]},"get":{"tags":["Domain"],"summary":"List URL forwards","description":"Retrieve all active URL forwards for a domain. Supports both GET (with header auth) and POST (with body or header auth).","operationId":"getDomainUrlForwarding","parameters":[{"name":"domain","in":"path","required":true,"schema":{"type":"string"},"example":"example.com"},{"name":"X-API-Key","in":"header","required":false,"schema":{"type":"string"},"description":"API key header auth (use with X-Secret-API-Key)"},{"name":"X-Secret-API-Key","in":"header","required":false,"schema":{"type":"string"},"description":"Secret API key header auth (use with X-API-Key)"}],"responses":{"200":{"description":"URL forward list","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/GetUrlForwardingResponse"}}}},"400":{"description":"Error","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/ErrorResponse"}}}}},"x-codeSamples":[{"lang":"curl","label":"curl","source":"curl 'https:\/\/api.porkbun.com\/api\/json\/v3\/domain\/getUrlForwarding\/{domain}' \\\n  -H 'X-API-Key: pk1_...' \\\n  -H 'X-Secret-API-Key: sk1_...'"}]}},"\/domain\/addUrlForward\/{domain}":{"post":{"tags":["Domain"],"summary":"Add URL forward","description":"Add a URL forward for a domain or subdomain.","operationId":"domainAddUrlForward","parameters":[{"name":"domain","in":"path","required":true,"schema":{"type":"string"},"example":"example.com"}],"requestBody":{"required":true,"content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/AddUrlForwardRequest"}}}},"responses":{"200":{"description":"Forward added","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/BasicResponse"}}}},"400":{"description":"Validation error","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/ErrorResponse"}}}}},"x-codeSamples":[{"lang":"curl","label":"curl","source":"curl -X POST https:\/\/api.porkbun.com\/api\/json\/v3\/domain\/addUrlForward\/{domain} \\\n  -H 'Content-Type: application\/json' \\\n  -d '{\"apikey\":\"pk1_...\",\"secretapikey\":\"sk1_...\",\"subdomain\":\"www\",\"location\":\"https:\\\/\\\/destination.example.com\",\"type\":\"temporary\",\"includePath\":\"yes\",\"wildcard\":\"yes\"}'"}]}},"\/domain\/deleteUrlForward\/{domain}\/{id}":{"post":{"tags":["Domain"],"summary":"Delete URL forward","description":"Delete a specific URL forward by ID.","operationId":"domainDeleteUrlForward","parameters":[{"name":"domain","in":"path","required":true,"schema":{"type":"string"},"example":"example.com"},{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"URL forward record ID","example":"12345"}],"requestBody":{"required":true,"content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/AuthRequest"}}}},"responses":{"200":{"description":"Deleted","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/BasicResponse"}}}},"400":{"description":"Error","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/ErrorResponse"}}}}},"x-codeSamples":[{"lang":"curl","label":"curl","source":"curl -X POST https:\/\/api.porkbun.com\/api\/json\/v3\/domain\/deleteUrlForward\/{domain}\/{id} \\\n  -H 'Content-Type: application\/json' \\\n  -d '{\"apikey\":\"pk1_...\",\"secretapikey\":\"sk1_...\"}'"}]}},"\/dns\/retrieve\/{domain}":{"post":{"tags":["DNS"],"summary":"Retrieve all DNS records","description":"Retrieve all editable DNS records for a domain. SOA records and Porkbun default NS records are excluded. Supports both GET (with header auth) and POST (with body or header auth).","operationId":"dnsRetrieve","parameters":[{"name":"domain","in":"path","required":true,"schema":{"type":"string"},"example":"example.com"}],"requestBody":{"required":true,"content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/AuthRequest"}}}},"responses":{"200":{"description":"DNS records","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/DnsRecordsResponse"}}}},"400":{"description":"Error","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/ErrorResponse"}}}}},"x-codeSamples":[{"lang":"curl","label":"curl","source":"curl -X POST https:\/\/api.porkbun.com\/api\/json\/v3\/dns\/retrieve\/{domain} \\\n  -H 'Content-Type: application\/json' \\\n  -d '{\"apikey\":\"pk1_...\",\"secretapikey\":\"sk1_...\"}'"}]},"get":{"tags":["DNS"],"summary":"Retrieve all DNS records","description":"Retrieve all editable DNS records for a domain. SOA records and Porkbun default NS records are excluded. Supports both GET (with header auth) and POST (with body or header auth).","operationId":"getDnsRecords","parameters":[{"name":"domain","in":"path","required":true,"schema":{"type":"string"},"example":"example.com"},{"name":"X-API-Key","in":"header","required":false,"schema":{"type":"string"},"description":"API key header auth (use with X-Secret-API-Key)"},{"name":"X-Secret-API-Key","in":"header","required":false,"schema":{"type":"string"},"description":"Secret API key header auth (use with X-API-Key)"}],"responses":{"200":{"description":"DNS records","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/DnsRecordsResponse"}}}},"400":{"description":"Error","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/ErrorResponse"}}}}},"x-codeSamples":[{"lang":"curl","label":"curl","source":"curl 'https:\/\/api.porkbun.com\/api\/json\/v3\/dns\/retrieve\/{domain}' \\\n  -H 'X-API-Key: pk1_...' \\\n  -H 'X-Secret-API-Key: sk1_...'"}]}},"\/dns\/retrieve\/{domain}\/{id}":{"post":{"tags":["DNS"],"summary":"Retrieve DNS record by ID","description":"Retrieve a specific DNS record by its numeric ID. Supports both GET (with header auth) and POST (with body or header auth).","operationId":"dnsRetrieveById","parameters":[{"name":"domain","in":"path","required":true,"schema":{"type":"string"},"example":"example.com"},{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"Numeric DNS record ID","example":"123456789"}],"requestBody":{"required":true,"content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/AuthRequest"}}}},"responses":{"200":{"description":"DNS record(s) matching the ID","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/DnsRecordsResponse"}}}},"400":{"description":"Error","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/ErrorResponse"}}}}},"x-codeSamples":[{"lang":"curl","label":"curl","source":"curl -X POST https:\/\/api.porkbun.com\/api\/json\/v3\/dns\/retrieve\/{domain}\/{id} \\\n  -H 'Content-Type: application\/json' \\\n  -d '{\"apikey\":\"pk1_...\",\"secretapikey\":\"sk1_...\"}'"}]},"get":{"tags":["DNS"],"summary":"Retrieve DNS record by ID","description":"Retrieve a specific DNS record by its numeric ID. Supports both GET (with header auth) and POST (with body or header auth).","operationId":"getDnsRecordById","parameters":[{"name":"domain","in":"path","required":true,"schema":{"type":"string"},"example":"example.com"},{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"Numeric DNS record ID","example":"123456789"},{"name":"X-API-Key","in":"header","required":false,"schema":{"type":"string"},"description":"API key header auth (use with X-Secret-API-Key)"},{"name":"X-Secret-API-Key","in":"header","required":false,"schema":{"type":"string"},"description":"Secret API key header auth (use with X-API-Key)"}],"responses":{"200":{"description":"DNS record(s) matching the ID","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/DnsRecordsResponse"}}}},"400":{"description":"Error","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/ErrorResponse"}}}}},"x-codeSamples":[{"lang":"curl","label":"curl","source":"curl 'https:\/\/api.porkbun.com\/api\/json\/v3\/dns\/retrieve\/{domain}\/{id}' \\\n  -H 'X-API-Key: pk1_...' \\\n  -H 'X-Secret-API-Key: sk1_...'"}]}},"\/dns\/retrieveByNameType\/{domain}\/{type}\/{subdomain}":{"post":{"tags":["DNS"],"summary":"Retrieve DNS records by name and type","description":"Retrieve all DNS records for a domain that match a specific subdomain and record type. Omit `subdomain` (or leave the path segment empty) to query the root domain. Supports both GET (with header auth) and POST (with body or header auth).","operationId":"dnsRetrieveByNameType","parameters":[{"name":"domain","in":"path","required":true,"schema":{"type":"string"},"example":"example.com"},{"name":"type","in":"path","required":true,"schema":{"type":"string"},"description":"DNS record type (A, AAAA, CNAME, MX, TXT, etc.)","example":"A"},{"name":"subdomain","in":"path","required":false,"schema":{"type":"string"},"description":"Subdomain portion only. Omit or leave empty for root domain records.","example":"www"}],"requestBody":{"required":true,"content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/AuthRequest"}}}},"responses":{"200":{"description":"Matching DNS records","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/DnsRecordsResponse"}}}},"400":{"description":"Error","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/ErrorResponse"}}}}},"x-codeSamples":[{"lang":"curl","label":"curl","source":"curl -X POST https:\/\/api.porkbun.com\/api\/json\/v3\/dns\/retrieveByNameType\/{domain}\/{type}\/{subdomain} \\\n  -H 'Content-Type: application\/json' \\\n  -d '{\"apikey\":\"pk1_...\",\"secretapikey\":\"sk1_...\"}'"}]},"get":{"tags":["DNS"],"summary":"Retrieve DNS records by name and type","description":"Retrieve all DNS records for a domain that match a specific subdomain and record type. Omit `subdomain` (or leave the path segment empty) to query the root domain. Supports both GET (with header auth) and POST (with body or header auth).","operationId":"getDnsRecordsByNameType","parameters":[{"name":"domain","in":"path","required":true,"schema":{"type":"string"},"example":"example.com"},{"name":"type","in":"path","required":true,"schema":{"type":"string"},"description":"DNS record type (A, AAAA, CNAME, MX, TXT, etc.)","example":"A"},{"name":"subdomain","in":"path","required":false,"schema":{"type":"string"},"description":"Subdomain portion only. Omit or leave empty for root domain records.","example":"www"},{"name":"X-API-Key","in":"header","required":false,"schema":{"type":"string"},"description":"API key header auth (use with X-Secret-API-Key)"},{"name":"X-Secret-API-Key","in":"header","required":false,"schema":{"type":"string"},"description":"Secret API key header auth (use with X-API-Key)"}],"responses":{"200":{"description":"Matching DNS records","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/DnsRecordsResponse"}}}},"400":{"description":"Error","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/ErrorResponse"}}}}},"x-codeSamples":[{"lang":"curl","label":"curl","source":"curl 'https:\/\/api.porkbun.com\/api\/json\/v3\/dns\/retrieveByNameType\/{domain}\/{type}\/{subdomain}' \\\n  -H 'X-API-Key: pk1_...' \\\n  -H 'X-Secret-API-Key: sk1_...'"}]}},"\/dns\/create\/{domain}":{"post":{"tags":["DNS"],"summary":"Create DNS record","description":"Create a new DNS record for a domain. The record ID is returned in the response.","operationId":"dnsCreate","parameters":[{"name":"domain","in":"path","required":true,"schema":{"type":"string"},"example":"example.com"}],"requestBody":{"required":true,"content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/CreateDnsRequest"}}}},"responses":{"200":{"description":"Record created","content":{"application\/json":{"schema":{"type":"object","properties":{"status":{"type":"string","example":"SUCCESS"},"id":{"type":"string","description":"The numeric ID of the newly created record","example":"123456789"}}}}}},"400":{"description":"Validation error","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/ErrorResponse"}}}}},"x-codeSamples":[{"lang":"curl","label":"curl","source":"curl -X POST https:\/\/api.porkbun.com\/api\/json\/v3\/dns\/create\/{domain} \\\n  -H 'Content-Type: application\/json' \\\n  -d '{\"apikey\":\"pk1_...\",\"secretapikey\":\"sk1_...\",\"name\":\"www\",\"type\":\"A\",\"content\":\"1.2.3.4\",\"ttl\":600,\"prio\":10}'"}]}},"\/dns\/edit\/{domain}\/{id}":{"post":{"tags":["DNS"],"summary":"Edit DNS record by ID","description":"Edit a specific DNS record by its numeric ID. SOA and default Porkbun NS records cannot be edited.","operationId":"dnsEdit","parameters":[{"name":"domain","in":"path","required":true,"schema":{"type":"string"},"example":"example.com"},{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"Numeric DNS record ID","example":"123456789"}],"requestBody":{"required":true,"content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/EditDnsRequest"}}}},"responses":{"200":{"description":"Record updated","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/BasicResponse"}}}},"400":{"description":"Validation error","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/ErrorResponse"}}}}},"x-codeSamples":[{"lang":"curl","label":"curl","source":"curl -X POST https:\/\/api.porkbun.com\/api\/json\/v3\/dns\/edit\/{domain}\/{id} \\\n  -H 'Content-Type: application\/json' \\\n  -d '{\"apikey\":\"pk1_...\",\"secretapikey\":\"sk1_...\",\"type\":\"A\",\"content\":\"5.6.7.8\",\"ttl\":0,\"prio\":0}'"}]}},"\/dns\/editByNameType\/{domain}\/{type}\/{subdomain}":{"post":{"tags":["DNS"],"summary":"Edit DNS records by name and type","description":"Replace the content of all records matching the given subdomain and type. SOA and NS records cannot be edited with this method (use edit by ID instead).","operationId":"dnsEditByNameType","parameters":[{"name":"domain","in":"path","required":true,"schema":{"type":"string"},"example":"example.com"},{"name":"type","in":"path","required":true,"schema":{"type":"string"},"example":"A"},{"name":"subdomain","in":"path","required":false,"schema":{"type":"string"},"description":"Subdomain portion only. Omit or leave empty for root domain records.","example":"www"}],"requestBody":{"required":true,"content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/EditDnsByNameTypeRequest"}}}},"responses":{"200":{"description":"Records updated","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/BasicResponse"}}}},"400":{"description":"Validation error","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/ErrorResponse"}}}}},"x-codeSamples":[{"lang":"curl","label":"curl","source":"curl -X POST https:\/\/api.porkbun.com\/api\/json\/v3\/dns\/editByNameType\/{domain}\/{type}\/{subdomain} \\\n  -H 'Content-Type: application\/json' \\\n  -d '{\"apikey\":\"pk1_...\",\"secretapikey\":\"sk1_...\",\"content\":\"5.6.7.8\",\"ttl\":0,\"prio\":0}'"}]}},"\/dns\/delete\/{domain}\/{id}":{"post":{"tags":["DNS"],"summary":"Delete DNS record by ID","description":"Delete a specific DNS record. SOA and default Porkbun NS records cannot be deleted.","operationId":"dnsDelete","parameters":[{"name":"domain","in":"path","required":true,"schema":{"type":"string"},"example":"example.com"},{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"Numeric DNS record ID","example":"123456789"}],"requestBody":{"required":true,"content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/AuthRequest"}}}},"responses":{"200":{"description":"Deleted","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/BasicResponse"}}}},"400":{"description":"Error","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/ErrorResponse"}}}}},"x-codeSamples":[{"lang":"curl","label":"curl","source":"curl -X POST https:\/\/api.porkbun.com\/api\/json\/v3\/dns\/delete\/{domain}\/{id} \\\n  -H 'Content-Type: application\/json' \\\n  -d '{\"apikey\":\"pk1_...\",\"secretapikey\":\"sk1_...\"}'"}]}},"\/dns\/deleteByNameType\/{domain}\/{type}\/{subdomain}":{"post":{"tags":["DNS"],"summary":"Delete DNS records by name and type","description":"Delete all DNS records matching the given subdomain and type. SOA and NS records cannot be deleted with this method (use delete by ID instead).","operationId":"dnsDeleteByNameType","parameters":[{"name":"domain","in":"path","required":true,"schema":{"type":"string"},"example":"example.com"},{"name":"type","in":"path","required":true,"schema":{"type":"string"},"example":"A"},{"name":"subdomain","in":"path","required":false,"schema":{"type":"string"},"description":"Subdomain portion only. Omit or leave empty for root domain records.","example":"www"}],"requestBody":{"required":true,"content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/AuthRequest"}}}},"responses":{"200":{"description":"Deleted","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/BasicResponse"}}}},"400":{"description":"Error","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/ErrorResponse"}}}}},"x-codeSamples":[{"lang":"curl","label":"curl","source":"curl -X POST https:\/\/api.porkbun.com\/api\/json\/v3\/dns\/deleteByNameType\/{domain}\/{type}\/{subdomain} \\\n  -H 'Content-Type: application\/json' \\\n  -d '{\"apikey\":\"pk1_...\",\"secretapikey\":\"sk1_...\"}'"}]}},"\/dns\/getDnssecRecords\/{domain}":{"post":{"tags":["DNS"],"summary":"Get DNSSEC records","description":"Retrieve DNSSEC records associated with the domain at the registry. Supports both GET (with header auth) and POST (with body or header auth).","operationId":"dnsGetDnssecRecords","parameters":[{"name":"domain","in":"path","required":true,"schema":{"type":"string"},"example":"example.com"}],"requestBody":{"required":true,"content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/AuthRequest"}}}},"responses":{"200":{"description":"DNSSEC records keyed by key tag","content":{"application\/json":{"schema":{"type":"object","properties":{"status":{"type":"string","example":"SUCCESS"},"records":{"type":"object","description":"Object keyed by key tag value. Each value is an object containing the DNSSEC data fields.","additionalProperties":{"type":"object","properties":{"keyTag":{"type":"string"},"alg":{"type":"string"},"digestType":{"type":"string"},"digest":{"type":"string"},"pubKey":{"type":"string","description":"Present for key data records"}}}}}}}}},"400":{"description":"Error","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/ErrorResponse"}}}}},"x-codeSamples":[{"lang":"curl","label":"curl","source":"curl -X POST https:\/\/api.porkbun.com\/api\/json\/v3\/dns\/getDnssecRecords\/{domain} \\\n  -H 'Content-Type: application\/json' \\\n  -d '{\"apikey\":\"pk1_...\",\"secretapikey\":\"sk1_...\"}'"}]},"get":{"tags":["DNS"],"summary":"Get DNSSEC records","description":"Retrieve DNSSEC records associated with the domain at the registry. Supports both GET (with header auth) and POST (with body or header auth).","operationId":"getDnssecRecords","parameters":[{"name":"domain","in":"path","required":true,"schema":{"type":"string"},"example":"example.com"},{"name":"X-API-Key","in":"header","required":false,"schema":{"type":"string"},"description":"API key header auth (use with X-Secret-API-Key)"},{"name":"X-Secret-API-Key","in":"header","required":false,"schema":{"type":"string"},"description":"Secret API key header auth (use with X-API-Key)"}],"responses":{"200":{"description":"DNSSEC records keyed by key tag","content":{"application\/json":{"schema":{"type":"object","properties":{"status":{"type":"string","example":"SUCCESS"},"records":{"type":"object","description":"Object keyed by key tag value. Each value is an object containing the DNSSEC data fields.","additionalProperties":{"type":"object","properties":{"keyTag":{"type":"string"},"alg":{"type":"string"},"digestType":{"type":"string"},"digest":{"type":"string"},"pubKey":{"type":"string","description":"Present for key data records"}}}}}}}}},"400":{"description":"Error","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/ErrorResponse"}}}}},"x-codeSamples":[{"lang":"curl","label":"curl","source":"curl 'https:\/\/api.porkbun.com\/api\/json\/v3\/dns\/getDnssecRecords\/{domain}' \\\n  -H 'X-API-Key: pk1_...' \\\n  -H 'X-Secret-API-Key: sk1_...'"}]}},"\/dns\/createDnssecRecord\/{domain}":{"post":{"tags":["DNS"],"summary":"Create DNSSEC record","description":"Create a DNSSEC DS or key record at the registry. DNSSEC requirements vary by registry \u2014 `keyTag`, `alg`, `digestType`, and `digest` are the minimum required fields. Key data fields are optional and will be omitted if not accepted by the registry.","operationId":"dnsCreateDnssecRecord","parameters":[{"name":"domain","in":"path","required":true,"schema":{"type":"string"},"example":"example.com"}],"requestBody":{"required":true,"content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/CreateDnssecRequest"}}}},"responses":{"200":{"description":"DNSSEC record created","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/BasicResponse"}}}},"400":{"description":"Error","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/ErrorResponse"}}}}},"x-codeSamples":[{"lang":"curl","label":"curl","source":"curl -X POST https:\/\/api.porkbun.com\/api\/json\/v3\/dns\/createDnssecRecord\/{domain} \\\n  -H 'Content-Type: application\/json' \\\n  -d '{\"apikey\":\"pk1_...\",\"secretapikey\":\"sk1_...\",\"keyTag\":\"12345\",\"alg\":\"13\",\"digestType\":\"2\",\"digest\":\"ABCD1234...\"}'"}]}},"\/dns\/deleteDnssecRecord\/{domain}\/{keytag}":{"post":{"tags":["DNS"],"summary":"Delete DNSSEC record","description":"Delete a DNSSEC record from the registry by key tag. Note: most registries delete all records matching the key data, not only the record with the specified key tag.","operationId":"dnsDeleteDnssecRecord","parameters":[{"name":"domain","in":"path","required":true,"schema":{"type":"string"},"example":"example.com"},{"name":"keytag","in":"path","required":true,"schema":{"type":"string"},"description":"The DNSSEC key tag value","example":"12345"}],"requestBody":{"required":true,"content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/AuthRequest"}}}},"responses":{"200":{"description":"Deleted","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/BasicResponse"}}}},"400":{"description":"Error","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/ErrorResponse"}}}}},"x-codeSamples":[{"lang":"curl","label":"curl","source":"curl -X POST https:\/\/api.porkbun.com\/api\/json\/v3\/dns\/deleteDnssecRecord\/{domain}\/{keytag} \\\n  -H 'Content-Type: application\/json' \\\n  -d '{\"apikey\":\"pk1_...\",\"secretapikey\":\"sk1_...\"}'"}]}},"\/ssl\/retrieve\/{domain}":{"post":{"tags":["SSL"],"summary":"Retrieve SSL bundle","description":"Retrieve the Let's Encrypt SSL certificate bundle for a domain. The certificate must already be issued (status HAVECERT). Token-based access is not supported for this endpoint. Supports both GET (with header auth) and POST (with body or header auth).","operationId":"sslRetrieve","parameters":[{"name":"domain","in":"path","required":true,"schema":{"type":"string"},"example":"example.com"}],"requestBody":{"required":true,"content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/AuthRequest"}}}},"responses":{"200":{"description":"SSL certificate bundle","content":{"application\/json":{"schema":{"type":"object","properties":{"status":{"type":"string","example":"SUCCESS"},"certificatechain":{"type":"string","description":"The full PEM-encoded certificate chain (certificate + intermediates)"},"privatekey":{"type":"string","description":"The PEM-encoded private key"},"publickey":{"type":"string","description":"The PEM-encoded public key"}}}}}},"400":{"description":"Error (e.g. certificate not ready, domain not found)","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/ErrorResponse"}}}}},"x-codeSamples":[{"lang":"curl","label":"curl","source":"curl -X POST https:\/\/api.porkbun.com\/api\/json\/v3\/ssl\/retrieve\/{domain} \\\n  -H 'Content-Type: application\/json' \\\n  -d '{\"apikey\":\"pk1_...\",\"secretapikey\":\"sk1_...\"}'"}]},"get":{"tags":["SSL"],"summary":"Retrieve SSL bundle","description":"Retrieve the Let's Encrypt SSL certificate bundle for a domain. The certificate must already be issued (status HAVECERT). Token-based access is not supported for this endpoint. Supports both GET (with header auth) and POST (with body or header auth).","operationId":"getSslRetrieve","parameters":[{"name":"domain","in":"path","required":true,"schema":{"type":"string"},"example":"example.com"},{"name":"X-API-Key","in":"header","required":false,"schema":{"type":"string"},"description":"API key header auth (use with X-Secret-API-Key)"},{"name":"X-Secret-API-Key","in":"header","required":false,"schema":{"type":"string"},"description":"Secret API key header auth (use with X-API-Key)"}],"responses":{"200":{"description":"SSL certificate bundle","content":{"application\/json":{"schema":{"type":"object","properties":{"status":{"type":"string","example":"SUCCESS"},"certificatechain":{"type":"string","description":"The full PEM-encoded certificate chain (certificate + intermediates)"},"privatekey":{"type":"string","description":"The PEM-encoded private key"},"publickey":{"type":"string","description":"The PEM-encoded public key"}}}}}},"400":{"description":"Error (e.g. certificate not ready, domain not found)","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/ErrorResponse"}}}}},"x-codeSamples":[{"lang":"curl","label":"curl","source":"curl 'https:\/\/api.porkbun.com\/api\/json\/v3\/ssl\/retrieve\/{domain}' \\\n  -H 'X-API-Key: pk1_...' \\\n  -H 'X-Secret-API-Key: sk1_...'"}]}},"\/email\/setPassword":{"post":{"tags":["Email Hosting"],"summary":"Set email hosting password","description":"Set the password for an email hosting account associated with a domain managed by your API key.","operationId":"emailSetPassword","requestBody":{"required":true,"content":{"application\/json":{"schema":{"allOf":[{"$ref":"#\/components\/schemas\/AuthRequest"},{"type":"object","required":["emailAddress","password"],"properties":{"emailAddress":{"type":"string","description":"The full email address (e.g. user@example.com)","example":"user@example.com"},"password":{"type":"string","description":"The new password. Must pass Porkbun password validation rules."}}}]}}}},"responses":{"200":{"description":"Password updated","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/BasicResponse"}}}},"400":{"description":"Validation or permission error","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/ErrorResponse"}}}}},"x-codeSamples":[{"lang":"curl","label":"curl","source":"curl -X POST https:\/\/api.porkbun.com\/api\/json\/v3\/email\/setPassword \\\n  -H 'Content-Type: application\/json' \\\n  -d '{\"apikey\":\"pk1_...\",\"secretapikey\":\"sk1_...\",\"emailAddress\":\"user@example.com\"}'"}]}},"\/marketplace\/getAll":{"get":{"tags":["Marketplace"],"summary":"List marketplace domains","description":"GET form of `\/marketplace\/getAll` for read-friendly filtering and URL-shareable searches. Authenticate via `X-API-Key` and `X-Secret-API-Key` headers, or `Authorization: Bearer <token>`. All filter params are optional and mirror the POST body. For multi-value `tlds`, use bracket syntax: `?tlds[]=com&tlds[]=io`.\n\nSee the POST documentation for the full filtering semantics (unfiltered pagination vs filtered mode, `+include` \/ `-exclude` query prefixes, sort options).","operationId":"listMarketplaceListingsGet","parameters":[{"name":"X-API-Key","in":"header","required":false,"schema":{"type":"string"},"description":"API key header auth (use with X-Secret-API-Key)"},{"name":"X-Secret-API-Key","in":"header","required":false,"schema":{"type":"string"},"description":"Secret API key header auth (use with X-API-Key)"},{"name":"query","in":"query","required":false,"schema":{"type":"string"},"description":"SLD substring search. Multi-word; prefix a term with `-` to exclude. Example: `ai -test`."},{"name":"tlds","in":"query","required":false,"schema":{"type":"array","items":{"type":"string"}},"style":"form","explode":true,"description":"Filter to listings under these TLDs (without leading dot). Use bracket form: `?tlds[]=com&tlds[]=io`."},{"name":"sldLengthMin","in":"query","required":false,"schema":{"type":"integer"},"description":"Minimum SLD character length."},{"name":"sldLengthMax","in":"query","required":false,"schema":{"type":"integer"},"description":"Maximum SLD character length."},{"name":"sortName","in":"query","required":false,"schema":{"type":"string","enum":["domain","tld","price","sld_length"]},"description":"Field to sort filtered results by."},{"name":"sortDirection","in":"query","required":false,"schema":{"type":"string","enum":["asc","desc"]},"description":"Sort direction."},{"name":"start","in":"query","required":false,"schema":{"type":"integer","minimum":0},"description":"Pagination offset (unfiltered mode only)."},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","minimum":1,"maximum":5000},"description":"Page size (unfiltered mode only). Default 1000, max 5000."}],"responses":{"200":{"description":"Marketplace domain list (same shape as POST).","content":{"application\/json":{"schema":{"type":"object","properties":{"status":{"type":"string","example":"SUCCESS"},"count":{"type":"integer"},"filtered":{"type":"boolean"},"domains":{"type":"array","items":{"type":"object","properties":{"create_date":{"type":"string"},"domain":{"type":"string"},"tld":{"type":"string"},"sld_length":{"type":"integer"},"price":{"type":"number"}}}}}}}}}},"x-codeSamples":[{"lang":"curl","label":"curl","source":"curl 'https:\/\/api.porkbun.com\/api\/json\/v3\/marketplace\/getAll?query=ai&tlds[]=com&tlds[]=io&sldLengthMax=6&sortName=price&sortDirection=asc' \\\n  -H 'X-API-Key: pk1_...' \\\n  -H 'X-Secret-API-Key: sk1_...'"}]},"post":{"tags":["Marketplace"],"summary":"List marketplace domains","description":"Retrieve domains listed on the Porkbun marketplace. Two modes:\n\n- **Unfiltered (default):** paginated raw listing, up to 5000 entries per call via `start` \/ `limit`.\n- **Filtered:** when any of `query`, `tlds`, `sldLengthMin`, `sldLengthMax`, or `sortName` is provided, results are filtered server-side. Filtered mode returns up to 1000 matching listings (matches the web UI's marketplace search).\n\n`query` supports `+include` and `-exclude` prefixes per word against the SLD (e.g. `+ai -test` matches SLDs containing 'ai' but not 'test'). Token-based access is not supported.","operationId":"listMarketplaceListings","requestBody":{"required":true,"content":{"application\/json":{"schema":{"allOf":[{"$ref":"#\/components\/schemas\/AuthRequest"},{"type":"object","properties":{"start":{"type":"integer","description":"Pagination offset (unfiltered mode only). Default 0.","example":0},"limit":{"type":"integer","description":"Number of domains to return (unfiltered mode only). Default 1000, max 5000.","example":1000,"maximum":5000},"query":{"type":"string","description":"Search string. Each space-separated term filters by SLD substring. Prefix a term with `-` to exclude it.","example":"ai -test"},"tlds":{"type":"array","items":{"type":"string"},"description":"Filter to listings under these TLDs (without the leading dot).","example":["com","io"]},"sldLengthMin":{"type":"integer","description":"Filter to listings whose SLD has at least this many characters.","example":3},"sldLengthMax":{"type":"integer","description":"Filter to listings whose SLD has at most this many characters.","example":8},"sortName":{"type":"string","enum":["domain","tld","price","sld_length"],"description":"Field to sort filtered results by. Default `sld_length` ascending when `query` is set, otherwise `create_date` descending."},"sortDirection":{"type":"string","enum":["asc","desc"],"description":"Sort direction. Defaults vary by `sortName`."}}}]}}}},"responses":{"200":{"description":"Marketplace domain list","content":{"application\/json":{"schema":{"type":"object","properties":{"status":{"type":"string","example":"SUCCESS"},"count":{"type":"integer","description":"Number of domains returned in this response"},"filtered":{"type":"boolean","description":"True when one or more filter parameters were applied (query, tlds, sldLengthMin\/Max, sortName)."},"domains":{"type":"array","items":{"type":"object","properties":{"create_date":{"type":"string","description":"Date the listing was created"},"domain":{"type":"string"},"tld":{"type":"string"},"sld_length":{"type":"integer","description":"Character length of the SLD (the part of the domain before the TLD)"},"price":{"type":"number","description":"Listing price in USD"}}}}}}}}},"400":{"description":"Authentication error","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/ErrorResponse"}}}}},"x-codeSamples":[{"lang":"curl","label":"curl","source":"curl -X POST https:\/\/api.porkbun.com\/api\/json\/v3\/marketplace\/getAll \\\n  -H 'Content-Type: application\/json' \\\n  -d '{\"apikey\":\"pk1_...\",\"secretapikey\":\"sk1_...\",\"start\":0,\"limit\":1000}'"}]}},"\/account\/invite":{"post":{"tags":["Account"],"summary":"Create an account registration invite","operationId":"createAccountInvite","description":"Generates a one-time invite token and URL that you send to a prospective user. When the user visits the URL they go through Porkbun's normal account creation flow \u2014 including CAPTCHA, address collection, and TOS acceptance \u2014 in the browser. The invite expires in 48 hours. Each token can only be used once.\n\nOptionally supply an `email` to pre-fill the email field on the registration form.\n\nOptionally supply a `returnUrl` (must be HTTPS) to redirect the user back to your platform after they complete registration.\n\nAfter sending the invite URL, poll `\/account\/inviteStatus` to check whether the account was created.","requestBody":{"required":true,"content":{"application\/json":{"schema":{"type":"object","required":["apikey","secretapikey"],"properties":{"apikey":{"type":"string","description":"Your API key"},"secretapikey":{"type":"string","description":"Your secret API key"},"email":{"type":"string","format":"email","description":"Email address to pre-fill on the registration form (optional)"},"returnUrl":{"type":"string","format":"uri","description":"HTTPS URL to redirect the user to after successful registration (optional). Use this to send users back to your platform after they complete account creation.","example":"https:\/\/yourapp.com\/onboarding\/complete"}}}}}},"responses":{"200":{"description":"Invite created","content":{"application\/json":{"schema":{"type":"object","required":["status","inviteToken","inviteUrl","expires"],"properties":{"status":{"type":"string","example":"SUCCESS"},"inviteToken":{"type":"string","description":"Opaque token \u2014 pass to `\/account\/inviteStatus` to track completion","example":"a3f8c2..."},"inviteUrl":{"type":"string","format":"uri","description":"URL to send to the prospective user. Opens Porkbun's standard registration page.","example":"https:\/\/porkbun.com\/account\/create?invite=a3f8c2..."},"expires":{"type":"string","format":"date-time","description":"UTC datetime when the invite token expires (48 hours from creation)","example":"2024-01-16 14:30:00"}}}}}},"400":{"description":"Authentication failed","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/ErrorResponse"}}}}},"x-codeSamples":[{"lang":"curl","label":"curl","source":"curl -X POST https:\/\/api.porkbun.com\/api\/json\/v3\/account\/invite \\\n  -H 'Content-Type: application\/json' \\\n  -d '{\"apikey\":\"pk1_...\",\"secretapikey\":\"sk1_...\",\"email\":\"newuser@example.com\"}'"}]}},"\/account\/inviteStatus":{"get":{"tags":["Account"],"summary":"Check account invite status","operationId":"getAccountInviteStatus","description":"Returns the current status of a registration invite created by your API key.\n\n- `PENDING` \u2014 the invite URL has not yet been used\n- `ACCEPTED` \u2014 the user completed registration; `newAccountId` contains their account ID\n- `EXPIRED` \u2014 the invite was not used within 48 hours or was canceled\n\nYou can only query invites created by your own API key. Pass credentials via `X-API-Key` and `X-Secret-API-Key` headers.","parameters":[{"name":"token","in":"query","required":true,"schema":{"type":"string"},"description":"The `inviteToken` returned by `\/account\/invite`"},{"name":"X-API-Key","in":"header","required":true,"schema":{"type":"string"},"description":"Your API key"},{"name":"X-Secret-API-Key","in":"header","required":true,"schema":{"type":"string"},"description":"Your secret API key"}],"responses":{"200":{"description":"Status returned","content":{"application\/json":{"schema":{"type":"object","required":["status","inviteStatus"],"properties":{"status":{"type":"string","example":"SUCCESS"},"inviteStatus":{"type":"string","enum":["PENDING","ACCEPTED","EXPIRED"],"description":"Current state of the invite"},"newAccountId":{"type":"integer","description":"ID of the newly created account. Present only when `inviteStatus` is `ACCEPTED`.","example":12345}}}}}},"400":{"description":"Authentication failed or token not found \/ not owned by caller","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/ErrorResponse"}}}}},"x-codeSamples":[{"lang":"curl","label":"curl","source":"curl 'https:\/\/api.porkbun.com\/api\/json\/v3\/account\/inviteStatus?token=a3f8c2...' \\\n  -H 'X-API-Key: pk1_...' \\\n  -H 'X-Secret-API-Key: sk1_...'"}]}},"\/account\/balance":{"get":{"tags":["Account"],"summary":"Get account balance","description":"Returns the available account credit balance. Authenticate using `X-API-Key` and `X-Secret-API-Key` headers, or `Authorization: Bearer <token>`.","operationId":"getBalance","parameters":[{"name":"X-API-Key","in":"header","required":false,"schema":{"type":"string"},"description":"API key header auth (use with X-Secret-API-Key)"},{"name":"X-Secret-API-Key","in":"header","required":false,"schema":{"type":"string"},"description":"Secret API key header auth (use with X-API-Key)"}],"responses":{"200":{"description":"Account balance.","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/BalanceResponse"}}}}},"x-codeSamples":[{"lang":"curl","label":"curl","source":"curl 'https:\/\/api.porkbun.com\/api\/json\/v3\/account\/balance' \\\n  -H 'X-API-Key: pk1_...' \\\n  -H 'X-Secret-API-Key: sk1_...'"}]}},"\/account\/apiSettings":{"get":{"tags":["Account"],"summary":"Get API spend settings","description":"Returns the account's API spend control settings and current month's spend total. All amounts are in cents. Authenticate using `X-API-Key` and `X-Secret-API-Key` headers, or `Authorization: Bearer <token>`.","operationId":"getApiSettings","parameters":[{"name":"X-API-Key","in":"header","required":false,"schema":{"type":"string"},"description":"API key header auth (use with X-Secret-API-Key)"},{"name":"X-Secret-API-Key","in":"header","required":false,"schema":{"type":"string"},"description":"Secret API key header auth (use with X-API-Key)"}],"responses":{"200":{"description":"API spend settings and current month spend.","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/ApiSettingsResponse"}}}}},"x-codeSamples":[{"lang":"curl","label":"curl","source":"curl 'https:\/\/api.porkbun.com\/api\/json\/v3\/account\/apiSettings' \\\n  -H 'X-API-Key: pk1_...' \\\n  -H 'X-Secret-API-Key: sk1_...'"}]}},"\/webhook\/eventTypes":{"get":{"tags":["Webhooks"],"summary":"List subscribable event types","description":"Return the catalog of event types a webhook endpoint can subscribe to. Read-only; supports GET (header auth) or POST (body or header auth).","operationId":"webhookEventTypes","parameters":[{"name":"X-API-Key","in":"header","required":false,"schema":{"type":"string"},"description":"API key header auth (use with X-Secret-API-Key)"},{"name":"X-Secret-API-Key","in":"header","required":false,"schema":{"type":"string"},"description":"Secret API key header auth (use with X-API-Key)"}],"responses":{"200":{"description":"Event type catalog.","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/WebhookEventTypesResponse"}}}},"400":{"description":"Error","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/ErrorResponse"}}}}},"x-codeSamples":[{"lang":"curl","label":"curl","source":"curl 'https:\/\/api.porkbun.com\/api\/json\/v3\/webhook\/eventTypes' \\\n  -H 'X-API-Key: pk1_...' \\\n  -H 'X-Secret-API-Key: sk1_...'"}]}},"\/webhook\/list":{"get":{"tags":["Webhooks"],"summary":"List webhook endpoints","description":"List all webhook endpoints registered on the authenticated account, including each endpoint's signing secret and delivery health. Read-only; supports GET (header auth) or POST (body or header auth).","operationId":"webhookList","parameters":[{"name":"X-API-Key","in":"header","required":false,"schema":{"type":"string"},"description":"API key header auth (use with X-Secret-API-Key)"},{"name":"X-Secret-API-Key","in":"header","required":false,"schema":{"type":"string"},"description":"Secret API key header auth (use with X-API-Key)"}],"responses":{"200":{"description":"Your webhook endpoints.","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/WebhookListResponse"}}}},"400":{"description":"Error","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/ErrorResponse"}}}}},"x-codeSamples":[{"lang":"curl","label":"curl","source":"curl 'https:\/\/api.porkbun.com\/api\/json\/v3\/webhook\/list' \\\n  -H 'X-API-Key: pk1_...' \\\n  -H 'X-Secret-API-Key: sk1_...'"}]}},"\/webhook\/get\/{id}":{"get":{"tags":["Webhooks"],"summary":"Get a webhook endpoint","description":"Fetch a single webhook endpoint by id, including its signing secret and delivery health. Read-only; supports GET (header auth) or POST (body or header auth).","operationId":"webhookGet","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer"},"example":42},{"name":"X-API-Key","in":"header","required":false,"schema":{"type":"string"},"description":"API key header auth (use with X-Secret-API-Key)"},{"name":"X-Secret-API-Key","in":"header","required":false,"schema":{"type":"string"},"description":"Secret API key header auth (use with X-API-Key)"}],"responses":{"200":{"description":"The webhook endpoint.","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/WebhookEndpointResponse"}}}},"404":{"description":"Endpoint not found","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/ErrorResponse"}}}}},"x-codeSamples":[{"lang":"curl","label":"curl","source":"curl 'https:\/\/api.porkbun.com\/api\/json\/v3\/webhook\/get\/42' \\\n  -H 'X-API-Key: pk1_...' \\\n  -H 'X-Secret-API-Key: sk1_...'"}]}},"\/webhook\/create":{"post":{"tags":["Webhooks"],"summary":"Create a webhook endpoint","description":"Register an HTTPS endpoint to receive signed event payloads. The response includes the generated `secret` \u2014 store it securely; it is the HMAC key used to verify the `X-Porkbun-Signature` header. Omit `events` (or pass `[\"*\"]`) to subscribe to all event types. Maximum 20 endpoints per account.","operationId":"webhookCreate","requestBody":{"required":true,"content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/CreateWebhookRequest"}}}},"responses":{"200":{"description":"Endpoint created (includes the signing secret).","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/WebhookEndpointResponse"}}}},"400":{"description":"Validation error","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/ErrorResponse"}}}}},"x-codeSamples":[{"lang":"curl","label":"curl","source":"curl -X POST https:\/\/api.porkbun.com\/api\/json\/v3\/webhook\/create \\\n  -H 'Content-Type: application\/json' \\\n  -d '{\"apikey\":\"pk1_...\",\"secretapikey\":\"sk1_...\",\"url\":\"https:\/\/example.com\/porkbun\/webhook\",\"events\":[\"*\"]}'"}]}},"\/webhook\/update":{"post":{"tags":["Webhooks"],"summary":"Update a webhook endpoint","description":"Update an endpoint's URL, event subscriptions, and\/or status. Only the supplied fields change. Set `status` to `DISABLED` to pause deliveries or `ACTIVE` to resume (resuming also resets the consecutive-failure counter).","operationId":"webhookUpdate","requestBody":{"required":true,"content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/UpdateWebhookRequest"}}}},"responses":{"200":{"description":"Updated endpoint.","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/WebhookEndpointResponse"}}}},"400":{"description":"Error","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/ErrorResponse"}}}},"404":{"description":"Endpoint not found","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/ErrorResponse"}}}}},"x-codeSamples":[{"lang":"curl","label":"curl","source":"curl -X POST https:\/\/api.porkbun.com\/api\/json\/v3\/webhook\/update \\\n  -H 'Content-Type: application\/json' \\\n  -d '{\"apikey\":\"pk1_...\",\"secretapikey\":\"sk1_...\",\"id\":42,\"status\":\"DISABLED\"}'"}]}},"\/webhook\/rotateSecret":{"post":{"tags":["Webhooks"],"summary":"Rotate the signing secret","description":"Generate a new signing secret for an endpoint and return the endpoint with the new secret. Deliveries are signed with the new secret immediately, so update your verifier as part of the same operation.","operationId":"webhookRotateSecret","requestBody":{"required":true,"content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/WebhookIdRequest"}}}},"responses":{"200":{"description":"Endpoint with the rotated secret.","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/WebhookEndpointResponse"}}}},"404":{"description":"Endpoint not found","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/ErrorResponse"}}}}},"x-codeSamples":[{"lang":"curl","label":"curl","source":"curl -X POST https:\/\/api.porkbun.com\/api\/json\/v3\/webhook\/rotateSecret \\\n  -H 'Content-Type: application\/json' \\\n  -d '{\"apikey\":\"pk1_...\",\"secretapikey\":\"sk1_...\",\"id\":42}'"}]}},"\/webhook\/test":{"post":{"tags":["Webhooks"],"summary":"Send a test event","description":"Enqueue a `webhook.test` event to the endpoint so you can confirm reachability and that your signature verification works. The endpoint must be ACTIVE. Delivery is asynchronous (usually within a minute).","operationId":"webhookTest","requestBody":{"required":true,"content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/WebhookIdRequest"}}}},"responses":{"200":{"description":"Test event queued.","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/WebhookTestResponse"}}}},"400":{"description":"Endpoint disabled or invalid","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/ErrorResponse"}}}},"404":{"description":"Endpoint not found","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/ErrorResponse"}}}}},"x-codeSamples":[{"lang":"curl","label":"curl","source":"curl -X POST https:\/\/api.porkbun.com\/api\/json\/v3\/webhook\/test \\\n  -H 'Content-Type: application\/json' \\\n  -d '{\"apikey\":\"pk1_...\",\"secretapikey\":\"sk1_...\",\"id\":42}'"}]}},"\/webhook\/delete":{"post":{"tags":["Webhooks"],"summary":"Delete a webhook endpoint","description":"Delete a webhook endpoint by id. Deliveries stop immediately.","operationId":"webhookDelete","requestBody":{"required":true,"content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/WebhookIdRequest"}}}},"responses":{"200":{"description":"Endpoint deleted.","content":{"application\/json":{"schema":{"type":"object","properties":{"status":{"type":"string","example":"SUCCESS"},"message":{"type":"string","example":"Webhook endpoint deleted."}}}}}},"404":{"description":"Endpoint not found","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/ErrorResponse"}}}}},"x-codeSamples":[{"lang":"curl","label":"curl","source":"curl -X POST https:\/\/api.porkbun.com\/api\/json\/v3\/webhook\/delete \\\n  -H 'Content-Type: application\/json' \\\n  -d '{\"apikey\":\"pk1_...\",\"secretapikey\":\"sk1_...\",\"id\":42}'"}]}},"\/webhook\/deliveries":{"get":{"tags":["Webhooks"],"summary":"List webhook deliveries","description":"List recent delivery attempts across the account (newest first), optionally filtered by endpoint or status. The bulky payload is omitted \u2014 use GET \/webhook\/delivery\/{id} for it. History is retained about 30 days. Read-only; supports GET (header auth) or POST (body or header auth).","operationId":"webhookDeliveries","parameters":[{"name":"endpointId","in":"query","required":false,"schema":{"type":"integer"},"description":"Only deliveries for this endpoint."},{"name":"status","in":"query","required":false,"schema":{"type":"string","enum":["PENDING","PROCESSING","DELIVERED","FAILED"]},"description":"Filter by delivery status."},{"name":"start","in":"query","required":false,"schema":{"type":"integer"},"description":"Pagination offset (default 0)."},{"name":"limit","in":"query","required":false,"schema":{"type":"integer"},"description":"Page size, 1-200 (default 50)."},{"name":"X-API-Key","in":"header","required":false,"schema":{"type":"string"},"description":"API key header auth (use with X-Secret-API-Key)"},{"name":"X-Secret-API-Key","in":"header","required":false,"schema":{"type":"string"},"description":"Secret API key header auth (use with X-API-Key)"}],"responses":{"200":{"description":"Recent deliveries.","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/WebhookDeliveryListResponse"}}}},"400":{"description":"Error","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/ErrorResponse"}}}},"404":{"description":"Endpoint not found","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/ErrorResponse"}}}}},"x-codeSamples":[{"lang":"curl","label":"curl","source":"curl 'https:\/\/api.porkbun.com\/api\/json\/v3\/webhook\/deliveries?status=FAILED&limit=50' \\\n  -H 'X-API-Key: pk1_...' \\\n  -H 'X-Secret-API-Key: sk1_...'"}]}},"\/webhook\/delivery\/{id}":{"get":{"tags":["Webhooks"],"summary":"Get a webhook delivery","description":"Fetch a single delivery including the full event payload that was (or will be) sent and its delivery status. Read-only; supports GET (header auth) or POST (body or header auth).","operationId":"webhookDelivery","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer"},"example":9001},{"name":"X-API-Key","in":"header","required":false,"schema":{"type":"string"},"description":"API key header auth (use with X-Secret-API-Key)"},{"name":"X-Secret-API-Key","in":"header","required":false,"schema":{"type":"string"},"description":"Secret API key header auth (use with X-API-Key)"}],"responses":{"200":{"description":"The delivery (includes payload).","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/WebhookDeliveryResponse"}}}},"404":{"description":"Delivery not found","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/ErrorResponse"}}}}},"x-codeSamples":[{"lang":"curl","label":"curl","source":"curl 'https:\/\/api.porkbun.com\/api\/json\/v3\/webhook\/delivery\/9001' \\\n  -H 'X-API-Key: pk1_...' \\\n  -H 'X-Secret-API-Key: sk1_...'"}]}},"\/webhook\/resend":{"post":{"tags":["Webhooks"],"summary":"Resend a delivery","description":"Re-queue a past delivery to its endpoint. Clones it into a fresh attempt reusing the ORIGINAL event id (so consumers that dedupe on X-Porkbun-Webhook-Id treat it as the same event). The endpoint must still exist and be ACTIVE. The original delivery row is left intact as history.","operationId":"webhookResend","requestBody":{"required":true,"content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/WebhookIdRequest"}}}},"responses":{"200":{"description":"Delivery re-queued.","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/WebhookResendResponse"}}}},"400":{"description":"Endpoint missing or disabled","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/ErrorResponse"}}}},"404":{"description":"Delivery not found","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/ErrorResponse"}}}}},"x-codeSamples":[{"lang":"curl","label":"curl","source":"curl -X POST https:\/\/api.porkbun.com\/api\/json\/v3\/webhook\/resend \\\n  -H 'Content-Type: application\/json' \\\n  -d '{\"apikey\":\"pk1_...\",\"secretapikey\":\"sk1_...\",\"id\":9001}'"}]}},"\/domain\/getRegistrationRequirements\/{tld}":{"get":{"tags":["Domain"],"summary":"Get TLD registration requirements (JSON Schema)","description":"Machine-readable registration requirements for a TLD. Returns whether the TLD is registerable via the API (`apiRegisterable`), the `\/domain\/create` request body as a JSON Schema, the fixed registration term, WHOIS-privacy\/validated-address\/registrant-only flags, and \u2014 for TLDs with registry eligibility rules (e.g. .us nexus, .ca legal type) \u2014 a second JSON Schema (`registryRequirements`) enumerating those fields with allowed values and labels. Call this before \/domain\/create to know upfront whether and how a TLD can be registered. Read-only; GET (header auth) or POST (body or header auth).","operationId":"domainGetRegistrationRequirements","parameters":[{"name":"tld","in":"path","required":true,"schema":{"type":"string"},"example":"us","description":"TLD without a leading dot, e.g. `com`, `us`, `ca`."},{"name":"X-API-Key","in":"header","required":false,"schema":{"type":"string"},"description":"API key header auth (use with X-Secret-API-Key)"},{"name":"X-Secret-API-Key","in":"header","required":false,"schema":{"type":"string"},"description":"Secret API key header auth (use with X-API-Key)"}],"responses":{"200":{"description":"Registration requirements for the TLD.","content":{"application\/json":{"schema":{"type":"object","properties":{"status":{"type":"string","example":"SUCCESS"},"tld":{"type":"string","example":"us"},"apiRegisterable":{"type":"boolean","description":"Whether this TLD can be registered via the API. False for TLDs with registry eligibility requirements the API cannot submit (register those on the website).","example":false},"registrationDurationYears":{"type":"integer","description":"Fixed registration term the API uses for this TLD.","example":1},"maxRegistrationYears":{"type":"integer","nullable":true,"description":"Maximum years the registry allows, or null if unspecified."},"whoisPrivacySupported":{"type":"boolean","example":true},"requiresValidatedAddress":{"type":"boolean","example":true},"registrantOnly":{"type":"boolean","description":"TLD uses only the registrant contact (no admin\/tech\/billing).","example":false},"requestSchema":{"type":"object","description":"JSON Schema (Draft 2020-12) for the \/domain\/create request body this TLD accepts (cost, agreeToTerms, whoisPrivacy, credentials), including the fixed registration term.","example":{"$schema":"https:\/\/json-schema.org\/draft\/2020-12\/schema","title":"domain\/create request for .com","type":"object","required":["apikey","secretapikey","cost","agreeToTerms"],"additionalProperties":false,"properties":{"apikey":{"type":"string","description":"Public API key (pk1_...). Omit if using the X-API-Key header."},"secretapikey":{"type":"string","description":"Secret API key (sk1_...). Omit if using the X-Secret-API-Key header."},"cost":{"type":"integer","minimum":0,"description":"Total price in US cents; must match the quote from \/domain\/checkDomain."},"agreeToTerms":{"type":"string","enum":["yes","1"],"description":"Must be \"yes\" to accept the registration agreement and terms."},"whoisPrivacy":{"type":"string","enum":["yes","no"],"description":"Optional WHOIS privacy override; defaults to enabled where supported."}}}},"registryRequirements":{"type":"object","nullable":true,"description":"JSON Schema of extra registry\/eligibility fields the TLD requires (e.g. .us purpose+category, .ca legal type) with enums and human labels, plus an x-policyNote. Null when the TLD has no structured extra data. These fields are documented for eligibility; they are not accepted by \/domain\/create today.","example":{"$schema":"https:\/\/json-schema.org\/draft\/2020-12\/schema","title":"Registry eligibility data for .us","description":"Extra registrant data the registry requires for this TLD. These fields are not accepted by \/domain\/create today (such TLDs are website-only); this schema documents the requirements.","type":"object","properties":{"purpose":{"type":"string","title":"Purpose","x-appliesTo":"registrant contact","enum":["P1","P2","P3","P4","P5"],"x-enumDescriptions":{"P1":"Business use for profit.","P2":"Non-profit organization.","P3":"Personal use.","P4":"Education purposes.","P5":"Government purposes."}},"category":{"type":"string","title":"Category","x-appliesTo":"registrant contact","enum":["C11","C12","C21","C31","C32"],"x-enumDescriptions":{"C11":"A US citizen.","C12":"A permanent resident of the US.","C21":"A US-based organization or company.","C31":"A foreign entity with a bona fide US presence.","C32":"An entity with a US office or facility."}}},"x-policyNote":"To register a .us domain you must accurately complete the Purpose and Category fields; inaccurate information can lead to seizure without refund."}},"notApiRegisterableReason":{"type":"string","description":"Present only when apiRegisterable is false."}}}}}},"400":{"description":"Unknown\/unsupported TLD or missing TLD.","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/ErrorResponse"}}}}},"x-codeSamples":[{"lang":"curl","label":"curl","source":"curl 'https:\/\/api.porkbun.com\/api\/json\/v3\/domain\/getRegistrationRequirements\/us' \\\n  -H 'X-API-Key: pk1_...' \\\n  -H 'X-Secret-API-Key: sk1_...'"}]}}},"components":{"schemas":{"IpResponse":{"type":"object","properties":{"status":{"type":"string","example":"SUCCESS"},"yourIp":{"type":"string","example":"1.2.3.4","description":"The caller's public IP address"},"xForwardedFor":{"type":"string","example":"1.2.3.4","description":"Raw value of the X-Forwarded-For header"}},"required":["status","yourIp"]},"AuthRequest":{"type":"object","description":"API credentials. Provide `apikey`\/`secretapikey` in the request body, OR supply them as `X-API-Key`\/`X-Secret-API-Key` request headers. One of the two methods is required.","properties":{"apikey":{"type":"string","description":"Your API key. Required in body when not using header auth.","example":"pk1_..."},"secretapikey":{"type":"string","description":"Your secret API key. Required in body when providing apikey.","example":"sk1_..."}}},"BasicResponse":{"type":"object","properties":{"status":{"type":"string","enum":["SUCCESS","ERROR"],"example":"SUCCESS"},"message":{"type":"string","description":"Human-readable message. Present on ERROR, sometimes on SUCCESS."},"code":{"type":"string","description":"Machine-readable error code. Present when status is ERROR."}},"required":["status"]},"ErrorResponse":{"type":"object","required":["status","message"],"properties":{"status":{"type":"string","enum":["ERROR"],"example":"ERROR"},"message":{"type":"string","description":"Human-readable description of the error","example":"Invalid domain."},"code":{"type":"string","description":"Machine-readable error code. Use for programmatic handling; use `message` for display. See the Error codes section in the API description for a full list.","example":"INVALID_DOMAIN"},"next_action":{"type":"object","description":"Present on many errors: a machine-readable remediation hint so an agent can self-correct without parsing the message. Absent when no specific action applies.","properties":{"type":{"type":"string","description":"Stable action category an agent can branch on.","enum":["fix_request","authenticate","enable_setting","verify_account","add_funds","retry","wait_and_retry","use_website","choose_alternative","contact_support","none"],"example":"fix_request"},"hint":{"type":"string","description":"Human-readable instruction.","example":"Re-fetch the price via \/domain\/checkDomain and resend the matching cost."},"url":{"type":"string","description":"Where to take the action, when applicable.","example":"https:\/\/porkbun.com\/account\/api"}}}}},"RateLimitExceeded":{"type":"object","required":["status","message"],"properties":{"status":{"type":"string","enum":["ERROR"],"example":"ERROR"},"message":{"type":"string","example":"Rate limit exceeded. Please try again later."},"code":{"type":"string","example":"RATE_LIMIT_EXCEEDED"},"ttlRemaining":{"type":"integer","description":"Seconds until the rate limit window resets. Present on some endpoints."}}},"ListAllRequest":{"type":"object","required":["apikey","secretapikey"],"properties":{"apikey":{"type":"string"},"secretapikey":{"type":"string"},"start":{"type":"integer","default":0,"description":"Zero-based offset for pagination (default: 0). Returns up to 1000 domains per call."},"includeLabels":{"type":"string","enum":["yes","no"],"description":"Return label metadata for each domain. Defaults to no."},"domain":{"type":"string","description":"Exact domain name match. Returns 0 or 1 result. Useful as an alternative to `\/domain\/get\/{domain}`.","example":"example.com"},"nameContains":{"type":"string","description":"Substring match against the full domain name. Case-insensitive.","example":"shop"},"expiringWithinDays":{"type":"integer","description":"Filter to domains expiring within this many days (relative to now).","example":30},"tlds":{"type":"array","items":{"type":"string"},"description":"Limit to these TLDs (without leading dot).","example":["com","io"]},"autoRenew":{"type":"string","enum":["yes","no"],"description":"Filter to domains with auto-renew on or off."},"apiAccess":{"type":"string","enum":["yes","no"],"description":"Filter to domains opted in to API access (yes) or not (no). Useful for finding domains an API key can actually operate on."},"sortName":{"type":"string","enum":["domain","tld","create_date","expire_date"],"description":"Field to sort by. Default: `expire_date` ascending."},"sortDirection":{"type":"string","enum":["asc","desc"],"description":"Sort direction. Default: asc."}}},"DomainListAllResponse":{"type":"object","properties":{"status":{"type":"string","example":"SUCCESS"},"count":{"type":"integer","description":"Number of domains returned in this page."},"domains":{"type":"array","items":{"type":"object","properties":{"domain":{"type":"string","example":"example.com"},"status":{"type":"string","description":"Domain registration status (e.g. ACTIVE)","example":"ACTIVE"},"tld":{"type":"string","example":"com"},"createDate":{"type":"string","example":"2021-01-15 10:00:00"},"expireDate":{"type":"string","example":"2027-01-15 10:00:00"},"securityLock":{"type":"integer","description":"1 if transfer lock is enabled, 0 otherwise","example":1},"whoisPrivacy":{"type":"integer","description":"1 if WHOIS privacy is enabled, 0 otherwise","example":1},"autoRenew":{"type":"integer","description":"1 if auto-renew is enabled, 0 otherwise","example":1},"apiAccess":{"type":"integer","description":"1 if the domain is opted in to API access, 0 otherwise. Per-domain API access can be toggled at porkbun.com\/account or globally via the `Opt In All Domains` setting.","example":1},"notLocal":{"type":"integer","description":"1 if the domain is externally managed (not authoritative), 0 otherwise","example":0},"labels":{"type":"array","description":"Only present when includeLabels=yes","items":{"type":"object","properties":{"id":{"type":"string"},"title":{"type":"string"},"color":{"type":"string"}}}}}}}},"required":["status","domains"]},"UpdateNsRequest":{"type":"object","required":["apikey","secretapikey","ns"],"properties":{"apikey":{"type":"string"},"secretapikey":{"type":"string"},"ns":{"type":"array","items":{"type":"string"},"description":"Ordered array of nameserver hostnames","example":["ns1.example.com","ns2.example.com"]}}},"UpdateAutoRenewRequest":{"type":"object","required":["apikey","secretapikey","status"],"properties":{"apikey":{"type":"string"},"secretapikey":{"type":"string"},"status":{"type":"string","enum":["on","off"],"description":"Auto-renew status to set"},"domains":{"type":"array","items":{"type":"string"},"description":"Array of additional domain names to update. Combined with the domain in the URL path if provided."}}},"CheckDomainResponse":{"type":"object","properties":{"status":{"type":"string","example":"SUCCESS"},"response":{"type":"object","properties":{"avail":{"type":"string","enum":["yes","no"],"description":"Whether the domain is available for registration"},"type":{"type":"string","example":"registration","description":"The price type (always 'registration' for the primary price)"},"price":{"type":"string","description":"Registration price per year in USD","example":"9.73"},"firstYearPromo":{"type":"string","enum":["yes","no"],"description":"Whether the returned price is a first-year promotional price"},"regularPrice":{"type":"string","description":"Standard (non-promo) registration price in USD","example":"9.73"},"premium":{"type":"string","enum":["yes","no"],"description":"Whether this is a premium domain"},"minDuration":{"type":"integer","description":"Minimum registration duration in years required by the registry","example":1},"additional":{"type":"object","description":"Renewal and transfer pricing for this domain","properties":{"renewal":{"type":"object","properties":{"type":{"type":"string"},"price":{"type":"string"},"regularPrice":{"type":"string"}}},"transfer":{"type":"object","properties":{"type":{"type":"string"},"price":{"type":"string"},"regularPrice":{"type":"string"}}}}}}},"limits":{"type":"object","description":"Current rate limit usage for this account","properties":{"TTL":{"type":"integer","description":"Rate limit window in seconds"},"limit":{"type":"integer","description":"Maximum checks allowed in the window"},"used":{"type":"integer","description":"Number of checks used so far in the current window"},"naturalLanguage":{"type":"string","description":"Human-readable rate limit summary","example":"1 out of 1 checks within 10 seconds used."}}},"ttlRemaining":{"type":"integer","description":"Seconds remaining until the rate limit window resets"}},"required":["status","response"]},"DryRunPreviewResponse":{"type":"object","description":"Returned (HTTP 200) by \/domain\/create, \/domain\/renew, and \/domain\/transfer when the request includes `dryRun: true`. All validation has run but nothing was created or charged. All money amounts are in pennies (USD cents).","example":{"status":"SUCCESS","dryRun":true,"wouldSucceed":true,"operation":"registration","domain":"example.com","tld":"com","available":"available","premium":false,"duration":1,"cost":973,"costDisplay":"$9.73","balance":5000,"sufficientFunds":true,"monthlySpendLimit":50000,"monthlySpendSoFar":12000,"withinMonthlySpendLimit":true,"message":"Dry run: this registration would succeed and cost $9.73. No order was created and no charge was made."},"properties":{"status":{"type":"string","example":"SUCCESS"},"dryRun":{"type":"boolean","example":true,"description":"Always true on a dry-run preview \u2014 distinguishes it from a real success response."},"wouldSucceed":{"type":"boolean","description":"True if the operation would complete given current funds and spend-limit state. (Hard validation failures \u2014 unavailable, bad price, ineligible \u2014 return a normal error response instead of a preview.)"},"operation":{"type":"string","enum":["registration","renewal","transfer"]},"domain":{"type":"string","example":"example.com"},"tld":{"type":"string","example":"com"},"available":{"type":"string","description":"Availability as reported by the registry check (e.g. `available` \/ `unavailable`).","example":"available"},"premium":{"type":"boolean","description":"Whether the domain is a premium\/aftermarket name."},"duration":{"type":"integer","description":"Term in years that would be purchased.","example":1},"cost":{"type":"integer","description":"Total cost in pennies that would be charged.","example":973},"costDisplay":{"type":"string","description":"Human-readable cost.","example":"$9.73"},"balance":{"type":"integer","description":"Current account credit balance in pennies."},"sufficientFunds":{"type":"boolean","description":"Whether the balance covers the cost."},"monthlySpendLimit":{"type":"integer","description":"The account's monthly API spend cap in pennies. Present only if a cap is configured."},"monthlySpendSoFar":{"type":"integer","description":"API spend so far this calendar month in pennies. Present only if a cap is configured."},"withinMonthlySpendLimit":{"type":"boolean","description":"Whether this cost stays within the monthly cap. Present only if a cap is configured."},"message":{"type":"string","description":"Human-readable summary of the preview outcome."},"requestId":{"type":"string","description":"Per-request UUID (also in the X-Request-Id header). Present on every API response."}},"required":["status","dryRun","wouldSucceed","operation","domain","cost"]},"CreateDomainRequest":{"type":"object","required":["apikey","secretapikey","cost","agreeToTerms"],"properties":{"apikey":{"type":"string"},"secretapikey":{"type":"string"},"cost":{"type":"integer","description":"The registration cost in pennies (USD cents). Must exactly equal the total price for the domain at its minimum registration duration. Obtain this from \/domain\/checkDomain first."},"agreeToTerms":{"type":"string","enum":["yes","1"],"description":"Must be 'yes' or '1' to confirm agreement to the Domain Name Registration Agreement, Product Terms of Service, Privacy Policy, and automatic renewal terms."},"whoisPrivacy":{"type":"boolean","description":"Optional. Override WHOIS privacy for this registration. When omitted, the account-level default is used (set under Account Security Settings on porkbun.com\/account \u2014 defaults to enabled). Pass `true` to force-enable privacy or `false` to register with public contact info. Strings `\"on\"`\/`\"off\"`, `\"true\"`\/`\"false\"`, `\"yes\"`\/`\"no\"`, `\"1\"`\/`\"0\"` are also accepted. Has no effect on TLDs that don't support WHOIS privacy (privacy stays off regardless)."},"dryRun":{"type":"boolean","description":"Optional. When true, runs all pre-flight validation (availability, pricing, cost match, eligibility, funds, spend limit) and returns a preview with `dryRun: true` and `wouldSucceed` WITHOUT creating an order or charging. Nothing is registered and the rate-limit budget is not consumed. Use it to safely confirm an operation before committing."}}},"CreateDomainResponse":{"type":"object","example":{"status":"SUCCESS","domain":"example.com","cost":973,"orderId":12345678,"limits":{"attempts":{"TTL":1,"limit":1,"used":1,"naturalLanguage":"1 out of 1 create attempts within 1 seconds used."},"success":{"TTL":86400,"limit":50,"used":1,"naturalLanguage":"1 out of 50 successful creates within 86400 seconds used."}},"balance":4027,"ttlRemaining":86400,"requestId":"019e04fa-258d-7d11-aa86-4d5795c3fe8f"},"properties":{"status":{"type":"string","example":"SUCCESS"},"domain":{"type":"string","description":"The registered domain name","example":"example.com"},"cost":{"type":"integer","description":"The total amount charged in pennies"},"orderId":{"type":"integer","description":"Internal Porkbun order ID"},"limits":{"type":"object","description":"Current rate limit state for both attempt and success limits","properties":{"attempts":{"type":"object","description":"Create-attempt rate limit state","properties":{"TTL":{"type":"integer","description":"Window in seconds"},"limit":{"type":"integer","description":"Max attempts allowed"},"used":{"type":"integer","description":"Attempts used"},"naturalLanguage":{"type":"string"}}},"success":{"type":"object","description":"Successful-registration rate limit state","properties":{"TTL":{"type":"integer","description":"Window in seconds"},"limit":{"type":"integer","description":"Max successes allowed"},"used":{"type":"integer","description":"Successes used"},"naturalLanguage":{"type":"string"}}}}},"balance":{"type":"integer","description":"Remaining account credit balance in pennies after the charge"},"ttlRemaining":{"type":"integer","description":"Seconds until the success rate limit window resets"},"requestId":{"type":"string","description":"Per-request UUID (also in the X-Request-Id header). Present on every API response."}},"required":["status","domain","orderId"]},"AddUrlForwardRequest":{"type":"object","required":["apikey","secretapikey","location","type","includePath","wildcard"],"properties":{"apikey":{"type":"string"},"secretapikey":{"type":"string"},"subdomain":{"type":"string","description":"Subdomain to forward (optional, leave blank or omit for root domain). Alphanumeric and hyphens only.","example":"www"},"location":{"type":"string","description":"Destination URL to forward to","example":"https:\/\/destination.example.com"},"type":{"type":"string","enum":["temporary","permanent"],"description":"'permanent' sends HTTP 301, 'temporary' sends the configured default redirect code"},"includePath":{"type":"string","enum":["yes","no"],"description":"Whether to append the request URI path to the forwarding destination"},"wildcard":{"type":"string","enum":["yes","no"],"description":"Whether to also forward all subdomains of the forwarded subdomain"}}},"GetUrlForwardingResponse":{"type":"object","properties":{"status":{"type":"string","example":"SUCCESS"},"forwards":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","description":"Numeric record ID"},"subdomain":{"type":"string","description":"Subdomain portion (empty string for root)"},"location":{"type":"string"},"type":{"type":"string","enum":["permanent","temporary"],"description":"Redirect type"},"includePath":{"type":"string","enum":["yes","no"]},"wildcard":{"type":"string","enum":["yes","no"]}}}}},"required":["status","forwards"]},"GlueRecordRequest":{"type":"object","required":["apikey","secretapikey","ips"],"properties":{"apikey":{"type":"string"},"secretapikey":{"type":"string"},"ips":{"type":"array","items":{"type":"string"},"description":"Array of IP addresses (IPv4 and\/or IPv6) to associate with the host record","example":["1.2.3.4","2001:db8::1"]}}},"DnsRecordsResponse":{"type":"object","properties":{"status":{"type":"string","example":"SUCCESS"},"cloudflare":{"type":"string","enum":["enabled","disabled"],"description":"Whether Cloudflare proxy is enabled for this domain"},"records":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","description":"Numeric record ID"},"name":{"type":"string","description":"Fully-qualified record name","example":"www.example.com"},"type":{"type":"string","description":"DNS record type","example":"A"},"content":{"type":"string","description":"Record value","example":"1.2.3.4"},"ttl":{"type":"string","description":"Time to live in seconds","example":"600"},"prio":{"type":"string","nullable":true,"description":"Priority (used for MX, SRV records). Null if not applicable.","example":"10"},"notes":{"type":"string","nullable":true,"description":"Optional notes attached to the record. Null if not set."}}}}},"required":["status","records"]},"CreateDnsRequest":{"type":"object","required":["apikey","secretapikey","type","content"],"properties":{"apikey":{"type":"string"},"secretapikey":{"type":"string"},"name":{"type":"string","description":"Subdomain for the record (e.g. 'www', '*' for wildcard, blank for root). Do not include the domain name itself.","example":"www"},"type":{"type":"string","description":"DNS record type","enum":["A","AAAA","MX","CNAME","ALIAS","TXT","NS","SRV","TLSA","CAA","SSHFP","HTTPS","SVCB"],"example":"A"},"content":{"type":"string","description":"The record value","example":"1.2.3.4"},"ttl":{"type":"integer","description":"Time to live in seconds. Minimum is determined by account settings (typically 600). Defaults to the account minimum if omitted or 0.","example":600},"prio":{"type":"integer","description":"Priority for MX and SRV records. Defaults to 0 if omitted.","example":10},"notes":{"type":"string","description":"Optional notes to store with the record (not served in DNS)"},"dryRun":{"type":"boolean","description":"If true, validate only \u2014 checks ownership\/type\/permissions and returns wouldSucceed without creating the record.","example":false}}},"EditDnsRequest":{"type":"object","required":["apikey","secretapikey","type","content"],"properties":{"apikey":{"type":"string"},"secretapikey":{"type":"string"},"name":{"type":"string","description":"Subdomain for the record. Do not include the domain name itself."},"type":{"type":"string","description":"DNS record type","enum":["A","AAAA","MX","CNAME","ALIAS","TXT","NS","SRV","TLSA","CAA","SSHFP","HTTPS","SVCB"],"example":"A"},"content":{"type":"string","description":"The record value","example":"5.6.7.8"},"ttl":{"type":"integer","description":"Time to live in seconds (optional)"},"prio":{"type":"integer","description":"Priority for MX\/SRV records (optional)"},"notes":{"type":"string","description":"Notes (optional). Pass empty string to clear notes; omit or pass null to leave unchanged."}}},"EditDnsByNameTypeRequest":{"type":"object","required":["apikey","secretapikey","content"],"properties":{"apikey":{"type":"string"},"secretapikey":{"type":"string"},"content":{"type":"string","description":"New record value to set on all matching records","example":"5.6.7.8"},"ttl":{"type":"integer","description":"Time to live in seconds (optional)"},"prio":{"type":"integer","description":"Priority (optional)"},"notes":{"type":"string","description":"Notes to store with the record (not served in DNS). Pass an empty string to clear existing notes; pass null or omit this field to leave notes unchanged."}}},"CreateDnssecRequest":{"type":"object","required":["apikey","secretapikey","keyTag","alg","digestType","digest"],"properties":{"apikey":{"type":"string"},"secretapikey":{"type":"string"},"keyTag":{"type":"string","description":"DNSSEC key tag","example":"12345"},"alg":{"type":"string","description":"DS Data algorithm number (e.g. 13 for ECDSA P-256 SHA-256)","example":"13"},"digestType":{"type":"string","description":"Digest type number (e.g. 2 for SHA-256)","example":"2"},"digest":{"type":"string","description":"Hex-encoded digest value","example":"ABCD1234..."},"maxSigLife":{"type":"string","description":"Maximum signature lifetime in seconds (optional, registry-specific)"},"keyDataFlags":{"type":"string","description":"Key data flags (optional, used when submitting full key data)"},"keyDataProtocol":{"type":"string","description":"Key data protocol (optional)"},"keyDataAlgo":{"type":"string","description":"Key data algorithm (optional)"},"keyDataPubKey":{"type":"string","description":"Key data public key in base64 (optional)"}}},"RenewDomainRequest":{"type":"object","required":["apikey","secretapikey","cost"],"properties":{"apikey":{"type":"string"},"secretapikey":{"type":"string"},"cost":{"type":"integer","description":"The renewal cost in pennies (USD cents). Must exactly equal the total price for the domain at its minimum renewal duration. Obtain this from \/domain\/checkDomain first."},"dryRun":{"type":"boolean","description":"Optional. When true, runs all pre-flight validation and returns a preview with `dryRun: true` and `wouldSucceed` WITHOUT renewing or charging. Nothing changes and the rate-limit budget is not consumed."}}},"RenewDomainResponse":{"type":"object","example":{"status":"SUCCESS","domain":"example.com","expirationDate":"2027-04-21","cost":1099,"orderId":12345679,"limits":{"attempts":{"TTL":1,"limit":1,"used":1,"naturalLanguage":"1 out of 1 renewal attempts within 1 seconds used."},"success":{"TTL":86400,"limit":50,"used":1,"naturalLanguage":"1 out of 50 successful renewals within 86400 seconds used."}},"balance":3928,"ttlRemaining":86400,"requestId":"019e04fa-3c11-7a02-9bd2-1f7c0e4a8b55"},"required":["status","domain","orderId"],"properties":{"status":{"type":"string","example":"SUCCESS"},"domain":{"type":"string","description":"The renewed domain name","example":"example.com"},"expirationDate":{"type":"string","description":"The new expiration date returned by the registry","example":"2026-04-21"},"cost":{"type":"integer","description":"The total amount charged in pennies"},"orderId":{"type":"integer","description":"Internal Porkbun order ID"},"limits":{"type":"object","description":"Current rate limit state for both attempt and success limits","properties":{"attempts":{"type":"object","properties":{"TTL":{"type":"integer","description":"Window in seconds"},"limit":{"type":"integer","description":"Max attempts allowed"},"used":{"type":"integer","description":"Attempts used"},"naturalLanguage":{"type":"string"}}},"success":{"type":"object","properties":{"TTL":{"type":"integer","description":"Window in seconds"},"limit":{"type":"integer","description":"Max successes allowed"},"used":{"type":"integer","description":"Successes used"},"naturalLanguage":{"type":"string"}}}}},"balance":{"type":"integer","description":"Remaining account credit balance in pennies after the charge"},"ttlRemaining":{"type":"integer","description":"Seconds until the success rate limit window resets"},"requestId":{"type":"string","description":"Per-request UUID (also in the X-Request-Id header). Present on every API response."}}},"TransferDomainRequest":{"type":"object","required":["secretapikey","apikey","authCode","cost"],"properties":{"secretapikey":{"type":"string","description":"Your API secret key."},"apikey":{"type":"string","description":"Your API key."},"authCode":{"type":"string","description":"The EPP auth code for the domain."},"cost":{"type":"integer","description":"The transfer cost in cents as returned by the pricing API. Must match exactly."},"dryRun":{"type":"boolean","description":"Optional. When true, runs all pre-flight validation and returns a preview with `dryRun: true` and `wouldSucceed` WITHOUT initiating the transfer or charging. Nothing changes and the rate-limit budget is not consumed."}}},"TransferDomainResponse":{"type":"object","example":{"status":"SUCCESS","domain":"example.com","orderId":12345680,"transferId":98765,"message":"Transfer initiated. The domain transfer process has begun and typically takes 5-7 days to complete.","balance":2829,"ttlRemaining":86400,"limits":{"attempts":{"TTL":1,"limit":1,"used":1,"naturalLanguage":"1 out of 1 transfer attempts within 1 seconds used."},"success":{"TTL":86400,"limit":50,"used":1,"naturalLanguage":"1 out of 50 successful transfers within 86400 seconds used."}},"requestId":"019e04fa-5f22-7c93-8a41-2e9d0b3f6c77"},"properties":{"status":{"type":"string","enum":["SUCCESS","ERROR"]},"domain":{"type":"string"},"orderId":{"type":"integer"},"transferId":{"type":"integer"},"message":{"type":"string"},"balance":{"type":"integer","description":"Remaining account credit balance in cents."},"ttlRemaining":{"type":"integer"},"limits":{"type":"object","properties":{"attempts":{"type":"object"},"success":{"type":"object"}}},"requestId":{"type":"string","description":"Per-request UUID (also in the X-Request-Id header). Present on every API response."}}},"GetTransferResponse":{"type":"object","properties":{"status":{"type":"string","enum":["SUCCESS","ERROR"]},"transfer":{"type":"object","properties":{"domain":{"type":"string"},"status":{"type":"string","enum":["NEW","PENDINGAUTH","PENDINGSUBMIT","PENDINGTRANSFER","DONE","CANCELED","INIT"]},"statusDescription":{"type":"string"},"transferDate":{"type":"string","format":"date-time"},"orderId":{"type":"integer"}}}}},"ListTransfersResponse":{"type":"object","properties":{"status":{"type":"string","enum":["SUCCESS","ERROR"]},"transfers":{"type":"array","items":{"type":"object","properties":{"domain":{"type":"string"},"status":{"type":"string","enum":["NEW","PENDINGAUTH","PENDINGSUBMIT","PENDINGTRANSFER","DONE","CANCELED","INIT"]},"statusDescription":{"type":"string"},"transferDate":{"type":"string","format":"date-time"},"orderId":{"type":"integer"}}}}}},"BalanceResponse":{"type":"object","properties":{"status":{"type":"string","enum":["SUCCESS","ERROR"]},"balance":{"type":"integer","description":"Available account credit balance in cents."},"display":{"type":"string","description":"Human-readable balance string (e.g. `$12.34`)."}}},"ApiSettingsResponse":{"type":"object","properties":{"status":{"type":"string","enum":["SUCCESS","ERROR"]},"settings":{"type":"object","properties":{"monthlySpendLimit":{"type":"integer","nullable":true,"description":"Maximum API spend per calendar month in cents. `null` means no limit."},"lowBalanceAlert":{"type":"integer","nullable":true,"description":"Send an alert email when balance drops below this amount (cents). `null` = disabled."},"autoTopup":{"type":"boolean","description":"Whether automatic balance top-up is enabled."},"topupThreshold":{"type":"integer","nullable":true,"description":"Trigger auto top-up when balance falls below this amount (cents). `null` = disabled."},"topupAmount":{"type":"integer","nullable":true,"description":"Amount to add during an auto top-up (cents)."}}},"monthlySpend":{"type":"integer","description":"Total API spend in the current calendar month, in cents."}}},"WebhookEndpoint":{"type":"object","properties":{"id":{"type":"integer","description":"Numeric endpoint id.","example":42},"url":{"type":"string","description":"Destination HTTPS URL.","example":"https:\/\/example.com\/porkbun\/webhook"},"secret":{"type":"string","description":"Signing secret used to verify the X-Porkbun-Signature header (HMAC-SHA256 key). Returned only to the authenticated owner.","example":"9f86d081..."},"events":{"type":"array","items":{"type":"string"},"description":"Subscribed event types, or [\"*\"] for all.","example":["domain.registered","dns.*"]},"status":{"type":"string","description":"ACTIVE or DISABLED.","example":"ACTIVE","enum":["ACTIVE","DISABLED"]},"consecutiveFailures":{"type":"integer","description":"Consecutive failed deliveries; reset to 0 on the next success or on re-enable. The endpoint auto-disables at 20.","example":0},"lastSuccessDate":{"type":"string","description":"Timestamp of the last successful delivery, or null.","example":"2026-06-17 18:30:00","nullable":true},"lastFailureDate":{"type":"string","description":"Timestamp of the last failed delivery, or null.","nullable":true},"lastError":{"type":"string","description":"Last delivery error, or null.","nullable":true},"createDate":{"type":"string","description":"When the endpoint was created.","example":"2026-06-17 12:00:00"}}},"WebhookEndpointResponse":{"type":"object","properties":{"status":{"type":"string","example":"SUCCESS"},"endpoint":{"$ref":"#\/components\/schemas\/WebhookEndpoint"}}},"WebhookListResponse":{"type":"object","properties":{"status":{"type":"string","example":"SUCCESS"},"endpoints":{"type":"array","items":{"$ref":"#\/components\/schemas\/WebhookEndpoint"}}}},"WebhookEventTypesResponse":{"type":"object","properties":{"status":{"type":"string","example":"SUCCESS"},"eventTypes":{"type":"array","items":{"type":"string"},"example":["domain.registered","domain.renewed","domain.transfer.completed","domain.expiring","dns.record.created","dns.record.updated","dns.record.deleted"]}}},"CreateWebhookRequest":{"type":"object","required":["apikey","secretapikey","url"],"properties":{"apikey":{"type":"string"},"secretapikey":{"type":"string"},"url":{"type":"string","description":"HTTPS URL to deliver events to.","example":"https:\/\/example.com\/porkbun\/webhook"},"events":{"type":"array","items":{"type":"string"},"description":"Event types to subscribe to. Omit, or pass [\"*\"], for all events. Prefix wildcards like \"dns.*\" are allowed.","example":["domain.registered","dns.*"]}}},"UpdateWebhookRequest":{"type":"object","required":["apikey","secretapikey","id"],"properties":{"apikey":{"type":"string"},"secretapikey":{"type":"string"},"id":{"type":"integer","description":"Endpoint id to update.","example":42},"url":{"type":"string","description":"New HTTPS URL (optional).","example":"https:\/\/example.com\/hook"},"events":{"type":"array","items":{"type":"string"},"description":"Replacement event subscription list (optional)."},"status":{"type":"string","description":"Set ACTIVE to resume (also clears the failure counter) or DISABLED to pause (optional).","example":"ACTIVE","enum":["ACTIVE","DISABLED"]}}},"WebhookIdRequest":{"type":"object","required":["apikey","secretapikey","id"],"properties":{"apikey":{"type":"string"},"secretapikey":{"type":"string"},"id":{"type":"integer","description":"Endpoint id.","example":42}}},"WebhookTestResponse":{"type":"object","properties":{"status":{"type":"string","example":"SUCCESS"},"eventId":{"type":"string","description":"UUID of the queued webhook.test event.","example":"018f9c2a-7b3e-7c41-9b8a-2f1e6d4c5a90"},"message":{"type":"string","example":"Test event queued. It will be delivered to your endpoint within about a minute."}}},"WebhookDelivery":{"type":"object","properties":{"id":{"type":"integer","description":"Delivery id.","example":9001},"endpointId":{"type":"integer","description":"Endpoint this delivery targets.","example":42},"eventType":{"type":"string","example":"domain.renewed"},"eventId":{"type":"string","description":"UUIDv7 of the event; sent as X-Porkbun-Webhook-Id. Stable across resends.","example":"018f9c2a-7b3e-7c41-9b8a-2f1e6d4c5a90"},"status":{"type":"string","description":"PENDING (queued\/awaiting retry), PROCESSING (in flight), DELIVERED (2xx), or FAILED (gave up after max attempts).","example":"DELIVERED","enum":["PENDING","PROCESSING","DELIVERED","FAILED"]},"attempts":{"type":"integer","description":"Delivery attempts made so far.","example":1},"maxAttempts":{"type":"integer","description":"Attempt cap before the delivery is marked FAILED.","example":6},"httpStatus":{"type":"integer","description":"HTTP status from the last attempt, or null if not yet attempted \/ connection error.","example":200,"nullable":true},"lastError":{"type":"string","description":"Last delivery error, or null.","nullable":true},"nextAttemptAt":{"type":"string","description":"When the next attempt is scheduled (for PENDING rows).","example":"2026-06-17 18:31:00"},"createDate":{"type":"string","description":"When the delivery was queued.","example":"2026-06-17 18:30:00"},"deliveredDate":{"type":"string","description":"When it was successfully delivered, or null.","nullable":true},"payload":{"type":"object","description":"The full event envelope that was sent. Present only on GET \/webhook\/delivery\/{id}."}}},"WebhookDeliveryListResponse":{"type":"object","properties":{"status":{"type":"string","example":"SUCCESS"},"deliveries":{"type":"array","items":{"$ref":"#\/components\/schemas\/WebhookDelivery"},"description":"Newest first. The bulky `payload` field is omitted here."},"total":{"type":"integer","description":"Total matching deliveries (for pagination).","example":128},"start":{"type":"integer","description":"Offset of this page.","example":0},"limit":{"type":"integer","description":"Page size used.","example":50},"message":{"type":"string","example":"Delivery history is retained for about 30 days."}}},"WebhookDeliveryResponse":{"type":"object","properties":{"status":{"type":"string","example":"SUCCESS"},"delivery":{"$ref":"#\/components\/schemas\/WebhookDelivery"}}},"WebhookResendResponse":{"type":"object","properties":{"status":{"type":"string","example":"SUCCESS"},"delivery":{"$ref":"#\/components\/schemas\/WebhookDelivery"},"message":{"type":"string","example":"Delivery re-queued. It will be re-sent within about a minute, reusing the original event id."}}}},"parameters":{"IdempotencyKeyHeader":{"name":"Idempotency-Key","in":"header","required":false,"schema":{"type":"string","maxLength":255},"description":"Optional. A unique string (e.g. UUID) to make this request safely retriable. Retries within 24 hours return the cached response. See the Idempotency section in the introduction for full semantics."}},"securitySchemes":{"ApiKeyHeader":{"type":"apiKey","in":"header","name":"X-API-Key","description":"Your API key. Use together with X-Secret-API-Key."},"SecretApiKeyHeader":{"type":"apiKey","in":"header","name":"X-Secret-API-Key","description":"Your secret API key. Use together with X-API-Key."}}},"security":[{"ApiKeyHeader":[],"SecretApiKeyHeader":[]}],"tags":[{"name":"Account","description":"Account credit balance, API spend controls, and onboarding"},{"name":"Domain","description":"Domain registration, nameservers, URL forwarding, glue records, and auto-renewal"},{"name":"DNS","description":"Create, read, update, and delete DNS records including DNSSEC"},{"name":"SSL","description":"Retrieve free SSL certificate bundles for domains registered at Porkbun"},{"name":"Email Hosting","description":"Email hosting password management"},{"name":"Marketplace","description":"Browse domains listed for sale on the Porkbun marketplace"},{"name":"Pricing","description":"Domain pricing across all supported TLDs \u2014 no authentication required"},{"name":"API Key Management","description":"Request and retrieve API keys programmatically"},{"name":"Utility","description":"IP detection and credential verification"},{"name":"Webhooks","description":"Register HTTPS endpoints to receive signed, real-time event notifications. See the Webhooks section in the introduction for the payload envelope and signature-verification recipe."}]}