# At a glance

Swap real **mainnet** tokens for **testnet** funds in four API calls. Base URL
`https://drip.tools/api`, JSON over HTTPS, no auth, open CORS. Pay from ten EVM mainnets, Solana
or TON; receive on 30+ EVM, Solana, TON and Bitcoin testnets.

## The flow

| # | Step | Call | You get |
| --- | --- | --- | --- |
| 1 | **Discover** | `GET /api/chains?unwrap=true` | FROM chains (`isTestnet: false`) with their **pay target** `contracts.depository`; TO chains (`isTestnet: true`; skip `isEnabled: false`) and tokens. |
| 2 | **Quote** | `POST /api/quote` `{ chainId, fromToken, sender, toChainId, toToken, recipients[], toAmounts[] }` | `quoteId`, `vault` (= pay target), `fromTotal`, `deadline`, `signature`. Free, non-binding, valid 180 s. |
| 3 | **Pay** | one transaction on the FROM chain, **exactly `fromTotal`**, before `deadline` | EVM: `pay(quoteId, deadline)` on `vault` with `msg.value = fromTotal` (or `payWithToken` / `payWithTokenPermit`). Solana: transfer to `vault` + SPL memo = `quoteId`. TON: non-bounceable transfer to `vault` + comment = `quoteId`. |
| 4 | **Track** | `GET /api/order?from_tx_hash=<ref>` | one order per recipient; `completed` once `to.txHash` is set. `ref` = EVM tx hash, Solana signature, or the `quoteId` on TON. |

Ready-to-run scripts for every variant, in JavaScript and Python: [Examples](https://docs.drip.tools/swap/examples.md).

## Endpoints

| Endpoint | Purpose |
| --- | --- |
| [`GET /api/chains`](https://docs.drip.tools/api/discovery.md#get-api-chains) | Chains, tokens, pay targets. |
| [`GET /api/quotes`](https://docs.drip.tools/api/discovery.md#get-api-quotes-rates-liquidity) | TO-token rates and dispensable liquidity (not the quote endpoint). |
| [`GET /api/prices`](https://docs.drip.tools/api/prices.md) · [`/prices/at`](https://docs.drip.tools/api/prices.md#get-api-prices-at) | Live and historical FROM-token prices. |
| [`POST /api/quote`](https://docs.drip.tools/api/quote.md) | Price and sign a swap. |
| [`GET /api/order`](https://docs.drip.tools/api/orders.md#get-api-order) | Orders of one payment (`from_tx_hash`) or one order (`id`); `&paginate=1` for big batches. |
| [`GET /api/orders`](https://docs.drip.tools/api/orders.md#get-api-orders) | A payer's history, `view=batches` for one row per payment. |
| [`POST /api/orders/status`](https://docs.drip.tools/api/orders.md#post-api-orders-status) | Bulk status by order id (≤ 500). |
| [`GET /api/orders/load`](https://docs.drip.tools/api/orders.md#get-api-orders-load) | Queue depth and your position (ETA). |
| [`GET /api/orders/stream`](https://docs.drip.tools/api/orders.md#get-api-orders-stream) | Server-Sent Events when your orders change. |

## Numbers to remember

| What | Value |
| --- | --- |
| Minimum order | **$1** single recipient · **$5** multisend |
| TO amount precision | 4 decimal places (whole sats on Bitcoin); ≥ 0.001 SOL per recipient on Solana |
| Quote lifetime | **180 s** (`deadline` = `expiry`) |
| Recipients per quote | up to **10 000**, one payment |
| Rate limits | 600 requests / min per IP · 10 quotes / min per IP · 30 quotes / min per `sender` |
| Amounts | base-unit integer strings (`toAmounts`, `fromTotal`); order history amounts are human decimals |
| Native coin | token address `0x0000000000000000000000000000000000000000` on every chain |
| Non-EVM FROM ids | Solana `1399811149` · TON `1667471768` (Solana testnet `1399811150`, devnet `1399811151`, TON testnet `1667471769`) |
| Price | TO amount × listed rate, converted at the live Chainlink price; no extra fee. You pay the FROM chain's gas. |

## Payment rules

Same payer as `sender` · same token as `fromToken` · **exactly** `fromTotal` · before `deadline` ·
one `quoteId` per payment. Anything else does not become an order — see
[Payment rules](https://docs.drip.tools/reference/lifecycle.md#payment-rules).

## When something goes wrong

| You see | Meaning | Do |
| --- | --- | --- |
| `400 BELOW_MIN_TOTAL` | order under $1 / $5 | raise `toAmounts` |
| `400 NO_LIQUIDITY` / `503 NO_TO_PRICE` | that TO token can't be dispensed now | check [`GET /api/quotes`](https://docs.drip.tools/api/discovery.md#get-api-quotes-rates-liquidity), try later or another token |
| `429 RATE_LIMITED` | too many requests / quotes | sleep `Retry-After` seconds |
| `503 WARMING_UP` | backend restarting | retry in `retryAfterSec` |
| revert `Expired` (EVM) | paid after `deadline` | request a new quote |
| order `failed` | payout failed for that recipient | the FROM slice is refunded — see the `refund` field of the `GET /api/order` response |
| no order after paying | paid after `deadline`, or no usable `quoteId` in the memo / comment | a refund is recorded — `refund` on `GET /api/order`, or your history |
| no order, no refund | wrong payer / token / amount, or the same quote paid twice | [Errors → held for review](https://docs.drip.tools/reference/errors.md#payments-held-for-review) |

Every code with its fix: [Errors](https://docs.drip.tools/reference/errors.md).
