> For the complete index of the 402pay docs, see [llms.txt](https://developer.402pay.co/llms.txt).

# Claim a transfer

Let a customer report a transfer by its hash after their checkout closed.

`POST https://dash.402pay.co/api/v1/checkouts/{id}/claim`

For a customer who paid after their checkout closed, or after canceling it. Public, like [creating a checkout](https://developer.402pay.co/api/checkouts/create.md): the checkout's ID is all it takes. Called with your secret key, the response also has `email`, `reporting` and `fee_rate_bps`.

Works on an `expired` or `canceled` crypto checkout. The checkout and its payment become `needs_review` with a `review_reason` of `claimed`, the payment's timeline gains a `claimed` event with the hash, and you receive `payment.needs_review`.

> Nothing checks the hash for you. Look it up on the network first, then [accept the payment](https://developer.402pay.co/api/payments/accept.md): accepting a claim counts the full quoted amount as received.

### Path

- `id` (string, required): The checkout's ID, such as `chk_8zXVc2SbCBDho78Q`.

### Body

- `tx_hash` (string, required): The transaction hash from the customer's wallet, on the checkout's network.
- `email` (string): The customer's email, kept when the checkout has none yet, so you can reach them.

### Errors

- 400 `invalid_request` A field other than `tx_hash` or `email` was sent.
- 400 `invalid_tx_hash` `tx_hash` isn't a transaction hash on the checkout's network.
- 400 `invalid_email` `email` isn't a valid email address.
- 404 `not_found` No checkout has that ID.
- 409 `wrong_rail` The checkout is for a card, which finishes on the secure payment page.
- 409 `payment_paid` The payment has already succeeded.
- 409 `already_claimed` The checkout already needs review.
- 409 `checkout_not_claimable` The checkout isn't expired or canceled, so it's still watching for the transfer.

Any request can also fail on its key or its body. See [errors](https://developer.402pay.co/api/errors.md).

Request, cURL:

```bash
curl -X POST "https://dash.402pay.co/api/v1/checkouts/chk_8zXVc2SbCBDho78Q/claim" \
  -H "Content-Type: application/json" \
  -d '{
    "tx_hash": "0x5e2b8c0f4a91d37e6b0c2f8a14d9e7c3b6a05f1d28e4c9b7a3f6d0e1c8b2a4f7"
  }'
```

Request, Node.js:

```js
const response = await fetch("https://dash.402pay.co/api/v1/checkouts/chk_8zXVc2SbCBDho78Q/claim", {
  method: "POST",
  headers: {
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    tx_hash: "0x5e2b8c0f4a91d37e6b0c2f8a14d9e7c3b6a05f1d28e4c9b7a3f6d0e1c8b2a4f7"
  }),
});
const { data } = await response.json();
```

Request, Python:

```python
import requests

response = requests.post(
    "https://dash.402pay.co/api/v1/checkouts/chk_8zXVc2SbCBDho78Q/claim",
    json={
        "tx_hash": "0x5e2b8c0f4a91d37e6b0c2f8a14d9e7c3b6a05f1d28e4c9b7a3f6d0e1c8b2a4f7"
    },
)
data = response.json()["data"]
```

Response, 200 OK:

```json
{
  "data": {
    "id": "chk_8zXVc2SbCBDho78Q",
    "kind": "checkout",
    "status": "needs_review",
    "rail": "crypto",
    "link_id": null,
    "payment_id": "pmt_pxYW5vHfVt1xTIT2",
    "amount": 4900,
    "currency": "USD",
    "breakdown": {
      "currency": "USD",
      "price": 4900,
      "processing_fee": null,
      "network_fee": 90,
      "total": 4990
    },
    "crypto": {
      "asset": "USDC",
      "network": "ethereum",
      "amount": "49.00",
      "address": "0xB82AFd9E40ED990A37c7eeB43e8d04528732ef39",
      "payment_uri": "ethereum:0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48@1/transfer?address=0xB82AFd9E40ED990A37c7eeB43e8d04528732ef39&uint256=49000000",
      "rate": {
        "amount": 100,
        "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": 4
    },
    "remainder": false,
    "canceled_by": null,
    "replaced_by": null,
    "failure_code": null,
    "review_reason": "claimed",
    "success_url": "https://example.com/thanks",
    "expires_at": "2026-09-27T18:27:57.906Z",
    "sent_at": null,
    "created_at": "2026-09-27T18:12:57.906Z",
    "updated_at": "2026-09-27T18:13:10.639Z"
  }
}
```
