curl --request POST \
--url https://examples.staging.rampapay.com/v1/fx/quotes \
--header 'Content-Type: application/json' \
--header 'X-API-Key: <api-key>' \
--data '
{
"source_currency": "USDT",
"target_currency": "BOB",
"target_amount": "1000.00"
}
'const options = {
method: 'POST',
headers: {'X-API-Key': '<api-key>', 'Content-Type': 'application/json'},
body: JSON.stringify({source_currency: 'USDT', target_currency: 'BOB', target_amount: '1000.00'})
};
fetch('https://examples.staging.rampapay.com/v1/fx/quotes', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));import requests
url = "https://examples.staging.rampapay.com/v1/fx/quotes"
payload = {
"source_currency": "USDT",
"target_currency": "BOB",
"target_amount": "1000.00"
}
headers = {
"X-API-Key": "<api-key>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text){
"id": "6f0c2a8e-4b7d-4f1e-9a51-3c2d8e7b9a10",
"source": {
"currency": "USDT",
"amount": "101.500000"
},
"target": {
"currency": "BOB",
"amount": "1000.00"
},
"rate": "9.9500",
"fee": {
"currency": "USDT",
"amount": "1.000000",
"bps": 100,
"flat": "0.000000"
},
"fixed_side": "target",
"resolution_id": "qrr_8KqT2mWx5ZbN7cJ4hRvP1sLd",
"expires_at": "2026-09-27T14:05:00.000Z",
"created_at": "2026-09-27T14:02:00.000Z"
}Get a firm quote
Scope: payouts:write
The price your end user accepts. Name the two currencies and fix the amount on one side: for a QR, target_amount in BOB. Show source.amount and count down to expires_at (3 minutes at most). If they accept, pay the QR with POST /payouts and this id as quote_id: it debits exactly source.amount. Nothing is reserved until then. A quote pays one payment. Asking again is just another quote — show the one you got.
Today only USDT → BOB with target_amount is priced. Other pairs and source_amount are validated, then answered 422, so you can build against them now.
curl --request POST \
--url https://examples.staging.rampapay.com/v1/fx/quotes \
--header 'Content-Type: application/json' \
--header 'X-API-Key: <api-key>' \
--data '
{
"source_currency": "USDT",
"target_currency": "BOB",
"target_amount": "1000.00"
}
'const options = {
method: 'POST',
headers: {'X-API-Key': '<api-key>', 'Content-Type': 'application/json'},
body: JSON.stringify({source_currency: 'USDT', target_currency: 'BOB', target_amount: '1000.00'})
};
fetch('https://examples.staging.rampapay.com/v1/fx/quotes', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));import requests
url = "https://examples.staging.rampapay.com/v1/fx/quotes"
payload = {
"source_currency": "USDT",
"target_currency": "BOB",
"target_amount": "1000.00"
}
headers = {
"X-API-Key": "<api-key>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text){
"id": "6f0c2a8e-4b7d-4f1e-9a51-3c2d8e7b9a10",
"source": {
"currency": "USDT",
"amount": "101.500000"
},
"target": {
"currency": "BOB",
"amount": "1000.00"
},
"rate": "9.9500",
"fee": {
"currency": "USDT",
"amount": "1.000000",
"bps": 100,
"flat": "0.000000"
},
"fixed_side": "target",
"resolution_id": "qrr_8KqT2mWx5ZbN7cJ4hRvP1sLd",
"expires_at": "2026-09-27T14:05:00.000Z",
"created_at": "2026-09-27T14:02:00.000Z"
}Authorizations
On the example server, any key that starts with rpk_mock_, e.g. rpk_mock_yourname. Never your real key.
Body
currency code. Required. What you pay with: USDT.
currency code. Required. What the destination receives: BOB.
decimal, target's decimals (BOB: ≤ 2). Send this or source_amount. Required for USDT → BOB. The QR's amount — or, for an open-amount QR, the amount the end user typed.
decimal, source's decimals. Not available yet: 422 SOURCE_AMOUNT_NOT_AVAILABLE. Fixes what you pay instead.
qrr_…. The id POST /payouts/qr/resolve answered for this QR. The quote and the payout made at it carry it, so you can follow one payment from the QR read to its outcome. It does not change the price.