PapaProxy.net API
The PapaProxy.net REST API exposes the same operations as the Dashboard: price quotes, orders, IP top-ups, proxy credentials, IP whitelisting, rotating-proxy sessions, wallet, support tickets, and webhooks.
https://papaproxy.net/account_newAuthentication
Pass an API key as a bearer token:
Authorization: Bearer <api_key>
Create and revoke keys in the Dashboard under Settings → API keys (papaproxy.net/account_new/settings#api-keys). The /api/v1/customers/me/api-keys endpoints work only in a signed-in Dashboard session: an API key can't list, create, or revoke keys, so a leaked key can't be used to issue new ones. Each key has an explicit set of scopes. A request made with a key that lacks the scope an endpoint requires fails with 403; a missing, malformed, revoked, or expired key fails with 401.
A few endpoints work without a key: GET /api/v1/billing/countries, GET /api/v1/billing/composite/pricing-info, POST /api/v1/billing/composite/auto-plan, POST /api/v1/billing/composite/quote, GET /api/v1/billing/dedicated/countries, and POST /api/v1/billing/dedicated/quote.
Scopes
Each API key has an explicit set of scopes, chosen when you create the key. Every endpoint in this reference and every MCP tool lists the scope it requires, and a request with a key that lacks it fails with 403. Scopes work the same way for the REST API and the MCP server.
| Scope | What it allows |
|---|---|
catalog:read | Products, countries, stock, and prices. Countries, pricing terms, and quotes also work without a key. |
services:read | Your services, proxy IPs, credentials, IP whitelisting, refresh status, and add-ons |
services:write | Orders, renewals, cancellation, auto-renewal, credentials, IP whitelisting and connection limits, IP refresh, add-ons, and sticky sessions |
usage:read | Usage statistics and analytics |
wallet:read | Balance, transactions, invoices, and payment methods |
wallet:deposit | Start a balance top-up, get a checkout URL, and track its status |
wallet:spend | Pay from your balance: purchases, renewals, add-ons, extra IPs, and paid IP refreshes |
tickets:read | Read support tickets |
tickets:write | Open, reply to, and close tickets |
customer:read | Profile details and login history |
customer:write | Update profile details |
webhooks | Manage webhook endpoints and deliveries |
Typical key setups for monitoring and provisioning: papaproxy.net/developers.php#scopes
Conventions
- Money is always an integer number of cents (USD). Fields ending in
_millicentsare thousandths of a cent:220000millicents is $2.20. - Countries in requests are ISO 3166-1 alpha-2 codes (
DE,GB,US). Proxy-package endpoints also accept the numeric country ID fromGET /api/v1/billing/countries; dedicated-proxy endpoints accept ISO codes only. - In proxy-package responses,
countryis the numeric country ID andcountry_codeis the ISO code. - Timestamps are ISO 8601 in UTC.
- Requests that charge your wallet need the
wallet:spendscope in addition toservices:write. A key withoutwallet:spendcan read, quote, and configure, but its paid requests fail with403. - Requests that charge your wallet confirm the price you showed the user (
expected_price_centsorexpected_total_cents). If the price is missing or has changed, the request fails and nothing is charged. - Endpoints that charge your wallet take an idempotency key; see Idempotency below.
Order minimums
- Proxy packages (datacenter and ISP proxies,
/api/v1/billing/composite/*): at least 100 IPs per order and at least 10 IPs per country. Adding IPs to a package follows the same rule: at least 100 IPs per request, at least 10 per country.GET /api/v1/billing/composite/pricing-inforeturns these values asmin_ips_per_orderandmin_ips_per_segment. - Dedicated proxies (
/api/v1/billing/dedicated/*): from 1 IP per order, and from 1 IP when you add IPs to a dedicated service. - An order, auto-plan, or quote with fewer than 100 IPs in total fails with
422. A quote with a country below 10 IPs still returns200: that country is listed inerrorsand left out ofsegmentsand the total. Always checkerrorsbefore you place the order.
Errors
Every error response is JSON with a detail field. Check the HTTP status first, then read detail, which is either a string or an object:
{"detail": "Invalid or revoked API key."}
{"detail": {"error": "PRICE_CHANGED", "expected_price_cents": 1, "actual_price_cents": 3}}When detail is an object, the machine-readable code is in detail.error (proxy-package orders, add-ons, service cancellation) or in detail.code (dedicated proxies, IP refresh). Schema validation errors return 422 with {"detail": "Validation error"} and don't name the field, so compare the request with the field table of the endpoint.
400— the request can't be completed in the current state: an unknown add-on type or a missing add-on parameter, a reply to a closed ticket, or insufficient balance for a renewal.401— the API key is missing, malformed, revoked, or expired, or the account is inactive. The response includesWWW-Authenticate: Bearer.402— insufficient wallet balance when adding IPs or buying an add-on. Nothing is charged.403— the API key lacks the required scope, or a top-up needs identity verification.404— the resource doesn't exist or doesn't belong to your account.409— the price wasn't confirmed or has changed, stock ran out, or a cancellation cooldown is active. Nothing is charged.422— a validation error or a business rule: order minimums, a required whitelisted IP, an invalid promo code.429— rate limit exceeded; see Rate limits.501— the operation isn't supported for this service.5xx— a temporary server error (500returns{"detail": "Internal server error"};503means the service is briefly unavailable). Retry after a few seconds with backoff, using the same idempotency key.
The MCP server doesn't return HTTP status codes to your agent: a failed tool call comes back as error text with a short code and an explanation, for example insufficient_pool: … Nothing was charged.
Rate limits
- Each account can make up to 60 requests per minute (a rolling window). All API keys of the account and the MCP server share this limit.
- Requests are also limited per source IP address, including requests without a key, and short bursts are limited separately. Spread requests evenly rather than sending them in bursts.
- A limited request returns
429with{"detail": "Too Many Requests"}. Wait and retry with exponential backoff (for example, 2, 4, 8 seconds); nothing is charged for a rejected request. - Each response includes an
X-Request-Idheader. Include it when you contact support about a specific request.
Testing
There's no sandbox or test mode: every order, top-up, renewal, and add-on charges your real wallet balance. To build and test an integration without spending money:
- Use quotes (
POST /api/v1/billing/composite/quote,POST /api/v1/billing/dedicated/quote), which never charge and work without an API key. - Test webhook handling with
POST /api/v1/customer/webhooks/{endpoint_id}/test, which sends apingevent. - Give a key only the scopes it needs, and keep keys that can spend money out of test environments.
Webhooks
Webhook deliveries are POST requests with a compact JSON body:
{"id": "3f1c2a9e-8b7d-4e6f-9a01-2c5d7e8f9b10", "type": "service.renewed", "created_at": "2026-11-09T13:16:07.181118Z", "data": {…}}id is the event ID, type is the event type, created_at is in UTC, and data depends on the event type. Each delivery carries these headers:
X-FB-Signature—v1=followed by the hex-encoded HMAC-SHA256 signature.X-FB-Timestamp— the Unix time (seconds) when the delivery was signed.X-FB-Event-Id— the event ID. It stays the same when a delivery is retried or redelivered.X-FB-Event-Type— the event type.
To verify a delivery, compute HMAC-SHA256 over {X-FB-Timestamp}.{raw body} with the endpoint's full signing secret, including the whsec_ prefix, as the key, and compare the hex digest with the value after v1=. Use the raw request bytes, not re-serialized JSON:
import hashlib, hmac, time
def verify(secret: str, body: bytes, timestamp: str, signature: str) -> bool:
if abs(time.time() - int(timestamp)) > 300:
return False
digest = hmac.new(secret.encode(), timestamp.encode() + b"." + body, hashlib.sha256).hexdigest()
return hmac.compare_digest("v1=" + digest, signature)- Reject deliveries whose timestamp is more than 5 minutes from your server's time, and skip event IDs you've already processed. Retries are signed again with a new timestamp.
- Respond with any
2xxstatus within 10 seconds. Other statuses, timeouts, and redirects (3xxisn't followed) count as failures. - A failed delivery is retried 5 more times: after 1 minute, 5 minutes, 30 minutes, 2 hours, and 6 hours. After that it's marked as failed; you can send it again with the redeliver endpoint.
- After 20 consecutive failed deliveries, the endpoint is disabled automatically and
disabled_reasonexplains why. A successful delivery resets the counter. - The URL must be a public
httpsaddress; private and internal addresses are rejected. - Deliveries don't come from a fixed set of IP addresses, so verify the signature instead of whitelisting sender IPs.
- Event types:
payment.succeeded,payment.failed,deposit.completed,service.provisioned,service.renewed,service.expiring,service.suspended,service.terminated, andwallet.balance_low.GET /api/v1/customer/webhooks/eventsreturns the current list.pingis sent only by the test endpoint and can't be subscribed to.
Pagination
List endpoints return results in pages. Pass offset (how many items to skip) and limit (page size: 50 by default) as query parameters, and keep increasing offset by limit until a page comes back with fewer items than limit.
GET /api/v1/customer/wallet/ledger— List wallet transactions (limitup to 200)GET /api/v1/customer/catalog— List products (limitup to 100)GET /api/v1/customer/services— List your services (limitup to 100)GET /api/v1/customer/tickets— List support tickets
Idempotency
The endpoints below take an idempotency key — idempotency_key in the request body unless noted otherwise. If a request times out or the connection drops, retry it with the same key and the same body: you get the result of the original request, and you aren't charged twice. Use a new key for each new purchase. Without a key, a repeated request is processed again.
POST /api/v1/billing/composite/order— Place an orderPOST /api/v1/billing/services/{service_id}/add-ips— Add IPs to a service (required)POST /api/v1/billing/services/{service_id}/addons— Buy an add-on (required)POST /api/v1/customer/wallet/deposit/init— Top up your walletPOST /api/v1/customer/services/{service_id}/renew— Renew a servicePOST /api/v1/customer/services/{service_id}/proxy/refresh— Refresh proxy IPs (required)POST /api/v1/billing/dedicated/order— Order dedicated proxies (in theIdempotency-Keyheader, required)
MCP tools
The MCP server at https://papaproxy.net/account_new/api/v1/mcp gives AI agents 56 tools for your account. They use the same API keys, scopes, and rate limit as the REST API. Most tools call one of the endpoints in this reference; tools marked MCP only have no REST endpoint. To connect Cursor, Claude Code, VS Code, or another client, see papaproxy.net/developers.php#mcp.
- Charges your balance: the tool requires
wallet:spendand takes the price you confirmed (expected_total_cents,expected_price_cents, or a similar field). If the price has changed, nothing is charged. - Needs confirmation: the tool cancels something immediately and runs only with
confirm: true. An agent should ask you before it sets this.
Catalog and pricing
| Tool | What it does | Scopes | REST endpoint |
|---|---|---|---|
list_countries | Countries available for proxy-package orders, with live IP stock and the minimum order size. Agents call it first when buying proxies. | catalog:read | GETList available countries |
get_pricing_info | Pricing terms for proxy packages: volume tiers, term discounts, and order minimums. | catalog:read | GETGet pricing terms |
plan_composite | Distribute a total IP count across available countries in proportion to stock. Doesn't charge anything. | catalog:read | POSTDistribute IPs across countries |
quote_composite | Price a country mix and term for a proxy package. Quotes are free and don't reserve IPs. | catalog:read | POSTGet a price quote |
list_catalog | Fixed-price products. The list is often empty: proxies are sold through quotes and orders. | catalog:read | GETList products |
Orders
| Tool | What it does | Scopes | REST endpoint |
|---|---|---|---|
order_composite | Buy a proxy package from your balance, with a price guard (expected_total_cents) and an idempotency key. Charges your balance | services:write, wallet:spend | POSTPlace an order |
add_ips | Add IPs to an active proxy package or dedicated proxy service. You pay the prorated cost for the remaining term. Charges your balance | services:write, wallet:spend | POSTAdd IPs to a service |
buy_service | Buy a fixed-price product from list_catalog. Charges your balance | services:write, wallet:spend | POSTBuy a service |
Dedicated proxies
| Tool | What it does | Scopes | REST endpoint |
|---|---|---|---|
quote_dedicated | Price a dedicated-proxy order, including add-ons and a promo code, and see how many IPs are available per country. | catalog:read | POSTGet a dedicated-proxy quote |
order_dedicated | Buy dedicated proxies from your balance, with a price guard and an idempotency key. Charges your balance | services:write, wallet:spend | POSTOrder dedicated proxies |
Services
| Tool | What it does | Scopes | REST endpoint |
|---|---|---|---|
list_services | Your services with status and expiration date. | services:read | GETList your services |
get_service | Full details of one service: status, expiration, parameters, and the price it renews at. | services:read | GETGet a service |
renew_service | Renew a service for more billing periods from your balance. This is also how a service suspended for non-payment gets its access back. Charges your balance | services:write, wallet:spend | POSTRenew a service |
set_auto_renew | Turn auto-renewal on or off. With auto-renewal off, the service expires at the end of the paid period and isn't charged again. | services:write | MCP only |
cancel_service | Cancel a service immediately. Unused paid time is refunded to your balance on a prorated basis. Needs confirmation | services:write | POSTCancel a service |
get_usage | Traffic and request statistics for one service over a time window. | usage:read | GETGet usage statistics |
get_import_shortfall_status | For services transferred from the previous Dashboard: check whether the service has fewer IPs than its plan includes. | services:read | MCP only |
quote_import_shortfall_restore | Preview restoring the missing IPs of a transferred service: availability per country. Doesn't change anything. | services:read | MCP only |
restore_import_shortfall | Restore the missing IPs of a transferred service at no charge. | services:write | MCP only |
Proxy access
| Tool | What it does | Scopes | REST endpoint |
|---|---|---|---|
list_proxy_ips | The proxy IPs allocated to a service. | services:read | GETList proxy IPs |
get_proxy_credentials | Proxy username and password. The password is returned in plain text only with reveal: true. | services:read | GETGet proxy credentials |
rotate_proxy_credentials | Change the proxy username or password. The new password is returned once, so store it right away. | services:write | PUTChange proxy credentials |
get_whitelist | Whitelisted IPs of a service, with per-IP connection limits. | services:read | GETList whitelisted IPs |
add_whitelist_ip | Add one IPv4 address to IP whitelisting (no CIDR ranges). | services:write | POSTAdd a whitelisted IP |
remove_whitelist_ip | Remove an IP from IP whitelisting. The last IP of a service can't be removed; replace it instead. | services:write | DELETERemove a whitelisted IP |
replace_whitelist_ip | Swap one whitelisted IP for another in a single step, without a free slot and without a gap in access. | services:write | MCP only |
update_whitelist_limits | Split the service's concurrent connections between whitelisted IPs. The limits must add up to the service total. | services:write | MCP only |
get_refresh_status | Whether the next IP refresh is free, and its price if it isn't. | services:read | GETCheck IP refresh cost |
quote_refresh | Preview an IP refresh: price and availability per country. Doesn't charge or change anything. | services:read | MCP only |
refresh_ips | Replace specific IPs or the whole list, optionally in other countries. The refresh in each free period costs nothing; off-cycle refreshes are paid. Charges your balance | services:write, wallet:spend | POSTRefresh proxy IPs |
Rotating sessions
| Tool | What it does | Scopes | REST endpoint |
|---|---|---|---|
get_proxy_config | Gateway hostnames and ports (HTTP, HTTPS, SOCKS5) of a rotating-proxy service, with sample connection strings. | services:read | GETGet rotating gateway settings |
Add-ons
| Tool | What it does | Scopes | REST endpoint |
|---|---|---|---|
list_available_addons | Add-ons you can buy for a service, with prices. | services:read | GETList available add-ons |
list_active_addons | Add-ons active on a service. | services:read | GETList active add-ons |
purchase_addon | Buy an add-on from your balance, with a price guard (expected_price_cents). Charges your balance | services:write, wallet:spend | POSTBuy an add-on |
disable_addon | Cancel an add-on. The unused part is refunded to your balance on a prorated basis. Needs confirmation | services:write | DELETECancel an add-on |
Analytics
| Tool | What it does | Scopes | REST endpoint |
|---|---|---|---|
get_usage_overview | Usage summary: requests and bytes, success rate, latency percentiles, and errors. For all services or one. | usage:read | MCP only |
get_usage_timeseries | Success rate and latency by hour or day. | usage:read | MCP only |
get_top_destinations | Top destination domains or IPs by request count. | usage:read | MCP only |
get_diagnostics | Why requests fail: HTTP status codes and errors by category (network, DNS, timeout, upstream, authentication, client). | usage:read | MCP only |
get_recommendations | Rule-based recommendations: approaching limits, high error rates, unused IPs. | usage:read | MCP only |
Wallet
| Tool | What it does | Scopes | REST endpoint |
|---|---|---|---|
wallet_balance | Your balance in cents. | wallet:read | GETGet wallet balance |
list_ledger | Balance transactions, newest first. | wallet:read | GETList wallet transactions |
list_invoices | Your invoices, newest first. Each has a PDF link you can download with the same API key. | wallet:read | MCP only |
get_invoice | One invoice with its PDF link. | wallet:read | MCP only |
list_payment_gateways | Payment methods available for topping up your balance. | wallet:read | MCP only |
init_deposit | Start a top-up and get a checkout URL to pay. Your balance is credited after the payment processor confirms the payment. | wallet:deposit | POSTTop up your wallet |
get_deposit_status | Status of a top-up. | wallet:deposit | MCP only |
list_payments | Top-up attempts, including pending and abandoned ones. | wallet:deposit | MCP only |
Account
| Tool | What it does | Scopes | REST endpoint |
|---|---|---|---|
get_profile | Your profile: email, name, verification status, and language. | customer:read | GETGet your profile |
get_my_ip | The IP the request comes from. Over MCP, that's the machine running the agent, which may not be your IP. | customer:read | MCP only |
get_access_log | Login history of your account. | customer:read | MCP only |
Support tickets
| Tool | What it does | Scopes | REST endpoint |
|---|---|---|---|
list_tickets | Your support tickets, newest first. | tickets:read | GETList support tickets |
get_ticket | One ticket with its full conversation. | tickets:read | GETGet a support ticket |
create_ticket | Open a ticket, optionally linked to a service. | tickets:write | POSTOpen a support ticket |
reply_ticket | Reply to an open ticket. | tickets:write | POSTReply to a support ticket |
close_ticket | Close a ticket. | tickets:write | MCP only |
REST only
These endpoints have no MCP tool and work only over REST:
- API keys: List API keys · Create an API key · Revoke an API key
- Orders: Quote additional IPs
- Account: Update your profile
- Catalog and pricing: Get a product
- Wallet: Download an invoice (PDF)
- Rotating sessions: List sticky sessions · Rotate a sticky session · End a sticky session · End all sticky sessions · Get session mode · Set session mode · Get sticky session duration · Set sticky session duration · Reset sticky session duration
- Webhooks: List webhook event types · List webhook endpoints · Create a webhook endpoint · Get a webhook endpoint · Update a webhook endpoint · Delete a webhook endpoint · List webhook deliveries · Send a test event · Redeliver an event
- Dedicated proxies: List dedicated-proxy countries
Endpoints
62 operations in 12 groups.
Last updated: November 10, 2026. Generated from the OpenAPI 3.1 specification (API version 0.1.0). Markdown version for AI agents.