curl --request POST \
--url https://platform.spritz.finance/v1/off-ramp-quotes/{quoteId}/submit \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"transactionHash": "0x5c504ed432cb51138bcf09aa5e8a410dd4a1e204ef84bfed1be16dfba1b22060"
}
'import requests
url = "https://platform.spritz.finance/v1/off-ramp-quotes/{quoteId}/submit"
payload = { "transactionHash": "0x5c504ed432cb51138bcf09aa5e8a410dd4a1e204ef84bfed1be16dfba1b22060" }
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({
transactionHash: '0x5c504ed432cb51138bcf09aa5e8a410dd4a1e204ef84bfed1be16dfba1b22060'
})
};
fetch('https://platform.spritz.finance/v1/off-ramp-quotes/{quoteId}/submit', 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/{quoteId}/submit",
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([
'transactionHash' => '0x5c504ed432cb51138bcf09aa5e8a410dd4a1e204ef84bfed1be16dfba1b22060'
]),
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/{quoteId}/submit"
payload := strings.NewReader("{\n \"transactionHash\": \"0x5c504ed432cb51138bcf09aa5e8a410dd4a1e204ef84bfed1be16dfba1b22060\"\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/{quoteId}/submit")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"transactionHash\": \"0x5c504ed432cb51138bcf09aa5e8a410dd4a1e204ef84bfed1be16dfba1b22060\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://platform.spritz.finance/v1/off-ramp-quotes/{quoteId}/submit")
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 \"transactionHash\": \"0x5c504ed432cb51138bcf09aa5e8a410dd4a1e204ef84bfed1be16dfba1b22060\"\n}"
response = http.request(request)
puts response.read_body{
"id": "6a99b7bacc18094dfe644ba6",
"fulfillment": "sign_transaction",
"status": "created",
"createdAt": "2026-09-14T19:25:41.746Z",
"input": {
"amount": "101.50",
"currency": "USD",
"tokenAddress": "0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48",
"chain": "ethereum"
},
"output": {
"amount": "89.25",
"currency": "EUR",
"rail": "ach_standard",
"accountId": "6aa84a359702b1d9ae3d633b",
"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
}Report the transaction sent for a quote
Tells Spritz which on-chain transaction you broadcast for this quote, so tracking starts immediately instead of when the chain watcher notices it.
Works for both fulfillment types: the transaction you signed from POST /off-ramp-quotes/{id}/transaction, or the transfer you sent to sendTo.address. The quote moves to transaction_pending and its off-ramp (fiat leg) is created right away; confirmed still comes from the chain.
Idempotent for the same hash. Reporting a different hash once one is on record is rejected with 400 — the chain watcher is the authority from then on.
curl --request POST \
--url https://platform.spritz.finance/v1/off-ramp-quotes/{quoteId}/submit \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"transactionHash": "0x5c504ed432cb51138bcf09aa5e8a410dd4a1e204ef84bfed1be16dfba1b22060"
}
'import requests
url = "https://platform.spritz.finance/v1/off-ramp-quotes/{quoteId}/submit"
payload = { "transactionHash": "0x5c504ed432cb51138bcf09aa5e8a410dd4a1e204ef84bfed1be16dfba1b22060" }
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({
transactionHash: '0x5c504ed432cb51138bcf09aa5e8a410dd4a1e204ef84bfed1be16dfba1b22060'
})
};
fetch('https://platform.spritz.finance/v1/off-ramp-quotes/{quoteId}/submit', 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/{quoteId}/submit",
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([
'transactionHash' => '0x5c504ed432cb51138bcf09aa5e8a410dd4a1e204ef84bfed1be16dfba1b22060'
]),
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/{quoteId}/submit"
payload := strings.NewReader("{\n \"transactionHash\": \"0x5c504ed432cb51138bcf09aa5e8a410dd4a1e204ef84bfed1be16dfba1b22060\"\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/{quoteId}/submit")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"transactionHash\": \"0x5c504ed432cb51138bcf09aa5e8a410dd4a1e204ef84bfed1be16dfba1b22060\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://platform.spritz.finance/v1/off-ramp-quotes/{quoteId}/submit")
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 \"transactionHash\": \"0x5c504ed432cb51138bcf09aa5e8a410dd4a1e204ef84bfed1be16dfba1b22060\"\n}"
response = http.request(request)
puts response.read_body{
"id": "6a99b7bacc18094dfe644ba6",
"fulfillment": "sign_transaction",
"status": "created",
"createdAt": "2026-09-14T19:25:41.746Z",
"input": {
"amount": "101.50",
"currency": "USD",
"tokenAddress": "0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48",
"chain": "ethereum"
},
"output": {
"amount": "89.25",
"currency": "EUR",
"rail": "ach_standard",
"accountId": "6aa84a359702b1d9ae3d633b",
"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.
Path Parameters
The quote ID
"6a99b7bacc18094dfe644ba6"
Body
Hash / signature / digest of the transaction you broadcast for this quote, as the chain reports it.
1 - 200"0x5c504ed432cb51138bcf09aa5e8a410dd4a1e204ef84bfed1be16dfba1b22060"
Response
Response for status 200
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-14T19:25:41.746Z"
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"