API reference
Transactions
A transaction is one request for payment. Create it with your key, send the buyer to its checkout, and it settles on its own. Webhooks tell you when.
Create a transaction
/api/transaction/createCreates a pending transaction and returns the id the checkout uses plus a
private_key that is both the cancellation credential and the webhook signing
secret. private_key is returned exactly once here — store it.
A transaction expires 24 hours after it is created; that is not configurable.
The amount is checked in USD: it must be worth at least 0.1 USD and at most
1,000,000 USD. If the rate that check needs is stale, the request fails with
503 rate_unavailable rather than pricing off an old number.
Parameters
amountdecimal stringPrice, denominated in
currency. Omit for an open-ended transaction. Must be greater than zero and must not exceed the currency'stheoreticalprecision.currencycurrency codeDenomination of
amount— not what the buyer pays in. Required wheneveramountis sent.allowed_payment_methodscomma-separatedComma-separated allowlist restricting what the buyer may choose. Every entry must exist in the seller's
payment_methods. Maximum 25 entries.webhookURLEvent destination.
Up to 2,048 characters.http/httpsonly, no embedded credentials, and the host must resolve to a public address.deposit0 or 11creates a deposit transaction —amountandcurrencyare forced to null and settled funds land as a deposit rather than revenue.idempotency_keystringMakes a retry safe. Scoped to (your key, method, path, sorted parameters, this value). Honoured on POST/PUT/PATCH/DELETE only; ignored on GET. Server errors and 429s are never cached.
Returns
201 Created. Transaction created.
3 attributes
transaction_iduidprivate_keyuidReturned exactly once. Cancellation credential and webhook signing secret.
expiresunix time
Errors
parameter_missing400A required parameter is missing or empty. Also the answer when no API key is sent at all.
parameter_invalid400A parameter is present but fails validation.
currency_not_found400The currency code does not exist, or has no usable rate.
request_in_progress409A request with the same
idempotency_keyis still running.transaction_amount_must_be_over_{limit}_{currency}422The transaction is worth less than the minimum. The slug names the limit, as in
transaction_amount_must_be_over_0.1_usd; match on the prefix.transaction_amount_must_be_under_{limit}_{currency}422The transaction is worth more than the maximum. Match on the prefix.
invalid_payment_method422That method is not allowed on this transaction, or is not on your account.
idempotency_key_reused_with_different_parameters422That
idempotency_keywas already used for a request with different parameters.rate_unavailable503A price feed is stale, so the request is refused rather than priced off an old rate. Retry shortly.
curl https://anonpay.org/api/transaction/create \
-H "Authorization: Bearer $APA_KEY" \
-d amount=20 \
-d currency=usd \
-d allowed_payment_methods=btc,xmr,usdt-erc20 \
-d webhook=https://seller.example/hooks/apa \
-d idempotency_key=2c9a4e7b-8d1f-4a6cimport os
import requests
KEY = os.environ["APA_KEY"]
response = requests.post(
"https://anonpay.org/api/transaction/create",
headers={"Authorization": f"Bearer {KEY}"},
data={
"amount": "20",
"currency": "usd",
"allowed_payment_methods": "btc,xmr,usdt-erc20",
"webhook": "https://seller.example/hooks/apa",
"idempotency_key": "2c9a4e7b-8d1f-4a6c",
},
timeout=30,
)
print(response.json())const url = "https://anonpay.org/api/transaction/create";
const response = await fetch(url, {
method: "POST",
headers: { Authorization: `Bearer ${process.env.APA_KEY}` },
body: new URLSearchParams({
amount: "20",
currency: "usd",
allowed_payment_methods: "btc,xmr,usdt-erc20",
webhook: "https://seller.example/hooks/apa",
idempotency_key: "2c9a4e7b-8d1f-4a6c",
}),
});
console.log(await response.json());$url = 'https://anonpay.org/api/transaction/create';
$key = getenv("APA_KEY");
$ch = curl_init($url);
curl_setopt_array($ch, [
CURLOPT_HTTPHEADER => ["Authorization: Bearer $key"],
CURLOPT_POSTFIELDS => http_build_query([
"amount" => '20',
"currency" => 'usd',
"allowed_payment_methods" => 'btc,xmr,usdt-erc20',
"webhook" => 'https://seller.example/hooks/apa',
"idempotency_key" => '2c9a4e7b-8d1f-4a6c',
]),
CURLOPT_RETURNTRANSFER => true,
]);
$response = json_decode(curl_exec($ch), true);
{
"status": "success",
"transaction_id": "9c1f0b7a4e2d8f6a3b5c7d9e1f0a2b4c",
"private_key": "a3f9d0e1c2b4a6f8e0d2c4b6a8f0e2d4",
"expires": 1754006400
}
Choose how the buyer pays
/api/transaction/setpaymentmethodCalled by the checkout once the buyer picks a payment method. Returns the payment instructions: a fresh receiving address for crypto, or one of the seller's enabled PayPal accounts. You only need it if you build your own checkout.
Works without a key, because the buyer holds none, and is limited to 60 requests per minute per IP.
A method can be chosen once per transaction: a second call is
409 payment_method_already_set. Calling it on an expired transaction marks the
transaction expired.
Parameters
transaction_iduidRequiredpayment_methodstringRequiredA currency code (
btc,usdt-trc20, …) orppl.
Returns
200 OK. Payment instructions for the buyer.
1 attributes
paymentobject-
10 child attributes
addressstringReceiving address, or PayPal email.
currencystringWhat the buyer actually pays in.
topaydecimal stringQuoted at the currency's
practicalprecision, rounded up so the seller is never short-changed.paiddecimal stringObserved so far. Updated by the settlement job.
ratedecimal stringtransaction-currency → payment-currency, locked in at mint time.
confirmationsinteger or nullCrypto only.
-1means nothing observed yet.confirmations_neededinteger or nullCrypto only.
overpaiddecimal stringPresent only when the buyer paid more than
topay.gsbooleanPayPal only — Goods & Services accepted.
ffbooleanPayPal only — Friends & Family accepted.
Errors
parameter_invalid400A parameter is present but fails validation.
uid_not_found404No transaction or withdrawal with that id.
payment_method_already_set409A payment method was already chosen for this transaction.
transaction_inactive409The transaction is no longer pending.
invalid_payment_method422That method is not allowed on this transaction, or is not on your account.
disabled_payment_method422The seller has switched that payment method off.
payment_method_unavailable422The platform has paused or retired that payment method.
no_active_paypal_account422No PayPal account is enabled to receive the payment.
transaction_amount_must_be_over_{limit}_{currency}422The transaction is worth less than the minimum. The slug names the limit, as in
transaction_amount_must_be_over_0.1_usd; match on the prefix.rate_unavailable503A price feed is stale, so the request is refused rather than priced off an old rate. Retry shortly.
node_unavailable503The node for that currency is unreachable. Retry shortly.
curl https://anonpay.org/api/transaction/setpaymentmethod \
-d transaction_id=9c1f0b7a4e2d8f6a3b5c7d9e1f0a2b4c \
-d payment_method=btcimport requests
response = requests.post(
"https://anonpay.org/api/transaction/setpaymentmethod",
data={
"transaction_id": "9c1f0b7a4e2d8f6a3b5c7d9e1f0a2b4c",
"payment_method": "btc",
},
timeout=30,
)
print(response.json())const url = "https://anonpay.org/api/transaction/setpaymentmethod";
const response = await fetch(url, {
method: "POST",
body: new URLSearchParams({
transaction_id: "9c1f0b7a4e2d8f6a3b5c7d9e1f0a2b4c",
payment_method: "btc",
}),
});
console.log(await response.json());$url = 'https://anonpay.org/api/transaction/setpaymentmethod';
$ch = curl_init($url);
curl_setopt_array($ch, [
CURLOPT_POSTFIELDS => http_build_query([
"transaction_id" => '9c1f0b7a4e2d8f6a3b5c7d9e1f0a2b4c',
"payment_method" => 'btc',
]),
CURLOPT_RETURNTRANSFER => true,
]);
$response = json_decode(curl_exec($ch), true);
{
"status": "success",
"payment": {
"address": "bc1qar0srrr7xfkvy5l643lydnw9re59gtzzwf5mdq",
"currency": "btc",
"topay": "0.00021",
"paid": "0",
"rate": "0.0000105",
"confirmations": -1,
"confirmations_needed": 6
}
}
{
"status": "success",
"payment": {
"address": "[email protected]",
"currency": "usd",
"topay": "20.00",
"paid": "0",
"rate": "1",
"gs": true,
"ff": false
}
}
Cancel a pending transaction
/api/transaction/cancelRequires proof of ownership: your API key, or the transaction's private_key.
Anything else is 403 not_permitted.
Cancelling is final — nothing revisits a cancelled transaction, so funds already sent to the minted address will not settle. Cancel only what is known to be unpaid.
Parameters
transaction_iduidRequiredprivate_keyuidThe transaction's private key. An alternative to authenticating with the seller's API key — this is the credential the buyer-facing checkout holds.
Returns
200 OK. Success.
Errors
not_permitted403Authenticated, but the object belongs to someone else, or
current_passwordwas missing or wrong.uid_not_found404No transaction or withdrawal with that id.
transaction_inactive409The transaction is no longer pending.
transaction_already_completed409The transaction has already completed.
curl https://anonpay.org/api/transaction/cancel \
-H "Authorization: Bearer $APA_KEY" \
-d transaction_id=9c1f0b7a4e2d8f6a3b5c7d9e1f0a2b4cimport os
import requests
KEY = os.environ["APA_KEY"]
response = requests.post(
"https://anonpay.org/api/transaction/cancel",
headers={"Authorization": f"Bearer {KEY}"},
data={
"transaction_id": "9c1f0b7a4e2d8f6a3b5c7d9e1f0a2b4c",
},
timeout=30,
)
print(response.json())const url = "https://anonpay.org/api/transaction/cancel";
const response = await fetch(url, {
method: "POST",
headers: { Authorization: `Bearer ${process.env.APA_KEY}` },
body: new URLSearchParams({
transaction_id: "9c1f0b7a4e2d8f6a3b5c7d9e1f0a2b4c",
}),
});
console.log(await response.json());$url = 'https://anonpay.org/api/transaction/cancel';
$key = getenv("APA_KEY");
$ch = curl_init($url);
curl_setopt_array($ch, [
CURLOPT_HTTPHEADER => ["Authorization: Bearer $key"],
CURLOPT_POSTFIELDS => http_build_query([
"transaction_id" => '9c1f0b7a4e2d8f6a3b5c7d9e1f0a2b4c',
]),
CURLOPT_RETURNTRANSFER => true,
]);
$response = json_decode(curl_exec($ch), true);
{
"status": "success"
}
Fetch a transaction
/api/transaction/infoWithout a key, or with a key belonging to a different seller, returns the public
view. With the owning seller's key the response also carries private_key and
webhook.
A valid but unrelated seller key is not an error — it simply yields the public view.
Parameters
transaction_iduidRequired
Returns
200 OK. The transaction. The public view without the owning seller's key; with it, the response adds private_key and webhook.
1 attributes
transactionobject-
16 child attributes
uiduidThe transaction's id. Its checkout is at
/checkout/{uid}.seller_iduidThe seller it belongs to.
statusstring-
pending- Waiting for payment. Every transaction starts here.
completed- Paid in full and confirmed. A
completedwebhook was sent. cancelled- Cancelled with the seller's key or the transaction's private key. Final.
expired- 24 hours passed without full payment.
amount_topaydecimal string or nullThe price, in
currency. Null for open-ended and deposit transactions.amount_paiddecimal string or nullReceived so far, expressed in
currency.currencystring or nullThe unit of
amount_topay.allowed_payment_methodsarray of strings or nullThe method codes the buyer may choose from. Null means every method you enabled.
payment_methodstring or nullNull until the buyer chooses.
createdunix timeexpiresunix time24 hours after
created.cancelledunix time or nullcompletedunix time or nullis_depositinteger1for a top-up of your own balance.01paymentobject or nullWhat the buyer pays, and where. Null until a method is chosen.
10 child attributes
addressstringReceiving address, or PayPal email.
currencystringWhat the buyer actually pays in.
topaydecimal stringQuoted at the currency's
practicalprecision, rounded up so the seller is never short-changed.paiddecimal stringObserved so far. Updated by the settlement job.
ratedecimal stringtransaction-currency → payment-currency, locked in at mint time.
confirmationsinteger or nullCrypto only.
-1means nothing observed yet.confirmations_neededinteger or nullCrypto only.
overpaiddecimal stringPresent only when the buyer paid more than
topay.gsbooleanPayPal only — Goods & Services accepted.
ffbooleanPayPal only — Friends & Family accepted.
private_keyuidYour key onlyCancellation credential and webhook signing secret.
webhookstring or nullYour key onlyWhere this transaction's events are sent.
Errors
uid_not_found404No transaction or withdrawal with that id.
curl https://anonpay.org/api/transaction/info \
-H "Authorization: Bearer $APA_KEY" \
-d transaction_id=9c1f0b7a4e2d8f6a3b5c7d9e1f0a2b4cimport os
import requests
KEY = os.environ["APA_KEY"]
response = requests.post(
"https://anonpay.org/api/transaction/info",
headers={"Authorization": f"Bearer {KEY}"},
data={
"transaction_id": "9c1f0b7a4e2d8f6a3b5c7d9e1f0a2b4c",
},
timeout=30,
)
print(response.json())const url = "https://anonpay.org/api/transaction/info";
const response = await fetch(url, {
method: "POST",
headers: { Authorization: `Bearer ${process.env.APA_KEY}` },
body: new URLSearchParams({
transaction_id: "9c1f0b7a4e2d8f6a3b5c7d9e1f0a2b4c",
}),
});
console.log(await response.json());$url = 'https://anonpay.org/api/transaction/info';
$key = getenv("APA_KEY");
$ch = curl_init($url);
curl_setopt_array($ch, [
CURLOPT_HTTPHEADER => ["Authorization: Bearer $key"],
CURLOPT_POSTFIELDS => http_build_query([
"transaction_id" => '9c1f0b7a4e2d8f6a3b5c7d9e1f0a2b4c',
]),
CURLOPT_RETURNTRANSFER => true,
]);
$response = json_decode(curl_exec($ch), true);
{
"status": "success",
"transaction": {
"uid": "9c1f0b7a4e2d8f6a3b5c7d9e1f0a2b4c",
"seller_id": "4b8e2d0f6a1c3e5b7d9f0a2c4e6b8d0f",
"status": "completed",
"amount_topay": "20",
"amount_paid": "20",
"currency": "usd",
"allowed_payment_methods": [
"btc",
"xmr",
"usdt-erc20"
],
"payment_method": "btc",
"created": 1753919400,
"expires": 1754005800,
"cancelled": null,
"completed": 1753920000,
"is_deposit": 0,
"payment": {
"address": "bc1qar0srrr7xfkvy5l643lydnw9re59gtzzwf5mdq",
"currency": "btc",
"topay": "0.00021",
"paid": "0.00021",
"rate": "0.0000105",
"confirmations": 6,
"confirmations_needed": 6
},
"private_key": "a3f9d0e1c2b4a6f8e0d2c4b6a8f0e2d4",
"webhook": "https://seller.example/hooks/apa"
}
}