curl --request POST \
--url https://api.tetrafi.io/api/v1/quotes \
--header 'Content-Type: application/json' \
--header 'X-API-Key: <api-key>' \
--data '
{
"buy": {
"asset": "USDC",
"chain": "eip155:8453"
},
"sell": {
"asset": "USDC",
"chain": "eip155:8453"
},
"buyAmount": "10000",
"deliverTo": {
"financialAccountId": "<string>",
"kind": "financialAccount"
},
"filters": {
"firmOnly": true,
"locations": [],
"modalities": [],
"variants": {},
"venues": {
"exclude": [
"<string>"
],
"include": [
"<string>"
]
}
},
"integrationAppId": "<string>",
"onBehalfOf": "<string>",
"preferredWallets": {},
"priceProtectionBps": 1,
"sellAmount": "10000",
"source": {
"fundingAccountId": "<string>",
"tradingWallets": {},
"venueAccountId": "<string>"
},
"timeout": "PT120S"
}
'import requests
url = "https://api.tetrafi.io/api/v1/quotes"
payload = {
"buy": {
"asset": "USDC",
"chain": "eip155:8453"
},
"sell": {
"asset": "USDC",
"chain": "eip155:8453"
},
"buyAmount": "10000",
"deliverTo": {
"financialAccountId": "<string>",
"kind": "financialAccount"
},
"filters": {
"firmOnly": True,
"locations": [],
"modalities": [],
"variants": {},
"venues": {
"exclude": ["<string>"],
"include": ["<string>"]
}
},
"integrationAppId": "<string>",
"onBehalfOf": "<string>",
"preferredWallets": {},
"priceProtectionBps": 1,
"sellAmount": "10000",
"source": {
"fundingAccountId": "<string>",
"tradingWallets": {},
"venueAccountId": "<string>"
},
"timeout": "PT120S"
}
headers = {
"X-API-Key": "<api-key>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {'X-API-Key': '<api-key>', 'Content-Type': 'application/json'},
body: JSON.stringify({
buy: {asset: 'USDC', chain: 'eip155:8453'},
sell: {asset: 'USDC', chain: 'eip155:8453'},
buyAmount: '10000',
deliverTo: {financialAccountId: '<string>', kind: 'financialAccount'},
filters: {
firmOnly: true,
locations: [],
modalities: [],
variants: {},
venues: {exclude: ['<string>'], include: ['<string>']}
},
integrationAppId: '<string>',
onBehalfOf: '<string>',
preferredWallets: {},
priceProtectionBps: 1,
sellAmount: '10000',
source: {fundingAccountId: '<string>', tradingWallets: {}, venueAccountId: '<string>'},
timeout: 'PT120S'
})
};
fetch('https://api.tetrafi.io/api/v1/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://api.tetrafi.io/api/v1/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([
'buy' => [
'asset' => 'USDC',
'chain' => 'eip155:8453'
],
'sell' => [
'asset' => 'USDC',
'chain' => 'eip155:8453'
],
'buyAmount' => '10000',
'deliverTo' => [
'financialAccountId' => '<string>',
'kind' => 'financialAccount'
],
'filters' => [
'firmOnly' => true,
'locations' => [
],
'modalities' => [
],
'variants' => [
],
'venues' => [
'exclude' => [
'<string>'
],
'include' => [
'<string>'
]
]
],
'integrationAppId' => '<string>',
'onBehalfOf' => '<string>',
'preferredWallets' => [
],
'priceProtectionBps' => 1,
'sellAmount' => '10000',
'source' => [
'fundingAccountId' => '<string>',
'tradingWallets' => [
],
'venueAccountId' => '<string>'
],
'timeout' => 'PT120S'
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json",
"X-API-Key: <api-key>"
],
]);
$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.tetrafi.io/api/v1/quotes"
payload := strings.NewReader("{\n \"buy\": {\n \"asset\": \"USDC\",\n \"chain\": \"eip155:8453\"\n },\n \"sell\": {\n \"asset\": \"USDC\",\n \"chain\": \"eip155:8453\"\n },\n \"buyAmount\": \"10000\",\n \"deliverTo\": {\n \"financialAccountId\": \"<string>\",\n \"kind\": \"financialAccount\"\n },\n \"filters\": {\n \"firmOnly\": true,\n \"locations\": [],\n \"modalities\": [],\n \"variants\": {},\n \"venues\": {\n \"exclude\": [\n \"<string>\"\n ],\n \"include\": [\n \"<string>\"\n ]\n }\n },\n \"integrationAppId\": \"<string>\",\n \"onBehalfOf\": \"<string>\",\n \"preferredWallets\": {},\n \"priceProtectionBps\": 1,\n \"sellAmount\": \"10000\",\n \"source\": {\n \"fundingAccountId\": \"<string>\",\n \"tradingWallets\": {},\n \"venueAccountId\": \"<string>\"\n },\n \"timeout\": \"PT120S\"\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("X-API-Key", "<api-key>")
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.tetrafi.io/api/v1/quotes")
.header("X-API-Key", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"buy\": {\n \"asset\": \"USDC\",\n \"chain\": \"eip155:8453\"\n },\n \"sell\": {\n \"asset\": \"USDC\",\n \"chain\": \"eip155:8453\"\n },\n \"buyAmount\": \"10000\",\n \"deliverTo\": {\n \"financialAccountId\": \"<string>\",\n \"kind\": \"financialAccount\"\n },\n \"filters\": {\n \"firmOnly\": true,\n \"locations\": [],\n \"modalities\": [],\n \"variants\": {},\n \"venues\": {\n \"exclude\": [\n \"<string>\"\n ],\n \"include\": [\n \"<string>\"\n ]\n }\n },\n \"integrationAppId\": \"<string>\",\n \"onBehalfOf\": \"<string>\",\n \"preferredWallets\": {},\n \"priceProtectionBps\": 1,\n \"sellAmount\": \"10000\",\n \"source\": {\n \"fundingAccountId\": \"<string>\",\n \"tradingWallets\": {},\n \"venueAccountId\": \"<string>\"\n },\n \"timeout\": \"PT120S\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.tetrafi.io/api/v1/quotes")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["X-API-Key"] = '<api-key>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"buy\": {\n \"asset\": \"USDC\",\n \"chain\": \"eip155:8453\"\n },\n \"sell\": {\n \"asset\": \"USDC\",\n \"chain\": \"eip155:8453\"\n },\n \"buyAmount\": \"10000\",\n \"deliverTo\": {\n \"financialAccountId\": \"<string>\",\n \"kind\": \"financialAccount\"\n },\n \"filters\": {\n \"firmOnly\": true,\n \"locations\": [],\n \"modalities\": [],\n \"variants\": {},\n \"venues\": {\n \"exclude\": [\n \"<string>\"\n ],\n \"include\": [\n \"<string>\"\n ]\n }\n },\n \"integrationAppId\": \"<string>\",\n \"onBehalfOf\": \"<string>\",\n \"preferredWallets\": {},\n \"priceProtectionBps\": 1,\n \"sellAmount\": \"10000\",\n \"source\": {\n \"fundingAccountId\": \"<string>\",\n \"tradingWallets\": {},\n \"venueAccountId\": \"<string>\"\n },\n \"timeout\": \"PT120S\"\n}"
response = http.request(request)
puts response.read_body{
"quoteRequestId": "rq_01M5Z6TX3X834KT79RBP6X6FQB",
"quotes": [],
"sources": [
{
"asked": false,
"detail": "This account is still being set up. Complete its required activation steps in Treasury before requesting prices.",
"reason": "accountSetupIncomplete",
"status": "unavailable",
"venue": {
"id": "selini-rfq",
"integrationMode": "basic",
"logoUrl": null,
"modality": "rfq",
"name": "Selini Capital",
"protocolVersion": null,
"venueId": "selini",
"venueName": "Selini"
}
}
],
"venueAsked": false
}{
"docUrl": "<string>",
"error": "<string>",
"message": "<string>",
"retryable": true,
"timestamp": 123,
"details": {
"capabilityBlockers": [
{
"code": "WORKSPACE_NOT_FOUND",
"estimate": "minutes",
"message": "<string>",
"unlockStep": "finish_onboarding",
"currentlyDue": [
"<string>"
]
}
],
"conflicts": [
"<string>"
],
"field": "<string>",
"reason": "<string>",
"remediation": "<string>",
"retryAfter": "PT120S",
"value": "<string>"
},
"next": {
"kind": "order"
},
"requestId": "<string>"
}{
"docUrl": "<string>",
"error": "<string>",
"message": "<string>",
"retryable": true,
"timestamp": 123,
"details": {
"capabilityBlockers": [
{
"code": "WORKSPACE_NOT_FOUND",
"estimate": "minutes",
"message": "<string>",
"unlockStep": "finish_onboarding",
"currentlyDue": [
"<string>"
]
}
],
"conflicts": [
"<string>"
],
"field": "<string>",
"reason": "<string>",
"remediation": "<string>",
"retryAfter": "PT120S",
"value": "<string>"
},
"next": {
"kind": "order"
},
"requestId": "<string>"
}{
"docUrl": "<string>",
"error": "<string>",
"message": "<string>",
"retryable": true,
"timestamp": 123,
"details": {
"capabilityBlockers": [
{
"code": "WORKSPACE_NOT_FOUND",
"estimate": "minutes",
"message": "<string>",
"unlockStep": "finish_onboarding",
"currentlyDue": [
"<string>"
]
}
],
"conflicts": [
"<string>"
],
"field": "<string>",
"reason": "<string>",
"remediation": "<string>",
"retryAfter": "PT120S",
"value": "<string>"
},
"next": {
"kind": "order"
},
"requestId": "<string>"
}{
"docUrl": "<string>",
"error": "<string>",
"message": "<string>",
"retryable": true,
"timestamp": 123,
"details": {
"capabilityBlockers": [
{
"code": "WORKSPACE_NOT_FOUND",
"estimate": "minutes",
"message": "<string>",
"unlockStep": "finish_onboarding",
"currentlyDue": [
"<string>"
]
}
],
"conflicts": [
"<string>"
],
"field": "<string>",
"reason": "<string>",
"remediation": "<string>",
"retryAfter": "PT120S",
"value": "<string>"
},
"next": {
"kind": "order"
},
"requestId": "<string>"
}{
"docUrl": "<string>",
"error": "<string>",
"message": "<string>",
"retryable": true,
"timestamp": 123,
"details": {
"capabilityBlockers": [
{
"code": "WORKSPACE_NOT_FOUND",
"estimate": "minutes",
"message": "<string>",
"unlockStep": "finish_onboarding",
"currentlyDue": [
"<string>"
]
}
],
"conflicts": [
"<string>"
],
"field": "<string>",
"reason": "<string>",
"remediation": "<string>",
"retryAfter": "PT120S",
"value": "<string>"
},
"next": {
"kind": "order"
},
"requestId": "<string>"
}{
"docUrl": "<string>",
"error": "<string>",
"message": "<string>",
"retryable": true,
"timestamp": 123,
"details": {
"capabilityBlockers": [
{
"code": "WORKSPACE_NOT_FOUND",
"estimate": "minutes",
"message": "<string>",
"unlockStep": "finish_onboarding",
"currentlyDue": [
"<string>"
]
}
],
"conflicts": [
"<string>"
],
"field": "<string>",
"reason": "<string>",
"remediation": "<string>",
"retryAfter": "PT120S",
"value": "<string>"
},
"next": {
"kind": "order"
},
"requestId": "<string>"
}{
"docUrl": "<string>",
"error": "<string>",
"message": "<string>",
"retryable": true,
"timestamp": 123,
"details": {
"capabilityBlockers": [
{
"code": "WORKSPACE_NOT_FOUND",
"estimate": "minutes",
"message": "<string>",
"unlockStep": "finish_onboarding",
"currentlyDue": [
"<string>"
]
}
],
"conflicts": [
"<string>"
],
"field": "<string>",
"reason": "<string>",
"remediation": "<string>",
"retryAfter": "PT120S",
"value": "<string>"
},
"next": {
"kind": "order"
},
"requestId": "<string>"
}{
"docUrl": "<string>",
"error": "<string>",
"message": "<string>",
"retryable": true,
"timestamp": 123,
"details": {
"capabilityBlockers": [
{
"code": "WORKSPACE_NOT_FOUND",
"estimate": "minutes",
"message": "<string>",
"unlockStep": "finish_onboarding",
"currentlyDue": [
"<string>"
]
}
],
"conflicts": [
"<string>"
],
"field": "<string>",
"reason": "<string>",
"remediation": "<string>",
"retryAfter": "PT120S",
"value": "<string>"
},
"next": {
"kind": "order"
},
"requestId": "<string>"
}{
"docUrl": "<string>",
"error": "<string>",
"message": "<string>",
"retryable": true,
"timestamp": 123,
"details": {
"capabilityBlockers": [
{
"code": "WORKSPACE_NOT_FOUND",
"estimate": "minutes",
"message": "<string>",
"unlockStep": "finish_onboarding",
"currentlyDue": [
"<string>"
]
}
],
"conflicts": [
"<string>"
],
"field": "<string>",
"reason": "<string>",
"remediation": "<string>",
"retryAfter": "PT120S",
"value": "<string>"
},
"next": {
"kind": "order"
},
"requestId": "<string>"
}{
"docUrl": "<string>",
"error": "<string>",
"message": "<string>",
"retryable": true,
"timestamp": 123,
"details": {
"capabilityBlockers": [
{
"code": "WORKSPACE_NOT_FOUND",
"estimate": "minutes",
"message": "<string>",
"unlockStep": "finish_onboarding",
"currentlyDue": [
"<string>"
]
}
],
"conflicts": [
"<string>"
],
"field": "<string>",
"reason": "<string>",
"remediation": "<string>",
"retryAfter": "PT120S",
"value": "<string>"
},
"next": {
"kind": "order"
},
"requestId": "<string>"
}{
"docUrl": "<string>",
"error": "<string>",
"message": "<string>",
"retryable": true,
"timestamp": 123,
"details": {
"capabilityBlockers": [
{
"code": "WORKSPACE_NOT_FOUND",
"estimate": "minutes",
"message": "<string>",
"unlockStep": "finish_onboarding",
"currentlyDue": [
"<string>"
]
}
],
"conflicts": [
"<string>"
],
"field": "<string>",
"reason": "<string>",
"remediation": "<string>",
"retryAfter": "PT120S",
"value": "<string>"
},
"next": {
"kind": "order"
},
"requestId": "<string>"
}{
"docUrl": "<string>",
"error": "<string>",
"message": "<string>",
"retryable": true,
"timestamp": 123,
"details": {
"capabilityBlockers": [
{
"code": "WORKSPACE_NOT_FOUND",
"estimate": "minutes",
"message": "<string>",
"unlockStep": "finish_onboarding",
"currentlyDue": [
"<string>"
]
}
],
"conflicts": [
"<string>"
],
"field": "<string>",
"reason": "<string>",
"remediation": "<string>",
"retryAfter": "PT120S",
"value": "<string>"
},
"next": {
"kind": "order"
},
"requestId": "<string>"
}{
"docUrl": "<string>",
"error": "<string>",
"message": "<string>",
"retryable": true,
"timestamp": 123,
"details": {
"capabilityBlockers": [
{
"code": "WORKSPACE_NOT_FOUND",
"estimate": "minutes",
"message": "<string>",
"unlockStep": "finish_onboarding",
"currentlyDue": [
"<string>"
]
}
],
"conflicts": [
"<string>"
],
"field": "<string>",
"reason": "<string>",
"remediation": "<string>",
"retryAfter": "PT120S",
"value": "<string>"
},
"next": {
"kind": "order"
},
"requestId": "<string>"
}Unified protocol and venue-account quote auction
curl --request POST \
--url https://api.tetrafi.io/api/v1/quotes \
--header 'Content-Type: application/json' \
--header 'X-API-Key: <api-key>' \
--data '
{
"buy": {
"asset": "USDC",
"chain": "eip155:8453"
},
"sell": {
"asset": "USDC",
"chain": "eip155:8453"
},
"buyAmount": "10000",
"deliverTo": {
"financialAccountId": "<string>",
"kind": "financialAccount"
},
"filters": {
"firmOnly": true,
"locations": [],
"modalities": [],
"variants": {},
"venues": {
"exclude": [
"<string>"
],
"include": [
"<string>"
]
}
},
"integrationAppId": "<string>",
"onBehalfOf": "<string>",
"preferredWallets": {},
"priceProtectionBps": 1,
"sellAmount": "10000",
"source": {
"fundingAccountId": "<string>",
"tradingWallets": {},
"venueAccountId": "<string>"
},
"timeout": "PT120S"
}
'import requests
url = "https://api.tetrafi.io/api/v1/quotes"
payload = {
"buy": {
"asset": "USDC",
"chain": "eip155:8453"
},
"sell": {
"asset": "USDC",
"chain": "eip155:8453"
},
"buyAmount": "10000",
"deliverTo": {
"financialAccountId": "<string>",
"kind": "financialAccount"
},
"filters": {
"firmOnly": True,
"locations": [],
"modalities": [],
"variants": {},
"venues": {
"exclude": ["<string>"],
"include": ["<string>"]
}
},
"integrationAppId": "<string>",
"onBehalfOf": "<string>",
"preferredWallets": {},
"priceProtectionBps": 1,
"sellAmount": "10000",
"source": {
"fundingAccountId": "<string>",
"tradingWallets": {},
"venueAccountId": "<string>"
},
"timeout": "PT120S"
}
headers = {
"X-API-Key": "<api-key>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {'X-API-Key': '<api-key>', 'Content-Type': 'application/json'},
body: JSON.stringify({
buy: {asset: 'USDC', chain: 'eip155:8453'},
sell: {asset: 'USDC', chain: 'eip155:8453'},
buyAmount: '10000',
deliverTo: {financialAccountId: '<string>', kind: 'financialAccount'},
filters: {
firmOnly: true,
locations: [],
modalities: [],
variants: {},
venues: {exclude: ['<string>'], include: ['<string>']}
},
integrationAppId: '<string>',
onBehalfOf: '<string>',
preferredWallets: {},
priceProtectionBps: 1,
sellAmount: '10000',
source: {fundingAccountId: '<string>', tradingWallets: {}, venueAccountId: '<string>'},
timeout: 'PT120S'
})
};
fetch('https://api.tetrafi.io/api/v1/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://api.tetrafi.io/api/v1/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([
'buy' => [
'asset' => 'USDC',
'chain' => 'eip155:8453'
],
'sell' => [
'asset' => 'USDC',
'chain' => 'eip155:8453'
],
'buyAmount' => '10000',
'deliverTo' => [
'financialAccountId' => '<string>',
'kind' => 'financialAccount'
],
'filters' => [
'firmOnly' => true,
'locations' => [
],
'modalities' => [
],
'variants' => [
],
'venues' => [
'exclude' => [
'<string>'
],
'include' => [
'<string>'
]
]
],
'integrationAppId' => '<string>',
'onBehalfOf' => '<string>',
'preferredWallets' => [
],
'priceProtectionBps' => 1,
'sellAmount' => '10000',
'source' => [
'fundingAccountId' => '<string>',
'tradingWallets' => [
],
'venueAccountId' => '<string>'
],
'timeout' => 'PT120S'
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json",
"X-API-Key: <api-key>"
],
]);
$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.tetrafi.io/api/v1/quotes"
payload := strings.NewReader("{\n \"buy\": {\n \"asset\": \"USDC\",\n \"chain\": \"eip155:8453\"\n },\n \"sell\": {\n \"asset\": \"USDC\",\n \"chain\": \"eip155:8453\"\n },\n \"buyAmount\": \"10000\",\n \"deliverTo\": {\n \"financialAccountId\": \"<string>\",\n \"kind\": \"financialAccount\"\n },\n \"filters\": {\n \"firmOnly\": true,\n \"locations\": [],\n \"modalities\": [],\n \"variants\": {},\n \"venues\": {\n \"exclude\": [\n \"<string>\"\n ],\n \"include\": [\n \"<string>\"\n ]\n }\n },\n \"integrationAppId\": \"<string>\",\n \"onBehalfOf\": \"<string>\",\n \"preferredWallets\": {},\n \"priceProtectionBps\": 1,\n \"sellAmount\": \"10000\",\n \"source\": {\n \"fundingAccountId\": \"<string>\",\n \"tradingWallets\": {},\n \"venueAccountId\": \"<string>\"\n },\n \"timeout\": \"PT120S\"\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("X-API-Key", "<api-key>")
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.tetrafi.io/api/v1/quotes")
.header("X-API-Key", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"buy\": {\n \"asset\": \"USDC\",\n \"chain\": \"eip155:8453\"\n },\n \"sell\": {\n \"asset\": \"USDC\",\n \"chain\": \"eip155:8453\"\n },\n \"buyAmount\": \"10000\",\n \"deliverTo\": {\n \"financialAccountId\": \"<string>\",\n \"kind\": \"financialAccount\"\n },\n \"filters\": {\n \"firmOnly\": true,\n \"locations\": [],\n \"modalities\": [],\n \"variants\": {},\n \"venues\": {\n \"exclude\": [\n \"<string>\"\n ],\n \"include\": [\n \"<string>\"\n ]\n }\n },\n \"integrationAppId\": \"<string>\",\n \"onBehalfOf\": \"<string>\",\n \"preferredWallets\": {},\n \"priceProtectionBps\": 1,\n \"sellAmount\": \"10000\",\n \"source\": {\n \"fundingAccountId\": \"<string>\",\n \"tradingWallets\": {},\n \"venueAccountId\": \"<string>\"\n },\n \"timeout\": \"PT120S\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.tetrafi.io/api/v1/quotes")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["X-API-Key"] = '<api-key>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"buy\": {\n \"asset\": \"USDC\",\n \"chain\": \"eip155:8453\"\n },\n \"sell\": {\n \"asset\": \"USDC\",\n \"chain\": \"eip155:8453\"\n },\n \"buyAmount\": \"10000\",\n \"deliverTo\": {\n \"financialAccountId\": \"<string>\",\n \"kind\": \"financialAccount\"\n },\n \"filters\": {\n \"firmOnly\": true,\n \"locations\": [],\n \"modalities\": [],\n \"variants\": {},\n \"venues\": {\n \"exclude\": [\n \"<string>\"\n ],\n \"include\": [\n \"<string>\"\n ]\n }\n },\n \"integrationAppId\": \"<string>\",\n \"onBehalfOf\": \"<string>\",\n \"preferredWallets\": {},\n \"priceProtectionBps\": 1,\n \"sellAmount\": \"10000\",\n \"source\": {\n \"fundingAccountId\": \"<string>\",\n \"tradingWallets\": {},\n \"venueAccountId\": \"<string>\"\n },\n \"timeout\": \"PT120S\"\n}"
response = http.request(request)
puts response.read_body{
"quoteRequestId": "rq_01M5Z6TX3X834KT79RBP6X6FQB",
"quotes": [],
"sources": [
{
"asked": false,
"detail": "This account is still being set up. Complete its required activation steps in Treasury before requesting prices.",
"reason": "accountSetupIncomplete",
"status": "unavailable",
"venue": {
"id": "selini-rfq",
"integrationMode": "basic",
"logoUrl": null,
"modality": "rfq",
"name": "Selini Capital",
"protocolVersion": null,
"venueId": "selini",
"venueName": "Selini"
}
}
],
"venueAsked": false
}{
"docUrl": "<string>",
"error": "<string>",
"message": "<string>",
"retryable": true,
"timestamp": 123,
"details": {
"capabilityBlockers": [
{
"code": "WORKSPACE_NOT_FOUND",
"estimate": "minutes",
"message": "<string>",
"unlockStep": "finish_onboarding",
"currentlyDue": [
"<string>"
]
}
],
"conflicts": [
"<string>"
],
"field": "<string>",
"reason": "<string>",
"remediation": "<string>",
"retryAfter": "PT120S",
"value": "<string>"
},
"next": {
"kind": "order"
},
"requestId": "<string>"
}{
"docUrl": "<string>",
"error": "<string>",
"message": "<string>",
"retryable": true,
"timestamp": 123,
"details": {
"capabilityBlockers": [
{
"code": "WORKSPACE_NOT_FOUND",
"estimate": "minutes",
"message": "<string>",
"unlockStep": "finish_onboarding",
"currentlyDue": [
"<string>"
]
}
],
"conflicts": [
"<string>"
],
"field": "<string>",
"reason": "<string>",
"remediation": "<string>",
"retryAfter": "PT120S",
"value": "<string>"
},
"next": {
"kind": "order"
},
"requestId": "<string>"
}{
"docUrl": "<string>",
"error": "<string>",
"message": "<string>",
"retryable": true,
"timestamp": 123,
"details": {
"capabilityBlockers": [
{
"code": "WORKSPACE_NOT_FOUND",
"estimate": "minutes",
"message": "<string>",
"unlockStep": "finish_onboarding",
"currentlyDue": [
"<string>"
]
}
],
"conflicts": [
"<string>"
],
"field": "<string>",
"reason": "<string>",
"remediation": "<string>",
"retryAfter": "PT120S",
"value": "<string>"
},
"next": {
"kind": "order"
},
"requestId": "<string>"
}{
"docUrl": "<string>",
"error": "<string>",
"message": "<string>",
"retryable": true,
"timestamp": 123,
"details": {
"capabilityBlockers": [
{
"code": "WORKSPACE_NOT_FOUND",
"estimate": "minutes",
"message": "<string>",
"unlockStep": "finish_onboarding",
"currentlyDue": [
"<string>"
]
}
],
"conflicts": [
"<string>"
],
"field": "<string>",
"reason": "<string>",
"remediation": "<string>",
"retryAfter": "PT120S",
"value": "<string>"
},
"next": {
"kind": "order"
},
"requestId": "<string>"
}{
"docUrl": "<string>",
"error": "<string>",
"message": "<string>",
"retryable": true,
"timestamp": 123,
"details": {
"capabilityBlockers": [
{
"code": "WORKSPACE_NOT_FOUND",
"estimate": "minutes",
"message": "<string>",
"unlockStep": "finish_onboarding",
"currentlyDue": [
"<string>"
]
}
],
"conflicts": [
"<string>"
],
"field": "<string>",
"reason": "<string>",
"remediation": "<string>",
"retryAfter": "PT120S",
"value": "<string>"
},
"next": {
"kind": "order"
},
"requestId": "<string>"
}{
"docUrl": "<string>",
"error": "<string>",
"message": "<string>",
"retryable": true,
"timestamp": 123,
"details": {
"capabilityBlockers": [
{
"code": "WORKSPACE_NOT_FOUND",
"estimate": "minutes",
"message": "<string>",
"unlockStep": "finish_onboarding",
"currentlyDue": [
"<string>"
]
}
],
"conflicts": [
"<string>"
],
"field": "<string>",
"reason": "<string>",
"remediation": "<string>",
"retryAfter": "PT120S",
"value": "<string>"
},
"next": {
"kind": "order"
},
"requestId": "<string>"
}{
"docUrl": "<string>",
"error": "<string>",
"message": "<string>",
"retryable": true,
"timestamp": 123,
"details": {
"capabilityBlockers": [
{
"code": "WORKSPACE_NOT_FOUND",
"estimate": "minutes",
"message": "<string>",
"unlockStep": "finish_onboarding",
"currentlyDue": [
"<string>"
]
}
],
"conflicts": [
"<string>"
],
"field": "<string>",
"reason": "<string>",
"remediation": "<string>",
"retryAfter": "PT120S",
"value": "<string>"
},
"next": {
"kind": "order"
},
"requestId": "<string>"
}{
"docUrl": "<string>",
"error": "<string>",
"message": "<string>",
"retryable": true,
"timestamp": 123,
"details": {
"capabilityBlockers": [
{
"code": "WORKSPACE_NOT_FOUND",
"estimate": "minutes",
"message": "<string>",
"unlockStep": "finish_onboarding",
"currentlyDue": [
"<string>"
]
}
],
"conflicts": [
"<string>"
],
"field": "<string>",
"reason": "<string>",
"remediation": "<string>",
"retryAfter": "PT120S",
"value": "<string>"
},
"next": {
"kind": "order"
},
"requestId": "<string>"
}{
"docUrl": "<string>",
"error": "<string>",
"message": "<string>",
"retryable": true,
"timestamp": 123,
"details": {
"capabilityBlockers": [
{
"code": "WORKSPACE_NOT_FOUND",
"estimate": "minutes",
"message": "<string>",
"unlockStep": "finish_onboarding",
"currentlyDue": [
"<string>"
]
}
],
"conflicts": [
"<string>"
],
"field": "<string>",
"reason": "<string>",
"remediation": "<string>",
"retryAfter": "PT120S",
"value": "<string>"
},
"next": {
"kind": "order"
},
"requestId": "<string>"
}{
"docUrl": "<string>",
"error": "<string>",
"message": "<string>",
"retryable": true,
"timestamp": 123,
"details": {
"capabilityBlockers": [
{
"code": "WORKSPACE_NOT_FOUND",
"estimate": "minutes",
"message": "<string>",
"unlockStep": "finish_onboarding",
"currentlyDue": [
"<string>"
]
}
],
"conflicts": [
"<string>"
],
"field": "<string>",
"reason": "<string>",
"remediation": "<string>",
"retryAfter": "PT120S",
"value": "<string>"
},
"next": {
"kind": "order"
},
"requestId": "<string>"
}{
"docUrl": "<string>",
"error": "<string>",
"message": "<string>",
"retryable": true,
"timestamp": 123,
"details": {
"capabilityBlockers": [
{
"code": "WORKSPACE_NOT_FOUND",
"estimate": "minutes",
"message": "<string>",
"unlockStep": "finish_onboarding",
"currentlyDue": [
"<string>"
]
}
],
"conflicts": [
"<string>"
],
"field": "<string>",
"reason": "<string>",
"remediation": "<string>",
"retryAfter": "PT120S",
"value": "<string>"
},
"next": {
"kind": "order"
},
"requestId": "<string>"
}{
"docUrl": "<string>",
"error": "<string>",
"message": "<string>",
"retryable": true,
"timestamp": 123,
"details": {
"capabilityBlockers": [
{
"code": "WORKSPACE_NOT_FOUND",
"estimate": "minutes",
"message": "<string>",
"unlockStep": "finish_onboarding",
"currentlyDue": [
"<string>"
]
}
],
"conflicts": [
"<string>"
],
"field": "<string>",
"reason": "<string>",
"remediation": "<string>",
"retryAfter": "PT120S",
"value": "<string>"
},
"next": {
"kind": "order"
},
"requestId": "<string>"
}{
"docUrl": "<string>",
"error": "<string>",
"message": "<string>",
"retryable": true,
"timestamp": 123,
"details": {
"capabilityBlockers": [
{
"code": "WORKSPACE_NOT_FOUND",
"estimate": "minutes",
"message": "<string>",
"unlockStep": "finish_onboarding",
"currentlyDue": [
"<string>"
]
}
],
"conflicts": [
"<string>"
],
"field": "<string>",
"reason": "<string>",
"remediation": "<string>",
"retryAfter": "PT120S",
"value": "<string>"
},
"next": {
"kind": "order"
},
"requestId": "<string>"
}Authorizations
Send the API key in X-API-Key.
Request signing. A key with signing enabled (POST /api/v1/workspaces/{workspaceId}/users/me/api-keys/{keyId}/signing, which returns the signing secret once) must also sign every request:
X-Timestamp: the current Unix time in seconds, within 300 seconds of the server clock.X-Signature: lower-case hex HMAC-SHA256 of the canonical string, keyed with the signing secret's 32 bytes (the secret is 64 hex characters; decode it first).
The canonical string is four lines joined by \n, with no trailing newline: the X-Timestamp value, the upper-case method, the path with its query exactly as sent (/api/v1/orders?limit=1), and the lower-case hex SHA-256 of the exact body bytes (the SHA-256 of an empty body when there is none).
A write's signature (POST, PUT, PATCH, DELETE) is accepted once: sending the same signed write again is refused, so a retry signs again. A read (GET, HEAD) changes nothing, so an identical signed read inside the window is admitted again and polling needs no nonce.
A signing refusal is a 401 AUTH_REQUIRED whose details.reason names the cause: SIGNATURE_REQUIRED (a header is missing), SIGNATURE_INVALID (a malformed header or a wrong signature), TIMESTAMP_OUT_OF_RANGE or SIGNATURE_REPLAYED.
Headers
The workspace the request acts in. An API key bound to a workspace implies it: omit the header, or send that same id (another id answers 403 WORKSPACE_SCOPE_MISMATCH). A member session must send it (400 MISSING_WORKSPACE without it).
Body
- Option 1
- Option 2
The POST /quotes request body, told apart by shape: a top-level requote is a
Requote; any other object is a pair request (the legacy intent body is retired).
The Asset the taker buys, and optionally its chain.
Show child attributes
Show child attributes
The Asset the taker sells, and optionally its chain.
Show child attributes
Show child attributes
The exact amount to buy, a positive decimal string in Asset units. Exactly one of
sellAmount and buyAmount.
"10000"
Output to own money, a third-party payee, or an explicit chain address.
New values may be added; treat unknown values as other.
- Option 1
- Option 2
- Option 3
Show child attributes
Show child attributes
The public request's narrowing filters; an omitted filter means all.
Show child attributes
Show child attributes
The direct user a broker quotes for.
Per CAIP-2 chain: a wallet the caller prefers to sell from, by target id or address. A
preference, not a choice: a venue account uses it only where it is one of that account's
linked wallets on the venue's network, and otherwise quotes from its own default; a venue is
never refused because of it. source.tradingWallets is the explicit choice and wins on its chain.
Show child attributes
Show child attributes
The bound between a non-firm executable quote and what execution delivers.
x >= 0The exact amount to sell, a positive decimal string in Asset units. Exactly one of
sellAmount and buyAmount (400 INVALID_REQUEST naming both otherwise).
"10000"
Default netReceived.
netReceived, eta An explicit request choice. Every value is a financial-account id.
Show child attributes
Show child attributes
Collection deadline, an ISO 8601 duration; default PT6S, at least 100 milliseconds and at
most PT10S.
^PT(?:[0-9]+H(?:[0-9]+M)?(?:[0-9]+(?:\.[0-9]{1,3})?S)?|[0-9]+M(?:[0-9]+(?:\.[0-9]{1,3})?S)?|[0-9]+(?:\.[0-9]{1,3})?S)$"PT120S"
Response
Quotes aggregated successfully: a PairQuoteSet. Accept: text/event-stream selects JSON-data SSE events: quote (PairQuote), source (QuoteSourceEntry), complete (PairQuoteSet), error. A venue the workspace's LP relationship does not allow reads restricted venueRelationship with neutral words in detail and is never asked. Event IDs increase monotonically; the stream includes keepalive comments. Example: broad USD 25000 to USDC, Selini source unavailable accountSetupIncomplete and asked=false; captured live (rfq 2ef31a1ea), one of twelve sources retained and referenceMid omitted. No Selini price or firm ask is implied; Selini USD settlement precision is six decimal places.
POST /quotes 200 body: the quote set. Schema only.
The quote set's id (rq_…), read back at GET /quotes/requests/{quoteRequestId}.
The HTTP request id is separate (X-Request-Id, an error body's requestId).
One venue's quote for the pair. Every field is always present; one that does not
apply to the quote's firmness is null:
| field | indicative | executable, firm | executable, non-firm |
|---|---|---|---|
firm | false | true | false |
expiresAt | null | set | set |
minOut | null | null | set |
observedAt, staleAfter | set | null | null |
A stub (sources[].priceOnRequest) is indicative with null amounts.
The example is an executable non-firm quote: 10000 USDC paid,
buy.amount 9996.0 USDT lands after the included 4.0 USDT provider fee;
netReceived 9994.8 also subtracts the 0.0004 ETH network fee the taker pays
separately (included: false, about 1.2 USDT at the Reference mid), so it is lower
than buy.amount; minOut 9966.01 (30 bps) bounds buy.amount, not
netReceived.
- Option 1
- Option 2
Show child attributes
Show child attributes
{
"advisories": [],
"assurance": null,
"basis": "liveQuote",
"buy": {
"amount": "9996.0",
"asset": "USDT",
"chain": "eip155:8453",
"variant": { "kind": "native", "name": "USDT" }
},
"corridors": [{ "from": "eip155:1", "to": "eip155:8453" }],
"eta": "PT40S",
"expiresAt": "2026-10-17T10:01:00Z",
"failureHandling": "refundOnSource",
"fees": [
{
"amount": "4.0",
"asset": "USDT",
"chain": null,
"included": true,
"kind": "provider",
"leg": 0,
"paidBy": "taker"
},
{
"amount": "0.0004",
"asset": "ETH",
"chain": "eip155:42161",
"included": false,
"kind": "network",
"leg": 0,
"paidBy": "taker"
}
],
"firm": false,
"id": "q_01JAY7Q5M3ZK8V2N4R6T8W0XYB",
"lastLook": false,
"legs": [
{
"expectedArrival": null,
"fundingModel": null,
"location": {
"from": "eip155:42161",
"kind": "crossChain",
"to": "eip155:8453"
},
"venue": {
"id": "tetrafi-solver",
"logoUrl": null,
"modality": "solver",
"name": "TetraFi Solver",
"protocolVersion": null
}
}
],
"location": { "kind": "crossChain" },
"minOut": "9966.01",
"minReceiveRequired": false,
"netReceived": { "amount": "9994.8", "kind": "known" },
"next": { "kind": "sign", "typedData": {} },
"observedAt": null,
"readiness": { "kind": "ready" },
"requoteOf": null,
"screening": "screened",
"sell": {
"amount": "10000",
"asset": "USDC",
"chain": "eip155:42161",
"variant": { "kind": "native", "name": "USDC" }
},
"signaturesRequired": 1,
"spreadFromMidBps": { "bps": 6, "kind": "known" },
"staleAfter": null
}
The trading wallets this caller may name in source.tradingWallets, per network:
each one's stored financial account (acct_…), scoped to the principal (an API key
sees only the organisation wallets granted to it). Sent even when no card was priced,
so an unbound request learns what to bind. Empty when none is usable.
New values may be added; treat unknown values as other.
- Option 1
- Option 2
- Option 3
- Option 4
Show child attributes
Show child attributes
Every considered venue, with its outcome.
One considered venue's outcome, a closed set tagged status:
| status | meaning |
|---|---|
asking | in flight on the stream only: the auction is consulting this venue now; its final outcome replaces it under the same venue key, and none remains at complete |
answered | the venue produced a quote |
needsWallet | no wallet of family to ask with |
walletRefused | the bound wallet is refused (Revoked, a confirmed sanctions hit) |
firmQuoteLimited | a desk's firm-quote cap applies; explanation is product copy |
priceOnRequest | no venue price was requested; quoteId identifies the held estimate or stub to Requote |
askLimitReached | the venue's ask limit is reached for now; retryAfter says when to ask again |
timedOut | no answer inside the deadline |
refused | the venue refused the live ask |
restricted | a gate kept the venue from this principal |
unsupported | the venue does not serve the pair |
filteredOut | the request's own filters exclude it (never a coverage or chain gap) |
unavailable | a read failed (admissionUnavailable, …) |
An unscreened default wallet is not a status: the quote carries screening. venue
is the venue block, its id the one quote legs and /prices rows carry. Durations
(retryAfter) are ISO 8601, counted from when the response was sent. Every entry
carries asked: whether this venue was consulted for this request: a live ask, or a
fresh read of its published book or live desk price within that source's freshness
window. An estimate no venue gave (a model or reference price) is not consulted, and
an answered entry is always consulted. How a card's price was obtained is its own
price basis, never this flag.
New values may be added; treat unknown values as other.
- Option 1
- Option 2
- Option 3
- Option 4
- Option 5
- Option 6
- Option 7
- Option 8
- Option 9
- Option 10
- Option 11
- Option 12
- Option 13
- Option 14
Show child attributes
Show child attributes
Whether answering this request contacted any venue (a live or firm ask), always
sent; false when every quote came from cache.
The Reference mid this request's cards were priced against, read once per request.
Absent when the read failed or ran past its budget: the cards then read
noReferenceMid, never a spread of 0.
Show child attributes
Show child attributes