API Reference

API Reference

MethodEndpointAuthPurpose
POST/session/depositoperator keyCreate a deposit session → widget URL. Body: externalUserId, lang, platformFiatCurrency, userBalance, amount (+ optional email, operatorReference, redirectUrl). See Deposits for return URL rules.
POST/session/withdrawoperator keyCreate a withdraw session → widget URL (201). Required: externalUserId, lang, platformFiatCurrency, userBalance, amount; optional: email, operatorReference. For executionMode:"HEADLESS", operatorReference, address, chainId and tokenAddress are additionally required; it returns sessionRef + expiry, not a widget URL.
POST/session/:uuid/test-webhookoperator keySelf-service test: fire a real, signed completion webhook for one of your sessions at your own webhookUrl — no funds move. See note
POST/depositor/addresssession (sid)Get the deposit address — body: sid, currency, chainId
GET/chainpublicList networks + token contracts/decimals
POST/withdraw/direct-transfersession (sid)Initiate a withdrawal
POST/withdraw/:id/decisionoperator keyApprove / reject a withdrawal (external-approval mode)
GET/withdraw/optionsoperator keyHeadless: supported chains/tokens + availability in token units (AVAILABLE/UNAVAILABLE/UNKNOWN). Optional ?sessionRef= for a final pre-execute check
POST/withdrawals/:sessionRef/executeoperator keyHeadless: bodyless, idempotent — reserve, price and queue settlement → 202
GET/withdrawals/:sessionRefoperator keyHeadless: safe status — domain status, tx-hash/confirmation state, retryability, callback state
POST/withdrawals/:sessionRef/canceloperator keyHeadless: cancel — succeeds only before a tx hash exists; releases the reservation
GET/admin/withdrawalsadmin (dashboard-only)List withdrawals (management panel)
PATCH/admin/withdrawals/:id/statusadmin (dashboard-only)Approve / reject a withdrawal
POST/admin/withdrawals/:id/retryadmin (dashboard-only)Headless: safe requeue of a WAITING_FOR_GAS / FAILED(retryable) payout with no tx hash — bodyless; never re-broadcasts

POST /session/deposit accepts an optional redirectUrl, for example "https://cashier.example.com/deposit/return?order=order-123". For a new session it overrides the operator panel's return address; omit it or send null for the panel fallback. It must be a browser-parseable absolute HTTP(S) URL without credentials or literal NUL (U+0000) characters, at most 2048 characters (localhost allowed); invalid values, including an empty string, return 400. The domain does not need to match the panel default. The supplied URL is stored unchanged. Reusing operatorReference preserves the first session's return URL.

The full-page widget uses it on Close/dismiss, setting status=success or status=cancelled, reserializing query parameters with standard browser URL handling and retaining the fragment; iframe hosts handle the close event instead. Navigation does not guarantee byte-for-byte query preservation: %20 can become +, and invalid UTF-8 query bytes such as %FF become %EF%BF%BD. Use valid UTF-8 query values; do not rely on the original raw query encoding for signed return URLs. The signed webhook, not the redirect status, is authoritative for crediting. This does not change operator settings, webhook delivery or the withdrawal request contract. Full example and behavior: Deposits.

POST /depositor/address is session-scoped: it is authenticated by the sid in the request body (called by the hosted widget), and takes no Bearer key. It requires the body fields sid, currency, and chainId.

POST /withdraw/:id/decision is operator-authenticated with your OPERATOR_SECRET_KEY (Bearer) — used only when your operator is on external-approval mode. :id is the withdrawal UUID from the async WITHDRAW_REQUEST webhook; body: { "decision": "APPROVE" | "REJECT", "reason"?: string }. See Withdrawals → External approval. Unlike the /admin/* endpoints, this one is partner-callable with your operator key.

POST /session/:uuid/test-webhook fires a real, signed webhook at your own webhookUrl without moving funds, so you can verify your integration end-to-end. Authenticate with your OPERATOR_SECRET_KEY (Bearer); :uuid is the session UUID (the sid returned when you created the session). The payload is identical to a production DEPOSIT / WITHDRAW_COMPLETE event apart from an extra test: "true" field, and delivery is synchronous, so the response carries your endpoint's real result:

{ "status": "success", "data": { "delivered": true, "status": 200, "event": "DEPOSIT" } }

Optional body overrides: { "amount", "currency", "chainId", "address" }. Scoped to your own operator (and sub-operators); rate-limited to 5/minute. Your handler must check test === "true" and skip all real ledger side effects. Full guide: Webhooks → Testing Your Integration.

The headless withdrawal endpoints (/withdraw/options, /withdrawals/:sessionRef/execute, /withdrawals/:sessionRef, /withdrawals/:sessionRef/cancel) are operator-authenticated with your OPERATOR_SECRET_KEY (Bearer), scoped to your own operator, and available only when the AbstraPay team has enabled headless for you (otherwise HEADLESS_NOT_ENABLED). They are keyed on the sessionRef returned by POST /session/withdraw when you pass executionMode:"HEADLESS" — that call returns { sessionRef, expiresAt }, not a sid or widget URL. execute takes no body and is idempotent (safe to retry; never a second reservation or payout). Full walk-through: Withdrawals → Mode C — Headless. Scope: EVM / ERC-20 only.

Headless execute enforces the owning operator's panel single-withdrawal and rolling-24h daily caps atomically with acceptance, shared with legacy payouts and active reservations of any age. Unset headless caps are unlimited; create/options do not reserve capacity, and accepted replays/retries do not consume it again. Rejections are 400 WITHDRAW_AMOUNT_TOO_HIGH, 400 DAILY_LIMIT_EXCEEDED or 409 WITHDRAW_CAP_UNVERIFIABLE, with no price/reservation/job writes. See operator withdrawal limits for currency and daily-window rules.

The /admin/* endpoints are dashboard/admin-only — used internally by the management panel under a separate admin login. They are not partner-callable with your OPERATOR_SECRET_KEY. POST /admin/withdrawals/:id/retry is a safe recovery action for headless payouts: it only requeues a WAITING_FOR_GAS or FAILED(retryable) request that has no transaction hash, is bodyless, and never broadcasts on-chain from the HTTP request.