Guides

Withdrawals

Send money from your balance to an external address, and know when it has left.

How it works

Debits the balance and queues a payout. The debit, the ledger entry and the withdrawal record commit together or not at all, under a row lock on the balance.

type amount means Charged Recipient receives
standard the amount to debit amount amount − withdrawal_fee
payment what the recipient must receive amount + network_fee + withdrawal_fee amount

withdrawal_fee comes from the seller's plan. network_fee is a fixed absolute amount converted into the withdrawal currency — 1 USD for xmr, 4 USD otherwise.

The minimum (0.1 USD) is checked against amount_charged, not amount.

private_key in the response is the webhook signing secret for this withdrawal.

Send an idempotency_key.

Request
curl https://anonpay.org/api/user/withdraw \
  -H "Authorization: Bearer $APA_KEY" \
  -d user_id=4b8e2d0f6a1c3e5b7d9f0a2c4e6b8d0f \
  -d currency=btc \
  -d amount=0.0153 \
  -d recipient_address=bc1q9h7garjf3p8rk5tjz7w8a4v3gmn2zd7xkq8fy6 \
  -d idempotency_key=2c9a4e7b-8d1f-4a6c
import os
import requests

KEY = os.environ["APA_KEY"]

response = requests.post(
    "https://anonpay.org/api/user/withdraw",
    headers={"Authorization": f"Bearer {KEY}"},
    data={
        "user_id": "4b8e2d0f6a1c3e5b7d9f0a2c4e6b8d0f",
        "currency": "btc",
        "amount": "0.0153",
        "recipient_address": "bc1q9h7garjf3p8rk5tjz7w8a4v3gmn2zd7xkq8fy6",
        "idempotency_key": "2c9a4e7b-8d1f-4a6c",
    },
    timeout=30,
)
print(response.json())
const url = "https://anonpay.org/api/user/withdraw";

const response = await fetch(url, {
  method: "POST",
  headers: { Authorization: `Bearer ${process.env.APA_KEY}` },
  body: new URLSearchParams({
    user_id: "4b8e2d0f6a1c3e5b7d9f0a2c4e6b8d0f",
    currency: "btc",
    amount: "0.0153",
    recipient_address: "bc1q9h7garjf3p8rk5tjz7w8a4v3gmn2zd7xkq8fy6",
    idempotency_key: "2c9a4e7b-8d1f-4a6c",
  }),
});
console.log(await response.json());
$url = 'https://anonpay.org/api/user/withdraw';
$key = getenv("APA_KEY");

$ch = curl_init($url);
curl_setopt_array($ch, [
    CURLOPT_HTTPHEADER => ["Authorization: Bearer $key"],
    CURLOPT_POSTFIELDS => http_build_query([
        "user_id" => '4b8e2d0f6a1c3e5b7d9f0a2c4e6b8d0f',
        "currency" => 'btc',
        "amount" => '0.0153',
        "recipient_address" => 'bc1q9h7garjf3p8rk5tjz7w8a4v3gmn2zd7xkq8fy6',
        "idempotency_key" => '2c9a4e7b-8d1f-4a6c',
    ]),
    CURLOPT_RETURNTRANSFER => true,
]);
$response = json_decode(curl_exec($ch), true);

What you can withdraw

Only the actual part of a balance can leave. credit, such as a reward or the registration bonus, pays fees and nothing else. Per-currency balances returns both.

Statuses

pending
Queued. Nothing has been sent yet.
submitted
Handed to the payout node, which owns the retries.
completed
Broadcast. crypto_transaction_id is set.
failed
Definitely not sent.
needs_review
Outcome unknown. Verify on-chain before acting; it is never retried automatically.
refunded
Reversed back to your balance.
needs_review means look before you act

The payout may or may not have been broadcast. Check the chain before doing anything, and never request the same payout again until you know.

The webhook

Pass webhook and we send withdrawal.completed once the payout is broadcast, with its crypto_transaction_id. It is signed with the private_key from the withdrawal's own response, not a transaction's, and verified exactly as in Webhooks.