# Get Withdrawal

> Retrieve a withdrawal by ID, inspect its current state and transaction reference, and reconcile completion with the signed webhook.

`GET /v1/withdrawals/:withdrawal_id`

:::endpoint
GET /v1/withdrawals/:withdrawal_id
:::

**API key:** `Payout`

Returns the current state of a withdrawal. The confirmed `tx_hash` and `explorer_url` appear once the payout reaches `completed`.

## Response (200 OK)

```json
{
  "withdrawal_id": "wdr_2M8K6Q4P9X1Z7A3B",
  "external_order_id": "payout-001",
  "status": "completed",
  "is_final": true,
  "is_test": false,
  "amount": "100.00",
  "fee": "1.00",
  "currency": "USDT",
  "network": "TRC20",
  "destination_address": "TN3W4H6rK2ce4vX9YnFQHwKENnHjoxb3m9",
  "tx_hash": "9f3b8c2a1d0e4f6789abc123def4567890abc123def4567890abc123def45678",
  "explorer_url": "https://tronscan.org/#/transaction/9f3b8c2a1d0e4f6789abc123def4567890abc123def4567890abc123def45678",
  "created_at": 1739289600,
  "completed_at": 1739289932
}
```

## Withdrawal statuses

| Status | Description | Terminal |
|--------|-------------|----------|
| `created` | Withdrawal created, awaiting signing | No |
| `signed` | Transaction signed and broadcast to blockchain | No |
| `cancelling` | Admin issued a cancellation while in `pending_review`; awaiting on-chain confirmation of which transaction lands | No |
| `completed` | Transaction confirmed on-chain, payout delivered. Final on the wire (`is_final: true`), though a deep reorg can send it back to `signed` — see the transitions below | Yes |
| `failed` | Signing failed before broadcast, or an operator abandoned a stuck payout, or a cancellation confirmed on-chain. Funds returned to balance | Yes |
| `cancelled` | Merchant cancelled while still in `created` status | Yes |
| `pending_review` | Transaction was signed but not found on-chain after TTL expiry. Requires manual resolution | No |

### Status Transitions

- `created` -> `signed` -- transaction signed and broadcast
- `created` -> `cancelled` -- merchant cancels (only valid transition for cancel)
- `created` -> `failed` -- signing failed
- `created` -> `completed` -- the merchant simulates completion via `POST /v1/sandbox/withdrawals/{id}/simulate-completion` (sandbox only — no signing, no chain)
- `signed` -> `completed` -- transaction confirmed on-chain
- `signed` -> `pending_review` -- signed TX not found (or reverted) on-chain after TTL; a reverted TX stays `signed` until the TTL escalates it
- `pending_review` -> `cancelling` -- admin issues cancellation
- `pending_review` -> `completed` -- the original TX is found on-chain and confirms (scanner-driven, not an admin action)
- `pending_review` -> `failed` -- admin abandons the stuck payout
- `cancelling` -> `completed` -- the original transaction confirmed first, so the payout went through
- `cancelling` -> `failed` -- the cancellation transaction confirmed on-chain instead; funds returned to balance
- `completed` -> `signed` -- rare: a chain reorg displaced the confirmed payout TX, so the payout drops back to `signed` and completes again once that transaction (or its replacement) is mined

## Errors

A Payment (`pk_`) key is rejected with `403 payout_key_required`. See [Error Codes](/docs/errors/codes.md) for the full catalogue. The `type` URI in every error response deep-links to the matching row.
