Withdrawals

List customer withdrawal banks

List all withdrawal bank accounts configured for a customer.

GET
/api/v2/customers/{customerId}/withdrawal/banks

Returns all withdrawal banks configured for the customer. Only ACTIVE banks can be used for withdrawals.

Authorization

bearerAuth
AuthorizationBearer <token>

Organization API key obtained on Settings > API Keys page in Compose UI.

In: header

Path Parameters

customerId*string

Unique identifier of the customer

Response Body

application/json

application/json

application/json

application/json

application/json

application/json

curl -X GET 'https://compose.finance/api/v2/customers/{customerId}/withdrawal/banks' \  -H 'Authorization: Bearer YOUR_API_KEY'

[
  {
    "id": "bank_123abc",
    "beneficiaryName": "JOHN DOE",
    "iban": "DE89370400440532013000",
    "bic": "COBADEFFXXX",
    "addressLine1": "123 Main Street",
    "city": "Berlin",
    "postalCode": "10117",
    "country": "DE",
    "currency": "EUR",
    "paymentRail": "SEPA",
    "status": "ACTIVE",
    "fundingSource": "VIRTUAL_ACCOUNT",
    "createdAt": "2024-01-15T10:30:00.000Z",
    "wallets": [
      {
        "id": "wallet_123abc",
        "address": "0x1234567890abcdef1234567890abcdef12345678",
        "currency": "usdc",
        "chain": "base",
        "enabled": true,
        "createdAt": "2024-01-15T10:30:05.000Z",
        "updatedAt": "2024-01-15T10:30:05.000Z",
        "instructions": "Send USDC to this address to automatically receive funds in your bank account. Minimum: 5 USDC."
      }
    ]
  }
]

{
  "error": "Unauthorized - Invalid or missing API key or session"
}
{
  "error": "Customers feature is not enabled for your organization"
}
{
  "error": "Customer not found"
}
{
  "error": "Rate limit exceeded. Please try again later."
}

{
  "error": "Internal server error"
}

Create customer withdrawal bank POST

Adds a new bank account for withdrawals. The customer must be KYC verified, except for AUD withdrawal banks. **Currency and payment rails** - `SEPA` (EUR): provide `currency: "EUR"`, `paymentRail: "SEPA"`, `iban`, and `bic`. - `FEDWIRE` (USD): provide `currency: "USD"`, `paymentRail: "FEDWIRE"`, `accountNumber`, and `routingNumber`. - `SWIFT` (USD): provide `currency: "USD"`, `paymentRail: "SWIFT"`, `accountNumber` (or IBAN), `bic`, `bankName`, `bankAddress`, and `bankCountry`. - `AU_BANK_TRANSFER` (AUD): provide `currency: "AUD"`, `paymentRail: "AU_BANK_TRANSFER"`, `bsb`, `accountNumber`, the payee's `firstName`, `lastName` and `dateOfBirth`, and the full address (`addressLine1`, `city`, `postalCode`, `country`). Only for AUD-only customers, verified or not, when AUD functionality is enabled for your organization. The payee is an individual: `CUSTOMER` and `OTHER_INDIVIDUAL` are active immediately, and `OTHER_BUSINESS` is refused. AUD-only customers cannot add EUR or USD accounts. For backwards compatibility the API still accepts `currency` without `paymentRail` (`EUR` maps to SEPA, `USD` to FEDWIRE), but new integrations must send `paymentRail`. **Recipient Types** - `CUSTOMER` - The customer themselves. Auto-approved if the beneficiary name matches the customer's verified name (KYC name for individuals, organization name for corporates). Returns 400 on name mismatch. AUD withdrawal banks are not name-checked: they are active immediately. - `OTHER_INDIVIDUAL` - A third-party individual. Requires manual approval, except for AUD withdrawal banks, which are active immediately. - `OTHER_BUSINESS` - A third-party business. Requires manual approval. If `recipientType` is not specified, it defaults to `CUSTOMER`. **Address** For `CUSTOMER` recipients, `addressLine1` and `city` are optional. If omitted, the address is auto-resolved from the customer's KYC data (individuals) or stored business address (corporates). You can check the available address via `GET /customers/{customerId}/kyc/address`. For `OTHER_INDIVIDUAL` and `OTHER_BUSINESS`, address fields are required. AUD withdrawal banks always require the payee's full address (`addressLine1`, `city`, `postalCode`, `country`). **Validation** - EUR: IBAN and BIC/SWIFT formats are validated automatically - USD Fedwire: account number and routing number are validated automatically - USD SWIFT: BIC/SWIFT format is validated automatically, and bank name/address/country are required - AUD: the BSB must be 6 digits and the account number 1–9 digits; the account is checked with the payout provider before it is saved, and nothing is saved if that fails (502, safe to retry) - For CUSTOMER: beneficiary name is checked against the customer's verified identity (individual) or organization name (corporate), except for AUD withdrawal banks

Get withdrawal allowance GET

Returns the current allowance status for API withdrawals. Use this endpoint to check your available API allowance before initiating a withdrawal. The allowance determines whether withdrawals execute automatically (`PROCESSING`) or require manual approval (`PROPOSED`) from the dashboard. **Organization scope:** Allowance is configured at the organization level (your Safe wallet), not per customer. **Response states (all return 200):** - `enabled: false, allowance: null` — API withdrawals unavailable, Safe not configured, or module not enabled on-chain - `enabled: true, allowance: { "limit": "0", ... }` — Module and delegate configured, but no spending limit set yet (every amount is `"0"`) - `enabled: true, allowance: { ... }` — Fully configured; check `available` before withdrawing `enabled: true` means the on-chain module and delegate are configured. Automatic withdrawals still require sufficient `available` allowance. When `enabled` is `false` but API withdrawals are enabled, wallet USDC withdrawals fail with `500` (or `404` when no Safe wallet is configured) instead of falling back to `PROPOSED`. **Response Fields** - `enabled`: Whether the on-chain module and delegate are configured - `allowance.limit`: Total allowance amount per reset period (USDC) - `allowance.spent`: Amount already used this period (USDC) - `allowance.available`: Remaining amount you can withdraw automatically (USDC) - `allowance.resetPeriodMinutes`: How often the allowance resets (0 = one-time, no reset) - `allowance.nextResetAt`: When the allowance will reset (null if one-time)