Skip to content

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 ​

#StepCallYou get
1DiscoverGET /api/chains?unwrap=trueFROM chains (isTestnet: false) with their pay target contracts.depository; TO chains (isTestnet: true; skip isEnabled: false) and tokens.
2QuotePOST /api/quote { chainId, fromToken, sender, toChainId, toToken, recipients[], toAmounts[] }quoteId, vault (= pay target), fromTotal, deadline, signature. Free, non-binding, valid 180 s.
3Payone transaction on the FROM chain, exactly fromTotal, before deadlineEVM: 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.
4TrackGET /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.

Endpoints ​

EndpointPurpose
GET /api/chainsChains, tokens, pay targets.
GET /api/quotesTO-token rates and dispensable liquidity (not the quote endpoint).
GET /api/prices · /prices/atLive and historical FROM-token prices.
POST /api/quotePrice and sign a swap.
GET /api/orderOrders of one payment (from_tx_hash) or one order (id); &paginate=1 for big batches.
GET /api/ordersA payer's history, view=batches for one row per payment.
POST /api/orders/statusBulk status by order id (≤ 500).
GET /api/orders/loadQueue depth and your position (ETA).
GET /api/orders/streamServer-Sent Events when your orders change.

Numbers to remember ​

WhatValue
Minimum order$1 single recipient · $5 multisend
TO amount precision4 decimal places (whole sats on Bitcoin); ≥ 0.001 SOL per recipient on Solana
Quote lifetime180 s (deadline = expiry)
Recipients per quoteup to 10 000, one payment
Rate limits600 requests / min per IP · 10 quotes / min per IP · 30 quotes / min per sender
Amountsbase-unit integer strings (toAmounts, fromTotal); order history amounts are human decimals
Native cointoken address 0x0000000000000000000000000000000000000000 on every chain
Non-EVM FROM idsSolana 1399811149 · TON 1667471768 (Solana testnet 1399811150, devnet 1399811151, TON testnet 1667471769)
PriceTO 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.

When something goes wrong ​

You seeMeaningDo
400 BELOW_MIN_TOTALorder under $1 / $5raise toAmounts
400 NO_LIQUIDITY / 503 NO_TO_PRICEthat TO token can't be dispensed nowcheck GET /api/quotes, try later or another token
429 RATE_LIMITEDtoo many requests / quotessleep Retry-After seconds
503 WARMING_UPbackend restartingretry in retryAfterSec
revert Expired (EVM)paid after deadlinerequest a new quote
order failedpayout failed for that recipientthe FROM slice is refunded — see the refund field of the GET /api/order response
no order after payingpaid after deadline, or no usable quoteId in the memo / commenta refund is recorded — refund on GET /api/order, or your history
no order, no refundwrong payer / token / amount, or the same quote paid twiceErrors → held for review

Every code with its fix: Errors.