API Reference — POST /api/quote
Prices a swap, locks the exact TO amounts, and returns a backend-signed quote. This is the core of a programmatic swap: you send recipients and the amounts they should receive; the API returns the FROM cost and a quoteId you carry on-chain.
POST https://drip.tools/api/quote
Content-Type: application/jsonRequest body
{
"chainId": 8453,
"fromToken": "0x0000000000000000000000000000000000000000",
"sender": "0x9246ef7F2b7fEcE8AfD8a72271A76Cc2A8d8A3E5",
"toChainId": 421614,
"toToken": "0x0000000000000000000000000000000000000000",
"recipients": ["0x2F4edA5e7EEa6eb634C7FBb0acAFA04b8938F63A"],
"toAmounts": ["5000000000000000000"]
}| Field | Type | Description |
|---|---|---|
chainId | integer | FROM (mainnet) chain id. Must be an enabled FROM chain — an EVM id, or 1399811149 (Solana) / 1667471768 (TON). |
fromToken | string | FROM token as listed in /api/chains: an 0x… ERC-20 address, a base58 SPL mint on Solana, or 0x0…0 for the native coin on any chain. |
sender | string | The wallet that will send the payment. Bound into the signature — the payer must match. EVM 0x… (any case), Solana base58, TON any form. |
toChainId | integer | TO (testnet) chain id. Must be an enabled TO chain. |
toToken | address | TO token as listed in /api/chains. 0x0…0 = native (also for Solana / TON / Bitcoin testnets). |
recipients | string[] | Recipient addresses on the TO chain. 1 = single swap; >1 = multisend. Up to 10 000. |
toAmounts | string[] | Base-unit integer strings of the TO token, one per recipient (same length as recipients). No decimals/hex/exponents. |
Rules
recipientsandtoAmountsmust be non-empty and the same length.- Recipients are validated per the TO chain: EVM addresses in any case; TON, Solana and Bitcoin addresses are checked and delivered exactly as sent.
- The payment must come from
sender— a different paying wallet is not honoured. - Each
toAmounts[i]must sit on the TO token's precision grid and be at or above its per-recipient minimum (see error codes below).
Response 200
{
"quoteId": "0x1f5215a4577ef4548b550313d772594473e237c67514943751634818fdff9615",
"signer": "0x5C0917e114e49F3Cf266D6467ac129FEe42d77c5",
"vault": "0x52361c9412dcec6a83980fb065d0276ec001face",
"issuedAt": 1784120925,
"expiry": 1784121105,
"deadline": 1784121105,
"fromToken": "0x0000000000000000000000000000000000000000",
"fromTotal": "517554316856097",
"fromAmounts": ["517554316856097"],
"toAmounts": ["5000000000000000000"],
"usdTotal": "1.25",
"signature": "0x23fbc0…1b"
}| Field | Meaning |
|---|---|
quoteId | 32 random bytes — the only quote reference carried on-chain. Pass to the pay call, or put in the Solana memo / TON comment. |
signer | Address that produced the EIP-712 signature (verify against it). |
vault | Pay target = the FROM chain's contracts.depository, in canonical form: the depository contract (EVM) or the treasury account (Solana base58, TON UQ…). |
issuedAt / expiry | Quote validity window (epoch s). |
deadline | Passed to the pay call; the tx reverts Expired after it. On Solana / TON a payment landing after it is not honoured. Equals expiry. |
fromToken | The FROM token in canonical form. |
fromTotal | Total FROM to pay, base units. msg.value (native) or amount (ERC-20) on EVM; lamports / SPL units / nanotons on Solana / TON. Pay exactly this. |
fromAmounts | Per-recipient FROM breakdown, base units (the backend expands the batch by these). |
toAmounts | Echoes the requested TO amounts. Delivered exactly, regardless of later price moves. |
usdTotal | Human USD total, 2 decimals. |
signature | 65-byte EIP-712 signature. Optional to check — see Verifying the quote signature. |
Pricing model
You specify the TO amounts; the API computes the FROM cost using the live FROM-token price (Chainlink, see Prices) and the TO token's USD rate (GET /api/quotes):
fromAmount_i = floor( toAmount_i × toRateUsd × 10^fromDecimals / (10^toDecimals × fromPriceUsd) )
fromTotal = Σ fromAmount_iThe quote locks toAmounts — the backend delivers exactly those, even if prices move between quoting and payment.
What you pay is the listed rate of the testnet tokens converted at the live price of the token you pay with — nothing more. There is no additional fee or spread. Gas on the FROM chain is yours; gas for the testnet payouts is ours. Requesting a quote is free and commits you to nothing.
Minimums
| Order | Minimum USD value |
|---|---|
| Single recipient | $1 |
| Multisend (>1 recipient) | $5 |
Compared at cent precision (round half up), so a feed wobble like $4.9998 → $5.00 is not rejected.
Validity window
A quote expires 180 seconds after issue, on every chain. Submit the on-chain payment before deadline, or request a fresh quote.
Errors
All errors are { "error": "<message>", "code": "<CODE>" }, except the rate-limit and warming-up shapes, which carry retryAfterSec and a Retry-After header instead of code.
| Codes | |
|---|---|
| Your request | BAD_FROM_CHAIN · BAD_TO_CHAIN · BAD_ADDRESS · BAD_FROM_TOKEN · BAD_TO_TOKEN · BAD_ARRAYS · EMPTY · LENGTH_MISMATCH · TOO_MANY · BAD_RECIPIENT · BAD_TO_AMOUNT (all 400) |
| Your amounts | TO_TOO_SMALL · TO_TOO_PRECISE · FROM_ROUNDS_TO_ZERO · BELOW_SOL_RENT_MIN · BELOW_MIN_TOTAL · NO_LIQUIDITY (all 400) |
| Availability | NO_FROM_PRICE · NO_TO_PRICE · SIGNING_DISABLED · WARMING_UP (503) · NO_VAULT (500) |
| Rate limit | RATE_LIMITED (429, with Retry-After) |
Every code with its meaning and fix: Errors → POST /api/quote.
Once you have a quote, pay on-chain and then track the order.