Skip to main content

Create a transfer

Send funds from a customer’s wallet to an external address:
curl -X POST https://api.ledger.so/v1/transfers \
  -H "Authorization: Bearer $LEDGER_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: transfer-1" \
  -d '{
    "customerId": "cus_...",
    "amount": "10.00",
    "destinationCurrency": "usdc",
    "destinationPaymentRail": "solana",
    "destinationAddress": "7nwiVgP8..."
  }'
Response:
{
  "ok": true,
  "data": {
    "id": "txn_...",
    "customerId": "cus_...",
    "type": "transfer",
    "status": "in_review",
    "amount": "10.0",
    "currency": "usdc",
    "sourceCurrency": "usdc",
    "destinationCurrency": "usdc",
    "destinationAddress": "7nwiVgP8...",
    "finalAmount": "10.0",
    "destinationTxHash": null,
    "gasFee": "0.0",
    "exchangeFee": "0.0",
    "createdAt": 1710000000000,
    "updatedAt": 1710000000000
  }
}
The source wallet is automatically resolved from the customer. A transaction record is created to track progress.

Request fields

FieldTypeRequiredDescription
customerIdstringYesCustomer initiating the transfer
amountstringYesAmount to send (decimal string)
destinationCurrencystringYesCurrency to deliver (e.g. usdc)
destinationPaymentRailstringYesNetwork to send on (e.g. solana, ethereum)
destinationAddressstringYesRecipient address
sourceCurrencystringNoSource currency (defaults to usdc)
clientReferenceIdstringNoYour own reference ID

Onchain vs fiat transfers

The transfer endpoint handles both crypto and fiat rails:
Destination RailTypeKYC Required
solana, ethereum, polygon, arbitrum, base, optimism, tronOnchain transferNo
ach, sepa, faster_paymentsFiat transferYes
For fiat transfers, the customer must have completed KYC verification first.

Tracking transfers

After creating a transfer, track its progress via:
  • GET /v1/transactions/{id} to poll the status
  • Subscribe to transaction.updated webhooks for real-time updates
The destinationTxHash field populates once the transfer is settled onchain.