---
title: "Prepare or complete a client-executed crypto withdrawal"
method: POST
path: "/v1/withdrawal/crypto"
tags: ["withdrawal"]
---

# Prepare or complete a client-executed crypto withdrawal

`POST /v1/withdrawal/crypto`

Two-phase crypto withdrawal flow:

**Phase 1 — Prepare** (omit `tx_hash`):
- Creates a `pending` withdrawal event
- Returns `withdrawal_id`

**Phase 2 — Complete** (include `tx_hash` + `withdrawal_id`):
- Updates the pending withdrawal with the on-chain tx hash
- Marks the withdrawal as `submitted`

Both phases require JWT authentication.

## Headers

- `authorization` string, nullable — Bearer JWT issued by Grove.

## Request body

- CryptoWithdrawalRecordRequest — Request model for recording a client-executed crypto withdrawal. Supports a two-phase flow: 1. **Prepare phase** (no tx_hash): Creates a pending withdrawal, returns withdrawal_id. 2. **Complete phase** (with tx_hash + withdrawal_id): Updates the pending withdrawal with the tx hash and marks it as submitted.
  - `tx_hash` string, nullable — Transaction hash (omit for prepare phase, required for complete phase)
  - `withdrawal_id` string, nullable — Withdrawal event ID from prepare phase (required for complete phase)
  - `destination_address` string, required — Destination wallet address the funds were sent to
  - `amount` string, required — Amount withdrawn in token units (e.g., '5.00' for 5 USDC)
  - `token` string — Token symbol (default: USDC)
  - `network` string — Network the withdrawal was executed on

## Response `200`

Successful Response

- union
  - CryptoWithdrawalPrepareResponse — Response for the prepare phase (no tx_hash sent).
    - `withdrawal_id` string, required — Withdrawal event ID
    - `status` string, required — Withdrawal status (pending)
  - CryptoWithdrawalResponse — Response model for a recorded crypto withdrawal.
    - `withdrawal_id` string, required — Withdrawal event ID
    - `status` string, required — Withdrawal status (confirmed/submitted)
    - `destination_address` string, required — Destination wallet address
    - `amount` string, required — Amount withdrawn in token units
    - `token_symbol` string, required — Token symbol
    - `tx_hash` string, required — Transaction hash

## Other responses

- `400` — Invalid tx_hash, address, amount, missing Smart Account earnings wallet, or unsupported token
- `401` — Missing or invalid JWT
- `404` — Withdrawal event not found (complete phase)
- `409` — Withdrawal with this tx_hash already recorded
- `422` — Validation Error

---

[API](https://skmtc.net/grove/apis/grove-api.md) · [All operations](https://skmtc.net/grove/apis/grove-api/llms.txt) · [OpenAPI document](https://skmtc-service-staging.skmtc.workers.dev/v1/apis/grove/grove-api/revisions/f286b48a8105/schema)
