Developer Docs

Billing and credits

Billing for developers and AI agents

The dashboard, REST API and MCP tools share your account’s plans and credit wallet. Use this guide to authorize billing, complete payments and confirm changes safely.

Authorization and agent permissions

Use your personal pmcp_ key or an OAuth access token. Personal keys offer Billing access choices None, Read and Manage in Dashboard → API Keys. None grants no billing access; Read permits billing accounts, history and operation reads; Manage permits reads plus payment links, subscription previews or changes, and billing portal sessions. Manage includes Read. This same key setting applies to REST billing endpoints and MCP billing tools, and new personal keys default to None.

OAuth requires api:access for REST or mcp:access for MCP, plus billing:read to read billing data or billing:manage for billing reads and changes. Personal keys have a separate MCP tool setting: All tools grants current and future tools and hides the tool list; Selected tools shows the complete non-billing tool list and allows an explicit selection. Changing a key’s Billing access choice synchronizes the matching billing tools in a selected allowlist. An existing custom allowlist remains as saved until Billing access or the tool selection changes, and calling billing tools still requires the matching billing permission. MCP tool selection does not restrict REST access.

All billing calls cost zero service credits. A successful call can still create or confirm a financial action. Agents must obtain the account owner’s approval of the amount, recurring price and effective date before purchasing or confirming a change. Keep checkout, invoice and portal URLs private to the account owner.

Plans and service credits

Plans include monthly service credits. Free: 100 included credits per month; Developer: 2,500 included credits per month; Startup: 15,000 included credits per month. Credits are usage units, not a cash balance.

Any plan, including Free, can buy $5–$1000 in top-ups without subscribing. Amounts are integer USD cents; each cent buys one credit. Included credits refresh at the start of each UTC calendar month and do not roll over. Purchased credits are separate and do not expire while your account remains active. Included credits are spent first.

ping and get_credit_balance cost 0 credits; describe_website costs 1; contact_website costs 1, or 10 when AI is used. Requests reserve credits before execution. Invalid requests and internal failures before execution release the reservation; an executed external failure may still incur a charge. Check meta.billing and your credit history for the final charge. Credits never bypass contact rate limits.

Use GET /credits or the MCP get_credit_balance tool for spendable balance, including reserved credits. GET /credits/history gives the credit ledger. Billing account credits.totalBalance sums included and purchased balances and can include reserved credits. A plan change adjusts the remaining included allowance while preserving usage already consumed in the current UTC month.

Buy credits or start a subscription

Read get_billing_account first. Call create_credit_top_up with topUpCents and operationKey, or create_subscription_checkout with developer or startup and operationKey. Save data.operation.id and hand data.operation.checkoutUrl to the account owner to complete hosted Stripe Checkout. Card details are collected by Stripe, never as REST or MCP arguments.

Poll get_billing_operation with operationId after checkout. A return to the dashboard or an HTTP success does not prove payment or credit delivery. payment_pending means payment or webhook reconciliation is still underway. Wait for completed and reread get_billing_account or get_credit_balance before relying on the purchased balance.

A new paid plan becomes available only after the subscription is verified as active. To manage an existing subscription, use the preview and change flow. create_billing_portal_session returns data.operation.portalUrl for the account owner’s payment methods and invoices.

Preview and confirm subscription changes

Call preview_subscription_change with action upgrade, downgrade, cancel, resume or keep_current. Supply plan only for upgrade or downgrade. keep_current removes a Pingly-managed scheduled downgrade and keeps the current plan. A pending scheduled downgrade can also be replaced by another downgrade, canceled at renewal, or removed before an immediate upgrade. Review data.preview.fromPlan, toPlan, estimatedAmountCents, effectiveAt, expiresAt and cancelAtPeriodEnd with the account owner. Previews expire after five minutes and cannot be reused for another change.

After approval, call change_subscription with the previewId and a stable operationKey. Upgrades may charge the saved payment method immediately, including prorated amounts; the larger allowance is applied only after successful payment. An upgrade releases a pending scheduled downgrade first. If payment remains pending, the schedule stays removed and the subscription remains on its current plan; after resolving the pending payment, create a fresh preview to cancel or schedule another plan. If data.operation.requiresActionUrl is present, send it to the owner to finish payment authentication.

Downgrades and cancellation take effect at subscription renewal. resume reverses a scheduled cancellation. completed can mean a future change was successfully scheduled; check effectiveAt and account.subscription.pendingChange. A stale or expired preview requires a fresh preview and another review of its amount and date.

Operation status and safe retries

Generate operationKey once for each intended mutation and persist it before sending the request. It must be 8–128 characters using letters, digits, underscores, periods, colons or hyphens. Reuse exactly the same key and arguments after a timeout or retryable error. Changing the key may create another purchase. Reusing a key with different arguments returns BILLING_OPERATION_CONFLICT.

Operation states are processing (request underway), requires_action (owner must use checkoutUrl, portalUrl or requiresActionUrl), payment_pending (waiting for payment or reconciliation), completed (finished or scheduled), failed and expired. Poll by operation ID without repeatedly creating new purchases. Failed or expired operations need review before starting a new intent.

Responses use { ok, data, meta }. Read data.account, data.history, data.operation or data.preview according to the tool. Failures use { ok: false, error: { code, message, retryable }, meta }; preserve meta.requestId for support. In MCP, inspect the returned structuredContent for the same envelope.

BILLING_PERMISSION_REQUIRED (403): grant the required permission. INVALID_REQUEST (400): correct the inputs. BILLING_OPERATION_NOT_FOUND (404): check the account and operation ID. BILLING_OPERATION_IN_PROGRESS or BILLING_OPERATION_CONFLICT (409): inspect the existing operation instead of changing the key. SUBSCRIPTION_PREVIEW_EXPIRED or SUBSCRIPTION_PREVIEW_STALE (409): create and review a fresh preview. RATE_LIMITED (429): pause before another attempt. BILLING_RECONCILIATION_REQUIRED (409): stop and contact support; do not bypass it with a new key. For retryable service errors, back off and reuse the original key.

Sandbox and live payments

Read data.account.mode: test means Stripe sandbox, live means real payments, and null means billing is unavailable. Test payments move no real money. Test and live customers, subscriptions and billing operations are separate; a sandbox subscription is not a live subscription. Never infer the payment mode from the website hostname.

In sandbox, PinglyMCP automatically prepares a saved test card and billing details for hosted Checkout. Review the test-mode banner and complete checkout yourself. If Stripe requests fallback card entry, use 4242 4242 4242 4242, any future expiry, any three-digit CVC and any postal code. Never use real card details in sandbox or test card details in live mode. Card fields remain on Stripe’s hosted page.

Before enabling live payments, the owner should verify a sandbox top-up, subscription checkout, invoice, upgrade, downgrade and cancellation, then confirm the balance and operation status. The credit wallet is shared across payment modes: reconcile sandbox-generated credits and plan allowances before switching to live. Switching payment mode is an operator action; agents cannot enable live payments with a billing tool.

REST and MCP billing reference

GET arguments use query parameters; replace :id with operationId for operation reads. POST arguments use a JSON body. MCP tools use the same named arguments. Each card below uses the shared service catalog. For MCP examples, open the MCP billing reference.

Get billing account

GET/billingRead-only · uses credits

Read your subscription and credits. Requires billing:read. Costs 0 credits.

Try it live

Sign in to select an account key. Creating a key will take you through sign in.

Request JSON
{}
Live REST request
curl 'https://api.pinglymcp.com/billing' \
  -H "Authorization: Bearer $PINGLYMCP_API_KEY"

Get billing history

GET/billing/historyRead-only · uses credits

Read purchases, invoices and refunds. Requires billing:read. Costs 0 credits.

Try it live

Sign in to select an account key. Creating a key will take you through sign in.

Optional parameters

Maximum number of records.

Pagination cursor returned by the previous response.

Request JSON
{}
Live REST request
limitnumber

Optional

Maximum number of records.

cursorstring

Optional

Pagination cursor returned by the previous response.

curl 'https://api.pinglymcp.com/billing/history?limit=20' \
  -H "Authorization: Bearer $PINGLYMCP_API_KEY"

Create credit top-up

POST/billing/top-upsExternal action · confirm first

Create a hosted payment link to buy credits. Payment must complete before credits are granted. Requires billing:manage. Costs 0 service credits.

Try it live

Sign in to select an account key. Creating a key will take you through sign in.

Required parameters

USD cents to spend, from 500 ($5) to 100000 ($1,000). Each cent buys one credit.

A unique key for this operation. Reuse the same key and arguments when retrying.

Request JSON
{
  "topUpCents": 500,
  "operationKey": "purchase-2026-09-27-001"
}
Live REST request
topUpCentsnumber

Required

USD cents to spend, from 500 ($5) to 100000 ($1,000). Each cent buys one credit.

operationKeystring

Required

A unique key for this operation. Reuse the same key and arguments when retrying.

curl -X POST https://api.pinglymcp.com/billing/top-ups \
  -H "Authorization: Bearer $PINGLYMCP_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"topUpCents":500,"operationKey":"purchase-2026-09-27-001"}'

Get billing operation

GET/billing/operations/:idRead-only · uses credits

Check whether a billing operation requires payment, is pending, or has completed. Requires billing:read. Costs 0 credits.

Try it live

Sign in to select an account key. Creating a key will take you through sign in.

Required parameters

The operation ID returned when the operation was created.

Request JSON
{
  "operationId": "billing_operation_id"
}
Live REST request
operationIdstring

Required

The operation ID returned when the operation was created.

curl 'https://api.pinglymcp.com/billing/operations/billing_operation_id' \
  -H "Authorization: Bearer $PINGLYMCP_API_KEY"

Create subscription checkout

POST/billing/subscriptions/checkoutExternal action · confirm first

Create a hosted payment link for a new subscription. Requires billing:manage. Costs 0 service credits.

Try it live

Sign in to select an account key. Creating a key will take you through sign in.

Required parameters

The paid subscription plan.

A unique key for this operation. Reuse the same key and arguments when retrying.

Request JSON
{
  "plan": "developer",
  "operationKey": "purchase-2026-09-27-001"
}
Live REST request
plandeveloper | startup

Required

The paid subscription plan.

operationKeystring

Required

A unique key for this operation. Reuse the same key and arguments when retrying.

curl -X POST https://api.pinglymcp.com/billing/subscriptions/checkout \
  -H "Authorization: Bearer $PINGLYMCP_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"plan":"developer","operationKey":"purchase-2026-09-27-001"}'

Preview subscription change

POST/billing/subscriptions/previewRead-only · uses credits

Preview an upgrade, downgrade, cancellation at renewal, reversal of cancellation, or removal of a scheduled downgrade while keeping the current plan. Upgrades require successful payment; downgrades apply at renewal. Requires billing:manage. Costs 0 credits.

Try it live

Sign in to select an account key. Creating a key will take you through sign in.

Required parameters

The proposed subscription change.

Optional parameters

Required for an upgrade or downgrade; omit for cancel, resume, or keep_current.

Request JSON
{
  "action": "upgrade"
}
Live REST request
actionupgrade | downgrade | cancel | resume | keep_current

Required

The proposed subscription change.

plandeveloper | startup

Optional

Required for an upgrade or downgrade; omit for cancel, resume, or keep_current.

curl -X POST https://api.pinglymcp.com/billing/subscriptions/preview \
  -H "Authorization: Bearer $PINGLYMCP_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"action":"upgrade","plan":"developer"}'

Change subscription

POST/billing/subscriptions/changeExternal action · confirm first

Confirm an unexpired preview. May charge the saved payment method for an upgrade. Review the preview before calling. Requires billing:manage. Costs 0 service credits.

Try it live

Sign in to select an account key. Creating a key will take you through sign in.

Required parameters

The unexpired preview ID to confirm.

A unique key for this operation. Reuse the same key and arguments when retrying.

Request JSON
{
  "previewId": "billing_preview_id",
  "operationKey": "purchase-2026-09-27-001"
}
Live REST request
previewIdstring

Required

The unexpired preview ID to confirm.

operationKeystring

Required

A unique key for this operation. Reuse the same key and arguments when retrying.

curl -X POST https://api.pinglymcp.com/billing/subscriptions/change \
  -H "Authorization: Bearer $PINGLYMCP_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"previewId":"billing_preview_id","operationKey":"purchase-2026-09-27-001"}'

Create billing portal session

POST/billing/portalRead-only · uses credits

Create a private hosted link for payment methods and invoices. Share it only with the account owner. Requires billing:manage. Costs 0 credits.

Try it live

Sign in to select an account key. Creating a key will take you through sign in.

Required parameters

A unique key for this operation. Reuse the same key and arguments when retrying.

Request JSON
{
  "operationKey": "purchase-2026-09-27-001"
}
Live REST request
operationKeystring

Required

A unique key for this operation. Reuse the same key and arguments when retrying.

curl -X POST https://api.pinglymcp.com/billing/portal \
  -H "Authorization: Bearer $PINGLYMCP_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"operationKey":"purchase-2026-09-27-001"}'