# Porkbun API v3 — Account

> Account credit balance, API spend controls, and onboarding

Part of the Porkbun API v3.48. Topic index: https://porkbun.com/llms · Full reference: https://porkbun.com/llms-full.txt · Overview: https://porkbun.com/llms.txt · OpenAPI spec: https://porkbun.com/api/json/v3/spec

**Auth:** send `X-API-Key` / `X-Secret-API-Key` headers (preferred) or `apikey` / `secretapikey` in the JSON body. Create keys at https://porkbun.com/account/api

---

# Endpoints

## GET /api/json/v3/account/autoTopup

**Read auto top-up settings**

What auto top-up is set to, whether a payment method is on file, and what `POST /account/topup` would charge right now (`effectiveAmount`).

Auto top-up is how unattended work stops dead-ending on `INSUFFICIENT_FUNDS`: when an order drops the balance below `threshold`, Porkbun charges the saved payment method for `amount` and adds the credit.

If `paymentMethodOnFile` is false the settings are inert and the response says so in `warnings` — a card can only be saved on the website, never over the API.

Response fields (AutoTopupResponse):

| Field | Type | Description |
|---|---|---|
| `status` | string |  |
| `enabled` | boolean |  |
| `threshold` | integer | Balance in cents below which a top-up fires; null when auto top-up is off. |
| `amount` | integer | Configured amount to add, in cents; null when never set. |
| `effectiveAmount` | integer | What POST /account/topup would charge right now: the configured amount, or the $50 default. |
| `defaultAmount` | integer | The platform default used when the account has configured nothing. |
| `paymentMethodOnFile` | boolean | False means nothing can be charged and auto top-up cannot fire, whatever the settings say. |
| `balance` | integer | Current account credit, in cents. |
| `chargesToday` | integer |  |
| `chargesThisMonth` | integer |  |
| `maxChargesPerDay` | integer |  |
| `maxChargesPerMonth` | integer |  |
| `warnings` | string[] | Advisory. Present when the settings cannot do anything as they stand, e.g. no payment method is saved. |

## POST /api/json/v3/account/autoTopup

**Configure auto top-up**

Set the top-up amount, and/or switch auto top-up on or off.

`amount` stands on its own. It is what a top-up adds, and `POST /account/topup` charges the same figure on demand, so setting it without automating anything is a normal call: `{"amount": 10000}`.

`enabled: true` additionally makes it fire by itself and requires `threshold` (the balance, in integer US cents, below which a top-up happens) plus an amount — either in the same call or already on file. `enabled: false` stops it firing on a threshold and **keeps the amount**, because on-demand top-ups still use it.

**`amount` set over the API is capped at $500** ($5 minimum), because that value is also what `POST /account/topup` charges — an API key free to set it to anything would be setting its own limit, which is not a limit. A larger amount set by the account holder at porkbun.com/account/api is honoured as-is.

No card is touched here, and one cannot be added over the API. Supports `dryRun`.

Request body fields:

| Field | Type | Required | Description |
|---|---|---|---|
| `enabled` | boolean | yes | Turn auto top-up on or off. Omit to change only the amount. |
| `threshold` | integer | no | Balance in integer US cents below which a top-up fires. Required when enabling, and meaningless without it. |
| `amount` | integer | no | What a top-up adds, in integer US cents. Can be sent on its own; required when enabling if none is on file. Over the API: 500-50000. |
| `dryRun` | boolean | no | Validate only; change nothing. |

Response fields (AutoTopupResponse):

| Field | Type | Description |
|---|---|---|
| `status` | string |  |
| `enabled` | boolean |  |
| `threshold` | integer | Balance in cents below which a top-up fires; null when auto top-up is off. |
| `amount` | integer | Configured amount to add, in cents; null when never set. |
| `effectiveAmount` | integer | What POST /account/topup would charge right now: the configured amount, or the $50 default. |
| `defaultAmount` | integer | The platform default used when the account has configured nothing. |
| `paymentMethodOnFile` | boolean | False means nothing can be charged and auto top-up cannot fire, whatever the settings say. |
| `balance` | integer | Current account credit, in cents. |
| `chargesToday` | integer |  |
| `chargesThisMonth` | integer |  |
| `maxChargesPerDay` | integer |  |
| `maxChargesPerMonth` | integer |  |
| `warnings` | string[] | Advisory. Present when the settings cannot do anything as they stand, e.g. no payment method is saved. |

## POST /api/json/v3/account/topup

**Top up account credit now**

**Charges the saved payment method** and adds the money to account credit immediately. The call that unblocks work already in progress: enabling auto top-up does nothing until the next order trips the threshold, which is no help to a caller holding an `INSUFFICIENT_FUNDS` response right now.

**`amount` is optional.** Omitted, it charges the account's configured top-up amount, or $50 if the account has never set one — `amountSource` in the response says which of `configured`, `default` or `request` applied. Supplied, it charges that figure for this call only and leaves the stored setting alone, which is the point: an agent could always have written the amount to `/account/autoTopup` first, and making it do that turns a one-off charge into a silent edit of a setting the customer owns.

The card itself can only be saved outside the API, and a supplied amount is held to the same 500–50000 cent range as one set through `/account/autoTopup`. On top of that the dollars are bounded by the month: the account's **monthly spend limit** caps top-ups as well as domain spend (it is the account saying how much the API may move, and a card charge is the API moving money), and an account that has never set one still gets a $100/month ceiling — `monthlyCeiling` and `ceilingSource` on `GET /account/autoTopup` say which is in force. Top-ups are also limited to 5 per day and 20 per month (`TOPUP_LIMIT_EXCEEDED`), and every successful charge emails the account holder.

Errors that matter: `NO_PAYMENT_METHOD` (nothing saved to charge — the account holder has to save a card or buy credit on the website), `CARD_DECLINED` (nothing was added; the card needs attention), `TOPUP_FAILED` (nothing was charged; retry once).

With a sandbox key this grants simulated credit and charges nothing (`simulated: true`). Supports `dryRun`, which previews the amount and charges nothing in any environment. Honours `Idempotency-Key`.

Request body fields:

| Field | Type | Required | Description |
|---|---|---|---|
| `amount` | integer | no | Optional one-off amount in integer US cents (500-50000). Omit to charge the amount the account has configured, which is the common case. A supplied amount does NOT change the stored setting — use it instead of rewriting the customer's configuration for a single charge. |
| `dryRun` | boolean | no | Preview the charge without making it. |

Response fields:

| Field | Type | Description |
|---|---|---|
| `status` | string |  |
| `charged` | integer | Amount charged, in cents. |
| `chargedDisplay` | string |  |
| `balance` | integer | Account credit balance after the top-up, in cents. |
| `balanceDisplay` | string |  |
| `orderId` | integer | The captured order recorded for the purchase, 0 if order creation failed (the credit is granted either way). |
| `usedDefaultAmount` | boolean | True when the account had no configured amount and the $50 default was charged. |
| `chargesToday` | integer |  |
| `chargesThisMonth` | integer |  |
| `simulated` | boolean | Sandbox only: credit was granted without charging a card. |
| `message` | string |  |

## POST /api/json/v3/account/invite

**Create an account registration invite**

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 — including CAPTCHA, address collection, and TOS acceptance — in the browser. The invite expires in 48 hours. Each token can only be used once.

Optionally supply an `email` to pre-fill the email field on the registration form.

Optionally supply a `returnUrl` (must be HTTPS) to redirect the user back to your platform after they complete registration.

After sending the invite URL, poll `/account/inviteStatus` to check whether the account was created.

Request body fields:

| Field | Type | Required | Description |
|---|---|---|---|
| `email` | string | no | Email address to pre-fill on the registration form (optional) |
| `returnUrl` | string | no | 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. |

```bash
curl -X POST https://api.porkbun.com/api/json/v3/account/invite \
  -H 'Content-Type: application/json' \
  -d '{"apikey":"pk1_...","secretapikey":"sk1_...","email":"newuser@example.com"}'
```

Response fields:

| Field | Type | Description |
|---|---|---|
| `status` | string |  |
| `inviteToken` | string | Opaque token — pass to `/account/inviteStatus` to track completion |
| `inviteUrl` | string | URL to send to the prospective user. Opens Porkbun's standard registration page. |
| `expires` | string | UTC datetime when the invite token expires (48 hours from creation) |

## GET /api/json/v3/account/inviteStatus

**Check account invite status**

Returns the current status of a registration invite created by your API key.

- `PENDING` — the invite URL has not yet been used
- `ACCEPTED` — the user completed registration; `newAccountId` contains their account ID
- `EXPIRED` — the invite was not used within 48 hours or was canceled

You can only query invites created by your own API key. Pass credentials via `X-API-Key` and `X-Secret-API-Key` headers.

| Parameter | In | Required | Description |
|---|---|---|---|
| `token` | query | yes | The `inviteToken` returned by `/account/invite` |
| `X-API-Key` | header | yes | Your API key |
| `X-Secret-API-Key` | header | yes | Your secret API key |

```bash
curl 'https://api.porkbun.com/api/json/v3/account/inviteStatus?token=a3f8c2...' \
  -H 'X-API-Key: pk1_...' \
  -H 'X-Secret-API-Key: sk1_...'
```

Response fields:

| Field | Type | Description |
|---|---|---|
| `status` | string |  |
| `inviteStatus` | string | Current state of the invite |
| `newAccountId` | integer | ID of the newly created account. Present only when `inviteStatus` is `ACCEPTED`. |

## GET /api/json/v3/account/balance

**Get account balance**

Returns the available account credit balance. Authenticate using `X-API-Key` and `X-Secret-API-Key` headers, or `Authorization: Bearer <token>`.

| Parameter | In | Required | Description |
|---|---|---|---|
| `Authorization` | header | no | Bearer token: `Authorization: Bearer <token>` |
| `X-API-Key` | header | no | API key header auth (use with X-Secret-API-Key) |
| `X-Secret-API-Key` | header | no | Secret API key header auth (use with X-API-Key) |

```bash
curl 'https://api.porkbun.com/api/json/v3/account/balance' \
  -H 'X-API-Key: pk1_...' \
  -H 'X-Secret-API-Key: sk1_...'
```

Response fields (BalanceResponse):

| Field | Type | Description |
|---|---|---|
| `status` | string |  |
| `balance` | integer | Available account credit balance in cents. |
| `display` | string | Human-readable balance string (e.g. `$12.34`). |

## GET /api/json/v3/account/invoices

**List invoices**

The account's invoices (one per order), newest first, like the orders page on porkbun.com. `total_cents` is what the customer was left paying: refunds are netted out, and `state` says whether the invoice is paid, refunded or partially refunded. Any of the account's API keys can read them.

| Parameter | In | Required | Description |
|---|---|---|---|
| `Authorization` | header | no | Bearer token: `Authorization: Bearer <token>` |
| `X-API-Key` | header | no | API key header auth (use with X-Secret-API-Key) |
| `X-Secret-API-Key` | header | no | Secret API key header auth (use with X-API-Key) |
| `year` | query | no | Only invoices from this year, e.g. 2026. |
| `start` | query | no | Offset for paging. |
| `limit` | query | no |  |

```bash
curl 'https://api.porkbun.com/api/json/v3/account/invoices?year=2026' \
  -H 'X-API-Key: pk1_...' \
  -H 'X-Secret-API-Key: sk1_...'
```

Response fields:

| Field | Type | Description |
|---|---|---|
| `status` | string |  |
| `invoices` | object[] |  |
| `total` | integer | How many invoices match (for paging). |
| `start` | integer |  |
| `limit` | integer |  |
| `years` | integer[] | Years that have invoices. |

## GET /api/json/v3/account/invoice/{orderId}

**Get an invoice**

One invoice as data: bill-to details, payment method (card brand and last four only), each line with its term and resulting domain expiry, and gross, refunded and net totals. The same figures as the PDF.

| Parameter | In | Required | Description |
|---|---|---|---|
| `Authorization` | header | no | Bearer token: `Authorization: Bearer <token>` |
| `X-API-Key` | header | no | API key header auth (use with X-Secret-API-Key) |
| `X-Secret-API-Key` | header | no | Secret API key header auth (use with X-API-Key) |
| `orderId` | path | yes | Invoice (order) ID, from `GET /account/invoices`. |

```bash
curl 'https://api.porkbun.com/api/json/v3/account/invoice/9913779' \
  -H 'X-API-Key: pk1_...' \
  -H 'X-Secret-API-Key: sk1_...'
```

Response fields:

| Field | Type | Description |
|---|---|---|
| `status` | string |  |
| `invoice` | object |  |

## GET /api/json/v3/account/invoicePdf/{orderId}

**Download an invoice PDF**

The invoice as a PDF, base64-encoded in `contentBase64`: the same document as Download PDF on porkbun.com. Decode it and save it as `filename`.

| Parameter | In | Required | Description |
|---|---|---|---|
| `Authorization` | header | no | Bearer token: `Authorization: Bearer <token>` |
| `X-API-Key` | header | no | API key header auth (use with X-Secret-API-Key) |
| `X-Secret-API-Key` | header | no | Secret API key header auth (use with X-API-Key) |
| `orderId` | path | yes | Invoice (order) ID, from `GET /account/invoices`. |

```bash
curl 'https://api.porkbun.com/api/json/v3/account/invoicePdf/9913779' \
  -H 'X-API-Key: pk1_...' \
  -H 'X-Secret-API-Key: sk1_...'
```

Response fields:

| Field | Type | Description |
|---|---|---|
| `status` | string |  |
| `filename` | string |  |
| `contentType` | string |  |
| `sizeBytes` | integer |  |
| `contentBase64` | string |  |
| `downloadUrl` | string | Downloads the PDF without signing in, for 15 minutes (null on a sandbox key). The link to hand a user. |
| `downloadExpires` | string | When downloadUrl stops working (ISO 8601). |

## GET /api/json/v3/account/apiSettings

**Get API spend settings**

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

| Parameter | In | Required | Description |
|---|---|---|---|
| `Authorization` | header | no | Bearer token: `Authorization: Bearer <token>` |
| `X-API-Key` | header | no | API key header auth (use with X-Secret-API-Key) |
| `X-Secret-API-Key` | header | no | Secret API key header auth (use with X-API-Key) |

```bash
curl 'https://api.porkbun.com/api/json/v3/account/apiSettings' \
  -H 'X-API-Key: pk1_...' \
  -H 'X-Secret-API-Key: sk1_...'
```

Response fields (ApiSettingsResponse):

| Field | Type | Description |
|---|---|---|
| `status` | string |  |
| `settings` | object |  |
| `monthlySpend` | integer | Total API spend in the current calendar month, in cents. |

---

## More

- Guides (how-tos): https://porkbun.com/llms/guides
- Topic index: https://porkbun.com/llms
- Full reference (one file): https://porkbun.com/llms-full.txt
- OpenAPI spec (full schemas): https://porkbun.com/api/json/v3/spec
- Short overview: https://porkbun.com/llms.txt
- Official MCP server: https://porkbun.com/mcp (`npx -y @porkbunllc/mcp-server`)
- Create API keys: https://porkbun.com/account/api
