Concepts
Idempotency
A network can fail after a request arrives but before you hear back. An idempotency key makes the retry safe.
Send idempotency_key on a POST, and a retry of the same request returns the first
response instead of acting twice. It works on every endpoint, not only the ones that
list it, and it is ignored on GET.
The key is scoped to your API key, the method, the path and the parameters, so the same
value on a different request does not collide. Reusing a key with different parameters
is 422 idempotency_key_reused_with_different_parameters; retrying while the first
request is still running is 409 request_in_progress. A replayed response carries
Idempotent-Replay: true. Server errors and 429 answers are never stored, so a retry
after one of those runs for real.
Use it on everything that moves money: /api/transaction/create, /api/user/withdraw
and /api/user/exchange.
Example
Use one key per logical operation. An order or invoice id works well, because a retry of the same order then reuses it on its own.
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);
A 409 request_in_progress means the first attempt is still running: wait and retry with the same key. A 422 with a different payload is a bug in the caller, not a reason to pick a new key.