API

Three ways to get a drip on Filecoin Calibration: a public low-limit endpoint for open-source CLIs, the captcha-gated path the web UI uses, and an API-key path for CI / test runners that need a higher cap.

basehttps://faucet.reiers.io publicno auth, low cap keyBearer / X-API-Key

Public drip no auth, no captcha

For public open-source CLIs that ship to end users and cannot embed a secret. Smaller drip, stricter per-IP cap, same per-address cap.

curl -X POST https://faucet.reiers.io/api/public/drip/fil \
  -H 'content-type: application/json' \
  -d '{"address":"0xYourAddressHere"}'

Same shape for USDFC:

curl -X POST https://faucet.reiers.io/api/public/drip/usdfc \
  -H 'content-type: application/json' \
  -d '{"address":"0xYourAddressHere"}'

Live caps and amounts are advertised on /api/info under publicDrip, so CLIs can render real numbers without hardcoding. Defaults today:

Need more than once a day? See the API key path below.

Dual-drip endpoint tFIL + USDFC in one call

A single endpoint that drips both tFIL and USDFC in one call and returns an array of per-token results. Designed for testnet wallet bootstrap flows where the caller wants both assets in one step. The envelope shape is compatible with the legacy community-faucet contract that many existing Filecoin tooling CLIs already speak, so callers can point their existing client at Plumbline with a single URL change.

curl 'https://faucet.reiers.io/api/claim_token_all?address=0xYourAddressHere'

Response:

[
  { "faucetInfo": "CalibnetFIL",   "tx_hash": "0x…" },
  { "faucetInfo": "CalibnetUSDFC", "tx_hash": "0x…" }
]

Per-token errors are reported per-element, so a partial success (e.g. FIL ok, USDFC rate-limited) still returns 200 with an error object on the failed element. Full-failure responses return 429 with the same array shape.

Same caps as /api/public/drip/*: per-IP and per-address windows apply identically.

The response is streamed: the JSON array opens immediately and each element is written as soon as its on-chain transaction settles. Full dual-drip wall time is typically 60-90 seconds, so set the client request timeout to at least 120 seconds. Use ?assets=fil or ?assets=usdfc to drip just one token and cut wall time roughly in half.

API key for CI & test runners

Keys are issued out-of-band by the operator. Ping @Reiers on Filecoin Slack (or email [email protected]) with:

Default per-key allowance is 50 drips per asset per 24h, plenty for normal CI. Higher limits on request. Per-address limits still apply (2 per asset per 24h), so a single key can't be used to drain the faucet into one wallet.

Authenticating

Send the key as either of these headers on the drip endpoints:

Authorization: Bearer pk_yourkeyhere
X-API-Key: pk_yourkeyhere

A request that presents a valid, enabled key bypasses Cloudflare Turnstile entirely. Without a key, the drip endpoints require a Turnstile token from the web UI.

Dripping POST /api/drip/{fil,usdfc}

Body:

{
  "address": "0xYourAddressHere"
}

tFIL accepts any of 0x…, t410f…, t1…, t3…, t0…. USDFC is an ERC-20, so it only accepts 0x… or t410f….

Example (tFIL):

curl -X POST https://faucet.reiers.io/api/drip/fil \
  -H 'content-type: application/json' \
  -H 'Authorization: Bearer pk_yourkeyhere' \
  -d '{"address":"0xYourAddressHere"}'

Success response:

{
  "ok": true,
  "txHash": "0x…",
  "verified": true,
  "amount": "5000000000000000000",
  "asset": "fil"
}

verified: true means the server confirmed on-chain that the recipient's balance moved by at least the drip amount before returning.

Public read endpoints

No auth required. Useful for status dashboards or monitoring.

MethodPathReturns
GET/healthzliveness + dispenser balances
GET/api/infobrand, drip amounts, rate-limit defaults
GET/api/statslifetime + 24h aggregate counters
GET/api/recentlast N drips (default 10, max 50)
GET/api/convert?address=…0x ↔ t410f conversion via lotus RPC

Error responses

All errors return JSON with ok: false and an error code. HTTP status reflects the class.

StatusCodeWhen
400bad_requestBody didn't parse
400invalid_addressAddress couldn't be classified
400usdfc_native_unsupportedUSDFC drip to a t1/t3 address
400captchaNo API key, Turnstile token missing or invalid
401invalid_api_keyKey not recognised
401revoked_api_keyKey disabled by the operator
429api_key_rate_limitedPer-key drip window exhausted
429address_rate_limitedPer-address window exhausted
429ip_rate_limitedPer-IP window exhausted (captcha path)
429public_ip_rate_limitedPer-IP window exhausted on /api/public/drip/*
503faucet_dryDispenser balance below reserve
500drip_failedRPC error sending the on-chain tx

Every 429 includes retryAtUnix (epoch seconds) so a retry loop knows exactly when to come back:

{
  "ok": false,
  "error": "api_key_rate_limited",
  "scope": "api_key",
  "used": 50,
  "max": 50,
  "windowSec": 86400,
  "retryAfterSec": 41832,
  "retryAtUnix": 1778709058
}

More

Full reference (every endpoint, TypeScript example, shell helper for CI): docs/api.md on GitHub.

Source: github.com/Reiers/plumbline-faucet. Issues and PRs welcome.