---
title: "Initiate Withdrawal"
method: POST
path: "/v1/customers/{customer_id}/withdrawals"
tags: ["Withdrawals"]
---

# Initiate Withdrawal

`POST /v1/customers/{customer_id}/withdrawals`

Create a withdrawal to an external bank account.

**Withdrawal Types:**
- **Withdraw to Self**: Use `external_account_id` from the External Accounts API
- **Send to Others**: Use `external_account_id` from a Recipient's bank account

The system automatically detects whether the bank account belongs to the customer or a recipient based on the `external_account_id`.

If destination_address_id is an External Account ID, then the asset, network,
and country_code here should remain consistent with the External Account ID.

**Sandbox Simulation** 

In sandbox environments, you can simulate different withdrawal states by appending a suffix to the `Idempotency-Key` header:

| Suffix | Simulated State | Description |
|--------|-----------------|-------------|
| `:FAILED` | FAILED | Transaction failed |
| `:PENDING` | PENDING | Transaction is held for risk review |

**Example:**
- Normal: `Idempotency-Key: 550e8400-e29b-41d4-a716-446655440000`
- Simulate failure: `Idempotency-Key: 550e8400-e29b-41d4-a716-446655440000:FAILED`
- Simulate pending: `Idempotency-Key: 550e8400-e29b-41d4-a716-446655440000:PENDING`

**Important:** When querying by `idempotency_key`, you must use the **full key including the suffix**. For example, if you created a withdrawal with `550e8400-e29b-41d4-a716-446655440000:FAILED`, you must query with the same full key. Using only the UUID part will return 404 Not Found.

Note: Simulation suffixes are only available in sandbox environments and will be ignored in production.

## Path parameters

- `customer_id` string, required

## Headers

- `Idempotency-Key` string, required

## Request body

- WithdrawalRequest
  - `wallet_address` string, nullable — Wallet address for crypto withdrawals Required for crypto asset withdrawals (e.g., USDC, USDT). Cannot be provided together with external_account_id. Examples - **Wallet Address** `0x71a6c6be0be5f28ef4ea7541749d90d9c66fec7d`
  - `external_account_id` string, nullable — External account ID for fiat withdrawals Required for fiat currency withdrawals (e.g., USD, EUR). Identifies the external bank account used for the transfer. Cannot be provided together with wallet_address. Examples - **External Account ID** `ffb9e832-8e64-11f0-b308-2eaa4f6974f2`
  - `amount` string, required — Amount to withdraw
  - `asset` string, required — - Stablecoin assets: USDC, USDT, PYUSD, RLUSD, USDG, USDP, EURC, MXNB, 1USD(1USD/USDC conversion only, deposit/withdrawal not supported) - Digital assets: BTC - Fiat currencies: USD
  - `network` string, required
  - `code` string, nullable — The localized payment code used for fiat withdrawals Format: `{country_code}_{network}_{code}` (e.g., `in_swift_p0001`) - `country_code`: ISO 3166-1 alpha-2 code (2 letters, e.g., `in` for India) See <https://developer.1money.com/reference/local-payment-code> for supported codes
  - `memorandum` string, nullable — A string representing the message about the fiat transaction. Values longer than 256 characters are truncated.
  - `mode` 'prefunding', nullable — Withdrawal mode. Set to `prefunding` to fund the withdrawal from the main account on behalf of the customer specified in `on_behalf_of`.
  - `on_behalf_of` string, nullable — The customer ID to execute the withdrawal on behalf of. Required when `mode` is `prefunding`. The customer must belong to the same entity as the API key owner.
  - `amount_type` 'SEND_AMOUNT' | 'RECEIVE_AMOUNT', nullable — Controls how the fee is applied to the withdrawal amount. - `SEND_AMOUNT` (default): Fee is deducted from the amount. Amount = what leaves the sender. - `RECEIVE_AMOUNT`: Fee is added on top. Amount = what the recipient gets.

## Response `201`

- WithdrawalResponse
  - `wallet_address` string, nullable — Wallet address for crypto withdrawals Required for crypto asset withdrawals (e.g., USDC, USDT). Cannot be provided together with external_account_id. Examples - **Wallet Address** `0x71a6c6be0be5f28ef4ea7541749d90d9c66fec7d`
  - `external_account_id` string, nullable — External account ID for fiat withdrawals Required for fiat currency withdrawals (e.g., USD, EUR). Identifies the external bank account used for the transfer. Cannot be provided together with wallet_address. Examples - **External Account ID** `ffb9e832-8e64-11f0-b308-2eaa4f6974f2`
  - `amount` string, required — Amount to withdraw
  - `asset` string, required — - Stablecoin assets: USDC, USDT, PYUSD, RLUSD, USDG, USDP, EURC, MXNB, 1USD(1USD/USDC conversion only, deposit/withdrawal not supported) - Digital assets: BTC - Fiat currencies: USD
  - `network` string, required
  - `code` string, nullable — The localized payment code used for fiat withdrawals Format: `{country_code}_{network}_{code}` (e.g., `in_swift_p0001`) - `country_code`: ISO 3166-1 alpha-2 code (2 letters, e.g., `in` for India) See <https://developer.1money.com/reference/local-payment-code> for supported codes
  - `memorandum` string, nullable — A string representing the message about the fiat transaction. Values longer than 256 characters are truncated.
  - `mode` 'prefunding', nullable — Withdrawal mode. Set to `prefunding` to fund the withdrawal from the main account on behalf of the customer specified in `on_behalf_of`.
  - `on_behalf_of` string, nullable — The customer ID to execute the withdrawal on behalf of. Required when `mode` is `prefunding`. The customer must belong to the same entity as the API key owner.
  - `amount_type` 'SEND_AMOUNT' | 'RECEIVE_AMOUNT', nullable — Controls how the fee is applied to the withdrawal amount. - `SEND_AMOUNT` (default): Fee is deducted from the amount. Amount = what leaves the sender. - `RECEIVE_AMOUNT`: Fee is added on top. Amount = what the recipient gets.
  - `transaction_id` string, required — Unique transaction identifier
  - `idempotency_key` string, required — HTTP `Idempotency-Key` header value. Stricter than other IDs: ≤64 ASCII chars per the common REST API convention.
  - `status` 'PENDING' | 'COMPLETED' | 'FAILED' | 'RETURNED', required
  - `transaction_fee` FeeMeta, required
    - `value` string, required — Fee amount
    - `asset` string, required — - Stablecoin assets: USDC, USDT, PYUSD, RLUSD, USDG, USDP, EURC, MXNB, 1USD(1USD/USDC conversion only, deposit/withdrawal not supported) - Digital assets: BTC - Fiat currencies: USD
  - `platform_fee` FeeMeta, required
    - `value` string, required — Fee amount
    - `asset` string, required — - Stablecoin assets: USDC, USDT, PYUSD, RLUSD, USDG, USDP, EURC, MXNB, 1USD(1USD/USDC conversion only, deposit/withdrawal not supported) - Digital assets: BTC - Fiat currencies: USD
  - `partner_fee` FeeMeta, required
    - `value` string, required — Fee amount
    - `asset` string, required — - Stablecoin assets: USDC, USDT, PYUSD, RLUSD, USDG, USDP, EURC, MXNB, 1USD(1USD/USDC conversion only, deposit/withdrawal not supported) - Digital assets: BTC - Fiat currencies: USD
  - `transaction_action` 'WITHDRAWAL', required
  - `created_at` string, required
  - `modified_at` string, required
  - `reference` string, nullable — Transaction reference: on-chain tx hash (crypto) or UETR (fiat)
  - `funder_pid` string — Portfolio ID — also exposed as `customer_id` in OpenAPI. Identifies one individual application / portfolio row within an entity.
  - `funder_account_id` string, nullable
  - `recipient_id` string, nullable — Recipient ID for third-party payouts. Present only when this withdrawal targets a recipient (cpid is non-empty); absent for self-withdrawals.

## Other responses

- `400` — Bad Request
- `401` — Unauthorized
- `404` — Not Found
- `405` — Method Not Allowed
- `409` — Conflict
- `422` — Unprocessable Entity - Invalid enum value (e.g., unsupported network or asset name)
- `500` — Internal Server Error

---

[API](https://skmtc.net/1money/apis/1money-openapi.md) · [All operations](https://skmtc.net/1money/apis/1money-openapi/llms.txt) · [OpenAPI document](https://skmtc-service-staging.skmtc.workers.dev/v1/apis/1money/1money-openapi/versions/aa2718d28cb5/schema)
