Quotes are Grid’s mechanism for providing locked-in exchange rates, transparent fee calculations, and payment instructions. Understanding quotes is essential for all cross-currency or crypto-involved transactions.
What is a Quote?
A quote locks in:
An exchange rate between two currencies
Total fees for the transaction
Exact amounts to be sent and received
Payment instructions (if JIT funding is needed)
An expiration time (typically 1-5 minutes, up to 15 minutes depending on the payment type)
Quotes ensure that your customers know exactly what they’ll pay and what the recipient will receive before committing to a transaction.
When Do You Need a Quote?
Quotes Required
Quotes Optional
Use quotes for:
Cross-currency transfers (USD → EUR, BRL → MXN)
Fiat-to-crypto conversion (USD → BTC)
Crypto-to-fiat conversion (BTC → USD)
UMA payments (always require quotes)
JIT funded payments (need payment instructions)
These scenarios involve currency conversion, exchange rate risk, or complex routing.
Creating a Quote
Basic Cross-Currency Quote
This is a basic quote for a cross-currency transfer from an internal account to an external account,
which were pre-created as described in the Account Model section.
curl -X POST https://api.lightspark.com/grid/2025-10-13/quotes \
-u " $GRID_CLIENT_ID : $GRID_CLIENT_SECRET " \
-H "Content-Type: application/json" \
-d '{
"source": {
"accountId": "InternalAccount:e85dcbd6-dced-4ec4-b756-3c3a9ea3d965"
},
"destination": {
"currency": "BTC",
"accountId": "ExternalAccount:a12dcbd6-dced-4ec4-b756-3c3a9ea3d123"
},
"lockedCurrencySide": "SENDING",
"lockedCurrencyAmount": 100000
}'
Response:
{
"quoteId" : "Quote:019542f5-b3e7-1d02-0000-000000000020" ,
"status" : "PROCESSING" ,
"createdAt" : "2025-10-03T15:00:00Z" ,
"expiresAt" : "2025-10-03T15:05:00Z" ,
"source" : {
"accountId" : "InternalAccount:e85dcbd6-dced-4ec4-b756-3c3a9ea3d965" ,
"currency" : "USD"
},
"destination" : {
"accountId" : "ExternalAccount:a12dcbd6-dced-4ec4-b756-3c3a9ea3d123" ,
"currency" : "BTC"
},
"sendingCurrency" : {
"code" : "USD" ,
"name" : "United States Dollar" ,
"symbol" : "$" ,
"decimals" : 2
},
"receivingCurrency" : {
"code" : "BTC" ,
"name" : "Bitcoin" ,
"symbol" : "₿" ,
"decimals" : 8
},
"totalSendingAmount" : 100000 ,
"totalReceivingAmount" : 829167 ,
"exchangeRate" : 0.00000833 ,
"feesIncluded" : 500 ,
"transactionId" : "Transaction:019542f5-b3e7-1d02-0000-000000000025"
}
This quote says: Send 1 , 000 U S D , r e c i p i e n t r e c e i v e s 0.00829167 B T C , f e e s a r e 1,000 USD, recipient receives 0.00829167 BTC, fees are 1 , 000 U S D , rec i p i e n t rece i v es 0.00829167 BTC , f ees a re 5.00, expires in 5 minutes.
Locked Currency Side
You can lock either the sending or receiving amount:
Lock Sending Amount
Lock Receiving Amount
Use when: Customer knows exactly how much they want to send{
"lockedCurrencySide" : "SENDING" ,
"lockedCurrencyAmount" : 100000
}
Grid calculates what the recipient will receive based on current exchange rates.
Funding Models
Grid supports two funding models for quotes:
Prefunded (From Internal Account)
Source is an existing internal account with available balance:
{
"source" : {
"accountId" : "InternalAccount:e85dcbd6-dced-4ec4-b756-3c3a9ea3d965"
}
}
Funds are debited immediately when quote is executed
No payment instructions needed
Best for: Customers with pre-loaded balances
Just-In-Time (JIT) Funding
Source is the customer ID or the platform itself — Grid provides payment instructions:
{
"source" : {
"customerId" : "Customer:019542f5-b3e7-1d02-0000-000000000001"
}
}
Quote response includes payment instructions:
{
"quoteId" : "Quote:..." ,
"paymentInstructions" : [
{
"reference" : "UMA-Q12345-REF" ,
"instructionsNotes" : "Please ensure the reference code is included in the payment memo/description field" ,
"bankAccountInfo" : {
"accountType" : "US_ACCOUNT" ,
"accountNumber" : "9876543210" ,
"routingNumber" : "110000000" ,
"accountCategory" : "CHECKING" ,
"bankName" : "Chase Bank"
}
}
]
}
Customer sends funds to provided account with reference
Quote executes automatically when Grid receives payment
Best for: On-demand payments without maintaining balances
Executing a Quote
For a prefunded quote or one from a pullable external account source, once a quote is created, execute it before it expires:
curl -X POST https://api.lightspark.com/grid/2025-10-13/quotes/Quote:abc123/execute \
-u " $GRID_CLIENT_ID : $GRID_CLIENT_SECRET " \
-H "Content-Type: application/json"
Response:
{
"id" : "Transaction:019542f5-b3e7-1d02-0000-000000000060" ,
"status" : "PENDING" ,
"type" : "OUTGOING" ,
"quoteId" : "Quote:019542f5-b3e7-1d02-0000-000000000050"
...
}
Execution Timing
Transaction created with status PENDING
Funds debited from source account immediately
Settlement begins right away
For market rate execution without quote approval, use the immediatelyExecute
flag:
Immediate quote execution
curl -X POST https://api.lightspark.com/grid/2025-10-13/quotes \
-u " $GRID_CLIENT_ID : $GRID_CLIENT_SECRET " \
-H "Content-Type: application/json" \
-d '{
"source": {"accountId": "InternalAccount:e85dcbd6-dced-4ec4-b756-3c3a9ea3d965"},
"destination": {"accountId": "ExternalAccount:a12dcbd6-dced-4ec4-b756-3c3a9ea3d123", "currency": "EUR"},
"lockedCurrencySide": "SENDING",
"lockedCurrencyAmount": 100000,
"immediatelyExecute": true
}'
{
"quoteId" : "Quote:019542f5-b3e7-1d02-0000-000000000020" ,
"status" : "COMPLETED" ,
"createdAt" : "2025-10-03T15:00:00Z" ,
"expiresAt" : "2025-10-03T15:05:00Z" ,
"source" : {
"accountId" : "InternalAccount:e85dcbd6-dced-4ec4-b756-3c3a9ea3d965" ,
"currency" : "USD"
},
"destination" : {
"accountId" : "ExternalAccount:a12dcbd6-dced-4ec4-b756-3c3a9ea3d123" ,
"currency" : "EUR"
},
"sendingCurrency" : {
"code" : "USD" ,
"name" : "United States Dollar" ,
"symbol" : "$" ,
"decimals" : 2
},
"receivingCurrency" : {
"code" : "EUR" ,
"name" : "Euro" ,
"symbol" : "€" ,
"decimals" : 2
},
"totalSendingAmount" : 100000 ,
"totalReceivingAmount" : 91540 ,
"exchangeRate" : 0.92 ,
"feesIncluded" : 500 ,
"transactionId" : "Transaction:019542f5-b3e7-1d02-0000-000000000025"
}
Quote is created and executed in one API call
Best for: Rewards distribution, micro-payments, time-sensitive transfers
Customer doesn’t see rate before execution. If you want to lock a quote and confirm fees and exchange rate details before executing the quote, set immediatelyExecute
to false
or omit the field.
Creating External Accounts in Quotes
You can create an external account inline when creating a quote:
{
"source" : {
"accountId" : "InternalAccount:abc123"
},
"destination" : {
"externalAccountDetails" : {
"customerId" : "Customer:019542f5-b3e7-1d02-0000-000000000001" ,
"currency" : "EUR" ,
"accountInfo" : {
"accountType" : "IBAN_ACCOUNT" ,
"iban" : "DE89370400440532013000" ,
"beneficiary" : {
"beneficiaryType" : "INDIVIDUAL" ,
"fullName" : "Alice Smith"
}
}
}
},
"lockedCurrencySide" : "SENDING" ,
"lockedCurrencyAmount" : 100000
}
This is useful for one-time recipients or when you don’t want to manage external accounts separately.
Fees
All fees are transparently displayed in the quote response:
{
"quoteId" : "Quote:019542f5-b3e7-1d02-0000-000000000020" ,
"feesIncluded" : 500 ,
... quote response ...
"rateDetails" : {
"counterpartyMultiplier" : 1.08 ,
"counterpartyFixedFee" : 10 ,
"gridApiMultiplier" : 0.925 ,
"gridApiFixedFee" : 10 ,
"gridApiVariableFeeRate" : 0.003 ,
"gridApiVariableFeeAmount" : 30
}
}
Rate Details Breakdown:
counterpartyMultiplier
: Exchange rate from mSATs to receiving currency (1.08 = 1 mSAT = 1.08 cents EUR)
counterpartyFixedFee
: Fixed fee charged by counterparty (10 cents EUR)
gridApiMultiplier
: Exchange rate from sending currency to mSATs including variable fees (0.925 = $1 USD = 0.925 mSATs)
gridApiFixedFee
: Fixed fee charged by Grid API (10 cents USD)
gridApiVariableFeeRate
: Variable fee rate as percentage (0.003 = 0.3%)
gridApiVariableFeeAmount
: Variable fee amount (30 cents USD for $1,000 transaction)
Fees are deducted from the sending amount, so:
Customer sends : $1,000
Fees : $5.00
Amount converted : $995.00
Recipient receives : €915.40 (at 0.92 rate)
Best Practices
Always show the quote to customers before executing
Let customers review the exchange rate, fees, and final amounts before committing: // ✅ Good: Show quote details, await confirmation
const quote = await createQuote ( params );
showQuoteToUser ( quote );
if ( await userConfirms ()) {
await executeQuote ( quote . id );
}
// ❌ Bad: Immediate execution without review (unless micro-payments/rewards)
await createQuote ({ ... params , immediatelyExecute: true });
Handle expiration gracefully
Store quote parameters so you can recreate expired quotes: const quoteParams = {
source: { accountId: customerAccount },
destination: { accountId: recipientAccount },
lockedCurrencySide: 'SENDING' ,
lockedCurrencyAmount: amount
};
let quote = await createQuote ( quoteParams );
// Later, if expired...
try {
await executeQuote ( quote . id );
} catch ( error ) {
if ( error . code === 'QUOTE_EXPIRED' ) {
quote = await createQuote ( quoteParams ); // Recreate with fresh rate
await executeQuote ( quote . id );
}
}
Monitor quote status via webhooks
Subscribe to quote-related webhooks: app . post ( '/webhooks/grid' , ( req , res ) => {
const { transaction , type } = req . body ;
if ( type === 'OUTGOING_PAYMENT' && transaction . quoteId ) {
// Quote was executed, transaction created
updateCustomerUI ( transaction );
}
res . status ( 200 ). send ();
});