curl --request POST \
--url https://api.globalstack.io/v1/conversions/quotes \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"source_wallet_id": "<string>",
"destination_wallet_id": "<string>",
"source_amount": "<string>",
"target_amount": "6.05",
"reference": "<string>"
}
'import requests
url = "https://api.globalstack.io/v1/conversions/quotes"
payload = {
"source_wallet_id": "<string>",
"destination_wallet_id": "<string>",
"source_amount": "<string>",
"target_amount": "6.05",
"reference": "<string>"
}
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({
source_wallet_id: '<string>',
destination_wallet_id: '<string>',
source_amount: '<string>',
target_amount: '6.05',
reference: '<string>'
})
};
fetch('https://api.globalstack.io/v1/conversions/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.globalstack.io/v1/conversions/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([
'source_wallet_id' => '<string>',
'destination_wallet_id' => '<string>',
'source_amount' => '<string>',
'target_amount' => '6.05',
'reference' => '<string>'
]),
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.globalstack.io/v1/conversions/quotes"
payload := strings.NewReader("{\n \"source_wallet_id\": \"<string>\",\n \"destination_wallet_id\": \"<string>\",\n \"source_amount\": \"<string>\",\n \"target_amount\": \"6.05\",\n \"reference\": \"<string>\"\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.globalstack.io/v1/conversions/quotes")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"source_wallet_id\": \"<string>\",\n \"destination_wallet_id\": \"<string>\",\n \"source_amount\": \"<string>\",\n \"target_amount\": \"6.05\",\n \"reference\": \"<string>\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.globalstack.io/v1/conversions/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 \"source_wallet_id\": \"<string>\",\n \"destination_wallet_id\": \"<string>\",\n \"source_amount\": \"<string>\",\n \"target_amount\": \"6.05\",\n \"reference\": \"<string>\"\n}"
response = http.request(request)
puts response.read_body{
"status": true,
"message": "Quote created successfully",
"code": "ok",
"data": {
"id": "quo_01KPBK123456789ABCDEFG",
"operation": "onramp",
"status": "active",
"wallet_id": "wal_seed_alice_usdc",
"customer_id": "cust_01HXYZABC1234567890ABCDEFG",
"source_amount": "10000.00",
"source_currency": "NGN",
"destination_amount": "6.046600",
"destination_currency": "USDC",
"rate": "0.000605",
"expires_at": "2026-04-22T02:30:00.000Z",
"created_at": "2026-04-22T02:00:00.000Z",
"updated_at": "2026-04-22T02:00:00.000Z",
"reference": "INV-2026-001",
"destination_wallet_id": "wal_seed_alice_ngn",
"received_amount": "6.046600",
"fee": {
"line_items": [
{
"name": "gateway",
"amount": "100",
"currency": "NGN"
},
{
"name": "network",
"amount": "0.5",
"currency": "USDC"
}
]
}
},
"meta": {
"request_id": "req_01HXYZ4K5ABCDEFGHJKLMNPQRS",
"timestamp": "2026-05-14T15:43:55.732Z",
"version": "1"
}
}{
"status": false,
"message": "Resource not found",
"code": "not_found",
"data": null,
"meta": {
"next_steps": {
"action": "Verify the resource identifier and retry.",
"docs_url": "https://docs.globalstack.io/errors#not_found"
},
"request_id": "req_01HXYZ4K5ABCDEFGHJKLMNPQRS",
"timestamp": "2026-05-14T15:43:55.732Z",
"version": "1"
}
}{
"status": false,
"message": "Resource not found",
"code": "not_found",
"data": null,
"meta": {
"next_steps": {
"action": "Verify the resource identifier and retry.",
"docs_url": "https://docs.globalstack.io/errors#not_found"
},
"request_id": "req_01HXYZ4K5ABCDEFGHJKLMNPQRS",
"timestamp": "2026-05-14T15:43:55.732Z",
"version": "1"
}
}{
"status": false,
"message": "Resource not found",
"code": "not_found",
"data": null,
"meta": {
"next_steps": {
"action": "Verify the resource identifier and retry.",
"docs_url": "https://docs.globalstack.io/errors#not_found"
},
"request_id": "req_01HXYZ4K5ABCDEFGHJKLMNPQRS",
"timestamp": "2026-05-14T15:43:55.732Z",
"version": "1"
}
}{
"status": false,
"message": "Resource not found",
"code": "not_found",
"data": null,
"meta": {
"next_steps": {
"action": "Verify the resource identifier and retry.",
"docs_url": "https://docs.globalstack.io/errors#not_found"
},
"request_id": "req_01HXYZ4K5ABCDEFGHJKLMNPQRS",
"timestamp": "2026-05-14T15:43:55.732Z",
"version": "1"
}
}Create a conversion quote
Creates a conversion quote — a short-lived, priced offer to convert the balance
of one wallet (source_wallet_id) into another wallet (destination_wallet_id).
The source wallet’s currency (e.g. USDC) is the source; the destination wallet’s
currency (e.g. NGN) is the destination — the two currencies must differ. source_network and destination_network are each derived from the
respective wallet’s newest active credential, defaulting to solana when a crypto wallet has no active credential (a fiat wallet with no active credential is
rejected). reference is optional and echoed back as the quote reference. The
response carries the source wallet in wallet_id and the destination wallet in
destination_wallet_id.
The quote is created with status: active and an expires_at in the near future.
Specify either source_amount (the source-wallet amount converted) or
target_amount (the amount credited to the destination wallet) — exactly one, each a
positive decimal string. Providing both, or neither, is rejected with a 400. When
target_amount is supplied, we compute and return the required source_amount on the quote.
USDC amounts settle in whole US cents: source_amount may carry at most 2 significant
decimal places. Trailing zeros are fine — 2.980000 is accepted, 2.980228 is rejected
with 400 invalid_amount_precision. This precision check applies only when you supply
source_amount; a target_amount-driven quote is not constrained this way.
curl --request POST \
--url https://api.globalstack.io/v1/conversions/quotes \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"source_wallet_id": "<string>",
"destination_wallet_id": "<string>",
"source_amount": "<string>",
"target_amount": "6.05",
"reference": "<string>"
}
'import requests
url = "https://api.globalstack.io/v1/conversions/quotes"
payload = {
"source_wallet_id": "<string>",
"destination_wallet_id": "<string>",
"source_amount": "<string>",
"target_amount": "6.05",
"reference": "<string>"
}
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({
source_wallet_id: '<string>',
destination_wallet_id: '<string>',
source_amount: '<string>',
target_amount: '6.05',
reference: '<string>'
})
};
fetch('https://api.globalstack.io/v1/conversions/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.globalstack.io/v1/conversions/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([
'source_wallet_id' => '<string>',
'destination_wallet_id' => '<string>',
'source_amount' => '<string>',
'target_amount' => '6.05',
'reference' => '<string>'
]),
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.globalstack.io/v1/conversions/quotes"
payload := strings.NewReader("{\n \"source_wallet_id\": \"<string>\",\n \"destination_wallet_id\": \"<string>\",\n \"source_amount\": \"<string>\",\n \"target_amount\": \"6.05\",\n \"reference\": \"<string>\"\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.globalstack.io/v1/conversions/quotes")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"source_wallet_id\": \"<string>\",\n \"destination_wallet_id\": \"<string>\",\n \"source_amount\": \"<string>\",\n \"target_amount\": \"6.05\",\n \"reference\": \"<string>\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.globalstack.io/v1/conversions/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 \"source_wallet_id\": \"<string>\",\n \"destination_wallet_id\": \"<string>\",\n \"source_amount\": \"<string>\",\n \"target_amount\": \"6.05\",\n \"reference\": \"<string>\"\n}"
response = http.request(request)
puts response.read_body{
"status": true,
"message": "Quote created successfully",
"code": "ok",
"data": {
"id": "quo_01KPBK123456789ABCDEFG",
"operation": "onramp",
"status": "active",
"wallet_id": "wal_seed_alice_usdc",
"customer_id": "cust_01HXYZABC1234567890ABCDEFG",
"source_amount": "10000.00",
"source_currency": "NGN",
"destination_amount": "6.046600",
"destination_currency": "USDC",
"rate": "0.000605",
"expires_at": "2026-04-22T02:30:00.000Z",
"created_at": "2026-04-22T02:00:00.000Z",
"updated_at": "2026-04-22T02:00:00.000Z",
"reference": "INV-2026-001",
"destination_wallet_id": "wal_seed_alice_ngn",
"received_amount": "6.046600",
"fee": {
"line_items": [
{
"name": "gateway",
"amount": "100",
"currency": "NGN"
},
{
"name": "network",
"amount": "0.5",
"currency": "USDC"
}
]
}
},
"meta": {
"request_id": "req_01HXYZ4K5ABCDEFGHJKLMNPQRS",
"timestamp": "2026-05-14T15:43:55.732Z",
"version": "1"
}
}{
"status": false,
"message": "Resource not found",
"code": "not_found",
"data": null,
"meta": {
"next_steps": {
"action": "Verify the resource identifier and retry.",
"docs_url": "https://docs.globalstack.io/errors#not_found"
},
"request_id": "req_01HXYZ4K5ABCDEFGHJKLMNPQRS",
"timestamp": "2026-05-14T15:43:55.732Z",
"version": "1"
}
}{
"status": false,
"message": "Resource not found",
"code": "not_found",
"data": null,
"meta": {
"next_steps": {
"action": "Verify the resource identifier and retry.",
"docs_url": "https://docs.globalstack.io/errors#not_found"
},
"request_id": "req_01HXYZ4K5ABCDEFGHJKLMNPQRS",
"timestamp": "2026-05-14T15:43:55.732Z",
"version": "1"
}
}{
"status": false,
"message": "Resource not found",
"code": "not_found",
"data": null,
"meta": {
"next_steps": {
"action": "Verify the resource identifier and retry.",
"docs_url": "https://docs.globalstack.io/errors#not_found"
},
"request_id": "req_01HXYZ4K5ABCDEFGHJKLMNPQRS",
"timestamp": "2026-05-14T15:43:55.732Z",
"version": "1"
}
}{
"status": false,
"message": "Resource not found",
"code": "not_found",
"data": null,
"meta": {
"next_steps": {
"action": "Verify the resource identifier and retry.",
"docs_url": "https://docs.globalstack.io/errors#not_found"
},
"request_id": "req_01HXYZ4K5ABCDEFGHJKLMNPQRS",
"timestamp": "2026-05-14T15:43:55.732Z",
"version": "1"
}
}Authorizations
API key issued during merchant onboarding.
Headers
Optional client-supplied key. Identical key + identical body within 24h replays the original response. Identical key + different body returns 409 idempotency_conflict. The hash is over raw bytes — clients retrying must send the byte-identical body; a re-serialised JSON payload will produce a different hash and a 409. Strongly recommended for retry-safe clients.
^[A-Za-z0-9_\-]{8,255}$Body
CreateConversionQuoteDto
6464^\d+(\.\d+)?$Destination amount the recipient receives, as a decimal string. Provide exactly one of source_amount or target_amount.
^\d+(\.\d+)?$"6.05"
128Response
Quote created successfully