Skip to content

Idempotency

Retry any request safely with an Idempotency-Key header.

Send an Idempotency-Key header with any POST to make it safe to retry. Use a new random value, such as a UUID, for each operation.

  • A successful response, any 2xx, is kept for 24 hours. A retry with the same key, method, path and body returns it again, with Idempotent-Replayed: true.
  • An error isn't kept. It frees the key, so you can fix the request and send it again with the same key.
  • With a secret key or a session, the same key with a different method, path or body returns 409 idempotency_key_reused.
  • A retry while the first request is still running returns 409 idempotency_key_in_use. Wait a moment and try again.
  • A key is 1 to 255 characters, or the request returns 400 invalid_request.
  • Keys are kept per business, so they never collide with another business's. A request made without a key or session, like a checkout page's POST /checkouts, is kept by its key and its body together: a retry with both replays from any network, and the same key with a different body is a new request rather than a 409, so use a new random value for each operation.

Where it's required or ignored

  • POST /checkouts, POST /payments/{id}/request-remainder and POST /wallet/transactions require a key, and answer 400 idempotency_key_required without one.
  • Only POST uses it. PATCH and DELETE ignore the header: a repeated PATCH sets the same values again, and a repeated DELETE answers 404 once the object is gone.
  • A POST whose response carries a secret ignores it too, so a replay never hands the secret out again: POST /webhooks and POST /webhooks/{id}/rotate-secret. A retried POST /webhooks adds a second endpoint, so list your endpoints before you try again.
Creating a payment without a key is safe to retry only when you send a reference: a retry with the same reference, amount and currency returns the payment the first request made. Without a reference, send an Idempotency-Key, or a retry makes a second payment.
Request a remainder
curl -X POST "https://api.402pay.co/api/v1/payments/pmt_uYs2XjkL1jGJt44v/request-remainder" \
  -H "Authorization: Bearer $PAY402_SECRET_KEY" \
  -H "Idempotency-Key: $(uuidgen)"
Response201 Created
{
  "data": {
    "kind": "remainder_request",
    "payment": {
      "id": "pmt_uYs2XjkL1jGJt44v",
      "kind": "payment",
      "status": "underpaid",
      "amount": "199.00",
      "currency": "USD",
      "fee_payer": "business",
      "customer_fee": "0.00",
      "amount_received": "179.10",
      "reporting": {
        "currency": "USD",
        "amount": "199.00",
        "fee": "0.00",
        "transaction_fee": "0.00",
        "customer_fee": "0.00",
        "net": "0.00"
      },
      "fee_rate_bps": 0,
      "method": {
        "rail": "crypto",
        "asset": "USDC",
        "network": "ethereum",
        "amount": "179.10",
        "expected_amount": "199.00",
        "overpaid_amount": null,
        "from_address": "0xd2554462b44e258265af12a7d051e47bda66e5b6",
        "tx_hash": "0x1d346f1e2fdd7e6a7bdd4d0193dba2a938dfdb7beef4fab2669d55fef2607812",
        "explorer_url": "https://etherscan.io/tx/0x1d346f1e2fdd7e6a7bdd4d0193dba2a938dfdb7beef4fab2669d55fef2607812"
      },
      "settlement": {
        "destination": "wallet",
        "asset": "USDC",
        "network": "ethereum",
        "amount": "179.10",
        "wallet_id": "wal_1fIGZOrILmsCO0jw",
        "address": "0x7Ba69aE8cEf2987739F6E70e903F95a5028e3531",
        "tx_hash": "0x1d346f1e2fdd7e6a7bdd4d0193dba2a938dfdb7beef4fab2669d55fef2607812",
        "explorer_url": "https://etherscan.io/tx/0x1d346f1e2fdd7e6a7bdd4d0193dba2a938dfdb7beef4fab2669d55fef2607812"
      },
      "customer_id": "cst_gWFWcc7Ga0Pv7LSC",
      "link_id": "lnk_nt842tPNne3lf0ka",
      "url": null,
      "reference": null,
      "metadata": {},
      "success_url": null,
      "cancel_url": null,
      "expires_at": null,
      "canceled_at": null,
      "checkout_id": "chk_OuPmQnhYyQqpp2qZ",
      "description": "Team plan, monthly",
      "country": "US",
      "failure_code": null,
      "failure_message": null,
      "confirmed_at": null,
      "created_at": "2026-09-26T21:22:47.055Z",
      "updated_at": "2026-09-26T21:38:24.275Z",
      "events": [
        {
          "type": "created",
          "created_at": "2026-09-26T21:22:47.055Z",
          "data": null
        },
        {
          "type": "method_selected",
          "created_at": "2026-09-26T21:22:47.055Z",
          "data": {
            "rail": "crypto",
            "asset": "USDC",
            "network": "ethereum"
          }
        },
        {
          "type": "detected",
          "created_at": "2026-09-26T21:22:47.069Z",
          "data": {
            "amount": "179.10",
            "network": "ethereum",
            "tx_hash": "0x1d346f1e2fdd7e6a7bdd4d0193dba2a938dfdb7beef4fab2669d55fef2607812"
          }
        },
        {
          "type": "underpaid",
          "created_at": "2026-09-26T21:22:47.069Z",
          "data": {
            "expected": "199.00",
            "received": "179.10"
          }
        },
        {
          "type": "expired",
          "created_at": "2026-09-26T21:37:47.069Z",
          "data": null
        },
        {
          "type": "remainder_requested",
          "created_at": "2026-09-26T21:38:24.275Z",
          "data": {
            "checkout_id": "chk_XKOWx49himYIAnet",
            "amount": "19.90",
            "currency": "USD"
          }
        }
      ]
    },
    "checkout": {
      "id": "chk_XKOWx49himYIAnet",
      "kind": "checkout",
      "status": "open",
      "rail": "crypto",
      "link_id": "lnk_nt842tPNne3lf0ka",
      "payment_id": "pmt_uYs2XjkL1jGJt44v",
      "amount": "19.90",
      "currency": "USD",
      "breakdown": {
        "currency": "USD",
        "price": "19.90",
        "processing_fee": null,
        "network_fee": "0.90",
        "total": "20.80"
      },
      "crypto": {
        "asset": "USDC",
        "network": "ethereum",
        "amount": "19.90",
        "address": "0xb5C513376614F24fBf807B8c2B1FA3fD1E637A52",
        "payment_uri": "ethereum:0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48@1/transfer?address=0xb5C513376614F24fBf807B8c2B1FA3fD1E637A52&uint256=19900000",
        "rate": {
          "amount": "1.00",
          "currency": "USD"
        },
        "received_amount": "0.00",
        "remaining_amount": null,
        "remaining_payment_uri": null,
        "overpaid_amount": null,
        "detected_network": null,
        "tx_hash": null,
        "explorer_url": null
      },
      "card": null,
      "confirmations": {
        "current": 0,
        "required": 2
      },
      "remainder": true,
      "canceled_by": null,
      "replaced_by": null,
      "failure_code": null,
      "review_reason": null,
      "success_url": null,
      "expires_at": "2026-09-26T21:53:24.271Z",
      "sent_at": null,
      "created_at": "2026-09-26T21:38:24.271Z",
      "updated_at": "2026-09-26T21:38:24.271Z",
      "email": "[email protected]",
      "reporting": {
        "currency": "USD",
        "amount": "19.90",
        "fee": "0.00",
        "transaction_fee": "0.00",
        "customer_fee": "0.00",
        "net": "19.90"
      },
      "fee_rate_bps": 0
    },
    "url": "https://checkout.402pay.co/checkout/v6e4mrczwg?s=chk_XKOWx49himYIAnet"
  }
}