> For the complete documentation index, see [llms.txt](https://docs.nexus.xyz/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.nexus.xyz/api-reference/account/create-withdrawal.md).

# POST /withdrawals

Submit a withdrawal.

`operationId`: `createWithdrawal` · CCXT method: `withdraw`

**Authentication:** none declared, and the contract declares no document-level default — this operation carries its own signature in the request body. See the description above.

Withdraws USDX collateral from the venue back to the signing wallet.

**The signature is the authentication, not an API key.** This operation takes no `X-API-Key` and no session token: the caller signs an EIP-712 `WithdrawIntent` with the wallet's own key and the server recovers the signer from `signature`. The recovered address must equal `wallet`, or the request is refused with `401 SIGNER_MISMATCH`. `security` is omitted rather than `[]` for that reason — the operation is not public, it is authorized by something this document has no scheme for, the same way `POST /agents/register` expresses it.

EIP-712 domain: `{ name: 'Nexus Exchange', version: '1', chainId: 20056 }`. Unlike `POST /agents/register`, the chain id is **not** a request field here: the server always verifies against `20056`, so a signature produced under any other domain simply does not recover `wallet` and is refused with `401 SIGNATURE_INVALID`. Sign with that value; do not substitute a network chain id. Typed data type: `WithdrawIntent { uint256 amount, address asset, uint64 nonce }`, where `asset` is the USDX sentinel address `0xcccccccccccccccccccccccccccccccccccccccc`. The venue is single-collateral and ignores the asset; the address exists only so the typed data has a stable binding.

**The destination is implicit.** Funds are credited to the signing wallet; the typed data carries no destination, so there is nothing to redirect. `destination` may be sent for clarity but must equal `wallet` — any other value is refused with `400 destination_locked`.

**`nonce` is single-use per wallet.** Re-submitting an already-accepted `(wallet, nonce)` pair is refused with `401 NONCE_REPLAY` and creates no second withdrawal, so a client that retries on an ambiguous network error cannot double-withdraw. This operation is not idempotent: a replay is rejected rather than answered with the original result.

**`amount` is a whole smallest-unit count.** It is a decimal string on the wire, but `WithdrawIntent` commits to a `uint256`, so a fractional value cannot be represented and is refused with `400 fractional_amount` rather than rounded.

**Exposure must be closed first.** A withdrawal that would leave an open position under-collateralized is refused with `400 WITHDRAW_BLOCKED_BY_OPEN_POSITION`; close positions and cancel resting orders before withdrawing.

**Acceptance is not settlement.** A `200` means the collateral was debited and the withdrawal was recorded with status `pending`; it does not mean funds have moved on-chain. Poll `GET /withdrawals` for the lifecycle `status` and for `tx_hash`, which stays `null` until the withdrawal is submitted on-chain.

## Request body

**Required.** [`WithdrawalRequest`](/api-reference/guides/schemas.md#withdrawalrequest) — `application/json`.

```json
{
  "wallet": "0xAbCdEf0123456789AbCdEf0123456789AbCdEf01",
  "amount": "500",
  "asset": "USDX",
  "nonce": 1779225381434,
  "signature": "0xdeadbeef..."
}
```

## Responses

| Status | Body                                                                        | Meaning                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         |
| ------ | --------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `200`  | [`WithdrawalResponse`](/api-reference/guides/schemas.md#withdrawalresponse) | Withdrawal accepted and collateral debited. The withdrawal is recorded with status `pending`; this is an acceptance, not an on-chain settlement.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                |
| `400`  | [`WithdrawalError`](/api-reference/guides/schemas.md#withdrawalerror)       | The withdrawal was refused before or by the engine. Branch on `code`: - `WITHDRAW_BLOCKED_BY_OPEN_POSITION` — the account has open exposure; close it first. - `INSUFFICIENT_BALANCE` — the requested amount exceeds withdrawable collateral. - `INVALID_AMOUNT` — `amount` is absent, non-numeric, or not greater than zero. - `fractional_amount` — `amount` has a fractional part; `WithdrawIntent` carries a `uint256` smallest-unit count. - `destination_locked` — `destination` was supplied and does not equal `wallet`. - `BAD_WALLET` — `wallet` is not a 0x-prefixed 20-byte address. - `INVALID_JSON` / `BAD_REQUEST` — the body could not be read or parsed. An engine rejection with no dedicated classification is forwarded unchanged; it carries the same value under both `error` and `code`. |
| `401`  | [`WithdrawalError`](/api-reference/guides/schemas.md#withdrawalerror)       | The signature did not authorize this withdrawal. Branch on `code`: - `NONCE_REPLAY` — this `(wallet, nonce)` pair was already accepted. No second withdrawal was created; sign a fresh nonce. - `SIGNER_MISMATCH` — the address recovered from `signature` is not `wallet`. The response echoes the `claimed` and `recovered` addresses. - `SIGNATURE_INVALID` — `signature` is malformed, not 65 bytes, non-canonical (high-S), or recovered no key. - `STORE_ERROR` — the nonce could not be recorded, so the withdrawal was not attempted.                                                                                                                                                                                                                                                                   |
| `403`  | [`WithdrawalError`](/api-reference/guides/schemas.md#withdrawalerror)       | Withdrawals are refused for this wallet or this deployment. All three cases are decided before any signature work, so no nonce is consumed and a retry with the same signed intent is safe once the condition clears. Branch on `code`, or on `error` for the freeze envelope: - `WITHDRAWALS_DISABLED` (`code`) — the deployment-wide withdrawal kill switch is off. - `withdrawals_frozen` (`error`) — the exchange is frozen; balances remain tradeable but new outflows are suspended. - `EARLY_ACCESS_REQUIRED` (`code`) — the wallet is not on the early-access allowlist on a deployment that enforces one. Jurisdiction controls do **not** appear here: withdrawal paths are exempt from them by design, because a restriction that traps funds is worse than no restriction.                          |
| `429`  | — *(no schema declared)*                                                    | —                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               |

## Example

```bash
curl -X POST 'https://exchange.nexus.xyz/api/exchange/withdrawals' \
  -H 'Content-Type: application/json'
```

***

<sub>Generated from</sub> <sub></sub><sub>`eng/apps/exchange/api/openapi.json`</sub> <sub></sub><sub>(spec</sub> <sub></sub><sub>`0.9.27`</sub><sub>). Do not edit by hand — regenerate with</sub> <sub></sub><sub>`python3 product/docs/tools/api-reference/generate.py`</sub><sub>. Hand-authored context lives in the Guides pages.</sub>


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.nexus.xyz/api-reference/account/create-withdrawal.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
