Skip to content

API Reference — Orders ​

After you pay, one payment becomes one order per recipient. These endpoints track them.

Order status values: processing → completed (or failed); pending is reserved and not produced by the current flow. See Order lifecycle.

GET /api/order ​

Two modes — pass one of id or from_tx_hash.

By payment: ?from_tx_hash=<ref> ​

The most common tracking call — one payment can emit several orders (multisend). ref is:

FROM chainWhat to pass
EVMThe payment transaction hash (0x…).
SolanaThe transaction signature (base58).
TONThe quoteId — your wallet does not learn the treasury-side transaction hash. Resolved once the payment is honoured (afterwards the order's from.txHash, 64 hex characters, works too). A refused payment never resolves here — find its refund in the payer's history, GET /api/orders?address=<UQ…>&view=batches.
bash
curl 'https://drip.tools/api/order?from_tx_hash=0x<yourFromTx>'
json
{
  "data": [
    {
      "status": "completed",
      "id": "abc123…",
      "from": {
        "chainId": "8453", "displayName": "Base", "symbol": "ETH",
        "amount": "0.00051755", "address": "0xpayer",
        "tokenAddress": "0x0000000000000000000000000000000000000000",
        "txHash": "0x<from tx>", "ts": 1784120925,
        "explorer": "https://basescan.org", "family": null, "cluster": null
      },
      "to": {
        "chainId": "421614", "displayName": "Arbitrum Sepolia", "symbol": "ETH",
        "amount": "5.00000000", "address": "0xrecipient",
        "tokenAddress": "0x0000000000000000000000000000000000000000",
        "txHash": "0x<payout tx>", "ts": 1784120990,
        "explorer": "https://sepolia.arbiscan.io", "family": null, "cluster": null
      }
    }
  ],
  "refund": null
}
  • data is one order object per recipient (empty array until the payment is indexed — keep polling).
  • refund is null unless some/all of the payment is being returned (a payment that could not become an order, or the failed slices of a partial batch) — see refund object.

Paginated recipients: &paginate=1 ​

For large batches, ask for an aggregate summary plus a keyset page of recipients instead of the whole array:

bash
curl 'https://drip.tools/api/order?from_tx_hash=0x<yourFromTx>&paginate=1&limit=100'
ParameterDescription
limitPage size, default 100, max 1000. limit=all returns the whole remainder in one response; limit=0 returns the summary only.
cursornext_cursor from the previous page.
json
{
  "summary": {
    "recipients": 250,
    "statusCounts": { "completed": 240, "processing": 10, "failed": 0 },
    "fromTotal": "0.12500000",
    "toTotal": "1250.00000000",
    "completedTs": null,
    "lastPayout": null
  },
  "data": [ /* order objects, in recipient order */ ],
  "pagination": { "has_next_page": true, "next_cursor": "184233" },
  "refund": null
}

completedTs is filled once nothing is left processing; lastPayout ({ txHash, ts } of the last payout) additionally needs at least one completed order — an all-failed batch has completedTs but lastPayout: null. Until the payment is indexed, summary.recipients is 0 and fromTotal / toTotal are null.

By id: ?id=<order_id> ​

Returns a single order object, or null (with status 200) if the order isn't indexed yet — keep polling. Order ids are case-sensitive.

bash
curl 'https://drip.tools/api/order?id=abc123…'

Passing neither parameter → 400 Provide order id or from_tx_hash.

Order object ​

FieldMeaning
statusprocessing | completed | failed (pending is reserved, never produced today).
idThe order id (use with /order?id= and /orders/status).
fromThe payment side: chainId, displayName, symbol, amount (human), address (payer), tokenAddress, txHash, ts, plus explorer / family / cluster for building links.
toThe payout side: same fields for the recipient; txHash is the payout tx (null until dispensed), ts the completion time.

Identity forms on the from side follow the chain: an EVM payer is 0x… and txHash is the transaction hash; a Solana payer is base58 and txHash the transaction signature (family: "solana", cluster: "mainnet-beta"); a TON payer is the UQ… address and txHash the treasury-side transaction hash (64 hex characters, family: "ton").

Refund object ​

FieldMeaning
statusrefund_pending (recorded, not yet returned) | refunded (return tx sent).
reasonunknown_quote | unattributed | ambiguous_memo | expired | bad_signature | failed_order — see Refund reasons.
fromThe returned amount + payer + original payment tx.
refundTxHashThe return transaction, or null.
refundedAtEpoch seconds, or null.

GET /api/orders ​

A payer's order history, keyset-paginated.

Query parameters

NameTypeRequiredDescription
addressstringyesThe payer identity, or up to 10 identities comma-separated (0x…, Solana base58, TON address). EVM addresses match case-insensitively; Solana and TON identities must be exact (UQ… form for TON).
viewstringnobatches = one row per payment (multisend collapsed). Otherwise one row per order.
limitnumberno1–100, default 20.
cursorstringnonext_cursor from a prior response — the next (older) page.
since_cursorstringnoPoll for rows newer than this cursor.

view=batches also accepts filters (resend them with every page): status (processing|partial|completed|failed|refund), to_chain_id, and q (prefix search over order ids / FROM tx hashes, at least 2 characters).

Response

json
{
  "data": [ /* order or batch rows */ ],
  "pagination": {
    "has_next_page": true,
    "next_cursor": "eyJ0cyI6…",
    "latest_item_cursor": "eyJ0cyI6…"
  }
}

A batch row (view=batches) aggregates a payment:

json
{
  "status": "partial",
  "statusCounts": { "completed": 3, "processing": 0, "failed": 1 },
  "refund": { "status": "refund_pending", "reason": "failed_order" },
  "recipients": 4,
  "id": "firstOrderId",
  "from": { "chainId": "8453", "displayName": "Base", "symbol": "ETH", "amount": "0.16", "address": "0x<payer>", "txHash": "0x…", "ts": 1784120925 },
  "to":   { "chainId": "421614", "displayName": "Arbitrum Sepolia", "symbol": "ETH", "amount": "16.0", "address": null, "txHash": null, "ts": null }
}

Aggregate status is processing | completed | failed | partial (some paid, some failed). Amounts are decimal strings whose trailing zeros vary (a batch row's from.amount is padded to 18 places, other amounts to 8) — parse them as decimals, never compare them as strings.

Payments that could not become an order (unknown or missing quote, expired) appear in the unfiltered batches view as rows with status: "refund_pending" / "refunded", isRefund: true, reason, recipients: 0, id: null (no order id — look the payment up by its FROM tx hash) and to: null; status=refund lists only those.

Errors: 400 Incorrect address; 400 status must be one of: processing, partial, completed, failed, refund.

POST /api/orders/status ​

Lightweight bulk status for order ids you already hold.

bash
curl -X POST 'https://drip.tools/api/orders/status' \
  -H 'Content-Type: application/json' \
  -d '{ "ids": ["orderId1", "orderId2"] }'
json
{
  "data": [
    { "status": "completed", "id": "orderId1", "to": { "txHash": "0x<payout>", "ts": 1784120990 } }
  ]
}

Missing ids are simply omitted. Empty ids: [] → { "data": [] }. Non-array ids → 400 ids must be an array and is required. More than 500 ids → 400 too many ids (max 500).

GET /api/orders/load ​

Dispense-queue depth and drain rate, for estimating how long a payout will take.

Query parameters

NameTypeRequiredDescription
refstringnoAn order_id or a FROM tx hash (or the TON treasury-side hash) — adds your position in line.

Response

json
{
  "updatedAt": 1784120100,
  "ratePerSec": 25,
  "minEtaSec": 10,
  "chains": {
    "421614": { "depth": 42, "rate": 28.5, "measured": true, "stalled": false, "minEtaSec": null }
  },
  "ref": {
    "chainId": "421614",
    "depth": 17,
    "statusCounts": { "processing": 2, "completed": 15, "failed": 0 }
  }
}
  • chains[toChainId].depth — recipients still awaiting dispense on that TO chain; rate — measured drain rate (recipients/sec). Rough ETA ≈ max(minEtaSec, depth / rate). An idle chain is simply absent from chains.
  • ref.depth — recipients ahead of (and including) your batch on its TO chain; only shrinks as the queue reaches you. ref is null if the ref isn't indexed yet — fall back to the chain-wide depth.

GET /api/orders/stream ​

A Server-Sent Events feed that fires whenever an order or refund belonging to the given payer identities changes. It is a notification only — re-fetch with GET /api/order or GET /api/orders when it fires.

bash
curl -N 'https://drip.tools/api/orders/stream?address=0xpayer'
txt
: connected

event: orders-changed
data: {"txs":["0x<from tx>"]}

: ping
  • address — same as GET /api/orders: one or more identities, comma-separated.
  • orders-changed — data.txs lists the FROM tx hashes whose orders changed. Re-fetch those.
  • A : ping comment every 25 s keeps the connection alive. The stream is not rate-limited; a malformed address gets 400 Incorrect address, and if it answers 503, fall back to polling.