curl --request POST \
--url https://platform.spritz.finance/v1/off-ramp-quotes/ \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"accountId": "6a9fee5c215e5530b3530e70",
"amount": "100.00",
"tokenAddress": "0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48",
"memo": "Invoice #1234"
}
'import requests
url = "https://platform.spritz.finance/v1/off-ramp-quotes/"
payload = {
"accountId": "6a9fee5c215e5530b3530e70",
"amount": "100.00",
"tokenAddress": "0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48",
"memo": "Invoice #1234"
}
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({
accountId: '6a9fee5c215e5530b3530e70',
amount: '100.00',
tokenAddress: '0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48',
memo: 'Invoice #1234'
})
};
fetch('https://platform.spritz.finance/v1/off-ramp-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://platform.spritz.finance/v1/off-ramp-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([
'accountId' => '6a9fee5c215e5530b3530e70',
'amount' => '100.00',
'tokenAddress' => '0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48',
'memo' => 'Invoice #1234'
]),
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://platform.spritz.finance/v1/off-ramp-quotes/"
payload := strings.NewReader("{\n \"accountId\": \"6a9fee5c215e5530b3530e70\",\n \"amount\": \"100.00\",\n \"tokenAddress\": \"0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48\",\n \"memo\": \"Invoice #1234\"\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://platform.spritz.finance/v1/off-ramp-quotes/")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"accountId\": \"6a9fee5c215e5530b3530e70\",\n \"amount\": \"100.00\",\n \"tokenAddress\": \"0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48\",\n \"memo\": \"Invoice #1234\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://platform.spritz.finance/v1/off-ramp-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 \"accountId\": \"6a9fee5c215e5530b3530e70\",\n \"amount\": \"100.00\",\n \"tokenAddress\": \"0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48\",\n \"memo\": \"Invoice #1234\"\n}"
response = http.request(request)
puts response.read_body{
"id": "6a99b7bacc18094dfe644ba6",
"fulfillment": "sign_transaction",
"status": "created",
"createdAt": "2026-09-08T11:15:40.722Z",
"input": {
"amount": "101.50",
"currency": "USD",
"tokenAddress": "0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48",
"chain": "ethereum"
},
"output": {
"amount": "89.25",
"currency": "EUR",
"rail": "ach_standard",
"accountId": "6a9fee5c215e5530b3530e71",
"estimated": true,
"exchangeRate": {
"baseCurrency": "USD",
"quoteCurrency": "EUR",
"rate": "0.92010309"
}
},
"fees": {
"amount": "1.25",
"currency": "USD"
},
"sendTo": {
"address": "bc1qxy2kgdygjrsqtzq2n0yrf2493p83kkfjhx0wlh",
"amount": "0.00094877",
"token": "BTC",
"expiresAt": "2023-11-07T05:31:56Z"
},
"confirmation": {
"transactionHash": "0xabc123...",
"explorerUrl": "https://etherscan.io/tx/0xabc123..."
},
"offRampId": "6a99b80613a0c37251651788"
}{
"title": "Unauthorized",
"status": 401,
"type": "urn:problem-type:auth:unauthorized",
"detail": "Bearer token required",
"instance": "<string>",
"realm": "API",
"scope": "read:users"
}{
"title": "<string>",
"status": 404,
"resourceType": "user",
"resourceId": "<string>",
"type": "about:blank",
"detail": "<string>",
"instance": "<string>"
}{
"title": "Unauthorized",
"status": 400,
"type": "urn:problem-type:auth:unauthorized",
"detail": "<string>",
"instance": "/errors/1234567890",
"code": "transaction_limit",
"field": "amountUsd",
"retryable": true,
"retryAfter": 5,
"suggestedAction": "auto_ramp",
"clearsAt": "2023-11-07T05:31:56Z",
"availableAt": "2023-11-07T05:31:56Z",
"permanent": true
}Create an off-ramp quote
Creates a quote to convert crypto to fiat. Check fulfillment to determine the next step:
sign_transaction: CallPOST /off-ramp-quotes/{id}/transactionfor calldata, sign, and submit on-chain.send_to_address: Send crypto tosendTo.addressbeforesendTo.expiresAt.
Amount modes: output (default) fixes the destination fiat amount and remains supported for USD destinations. EUR destinations require input: amount is the exact USD value Spritz collects, while quote output is an estimate. Actual settlement is reported by the off-ramp resource.
curl --request POST \
--url https://platform.spritz.finance/v1/off-ramp-quotes/ \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"accountId": "6a9fee5c215e5530b3530e70",
"amount": "100.00",
"tokenAddress": "0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48",
"memo": "Invoice #1234"
}
'import requests
url = "https://platform.spritz.finance/v1/off-ramp-quotes/"
payload = {
"accountId": "6a9fee5c215e5530b3530e70",
"amount": "100.00",
"tokenAddress": "0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48",
"memo": "Invoice #1234"
}
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({
accountId: '6a9fee5c215e5530b3530e70',
amount: '100.00',
tokenAddress: '0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48',
memo: 'Invoice #1234'
})
};
fetch('https://platform.spritz.finance/v1/off-ramp-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://platform.spritz.finance/v1/off-ramp-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([
'accountId' => '6a9fee5c215e5530b3530e70',
'amount' => '100.00',
'tokenAddress' => '0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48',
'memo' => 'Invoice #1234'
]),
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://platform.spritz.finance/v1/off-ramp-quotes/"
payload := strings.NewReader("{\n \"accountId\": \"6a9fee5c215e5530b3530e70\",\n \"amount\": \"100.00\",\n \"tokenAddress\": \"0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48\",\n \"memo\": \"Invoice #1234\"\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://platform.spritz.finance/v1/off-ramp-quotes/")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"accountId\": \"6a9fee5c215e5530b3530e70\",\n \"amount\": \"100.00\",\n \"tokenAddress\": \"0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48\",\n \"memo\": \"Invoice #1234\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://platform.spritz.finance/v1/off-ramp-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 \"accountId\": \"6a9fee5c215e5530b3530e70\",\n \"amount\": \"100.00\",\n \"tokenAddress\": \"0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48\",\n \"memo\": \"Invoice #1234\"\n}"
response = http.request(request)
puts response.read_body{
"id": "6a99b7bacc18094dfe644ba6",
"fulfillment": "sign_transaction",
"status": "created",
"createdAt": "2026-09-08T11:15:40.722Z",
"input": {
"amount": "101.50",
"currency": "USD",
"tokenAddress": "0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48",
"chain": "ethereum"
},
"output": {
"amount": "89.25",
"currency": "EUR",
"rail": "ach_standard",
"accountId": "6a9fee5c215e5530b3530e71",
"estimated": true,
"exchangeRate": {
"baseCurrency": "USD",
"quoteCurrency": "EUR",
"rate": "0.92010309"
}
},
"fees": {
"amount": "1.25",
"currency": "USD"
},
"sendTo": {
"address": "bc1qxy2kgdygjrsqtzq2n0yrf2493p83kkfjhx0wlh",
"amount": "0.00094877",
"token": "BTC",
"expiresAt": "2023-11-07T05:31:56Z"
},
"confirmation": {
"transactionHash": "0xabc123...",
"explorerUrl": "https://etherscan.io/tx/0xabc123..."
},
"offRampId": "6a99b80613a0c37251651788"
}{
"title": "Unauthorized",
"status": 401,
"type": "urn:problem-type:auth:unauthorized",
"detail": "Bearer token required",
"instance": "<string>",
"realm": "API",
"scope": "read:users"
}{
"title": "<string>",
"status": 404,
"resourceType": "user",
"resourceId": "<string>",
"type": "about:blank",
"detail": "<string>",
"instance": "<string>"
}{
"title": "Unauthorized",
"status": 400,
"type": "urn:problem-type:auth:unauthorized",
"detail": "<string>",
"instance": "/errors/1234567890",
"code": "transaction_limit",
"field": "amountUsd",
"retryable": true,
"retryAfter": 5,
"suggestedAction": "auto_ramp",
"clearsAt": "2023-11-07T05:31:56Z",
"availableAt": "2023-11-07T05:31:56Z",
"permanent": true
}Authorizations
User bearer credential: either a Cognito JWT or an ak_ user API key. Backend integrators using HMAC must include the user API key alongside the three HMAC headers on user-scoped endpoints.
Body
Destination account ID
^[0-9a-fA-F]{24}$"6a9fee5c215e5530b3530e70"
Amount in the unit selected by amountMode: destination fiat for output, or USD for input.
"100.00"
ethereum, polygon, arbitrum, base, optimism, avalanche, binance-smart-chain, solana, bitcoin, dash, tron, sui, hyperevm, monad, sonic, unichain output, input ach_standard, ach_same_day, rtp, wire, eft, sepa, faster_payments, push_to_card, bill_pay, card_deposit Token contract address. Required on every chain except Bitcoin, Dash and XRP, which have no token layer — there is no native-token fallback, and omitting it is rejected. Different tokens carry different fee tiers (e.g. USDC is cheapest). Must be a valid address for the chain: 0x + 40 hex on EVM, base58 on Solana; Tron and Sui accept one specific token each.
"0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48"
Payment note (bank account payments only)
"Invoice #1234"
Response
Response for status 201
Quote ID
"6a99b7bacc18094dfe644ba6"
sign_transaction, send_to_address created, transaction_pending, transaction_failed, insufficient_funds, confirmed, completed, expired, failed, refunded When the quote was created
"2026-09-08T11:15:40.722Z"
Exact USD value collected by Spritz and the token route used to fund it. The exact token quantity is returned by the transaction endpoint.
Show child attributes
Show child attributes
Destination amount. Exact for supported exact-output quotes; estimated for EUR exact-input quotes.
Show child attributes
Show child attributes
Known Spritz fee. Provider FX movement and blockchain gas are not included.
Show child attributes
Show child attributes
Present when fulfillment is send_to_address. Send exactly amount of token to address before expiresAt.
Show child attributes
Show child attributes
Present after on-chain transaction is detected.
Show child attributes
Show child attributes
The off-ramp (fiat leg) created for this quote once the crypto payment confirms. Null until then — poll the quote or watch for payment.created and read it back.
"6a99b80613a0c37251651788"