Create your first payment

There are multiple features that support payments. This guide focuses on Transfers, but we also offer Payment Routes.

Transfer API

The Transfer API enables conversion between supported fiat and cryptocurrency currencies. There are two primary transfer types:

  • Crypto → Fiat (off-ramp): Convert cryptocurrency to traditional fiat currency
  • Fiat → Crypto (on-ramp): Convert traditional fiat currency to cryptocurrency

The Transfer API supports crypto → fiat (off-ramp) transfers. If you'd like to receive and pay out stablecoins, refer to the Payment Routes feature.

1. Get a Quote

Before we can initiate the transfer, need to fetch a quote.

curl -X POST "https://api.stables.money/api/v1/quotes" \
  -H "Authorization: Bearer YOUR_JWT_TOKEN" \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "Content-Type: application/json" \
  -d '{
    "source": {
      "currency": "usdt",
      "network": "polygon",
      "amount": "100.00"
    },
    "destination": {
      "currency": "aud",
      "country": "au",
      "network": "bank"
    }
  }'

2. Initiate the Transfer

Request

curl -X POST "https://api.stables.money/api/v1/transfer" \
  -H "Authorization: Bearer YOUR_JWT_TOKEN" \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "Content-Type: application/json" \
  -d '{
    "quote_id": "your-quote-id",
    "customer_id": "your-customer-id",
    "destination": {
      "type":"bank",
      "account_holder_name": "John Smith",
      "bank_name": "Australian Bank",
      "account_number": "1111111111",
      "bank_country": "au",
      "currency": "aud",
      "bsb_code": "633333"
    }
  }'

Response

{
    "id": "1997d55d-fcf1-424c-8b64-67ebee6b7795",
    "tenant_id": "your-tenant-id",
    "customer_id": "your-customer-id",
    "quote_id": "your-quote-id",
    "type": "offramp",
    "status": "created",
    "created_at": "2026-04-01T05:44:38.759Z",
    "updated_at": "2026-04-01T05:44:38.759Z",
    "source_deposit_instructions": {
        "wallet_address": "0xf2B14C1A5AFc4feaA50454C9Fb91f30bf03a0EE0",
        "currency": "usdt",
        "network": "polygon",
        "amount": "100"
    },
    "destination": {
        "amount": "133.52",
        "currency": "aud",
        "network": "bank",
        "account_holder_name": "John Smith",
        "bank_name": "Australian Bank",
        "account_number": "1111111111",
        "bank_country": "au",
        "bsb_code": "633333"
    },
    "fees": {
        "fx_fee": {
            "amount": "0.19",
            "currency": "usd"
        },
        "integrator_fee": {
            "amount": "0.1",
            "currency": "usd"
        },
        "platform_fee": {
            "amount": "0.12",
            "currency": "usd"
        },
        "payment_method_fee": {
            "amount": "5",
            "currency": "usd"
        },
        "network_fee": {
            "amount": "0.50",
            "currency": "usd"
        },
        "total_fee": {
            "amount": "5.91",
            "currency": "usd"
        }
    },
    "exchange_rate": 1.40000000,
    "origin": "api"
}

Quotes have a short expiry — check expires_at in the quote response and create a fresh quote if it has passed before initiating the transfer.

You can share the source_deposit_instructions with your customer. They will need to initiate a transaction of the specified amount, on the network to the given wallet address.

Once the stablecoins have been sent to the collection wallet, Stables will process the payment and send the funds to the bank account.

Additional response fields

The full TransferResponse may also include:

  • metadata: the metadata you attached when creating the transfer
  • destination.beneficiary_id: the saved beneficiary this transfer paid
  • source: details of the funding source, when known
  • compliance_hold: present while the transfer is held for a compliance review, with the rfi_id and the outstanding requirements

Paying the same recipient again

Stables saves every bank account you pay as a beneficiary. To pay the same recipient next time, send a beneficiary destination with the beneficiary_id from the first transfer instead of repeating the bank details:

"destination": {
  "type": "beneficiary",
  "beneficiary_id": "<beneficiary_id>"
}

See Beneficiaries for how beneficiaries are matched, validated and archived.

Next Steps

After creating your first payment

  1. Test the complete flow in your development environment
  2. Set up webhooks to receive real-time status updates for about your payments

On this page