> For the complete documentation index, see [llms.txt](https://docs.omypayments.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.omypayments.com/api/api-endpoints/withdrawals/withdraw-an-asset.md).

# Withdraw an asset

**Endpoint**\
`POST /1.0/merchant/asset-withdrawal`

**Prerequisites**

* API withdrawals must be enabled for your merchant account (otherwise `400` with `API withdrawals are currently inactive`).
* `amount` is expressed in the token’s base units (integer string, no decimal point). For a token with 6 decimals, `100` = `"100000000"` — see `crypto.decimals` on the Get Merchant Asset Data endpoint to convert.
* The withdrawal must meet the per-crypto **minimum USD amount**; amounts below it are rejected.

**Request body**

```json
{
  "assetId": "87d68a49-4b0c-4b4c-ad07-4f39aa4a39ab",
  "amount": "60000000000000000000",
  "address": "0x1111111111111111111111111111111111111111"
}
```

| Field     | Type   | Required | Description                                                                                                                                                                                                                                                                                                        |
| --------- | ------ | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `assetId` | string | yes      | UUID of the merchant asset to withdraw from.                                                                                                                                                                                                                                                                       |
| `amount`  | string | yes      | Withdrawal amount in the token’s base units (integer string).                                                                                                                                                                                                                                                      |
| `address` | string | no       | Destination address. **If omitted (or `null`), the asset’s default wallet is used** (configure it in **Assets** → *wallet*). If neither is provided, the request is rejected. The address must be valid for the asset’s network; if a **whitelist** is enabled for your merchant, the address must be whitelisted. |

> **Note on `payer`.** For API-created withdrawals the fee payer is always the **sender**: the system fee is added on top of `amount` and debited from your available balance, and the recipient receives exactly `amount`. `payer` is not an input parameter of this endpoint; it is returned in the response for reference.

**cURL**

```bash
curl -X POST "https://api.omypayments.com/1.0/merchant/asset-withdrawal" \
  -H "Content-Type: application/json" \
  -H "apiKey: <yourApiKey>" \
  -d '{"assetId":"87d68a49-4b0c-4b4c-ad07-4f39aa4a39ab","amount":"60000000000000000000","address":"0x1111111111111111111111111111111111111111"}'
```

**Response (200 OK)**

```json
{
  "id": "{uuid}",                                            // Withdrawal ID
  "status": "pending",                                       // pending | success | failed
  "address": "0x1111111111111111111111111111111111111111",   // Destination address (the provided one, or the asset's default wallet)
  "amount": "60000000000000000000",                          // Requested amount in base units
  "amountInUsd": "60.00",                                    // Requested amount in USD
  "payer": "sender",                                         // Fee payer (always "sender" for API withdrawals)
  "isPrivate": false,                                        // Whether this is a private withdrawal
  "asset": {
    "id": "{assetId}",                                       // Merchant asset ID
    "balance": "99940000000000000000000",                    // Asset available balance (base units) after reservation
    "balanceInUsd": "99940",                                 // Asset available balance in USD
    "wallet": "0x1111111111111111111111111111111111111111"   // Asset default wallet (or null)
  },
  "crypto": {
    "id": "{cryptoId}",                                      // Cryptocurrency ID
    "title": "Binance Pegged USDT",
    "symbol": "USDT",
    "contractAddress": "0x1111111111111111111111111111111111111111", // null for native coins
    "decimals": 18,
    "logoURI": "https://.../usdt.svg"
  },
  "network": {
    "id": "{networkId}",                                     // Network ID
    "title": "BNB Chain",
    "symbol": "BSC",
    "chainId": "56",                                         // External chain id (string)
    "networkType": "evm"
  },
  "fee": {
    "network": null,
    "service": {
      "amount": "1050000000000000000",
      "amountFormatted": "1.05",
      "currency": "USDT",
      "cryptoId": "{cryptoId}",
      "networkId": "{networkId}",
      "amountInUsd": "1.05",
      "isChargedToMerchant": true
    },
    "exchange": null,
    "totalInUsd": "1.05"
  },
  "txHash": null,                                            // On-chain transaction hash (null until the withdrawal is sent)
  "createdAt": "2026-07-11 10:28:58"                         // UTC, "Y-m-d H:i:s"
}
```

A freshly created withdrawal starts as `pending`. It transitions to `success` once sent on-chain, or `failed` if it is declined or the transaction is reverted. Track it via Get a withdrawal or callbacks.

**Validation errors**

`400 Bad Request` returns the standard validation envelope (see Error format):

```json
{
  "success": false,
  "message": "Input validation error.",
  "statusCode": 400,
  "errors": [
    { "field": "address", "messages": ["Please, provide the address. To use default - edit your asset and create wallet address"] }
  ]
}
```

Common messages:

* `Please, provide the address. To use default - edit your asset and create wallet address` — `address` was omitted and the asset has no default wallet.
* `The provided address is not valid` — the address is not a valid format for the asset’s network.
* `The provided address is not in whitelist` — a whitelist is enabled and the address is not on it.
* `API withdrawals are currently inactive` — API withdrawals are disabled for your merchant.
* `Insufficient balance` — the asset’s available balance is lower than `amount` + fee.
* `Minimum withdrawal amount is {amount}` — below the per-crypto minimum.
* `You have reached withdrawal limit` / `Maximum amount is {amount}` — a merchant withdrawal limit was reached.
* `Withdrawal is temporary unavailable` — withdrawals for this crypto/network are temporarily disabled.
* `Withdrawal amount must be greater than fee` — the amount does not cover the system fee.
* `Private payment is unavailable` — `isPrivate` was requested but the network does not support it.
* `Withdrawals to your wallet are not possible as they do not comply with our AML policy. Please enter a different address` — the destination address failed the AML risk check.

Other status codes:

* `401 Unauthorized` — missing `apiKey` header.
* `403 Forbidden` — the API key lacks the **withdrawal** permission.

***
