# Requires: npm i -g @infinite_dev/cli && export INFINITE_API_KEY=sk_sandbox_...
# Escape hatch for any endpoint: infinite api <METHOD> <path>
infinite api POST /v1/fx/quotes \
--body '<request-json>'Create a firm FX quote.
# Infinite MCP is read-only for this endpoint — use a dedicated MCP tool when one exists, otherwise run the CLI tab.import requests
url = "https://sandbox.api.infinite.dev/v1/fx/quotes"
payload = {
"onBehalfOf": "cus_abc123",
"pair": {
"sourceCurrency": "USDT",
"destinationCurrency": "USDC",
"sourceNetwork": "BASE",
"sourceRail": "SEPA",
"destinationNetwork": "BASE",
"destinationRail": "SEPA"
},
"amount": {
"value": "10000000",
"side": "SOURCE"
},
"maxSlippageBps": 25
}
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({
onBehalfOf: 'cus_abc123',
pair: {
sourceCurrency: 'USDT',
destinationCurrency: 'USDC',
sourceNetwork: 'BASE',
sourceRail: 'SEPA',
destinationNetwork: 'BASE',
destinationRail: 'SEPA'
},
amount: {value: '10000000', side: 'SOURCE'},
maxSlippageBps: 25
})
};
fetch('https://sandbox.api.infinite.dev/v1/fx/quotes', 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://sandbox.api.infinite.dev/v1/fx/quotes",
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([
'onBehalfOf' => 'cus_abc123',
'pair' => [
'sourceCurrency' => 'USDT',
'destinationCurrency' => 'USDC',
'sourceNetwork' => 'BASE',
'sourceRail' => 'SEPA',
'destinationNetwork' => 'BASE',
'destinationRail' => 'SEPA'
],
'amount' => [
'value' => '10000000',
'side' => 'SOURCE'
],
'maxSlippageBps' => 25
]),
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://sandbox.api.infinite.dev/v1/fx/quotes"
payload := strings.NewReader("{\n \"onBehalfOf\": \"cus_abc123\",\n \"pair\": {\n \"sourceCurrency\": \"USDT\",\n \"destinationCurrency\": \"USDC\",\n \"sourceNetwork\": \"BASE\",\n \"sourceRail\": \"SEPA\",\n \"destinationNetwork\": \"BASE\",\n \"destinationRail\": \"SEPA\"\n },\n \"amount\": {\n \"value\": \"10000000\",\n \"side\": \"SOURCE\"\n },\n \"maxSlippageBps\": 25\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://sandbox.api.infinite.dev/v1/fx/quotes")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"onBehalfOf\": \"cus_abc123\",\n \"pair\": {\n \"sourceCurrency\": \"USDT\",\n \"destinationCurrency\": \"USDC\",\n \"sourceNetwork\": \"BASE\",\n \"sourceRail\": \"SEPA\",\n \"destinationNetwork\": \"BASE\",\n \"destinationRail\": \"SEPA\"\n },\n \"amount\": {\n \"value\": \"10000000\",\n \"side\": \"SOURCE\"\n },\n \"maxSlippageBps\": 25\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://sandbox.api.infinite.dev/v1/fx/quotes")
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 \"onBehalfOf\": \"cus_abc123\",\n \"pair\": {\n \"sourceCurrency\": \"USDT\",\n \"destinationCurrency\": \"USDC\",\n \"sourceNetwork\": \"BASE\",\n \"sourceRail\": \"SEPA\",\n \"destinationNetwork\": \"BASE\",\n \"destinationRail\": \"SEPA\"\n },\n \"amount\": {\n \"value\": \"10000000\",\n \"side\": \"SOURCE\"\n },\n \"maxSlippageBps\": 25\n}"
response = http.request(request)
puts response.read_body{
"id": "quote_abc123",
"pair": {
"sourceCurrency": "USDT",
"destinationCurrency": "USDC",
"sourceNetwork": "BASE",
"sourceRail": "SEPA",
"destinationNetwork": "BASE",
"destinationRail": "SEPA"
},
"amount": {
"value": "10000000",
"side": "SOURCE"
},
"grossSource": "10000000",
"displayedDestination": "9998500",
"rate": "0.9998500",
"expiresAt": "2026-05-26T19:42:00.000Z",
"referenceRate": "1.158691536019208779",
"referenceRateAsOf": "2026-09-02T18:30:04.000Z",
"referenceProvider": "XE",
"quoteBinding": "PERSISTED",
"expectedDepositDetails": {
"kind": "CRYPTO_ADDRESS",
"note": "Deposit instructions become active only when the trade created by accepting this quote includes them — immediately on accept, or after the fx_trade.deposit_instructions_ready event if the trade starts in PENDING_WALLET_APPROVAL. Funds sent before then cannot be matched to a trade.",
"address": "0xCustomerInfiniteTxWallet...",
"network": "BASE"
}
}{
"message": "fx_quote_amount_too_large",
"hint": "Amount is above the maximum for this corridor.",
"limits": {
"sourceCurrency": "USDC",
"min": "0",
"max": "10000000"
},
"requested": "100000000"
}Create a firm FX quote
Always firm — consumes one vendor quote and persists a Quote row. Pass an Idempotency-Key header to make retries safe (returns the original response on replay).
# Requires: npm i -g @infinite_dev/cli && export INFINITE_API_KEY=sk_sandbox_...
# Escape hatch for any endpoint: infinite api <METHOD> <path>
infinite api POST /v1/fx/quotes \
--body '<request-json>'Create a firm FX quote.
# Infinite MCP is read-only for this endpoint — use a dedicated MCP tool when one exists, otherwise run the CLI tab.import requests
url = "https://sandbox.api.infinite.dev/v1/fx/quotes"
payload = {
"onBehalfOf": "cus_abc123",
"pair": {
"sourceCurrency": "USDT",
"destinationCurrency": "USDC",
"sourceNetwork": "BASE",
"sourceRail": "SEPA",
"destinationNetwork": "BASE",
"destinationRail": "SEPA"
},
"amount": {
"value": "10000000",
"side": "SOURCE"
},
"maxSlippageBps": 25
}
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({
onBehalfOf: 'cus_abc123',
pair: {
sourceCurrency: 'USDT',
destinationCurrency: 'USDC',
sourceNetwork: 'BASE',
sourceRail: 'SEPA',
destinationNetwork: 'BASE',
destinationRail: 'SEPA'
},
amount: {value: '10000000', side: 'SOURCE'},
maxSlippageBps: 25
})
};
fetch('https://sandbox.api.infinite.dev/v1/fx/quotes', 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://sandbox.api.infinite.dev/v1/fx/quotes",
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([
'onBehalfOf' => 'cus_abc123',
'pair' => [
'sourceCurrency' => 'USDT',
'destinationCurrency' => 'USDC',
'sourceNetwork' => 'BASE',
'sourceRail' => 'SEPA',
'destinationNetwork' => 'BASE',
'destinationRail' => 'SEPA'
],
'amount' => [
'value' => '10000000',
'side' => 'SOURCE'
],
'maxSlippageBps' => 25
]),
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://sandbox.api.infinite.dev/v1/fx/quotes"
payload := strings.NewReader("{\n \"onBehalfOf\": \"cus_abc123\",\n \"pair\": {\n \"sourceCurrency\": \"USDT\",\n \"destinationCurrency\": \"USDC\",\n \"sourceNetwork\": \"BASE\",\n \"sourceRail\": \"SEPA\",\n \"destinationNetwork\": \"BASE\",\n \"destinationRail\": \"SEPA\"\n },\n \"amount\": {\n \"value\": \"10000000\",\n \"side\": \"SOURCE\"\n },\n \"maxSlippageBps\": 25\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://sandbox.api.infinite.dev/v1/fx/quotes")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"onBehalfOf\": \"cus_abc123\",\n \"pair\": {\n \"sourceCurrency\": \"USDT\",\n \"destinationCurrency\": \"USDC\",\n \"sourceNetwork\": \"BASE\",\n \"sourceRail\": \"SEPA\",\n \"destinationNetwork\": \"BASE\",\n \"destinationRail\": \"SEPA\"\n },\n \"amount\": {\n \"value\": \"10000000\",\n \"side\": \"SOURCE\"\n },\n \"maxSlippageBps\": 25\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://sandbox.api.infinite.dev/v1/fx/quotes")
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 \"onBehalfOf\": \"cus_abc123\",\n \"pair\": {\n \"sourceCurrency\": \"USDT\",\n \"destinationCurrency\": \"USDC\",\n \"sourceNetwork\": \"BASE\",\n \"sourceRail\": \"SEPA\",\n \"destinationNetwork\": \"BASE\",\n \"destinationRail\": \"SEPA\"\n },\n \"amount\": {\n \"value\": \"10000000\",\n \"side\": \"SOURCE\"\n },\n \"maxSlippageBps\": 25\n}"
response = http.request(request)
puts response.read_body{
"id": "quote_abc123",
"pair": {
"sourceCurrency": "USDT",
"destinationCurrency": "USDC",
"sourceNetwork": "BASE",
"sourceRail": "SEPA",
"destinationNetwork": "BASE",
"destinationRail": "SEPA"
},
"amount": {
"value": "10000000",
"side": "SOURCE"
},
"grossSource": "10000000",
"displayedDestination": "9998500",
"rate": "0.9998500",
"expiresAt": "2026-05-26T19:42:00.000Z",
"referenceRate": "1.158691536019208779",
"referenceRateAsOf": "2026-09-02T18:30:04.000Z",
"referenceProvider": "XE",
"quoteBinding": "PERSISTED",
"expectedDepositDetails": {
"kind": "CRYPTO_ADDRESS",
"note": "Deposit instructions become active only when the trade created by accepting this quote includes them — immediately on accept, or after the fx_trade.deposit_instructions_ready event if the trade starts in PENDING_WALLET_APPROVAL. Funds sent before then cannot be matched to a trade.",
"address": "0xCustomerInfiniteTxWallet...",
"network": "BASE"
}
}{
"message": "fx_quote_amount_too_large",
"hint": "Amount is above the maximum for this corridor.",
"limits": {
"sourceCurrency": "USDC",
"min": "0",
"max": "10000000"
},
"requested": "100000000"
}Authorizations
API Key in Bearer format (e.g., Bearer sk_test_...)
Headers
API key
Client-supplied key to deduplicate retries (e.g. on network timeout). Replays return the original quote rather than burning another vendor quote.
Body
Customer this quote is for (the customer who will deposit).
"cus_abc123"
Show child attributes
Show child attributes
Show child attributes
Show child attributes
Per-trade max slippage tolerance on the re-quote step, in basis points (1 bp = 0.01%). Minimum 5, maximum 1000. Optional for stable sources — if omitted, the organization-level default for the pair applies. REQUIRED for volatile sources (e.g. BTC): a quote whose source can move materially across the deposit-confirmation window is rejected when this is omitted, so the tolerance the customer accepts is always explicit.
5 <= x <= 100025
Response
Firm quote created.
"quote_abc123"
Show child attributes
Show child attributes
Show child attributes
Show child attributes
Source amount, fees included, in source-currency minor units.
"10000000"
Destination amount the customer will receive, in destination-currency minor units.
"9998500"
All-in customer rate (displayedDestination / grossSource).
"0.9998500"
When the firm quote expires (ISO 8601).
"2026-05-26T19:42:00.000Z"
Independent reference rate used to price this quote, expressed as destination major units per source major unit. Present for benchmark-priced quotes.
"1.158691536019208779"
Timestamp of the independent reference rate used to price this quote (ISO 8601).
"2026-09-02T18:30:04.000Z"
Independent market that published referenceRate. Present when referenceRate is present.
XE "XE"
How this quote binds to a later trade. PERSISTED: the firm price is held and a trade created from this quote replays it, so accepting later (within expiresAt) is safe. AT_ACCEPT: pricing is finalized when the trade is created, so the price may move between quote and accept.
PERSISTED, AT_ACCEPT "PERSISTED"
Preview of the deposit details the trade will carry once this quote is accepted. Omitted when the preview could not be resolved (the quote itself is unaffected — accept normally and use the deposit instructions on the trade).
Show child attributes
Show child attributes
Was this page helpful?