Skip to main content
The API ordering endpoints let you place orders from your own code, paid directly from your account’s wallet balance. Same product catalogue and the same request shape as the marketing checkout — minus the gateway round-trip.
Both endpoints are admin-grant-only. They’re off by default for every account. Contact support to enable account:api_ordering:write (place orders) and/or account:api_ordering:read (read wallet balance).

Surface

EndpointPermissionWhat it does
POST /v4/account/orders/createaccount:api_ordering:writePlace a wallet-paid order.
GET /v4/account/orders/{orderId}/statusaccount:api_ordering:readPoll an order’s lifecycle and grab the new subaccount once processed.
GET /v4/account/orders/balanceaccount:api_ordering:readRead the wallet balance + currency.
Both accept the same two auth forms as the rest of the Account API — see Authentication:
  • api-token: <your-api-key> — for server-to-server calls.
  • Authorization: Bearer <jwt> — for the dashboard or any signed-in caller.

Place an order

The server forces pay_with_credit=1 and no_redirect=1 server-side — there’s no gateway redirect, the wallet is debited atomically right after the order row is created, and the call returns the new order ID. email, fname, and lname are derived from the authenticated identity. Omit them, or pass them explicitly to override.

Per-product request shapes

Each type accepts a different set of product-specific fields, identical to what the marketing checkout submits.
curl -X POST 'https://api.proxyscrape.com/v4/account/orders/create' \
  -H 'Content-Type: application/json' \
  -H 'api-token: <your-api-key>' \
  -d '{
    "type": "new_datacenter_shared",
    "country": "Belgium",
    "is_subscription": true,
    "days": 30,
    "proxies[mixed]": 1000,
    "bandwidth": 0
  }'
Field notes
  • country — Full country name (e.g. "Belgium"), not the ISO code. VAT is derived from it.
  • proxies[<location>] — Datacenter only. The location is one of mixed, us, gb, de, fr, ca, es, it, br, th. Value is the IP-pool size.
  • bandwidth — Datacenter: 0 means unlimited. Residential: bandwidth pack in GB.
  • duration — Omit for non-expiry residential / SERP packages. Otherwise 30d / 60d / 90d.
  • location — Residential unlimited only. Server-location ID; list them via the dashboard’s Residential Unlimited page.
  • coupon_code (optional) — Applied before any per-account API-ordering percentage discount.

Response

For wallet-credit orders the data field is the bare order ID string:
{ "success": true, "data": "0bc1a40f-2a17-4c84-9b2b-f4b9d3e0b3a1" }
On failure:
{ "success": false, "error": "Missing or invalid pricing configuration." }
Common errors:
StatusErrorWhen
400Missing or invalid pricing configuration.The type + parameter combo doesn’t match a buyable package.
400Insufficient wallet balance.Wallet doesn’t cover the order total at debit time.
401Could not determine account email from authenticated identity.JWT or api-token is invalid.
403API ordering is not enabled for this account. Contact support to request access.Account doesn’t have account:api_ordering:write.

Check order status

POST /v4/account/orders/create returns the order ID synchronously, but the order processor that turns the order into a usable subaccount runs asynchronously. For wallet-paid orders this typically takes well under a second, but it’s not guaranteed. Poll GET /v4/account/orders/{orderId}/status every 1–2 seconds until status === "processed". At that point data.subaccount is populated with the same shape as /v4/account/subaccounts entries — you can drop it straight into per-product endpoints.
curl -X GET 'https://api.proxyscrape.com/v4/account/orders/0bc1a40f-2a17-4c84-9b2b-f4b9d3e0b3a1/status' \
  -H 'api-token: <your-api-key>'
While processing:
{
  "success": true,
  "data": {
    "order_id": "0bc1a40f-2a17-4c84-9b2b-f4b9d3e0b3a1",
    "status": "paid",
    "type": "new_datacenter_shared",
    "created_at": 1717000000,
    "updated_at": 1717000000,
    "price": "26.10",
    "currency": "USD",
    "paid_with_credit": true,
    "subaccount": null
  }
}
Once processed:
{
  "success": true,
  "data": {
    "order_id": "0bc1a40f-2a17-4c84-9b2b-f4b9d3e0b3a1",
    "status": "processed",
    "type": "new_datacenter_shared",
    "created_at": 1717000000,
    "updated_at": 1717000010,
    "price": "26.10",
    "currency": "USD",
    "paid_with_credit": true,
    "subaccount": {
      "AccountID": "9e4d49b0-c999-46f6-aa98-47476a6aef0b",
      "AccountType": "datacenter_shared",
      "label": "Account 8 (Premium)",
      "time_added": 1717000010
    }
  }
}
The AccountID is the value you pass as {subAccountId} to the product endpoints:
GET /v4/account/9e4d49b0-c999-46f6-aa98-47476a6aef0b/datacenter_shared/proxy-list

Sample polling loop

import time
import requests

def wait_for_subaccount(order_id, api_token, *, timeout=30, interval=1.5):
    headers = {'api-token': api_token}
    deadline = time.monotonic() + timeout
    while time.monotonic() < deadline:
        r = requests.get(
            f'https://api.proxyscrape.com/v4/account/orders/{order_id}/status',
            headers=headers,
            timeout=10,
        )
        r.raise_for_status()
        data = r.json()['data']
        if data['status'] == 'processed':
            return data['subaccount']
        if data['status'] in ('blocked', 'failed', 'refunded'):
            raise RuntimeError(f"order rejected: {data.get('block_reason') or data['status']}")
        time.sleep(interval)
    raise TimeoutError(f'order {order_id} did not process within {timeout}s')

Statuses

StatusMeaning
paidWallet was debited; the processor will pick the order up shortly. Keep polling.
processedSubaccount has been created. data.subaccount is populated. Stop polling.
blockedRejected by the fraud / pricing guards. data.block_reason carries the specific cause.
failedProcessing failed. Stop polling and surface support contact.
refundedOrder was refunded (admin action). The subaccount is no longer valid.

Errors

StatusErrorWhen
401Could not determine account email from authenticated identity.JWT or api-token is invalid.
403Reading order status via the API-ordering endpoint is not enabled for this account. Contact support to request access.Account doesn’t have account:api_ordering:read.
404Order not found.Either the ID doesn’t exist, or it belongs to a different account. The endpoint deliberately does not distinguish the two so existence can’t be probed.

Read wallet balance

curl -X GET 'https://api.proxyscrape.com/v4/account/orders/balance' \
  -H 'api-token: <your-api-key>'
{
  "success": true,
  "data": { "balance": 42.50, "currency": "USD" }
}
The endpoint scopes the read to the authenticated identity — a token can only ever read its own wallet.

Coupons and discounts

You can pass a coupon_code field on POST /v4/account/orders/create. The order then applies, in this order:
  1. Coupon code (if any) — percent or fixed amount off the product price.
  2. Per-account API-ordering percentage (if your account has one) — applied on top of the post-coupon price.
Coupons cannot be applied to wallet top-ups; the server rejects the request. If your account has an active API-ordering discount, it shows up in the dashboard playground banner and in the me endpoint’s api_ordering_discount field. The percentage is applied automatically — no flag to set.

Try it in the dashboard

The dashboard hosts a live playground for both endpoints at /account/api-orders. It builds the request body interactively, renders cURL / Python / Node snippets, and runs the request against your real wallet so you can verify everything works end-to-end before wiring it into your code.

Permissions

These two permissions are documented in the permission reference:
  • account:api_ordering:write — required for POST /v4/account/orders/create.
  • account:api_ordering:read — required for GET /v4/account/orders/balance.
Both are admin-grant-only and don’t appear in the standard permissions picker. To enable them on your account, contact support.