curl --request POST \
--url https://api.rheon.io/v1/card/payout/quote \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"cryptoCurrency": "USDC",
"chain": 42161,
"fiatCurrency": "EUR",
"cryptoAmount": "1000.00",
"fiatAmount": "100"
}
'import requests
url = "https://api.rheon.io/v1/card/payout/quote"
payload = {
"cryptoCurrency": "USDC",
"chain": 42161,
"fiatCurrency": "EUR",
"cryptoAmount": "1000.00",
"fiatAmount": "100"
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
cryptoCurrency: 'USDC',
chain: 42161,
fiatCurrency: 'EUR',
cryptoAmount: '1000.00',
fiatAmount: '100'
})
};
fetch('https://api.rheon.io/v1/card/payout/quote', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.rheon.io/v1/card/payout/quote",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'cryptoCurrency' => 'USDC',
'chain' => 42161,
'fiatCurrency' => 'EUR',
'cryptoAmount' => '1000.00',
'fiatAmount' => '100'
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.rheon.io/v1/card/payout/quote"
payload := strings.NewReader("{\n \"cryptoCurrency\": \"USDC\",\n \"chain\": 42161,\n \"fiatCurrency\": \"EUR\",\n \"cryptoAmount\": \"1000.00\",\n \"fiatAmount\": \"100\"\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.rheon.io/v1/card/payout/quote")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"cryptoCurrency\": \"USDC\",\n \"chain\": 42161,\n \"fiatCurrency\": \"EUR\",\n \"cryptoAmount\": \"1000.00\",\n \"fiatAmount\": \"100\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.rheon.io/v1/card/payout/quote")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"cryptoCurrency\": \"USDC\",\n \"chain\": 42161,\n \"fiatCurrency\": \"EUR\",\n \"cryptoAmount\": \"1000.00\",\n \"fiatAmount\": \"100\"\n}"
response = http.request(request)
puts response.read_body{
"environment": "sandbox",
"mock": true,
"quoteId": "cpq_42161_7d31a80f5c1b2e94",
"cryptoAmount": "1234567.89",
"fiatAmount": "1234567.89",
"rate": "1234567.89",
"providerFee": "1234567.89",
"ourFee": "1234567.89",
"expiresAt": "2026-09-08T17:44:12.000Z"
}{
"environment": "sandbox",
"error": {
"code": "invalid_request",
"message": "amount must be a decimal string of the token's smallest unit.",
"fields": {
"applicantInfo.nationality": "iso3166_1_alpha2"
}
}
}{
"environment": "sandbox",
"error": {
"code": "invalid_request",
"message": "amount must be a decimal string of the token's smallest unit.",
"fields": {
"applicantInfo.nationality": "iso3166_1_alpha2"
}
}
}{
"environment": "sandbox",
"error": {
"code": "invalid_request",
"message": "amount must be a decimal string of the token's smallest unit.",
"fields": {
"applicantInfo.nationality": "iso3166_1_alpha2"
}
}
}{
"environment": "sandbox",
"error": {
"code": "invalid_request",
"message": "amount must be a decimal string of the token's smallest unit.",
"fields": {
"applicantInfo.nationality": "iso3166_1_alpha2"
}
}
}{
"environment": "sandbox",
"error": {
"code": "invalid_request",
"message": "amount must be a decimal string of the token's smallest unit.",
"fields": {
"applicantInfo.nationality": "iso3166_1_alpha2"
}
}
}Quote a card payout
Prices a payout that lands on a card. Anonymous: no account, no wallet, no identity, so the price can be shown before anyone signs up. chain and cryptoCurrency are checked against the catalogue and your key’s source chains for real.
The provider behind this endpoint is currently being connected, docs updating. Until then every answer carries mock: true, every money figure is the placeholder 1234567.89, and ids and shapes are real and deterministic from your input.
curl --request POST \
--url https://api.rheon.io/v1/card/payout/quote \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"cryptoCurrency": "USDC",
"chain": 42161,
"fiatCurrency": "EUR",
"cryptoAmount": "1000.00",
"fiatAmount": "100"
}
'import requests
url = "https://api.rheon.io/v1/card/payout/quote"
payload = {
"cryptoCurrency": "USDC",
"chain": 42161,
"fiatCurrency": "EUR",
"cryptoAmount": "1000.00",
"fiatAmount": "100"
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
cryptoCurrency: 'USDC',
chain: 42161,
fiatCurrency: 'EUR',
cryptoAmount: '1000.00',
fiatAmount: '100'
})
};
fetch('https://api.rheon.io/v1/card/payout/quote', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.rheon.io/v1/card/payout/quote",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'cryptoCurrency' => 'USDC',
'chain' => 42161,
'fiatCurrency' => 'EUR',
'cryptoAmount' => '1000.00',
'fiatAmount' => '100'
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.rheon.io/v1/card/payout/quote"
payload := strings.NewReader("{\n \"cryptoCurrency\": \"USDC\",\n \"chain\": 42161,\n \"fiatCurrency\": \"EUR\",\n \"cryptoAmount\": \"1000.00\",\n \"fiatAmount\": \"100\"\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.rheon.io/v1/card/payout/quote")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"cryptoCurrency\": \"USDC\",\n \"chain\": 42161,\n \"fiatCurrency\": \"EUR\",\n \"cryptoAmount\": \"1000.00\",\n \"fiatAmount\": \"100\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.rheon.io/v1/card/payout/quote")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"cryptoCurrency\": \"USDC\",\n \"chain\": 42161,\n \"fiatCurrency\": \"EUR\",\n \"cryptoAmount\": \"1000.00\",\n \"fiatAmount\": \"100\"\n}"
response = http.request(request)
puts response.read_body{
"environment": "sandbox",
"mock": true,
"quoteId": "cpq_42161_7d31a80f5c1b2e94",
"cryptoAmount": "1234567.89",
"fiatAmount": "1234567.89",
"rate": "1234567.89",
"providerFee": "1234567.89",
"ourFee": "1234567.89",
"expiresAt": "2026-09-08T17:44:12.000Z"
}{
"environment": "sandbox",
"error": {
"code": "invalid_request",
"message": "amount must be a decimal string of the token's smallest unit.",
"fields": {
"applicantInfo.nationality": "iso3166_1_alpha2"
}
}
}{
"environment": "sandbox",
"error": {
"code": "invalid_request",
"message": "amount must be a decimal string of the token's smallest unit.",
"fields": {
"applicantInfo.nationality": "iso3166_1_alpha2"
}
}
}{
"environment": "sandbox",
"error": {
"code": "invalid_request",
"message": "amount must be a decimal string of the token's smallest unit.",
"fields": {
"applicantInfo.nationality": "iso3166_1_alpha2"
}
}
}{
"environment": "sandbox",
"error": {
"code": "invalid_request",
"message": "amount must be a decimal string of the token's smallest unit.",
"fields": {
"applicantInfo.nationality": "iso3166_1_alpha2"
}
}
}{
"environment": "sandbox",
"error": {
"code": "invalid_request",
"message": "amount must be a decimal string of the token's smallest unit.",
"fields": {
"applicantInfo.nationality": "iso3166_1_alpha2"
}
}
}completed (it stops at processing), the settlement asset is the sandbox’s, not production’s (read cryptoCurrency from GET /v1/config), and the EUR window is unpublished (GET /v1/card/limits says window: unpublished). Every response says which environment answered in its environment field.mock: true: ids, shapes and statuses are real and deterministic from your input, every money figure is the placeholder 1234567.89, and nothing is sent to a provider. Integrate against the shape; do not compute anything from the figures.Authorizations
Your API key, issued by us and shown once at creation.
Body
Anonymous: no account, no identity - the price can be shown before anyone commits.
Symbol of the stablecoin the user pays out with, as GET /v1/currencies lists it on chain.
"USDC"
Chain id the stablecoins are sent from. Must be one your key may pay FROM (403 chain_not_allowed otherwise) and one the catalogue lists.
x <= 900719925474099142161
ISO 4217 code the card is settled in.
^[A-Za-z]{3}$"EUR"
What the user gives up, decimal string in major units of cryptoCurrency. Send this OR fiatAmount, never both.
^\d+(\.\d+)?$"1000.00"
What must arrive, decimal string in major units of fiatCurrency, solved backwards. Send this OR cryptoAmount, never both.
^\d+(\.\d+)?$"100"
Response
The quote.
Which environment answered. sandbox: at least one money upstream is the provider's sandbox - no real money moves there, and the card corridor is the sandbox's asset (read GET /v1/config), not the documented production one. production: every configured upstream is real. Derived from the configured upstream hosts at boot, never a flag.
sandbox, production "sandbox"
Always true on this endpoint: the provider behind it is currently being connected, docs updating. Ids, shapes and statuses are real and deterministic from your input; every money figure is the placeholder 1234567.89; nothing is sent to a provider. The field disappears the day the provider is wired, so branch on its presence, not its value.
true
Pass to POST /v1/card/payout. Deterministic for the same request from the same key.
"cpq_42161_7d31a80f5c1b2e94"
Placeholder while the provider is being connected: always 1234567.89, never a price. Do not compute anything from it. When the provider is wired this becomes a decimal string in major units.
"1234567.89""1234567.89"
Placeholder while the provider is being connected: always 1234567.89, never a price. Do not compute anything from it. When the provider is wired this becomes a decimal string in major units.
"1234567.89""1234567.89"
Placeholder while the provider is being connected: always 1234567.89, never a price. Do not compute anything from it. When the provider is wired this becomes a decimal string in major units.
"1234567.89""1234567.89"
Placeholder while the provider is being connected: always 1234567.89, never a price. Do not compute anything from it. When the provider is wired this becomes a decimal string in major units.
"1234567.89""1234567.89"
Placeholder while the provider is being connected: always 1234567.89, never a price. Do not compute anything from it. When the provider is wired this becomes a decimal string in major units.
"1234567.89""1234567.89"
ISO 8601. Execute before this. A quote past it is refused as expired rather than silently repriced.
"2026-09-08T17:44:12.000Z"