Get an indicative rate quote
Preview indicative exchange rates and fees before initiating a deposit or withdrawal.
Preview the exchange rate, fees, and estimated amounts for a deposit or withdrawal before initiating the transaction. Rates are indicative and not locked — the actual rate is determined when the transaction is executed. Provide exactly one of source_amount or target_amount. Supported currencies: fiat (EUR, USD, AUD) and stablecoin (USDC, EURC, USDT). Supported pairs: EUR<->USDC, EUR<->EURC, USD<->USDC, EURC->USD, USDT->EUR, USDT->USD (EURC and USDT are withdrawal-only when USD is the target, from a custodial balance), and USDC->AUD, USDT->AUD (withdrawal-only, on AU_BANK_TRANSFER, when AUD functionality is enabled for your organization; not for a standard customer_id). For customer wallet deposits where developer_fee is present, the wallet receive amount is target_amount - developer_fee.amount.
Authorization
bearerAuth Organization API key obtained on Settings > API Keys page in Compose UI.
In: header
Query Parameters
Currency being sent. Case-insensitive.
"EUR" | "USD" | "USDC" | "EURC" | "USDT"Currency to be received. Case-insensitive.
"EUR" | "USD" | "AUD" | "USDC" | "EURC" | "USDT"Amount in source currency to send. Provide exactly one of source_amount or target_amount.
Desired amount in target currency to receive. Provide exactly one of source_amount or target_amount.
Prices the quote for this customer: customer-specific provider routing and fee overrides apply, so fee, source_amount and target_amount can differ from the organization-level quote. Must belong to your organization, otherwise 404. When provided on a fiat-to-crypto deposit quote, the response may include a developer_fee object if the customer has an enabled deposit wallet and a spread fee configured. developer_fee is shown separately and is not deducted from target_amount. When developer_fee is present, customer wallet receive amount = target_amount - developer_fee.amount. AUD-only customers return 400 with Not available for AUD-only customers for any target but AUD, and standard customers return 400 with AUD is only available for AUD-only customers for AUD.
Optional deposit channel. When provided, the quote is priced for that specific deposit channel. When omitted, the cheapest available channel is selected automatically so the quote matches whatever the customer will actually pay. Case-insensitive. Ignored for withdrawals.
"REFERENCE" | "VIRTUAL_ACCOUNT"Optional payment rail. For USD, use FEDWIRE or SWIFT to price the quote for that rail. For AUD, omit it or use AU_BANK_TRANSFER. Case-insensitive.
"SEPA" | "SWIFT" | "FEDWIRE" | "AU_BANK_TRANSFER"Response Body
application/json
application/json
application/json
application/json
application/json
application/json
application/json
application/json
curl -X GET 'https://compose.finance/api/v2/rates?source_currency=EUR&target_currency=USDC&source_amount=1000' \ -H 'Authorization: Bearer YOUR_API_KEY'Customer sends 1000 EUR and receives approximately 1074.6 USDC after a 5 EUR fee.
{
"source_currency": "EUR",
"target_currency": "USDC",
"source_amount": "1000",
"target_amount": "1074.6",
"exchange_rate": "1.08",
"fee": "5",
"fee_currency": "EUR",
"payment_rail": "SEPA"
}{
"error": "source_currency: Required, target_currency: Required"
}{
"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"
}{
"error": "Exchange rate temporarily unavailable"
}Upload customer KYC document POST
Uploads a KYC document (identity or proof of address) for a customer to our verification provider. The customer must have initiated KYC verification first by calling `POST /customers/{customerId}/kyc`. **Identity Documents** (`idDocType`): - `PASSPORT` - Passport (any country) - `ID_CARD` - National ID card (front and back required) - `DRIVERS` - Driver's license (front and back required) - `RESIDENCE_PERMIT` - Residence permit **Proof of Address** (`idDocType: PROOF_OF_ADDRESS`): Documents must be dated within the **last 3 months**. Accepted documents: - Utility bills (gas, electricity, water) - Telecom bills (internet, cable, mobile phone) - Bank statements or bank letters (neobanks not accepted) - Government documents (tax bills, voter registration) - Lease or rental agreements **File Requirements:** - Formats: JPEG, PNG, PDF - Maximum size: 10MB
Get customer transaction GET
Returns details for a specific customer transaction. Use this to check the current status of a withdrawal or deposit. For deposit transactions where `developerFee` is present, wallet receive amount = `targetAmount - developerFee.amount`. **Status Values** - `PROCESSING` — Transaction is being processed (an in-flight deposit return also reports PROCESSING) - `PROPOSED` — Awaiting approval in dashboard - `PARTIALLY_SIGNED` — If multiple approvers configured: requires more approvals. - `COMPLETED` — Successfully completed - `FAILED` — Transaction failed - `CANCELLED` — Cancelled by user - `EXPIRED` — Expired before completion - `REVERSED` — Deposit returned to the sender's bank account **Action Required** When `requiresUiAction` is `true`, the transaction needs user approval in the dashboard. For AUD-only customers, each AUD payment is a `DEPOSIT` with `paymentRail: "AU_BANK_TRANSFER"`, `sourceCurrency: "AUD"` and `payerName`; payments on hold are reported as `PROCESSING`. A returned AUD payment reports `PROCESSING` while the return is in flight and `REVERSED` once it settles. An AUD withdrawal that reached `COMPLETED` can later move to `FAILED` if the receiving bank returns the payment.

