ProxioDocs
API Reference

Wallet

Read your Proxio wallet balance with GET /wallet, fund it with POST /wallet/topups (a 201 is a payment link, not money), and page through the transaction ledger with GET /wallet/transactions, filterable by type and date range, sortable by created_at or amount.

Your wallet is the balance that pays for orders and renewals. These endpoints read the current balance, fund it, and read the full transaction ledger.

Scope: read to read the balance, transactions, and top-ups; purchase to open a top-up.

Balance

GET /wallet returns the current balance.

curl https://dashboard.proxio.net/api/v1/wallet \
  -H "Authorization: Bearer pxo_9fJ2kQ7xR4mN8pL1dW6vB3cH5tZ0aYqS7dK2mN9x"
import requests

BASE = "https://dashboard.proxio.net/api/v1"
API_KEY = "pxo_9fJ2kQ7xR4mN8pL1dW6vB3cH5tZ0aYqS7dK2mN9x"

resp = requests.get(
    f"{BASE}/wallet",
    headers={"Authorization": f"Bearer {API_KEY}"},
    timeout=15,
)
resp.raise_for_status()
print(resp.json()["data"]["balance"])
const BASE = "https://dashboard.proxio.net/api/v1"
const API_KEY = "pxo_9fJ2kQ7xR4mN8pL1dW6vB3cH5tZ0aYqS7dK2mN9x"

const res = await fetch(`${BASE}/wallet`, {
  headers: { Authorization: `Bearer ${API_KEY}` },
})
console.log((await res.json()).data.balance)

200 response:

{
  "data": { "currency": "USD", "balance": "42.50" },
  "meta": { "request_id": "req_8Ke2jP4mQ" }
}

Top-ups

Funding a wallet from the API, so an unattended pipeline that hits INSUFFICIENT_BALANCE can refill itself instead of stopping dead.

Scope: purchase to create, read to list and read back.

A 201 here is a payment link, not money

Creating a top-up returns a provider-hosted payment link, it does not take card details and it does not credit anything. meta.funded is false on every creation response, always, for exactly this reason: a 201 means the link was minted, not that the balance moved. The balance changes only when the payment provider confirms the payment, and wallet.topup_completed is how a pipeline learns it can spend, poll GET /wallet/topups/{id} or subscribe to that event rather than assuming a 201 means funded.

Top up the wallet

POST /wallet/topups opens a hosted checkout. Requires the purchase scope and a required Idempotency-Key (same requirement as POST /orders): retrying with the same key returns the identical link rather than opening a second one.

Body

FieldTypeNotes
amountnumberRequired. 1 to 10,000 USD on this endpoint (the dashboard's own top-up form allows a wider range, this is the API's own ceiling).
currencystringOptional. USD is the only supported value today; anything else fails validation.
payment_methodstringOptional. card or crypto. Omit it to let Proxio pick (card first, then crypto) from what's currently available.
curl -X POST https://dashboard.proxio.net/api/v1/wallet/topups \
  -H "Authorization: Bearer pxo_9fJ2kQ7xR4mN8pL1dW6vB3cH5tZ0aYqS7dK2mN9x" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{ "amount": 25, "payment_method": "card" }'
import uuid
import requests

BASE = "https://dashboard.proxio.net/api/v1"
API_KEY = "pxo_9fJ2kQ7xR4mN8pL1dW6vB3cH5tZ0aYqS7dK2mN9x"

resp = requests.post(
    f"{BASE}/wallet/topups",
    headers={
        "Authorization": f"Bearer {API_KEY}",
        "Idempotency-Key": str(uuid.uuid4()),
    },
    json={"amount": 25, "payment_method": "card"},
    timeout=15,
)
resp.raise_for_status()
topup = resp.json()["data"]
print(topup["payment_url"])  # open this, it's not returned again
import { randomUUID } from "node:crypto"

const BASE = "https://dashboard.proxio.net/api/v1"
const API_KEY = "pxo_9fJ2kQ7xR4mN8pL1dW6vB3cH5tZ0aYqS7dK2mN9x"

const res = await fetch(`${BASE}/wallet/topups`, {
  method: "POST",
  headers: {
    Authorization: `Bearer ${API_KEY}`,
    "Content-Type": "application/json",
    "Idempotency-Key": randomUUID(),
  },
  body: JSON.stringify({ amount: 25, payment_method: "card" }),
})
const topup = (await res.json()).data
console.log(topup.payment_url) // open this, it's not returned again

201 response:

{
  "data": {
    "id": "cltop_4n7q3x",
    "status": "pending",
    "amount": "25.00",
    "currency": "USD",
    "payment_method": "card",
    "payment_url": "https://checkout.example.com/pay/cs_9fJ2kQ7xR4mN8pL1dW6vB3cH5tZ0aY",
    "created_at": "2026-08-20T13:30:00.000Z"
  },
  "meta": { "funded": false, "request_id": "req_8Ke2jP4mQ" }
}

payment_url is shown exactly once

Like the webhook signing secret and a credential's password, payment_url rides only this response. Neither GET /wallet/topups nor GET /wallet/topups/{id} ever include it again, there's nowhere it's stored to resurrect it from. Keep the URL you get back, or, if you lost the response before the customer paid, replay the create with the same Idempotency-Key to get it again rather than opening a second checkout.

A provider that refuses or times out opening the checkout returns UPSTREAM_ERROR (502); the idempotency key cannot be reused, so retry with a fresh one. No payment method currently available for API top-ups returns SERVICE_UNAVAILABLE (503).

List top-ups

GET /wallet/topups returns your top-up history, cursor-paginated, newest first. payment_url is absent on every row here, see the callout above.

Query parameters

ParameterValuesNotes
statuspending, completed, failed, refundedOptional, case-insensitive. Any other value fails with VALIDATION_ERROR rather than being ignored, so an empty page means you have no top-ups in that state.
limit, cursorsee Pagination
curl "https://dashboard.proxio.net/api/v1/wallet/topups?status=completed&limit=20" \
  -H "Authorization: Bearer pxo_9fJ2kQ7xR4mN8pL1dW6vB3cH5tZ0aYqS7dK2mN9x"
import requests

BASE = "https://dashboard.proxio.net/api/v1"
API_KEY = "pxo_9fJ2kQ7xR4mN8pL1dW6vB3cH5tZ0aYqS7dK2mN9x"

resp = requests.get(
    f"{BASE}/wallet/topups",
    headers={"Authorization": f"Bearer {API_KEY}"},
    params={"status": "completed", "limit": 20},
    timeout=15,
)
resp.raise_for_status()
print(resp.json()["data"])
const BASE = "https://dashboard.proxio.net/api/v1"
const API_KEY = "pxo_9fJ2kQ7xR4mN8pL1dW6vB3cH5tZ0aYqS7dK2mN9x"

const res = await fetch(`${BASE}/wallet/topups?status=completed&limit=20`, {
  headers: { Authorization: `Bearer ${API_KEY}` },
})
console.log((await res.json()).data)
{
  "data": [
    {
      "id": "cltop_4n7q3x",
      "status": "completed",
      "amount": "25.00",
      "currency": "USD",
      "payment_method": "card",
      "created_at": "2026-08-20T13:30:00.000Z"
    }
  ],
  "meta": { "next_cursor": null, "has_more": false, "request_id": "req_8Ke2jP4mQ" }
}

status covers four states an unattended caller actually needs to branch on: pending (opened, not yet resolved, this also covers a payment the provider has authorized but not yet captured), completed (the balance moved), failed (it won't complete, open a new one), and refunded.

Read back a top-up

GET /wallet/topups/{id} returns a single top-up, the same shape as a list row (no payment_url). This is the endpoint an unattended pipeline polls after creating a top-up, until status is completed.

curl https://dashboard.proxio.net/api/v1/wallet/topups/cltop_4n7q3x \
  -H "Authorization: Bearer pxo_9fJ2kQ7xR4mN8pL1dW6vB3cH5tZ0aYqS7dK2mN9x"
import requests

BASE = "https://dashboard.proxio.net/api/v1"
API_KEY = "pxo_9fJ2kQ7xR4mN8pL1dW6vB3cH5tZ0aYqS7dK2mN9x"

resp = requests.get(
    f"{BASE}/wallet/topups/cltop_4n7q3x",
    headers={"Authorization": f"Bearer {API_KEY}"},
    timeout=15,
)
resp.raise_for_status()
print(resp.json()["data"]["status"])
const BASE = "https://dashboard.proxio.net/api/v1"
const API_KEY = "pxo_9fJ2kQ7xR4mN8pL1dW6vB3cH5tZ0aYqS7dK2mN9x"

const res = await fetch(`${BASE}/wallet/topups/cltop_4n7q3x`, {
  headers: { Authorization: `Bearer ${API_KEY}` },
})
console.log((await res.json()).data.status)

A top-up id that isn't yours, or never existed, returns NOT_FOUND.

Transactions

GET /wallet/transactions returns the ledger, newest first, cursor-paginated.

Query parameters

ParameterValuesDefaultNotes
typeone or more of the transaction types below, comma-separated-e.g. type=DEBIT_ORDER or type=TOPUP,REFUND. An unrecognized value fails with VALIDATION_ERROR naming it.
created_after, created_beforeISO 8601 timestamps-Both inclusive. An unparseable value, or a created_before earlier than created_after, fails validation.
sortcreated_at | amountcreated_atamount is signed, so order=desc reads largest credit first and order=asc reads largest debit first.
orderasc | descdesc
limit, cursorsee Pagination

A cursor is tied to the sort it was issued under

Changing sort or order partway through a paginated walk invalidates the cursor you're holding: the next page fails with INVALID_CURSOR rather than silently skipping or repeating rows. Restart from cursor-less page one under the new sort/order instead of trying to resume. See Pagination for why.

curl "https://dashboard.proxio.net/api/v1/wallet/transactions?limit=20" \
  -H "Authorization: Bearer pxo_9fJ2kQ7xR4mN8pL1dW6vB3cH5tZ0aYqS7dK2mN9x"
import requests

BASE = "https://dashboard.proxio.net/api/v1"
API_KEY = "pxo_9fJ2kQ7xR4mN8pL1dW6vB3cH5tZ0aYqS7dK2mN9x"

resp = requests.get(
    f"{BASE}/wallet/transactions",
    headers={"Authorization": f"Bearer {API_KEY}"},
    params={"limit": 20},
    timeout=15,
)
resp.raise_for_status()
body = resp.json()
for txn in body["data"]:
    print(txn["type"], txn["amount"], txn["balance_after"])
print("next:", body["meta"]["next_cursor"])
const BASE = "https://dashboard.proxio.net/api/v1"
const API_KEY = "pxo_9fJ2kQ7xR4mN8pL1dW6vB3cH5tZ0aYqS7dK2mN9x"

const res = await fetch(`${BASE}/wallet/transactions?limit=20`, {
  headers: { Authorization: `Bearer ${API_KEY}` },
})
const body = await res.json()
for (const txn of body.data) {
  console.log(txn.type, txn.amount, txn.balance_after)
}
console.log("next:", body.meta.next_cursor)

200 response:

{
  "data": [
    {
      "id": "cltxn_5a1b",
      "type": "DEBIT_ORDER",
      "amount": "-12.50",
      "balance_after": "42.50",
      "related_order_id": "clord_9f2a",
      "note": "Order clord_9f2a",
      "created_at": "2026-07-16T10:00:00.000Z"
    }
  ],
  "meta": { "next_cursor": null, "has_more": false, "request_id": "req_8Ke2jP4mQ" }
}

Transaction types

TypeMeaningAmount sign
TOPUPFunds added to the wallet.Positive
DEBIT_ORDERAn order or renewal charge.Negative
REFUNDFunds returned.Positive
ADJUSTMENTA manual correction.Positive or negative

amount and balance_after are signed decimal strings. Parse them with a decimal type; a DEBIT_ORDER links back to its order via related_order_id.

On this page