Skip to content

API Reference — Discovery ​

The Drip Tools REST API is served at:

https://drip.tools/api

Conventions ​

  • Transport: JSON over HTTPS. Content-Type: application/json for POST bodies. CORS is open.
  • No auth. Endpoints are public. Requests are rate-limited per IP, POST /api/quote more tightly — see Rate limits.
  • Amounts. All token amounts in quotes (toAmounts in, fromTotal / fromAmounts / toAmounts out) are base-unit integer strings — no decimals, no scientific notation. Convert with the token's decimals. Order-history amounts (from.amount, to.amount) are instead human-readable decimal strings.
  • Native token sentinel. A token address of 0x0000000000000000000000000000000000000000 means 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-bounceable UQ… form; TON recipients are kept exactly as sent. Never change the case of a non-EVM identity.
  • chainId types vary by endpoint. GET /chains, GET /quotes, and order objects return chainId as a string; POST /quote and GET /prices use 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 .md appended. See For agents.
  • Warming up. For about a minute after a backend restart, GET /api/quotes, GET /api/prices and POST /api/quote can answer 503 { "error": "WARMING_UP", "retryAfterSec": 5, "waitingFor": [...] } with a Retry-After header. 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

NameTypeRequiredDescription
unwrap'true'noReturn one flat array [...testnet, ...mainnet] instead of { testnet, mainnet }.

Response — { testnet: [...], mainnet: [...] }, or a flat array with unwrap=true. Each chain:

json
{
  "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:

json
{
  "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.

FieldMeaning
chainIdChain id, as a string. Non-EVM chains use synthetic ids (Solana mainnet 1399811149, TON mainnet 1667471768).
nameInternal slug (arbitrum, solana_mainnet, …). Use displayName for labels.
displayNameHuman-readable chain name.
isTestnetfalse = FROM (mainnet) side; true = TO (testnet) side.
isEnabledDisabled chains are still listed but not swappable.
isPausedPresent, and true, only while the chain is temporarily paused: still listed, but POST /api/quote refuses it. Comes with pausedReason (free text or null).
familyPresent only on non-EVM chains: solana | ton | bitcoin. Absent = EVM.
clusterSolana only: mainnet-beta (FROM), testnet | devnet (TO).
networkBitcoin only: testnet | testnet4 | signet.
explorerBlock-explorer base URL for the chain.
rpcstring[] — 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.depositoryFROM 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

NameTypeRequiredDescription
chainIdstring/numberno*TO chain id.
symbolstringno*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

json
{
  "chainName": "Arbitrum Sepolia",
  "chainId": "421614",
  "symbol": "ETH",
  "address": "0x0000000000000000000000000000000000000000",
  "decimals": 18,
  "price": 0.25,
  "balance": "12513664307780914212000",
  "available": true
}
FieldMeaning
priceUSD rate of the TO token (a plain number) — the one POST /api/quote prices with.
balanceWhat can be dispensed right now, base units. Orders exceeding this are rejected NO_LIQUIDITY.
availablefalse 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 ​