API Reference — Discovery
The Drip Tools REST API is served at:
https://drip.tools/apiConventions
- Transport: JSON over HTTPS.
Content-Type: application/jsonfor POST bodies. CORS is open. - No auth. Endpoints are public. Requests are rate-limited per IP,
POST /api/quotemore tightly — see Rate limits. - Amounts. All token amounts in quotes (
toAmountsin,fromTotal/fromAmounts/toAmountsout) are base-unit integer strings — no decimals, no scientific notation. Convert with the token'sdecimals. Order-history amounts (from.amount,to.amount) are instead human-readable decimal strings. - Native token sentinel. A token
addressof0x0000000000000000000000000000000000000000means the chain's native coin (ETH, BNB, POL, SOL, TON, BTC, …) — on every chain family. - Identities are strings, per family. EVM addresses are
0x…and compared case-insensitively; quote fields (sender,fromToken,vault) come back lowercased, order objects return the checksummed form — never compare EVM strings byte for byte. Solana keys are base58 and case-sensitive. A TON payer (sender) is accepted in any form and normalized to the non-bounceableUQ…form; TON recipients are kept exactly as sent. Never change the case of a non-EVM identity. chainIdtypes vary by endpoint.GET /chains,GET /quotes, and order objects returnchainIdas a string;POST /quoteandGET /pricesuse a number. Coerce defensively.- Timestamps are epoch seconds.
- Machine-readable. The whole API is described in
/openapi.json(OpenAPI 3.1, validated against live responses by the docs checks). The docs themselves are available as markdown:/llms.txt(index),/llms-full.txt(everything in one file), or any page URL with.mdappended. See For agents. - Warming up. For about a minute after a backend restart,
GET /api/quotes,GET /api/pricesandPOST /api/quotecan answer503 { "error": "WARMING_UP", "retryAfterSec": 5, "waitingFor": [...] }with aRetry-Afterheader. Wait and retry; it is not a rate limit.
GET /api/chains
Lists every supported chain, its tokens, and where to pay. This is your entry point: FROM chains (mainnet) expose contracts.depository — the depository contract on EVM, the treasury account on Solana and TON. TO chains (testnet) carry no contract you interact with — payouts are sent to your recipients by our relayers.
Query parameters
| Name | Type | Required | Description |
|---|---|---|---|
unwrap | 'true' | no | Return one flat array [...testnet, ...mainnet] instead of { testnet, mainnet }. |
Response — { testnet: [...], mainnet: [...] }, or a flat array with unwrap=true. Each chain:
{
"chainId": "42161",
"name": "arbitrum",
"displayName": "Arbitrum",
"explorer": "https://arbiscan.io",
"isTestnet": false,
"isEnabled": true,
"rpc": ["https://arbitrum.drpc.org", "https://arbitrum-one-rpc.publicnode.com"],
"tokens": [
{
"symbol": "USDC",
"displayName": "USD Coin",
"decimals": 6,
"address": "0xaf88d065e77c8cc2239327c5edb3a432268e5831",
"priceFeed": "0x50834F3163758fcC1Df9973b6e91f0F0F0434aD3"
}
],
"contracts": { "depository": "0x52361c9412DceC6A83980fb065D0276ec001fACE" }
}A non-EVM FROM chain looks like this:
{
"chainId": "1399811149",
"name": "solana_mainnet",
"displayName": "Solana",
"explorer": "https://explorer.solana.com",
"family": "solana",
"cluster": "mainnet-beta",
"isTestnet": false,
"isEnabled": true,
"rpc": ["https://…"],
"tokens": [
{ "symbol": "SOL", "displayName": "SOL", "decimals": 9, "address": "0x0000000000000000000000000000000000000000",
"priceFeed": { "chainId": 1, "address": "0x4ffC43a60e009B551865A93d232E33Fce9f01507" } },
{ "symbol": "USDC", "displayName": "USDC", "decimals": 6, "address": "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v",
"priceFeed": { "chainId": 1, "address": "0x8fFfFfd4AfB6115b954Bd326cbe7B4BA576818f6" } }
],
"contracts": { "depository": "94BkmkTF6ZFASfLfqEv4HV61GcWj3dykKZP67C2HTQnU" }
}The TON FROM chain (1667471768, family: "ton", token GRAM) has the same shape; its contracts.depository is the treasury wallet UQCpSpH8mxHJ02uj2QEcyujXf9a1XIUY_ROgpcmPnz_Cp0VK, given in the non-bounceable UQ… form.
| Field | Meaning |
|---|---|
chainId | Chain id, as a string. Non-EVM chains use synthetic ids (Solana mainnet 1399811149, TON mainnet 1667471768). |
name | Internal slug (arbitrum, solana_mainnet, …). Use displayName for labels. |
displayName | Human-readable chain name. |
isTestnet | false = FROM (mainnet) side; true = TO (testnet) side. |
isEnabled | Disabled chains are still listed but not swappable. |
isPaused | Present, and true, only while the chain is temporarily paused: still listed, but POST /api/quote refuses it. Comes with pausedReason (free text or null). |
family | Present only on non-EVM chains: solana | ton | bitcoin. Absent = EVM. |
cluster | Solana only: mainnet-beta (FROM), testnet | devnet (TO). |
network | Bitcoin only: testnet | testnet4 | signet. |
explorer | Block-explorer base URL for the chain. |
rpc | string[] — ordered public RPC endpoints: rpc[0] is the primary, the rest are fallbacks to try in order. |
tokens[] | symbol, displayName, decimals, address (0x0…0 = native; a base58 mint on Solana), priceFeed (informational: the oracle feed the price comes from — a feed address, { chainId, address } when the feed lives on another chain, or 0x on TO tokens, which are not priced). Bitcoin testnet tokens add quoteDecimals (how many decimal places a TO amount may have) and minTo (per-recipient minimum, in whole tokens). |
contracts.depository | FROM chains — the pay target: the depository contract (EVM) or the treasury account (Solana base58, TON UQ…). Absent → swaps not enabled on that chain. |
GET /api/quotes (rates & liquidity)
The listed USD rate of each TO token and how much of it can be dispensed right now. Use it to estimate cost and check availability before quoting.
Not the quote endpoint
GET /api/quotes (plural) is a read-only price list. The swap itself starts with POST /api/quote (singular), which prices and signs your order.
Query parameters
| Name | Type | Required | Description |
|---|---|---|---|
chainId | string/number | no* | TO chain id. |
symbol | string | no* | TO token symbol. |
* With neither, returns the full array of enabled TO tokens. With both, returns the single matching object. With only one → 400 Missing chainId or symbol. Both but no match → 404 No quote found for symbol <symbol>.
Response
{
"chainName": "Arbitrum Sepolia",
"chainId": "421614",
"symbol": "ETH",
"address": "0x0000000000000000000000000000000000000000",
"decimals": 18,
"price": 0.25,
"balance": "12513664307780914212000",
"available": true
}| Field | Meaning |
|---|---|
price | USD rate of the TO token (a plain number) — the one POST /api/quote prices with. |
balance | What can be dispensed right now, base units. Orders exceeding this are rejected NO_LIQUIDITY. |
available | false when that token can't be dispensed right now (NO_TO_PRICE at quote time). |
The response carries a few more bookkeeping fields; the ones above are all you need.
503 WARMING_UP while the first balance pass after a restart is running.
OpenAPI specification
Every endpoint on these pages is also described in an OpenAPI 3.1 document at https://docs.drip.tools/openapi.json: query parameters, request and response schemas (conditional fields are optional), every error body with its code and HTTP status, and the rate-limit headers. Import it into Postman, Insomnia or Swagger UI, or generate a typed client from it. It is checked against the live API, like the field tables here. The docs themselves are available as markdown — see For agents.
Next
- Price your swap and lock the amounts: POST /api/quote.
- Live FROM-token prices: Prices.
- Track the resulting orders: Orders.