FaucetPay API reference.
Send micro-payouts, verify users, and look up balances over a single REST endpoint. Form-encoded requests, JSON responses, one api_key per faucet.
Build faucets, payouts, and automations on FaucetPay.
A small, predictable REST API over HTTPS. Every endpoint accepts form-encoded POST bodies, returns JSON with a top-level status integer, and authenticates with your faucet's api_key. No OAuth, no SDK needed.
REST over HTTPS
Every endpoint accepts form-encoded POST bodies and returns JSON.
One key per faucet
Your faucet api_key authenticates every request. Keep it server-side.
IP-aware
Send ip_address with /send to power cross-faucet abuse detection.
https://faucetpay.io/api/v1
Send your api_key with every request.
Pass your faucet's api_key in the api_key field of every POST body.
Send your first payout in under a minute.
Replace YOUR_API_KEY with a real faucet key, target a test user (your own email works) and fire.
curl -X POST https://faucetpay.io/api/v1/send \ -H "Content-Type: application/x-www-form-urlencoded" \ -d "api_key=YOUR_API_KEY&amount=100&to=user@example.com¤cy=BTC"
Request & response shape.
All endpoints are POST, form-encoded and return JSON. The envelope is identical across all endpoints so your client code can share parsing logic.
Content-Type: application/x-www-form-urlencoded api_key=YOUR_API_KEY amount=100 to=user@example.com currency=BTC ip_address=203.0.113.4
{
"status": 200,
"message": "Payout completed successfully!",
// …endpoint-specific fields
}
Response envelope
| Parameter | Type | Description |
|---|---|---|
| status Required | integer | Status |
| message Required | string | Message |
| … Optional | varies | Data |
The API surface
Five endpoints cover every faucet-owner scenario: send payouts, verify users, check balances, list history and introspect the coin list.
/send
Send
Pay out cryptocurrency from your account balance to a FaucetPay user.
Body parameters
| Parameter | Type | Description |
|---|---|---|
| api_key Required | string | Your faucet's API key. |
| amount Required | integer | Amount in the coin's smallest unit (satoshis for BTC). |
| to Required | string | Destination: email, username, or wallet address. |
| currency Required | string | Upper-case coin symbol, e.g. BTC, DOGE, USDT. |
| ip_address Optional | string | Claimer IP — strongly recommended; enables anti-abuse rate-limiting. |
| referral Optional | string | Referral tag attached to this payout for your own reporting. |
Example request
curl -X POST https://faucetpay.io/api/v1/send \ -H "Content-Type: application/x-www-form-urlencoded" \ -d "api_key=YOUR_API_KEY&amount=100&to=user@example.com¤cy=BTC&ip_address=203.0.113.4"
Example response
{
"status": 200,
"message": "OK",
"rate_limit_remaining": 0.00049900,
"currency": "BTC",
"balance": 49900,
"balance_bitcoin": 0.00049900,
"payout_id": 12834721,
"payout_user_hash": "3f9c1a2e6b7d0f5e8c4a9b2d1f6e0c8a7b5d2e91"
}
/checkaddress
Check address
Verify that a destination is a registered FaucetPay user for the chosen currency.
Body parameters
| Parameter | Type | Description |
|---|---|---|
| api_key Required | string | Your faucet's API key. |
| address Required | string | Email, username, or wallet address to verify. |
| currency Required | string | Upper-case coin symbol to check membership under. |
Example request
curl -X POST https://faucetpay.io/api/v1/checkaddress \ -H "Content-Type: application/x-www-form-urlencoded" \ -d "api_key=YOUR_API_KEY&address=user@example.com¤cy=BTC"
Example response
{
"status": 200,
"message": "This address belongs to a FaucetPay user.",
"payout_user_hash": "3f9c1a2e6b7d0f5e8c4a9b2d1f6e0c8a7b5d2e91"
}
/getbalance
Check balance
Fetch your current faucet balance for a given coin.
Body parameters
| Parameter | Type | Description |
|---|---|---|
| api_key Required | string | Your faucet's API key. |
| currency Required | string | Upper-case coin symbol. |
Example request
curl -X POST https://faucetpay.io/api/v1/getbalance \ -H "Content-Type: application/x-www-form-urlencoded" \ -d "api_key=YOUR_API_KEY¤cy=BTC"
Example response
{
"status": 200,
"message": "OK",
"currency": "BTC",
"balance": 49900,
"balance_bitcoin": 0.00049900
}
/payouts
List payouts
Return your most recent payouts, newest first.
Body parameters
| Parameter | Type | Description |
|---|---|---|
| api_key Required | string | Your faucet's API key. |
| count Optional | integer | How many payouts to return (1–100, default 10). |
| currency Optional | string | Filter to a single coin. Omit for all. |
Example request
curl -X POST https://faucetpay.io/api/v1/payouts \ -H "Content-Type: application/x-www-form-urlencoded" \ -d "api_key=YOUR_API_KEY&count=5¤cy=BTC"
Example response
{
"status": 200,
"message": "OK",
"rewards": [
{
"to": "user@example.com",
"amount": 100,
"date": "02-05-26 21:12:00 GMT"
}
]
}
/currencies
Supported currencies
Return every currency currently active on FaucetPay.
Body parameters
| Parameter | Type | Description |
|---|---|---|
| api_key Required | string | Your faucet's API key. |
Example request
curl -X POST https://faucetpay.io/api/v1/currencies \ -H "Content-Type: application/x-www-form-urlencoded" \ -d "api_key=YOUR_API_KEY"
Example response
{
"status": 200,
"message": "OK",
"currencies": ["BTC", "ETH", "USDT", "LTC", "DOGE"],
"currencies_names": [
{ "name": "Bitcoin", "acronym": "BTC" },
{ "name": "Ethereum", "acronym": "ETH" },
{ "name": "Tether", "acronym": "USDT" },
{ "name": "Litecoin", "acronym": "LTC" },
{ "name": "Dogecoin", "acronym": "DOGE" }
]
}
Status codes.
Every endpoint answers HTTP 200 and carries the real outcome in the response body's status field. Branch on that — these are the only values v1 sends.
| Code | Tone | Meaning |
|---|---|---|
| 200 | Success | OK — request succeeded |
| 401 | Error | Access denied — your IP is not whitelisted for this faucet, or the faucet owner's account is suspended |
| 402 | Error | The faucet does not have enough balance for this payout |
| 403 | Error | Forbidden — invalid or missing api_key |
| 404 | Error | Unknown API method, or the request was not a POST |
| 405 | Error | Invalid amount — must be a positive integer in the coin's smallest unit |
| 410 | Error | Invalid currency — not a coin FaucetPay supports |
| 450 | Warning | The send limit you set on your own faucet has been reached — try again later |
| 456 | Error | The recipient is not payable — no user owns that address, or the account is suspended or unverified |
| 457 | Error | The recipient was refused by your own rules — blacklisted, or failed your anti-fraud checks |
| 459 | Warning | Rate limited — too many API requests from your IP |
Supported coins.
Every coin active on FaucetPay is available for payouts.
Rate limits.
Limits are applied per faucet api_key and keep both your integration and our network healthy.
60 / min
Per-faucet api_key. Burst up to 120 tolerated.
Burst window
Short bursts above the limit are tolerated for up to 2 seconds.
Security best practices.
A short, opinionated checklist. Each item maps to a class of incident we've seen in the wild.
- Never ship your api_key to the browser. Treat it like a password: backend only, secrets manager, never in git.
- Always send ip_address with /send. It powers our cross-faucet abuse detection.
- Verify amount units in satoshis. A common bug is sending fractional coin values instead of the smallest-unit integer.
- Deduplicate claims server-side. Don't rely on the client to prevent double-submits.
- Rotate keys periodically. We support hot rotation: old keys stop working the moment you confirm a rotation.
Something unclear?
Open a ticket on the help desk and we'll update the docs.
Scoped, revocable keys with a Bearer token.
The v2 API is the modern surface for automation. Instead of one all-powerful faucet key, you mint narrow keys (read / send / manage / admin), send them as a Bearer token, and get a consistent JSON envelope. The legacy /api/v1 above is unchanged.
Bearer token auth
Send the key as Authorization: Bearer '<key>'.
Least-privilege scopes
Mint keys with only the scopes a tool needs.
Consistent JSON envelope
Every v2 response uses the same {status, message, data} shape.
https://faucetpay.io/api/v2
Example — authenticated request
curl -X POST https://faucetpay.io/api/v2/balances \
-H "Authorization: Bearer YOUR_SCOPED_KEY" \
-H "Content-Type: application/json" \
-d '{}'
Authentication & scopes.
Mint scoped keys from your faucet's Manage page. Each key is shown once, stored hashed, and can carry a per-key IP whitelist and (for send) a daily USD cap.
Read balances, payouts, statistics, currencies, settings, and anti-fraud status.
Make payouts — moves real funds. Keep server-side only.
Change faucet settings, rate limits, IP whitelist, and anti-fraud rules.
Create a faucet and request listing approval. Cannot delete faucets.
Endpoints.
Every v2 endpoint uses Bearer auth and returns the standard envelope.
| Endpoint | Scope | Body | Description |
|---|---|---|---|
/balance
|
read |
currency?
|
Check your faucet balance for a coin. |
/balances
|
read |
—
|
List balances across all coins. |
/currencies
|
read |
—
|
List supported currencies. |
/check-address
|
read |
address
|
Verify a destination address. |
/payouts
|
read |
currency?, count?
|
List recent payouts. |
/faucet
|
read |
—
|
Get faucet details |
/stats/daily
|
read |
—
|
Daily statistics |
/stats/users
|
read |
coin, page
|
User statistics |
/transactions
|
read |
coin, page
|
Transactions |
/ratelimits
|
read |
—
|
Rate limits |
/low-balance-notification
|
read |
—
|
Low-balance alerts |
| Endpoint | Scope | Body | Description |
|---|---|---|---|
/faucet/update
|
manage |
faucet_name, faucet_domain, faucet_url, faucet_description, timer_minutes, currencies_selected?, categories_selected?
|
Update faucet settings |
/ratelimits/set
|
manage |
ratelimits[]
|
Set rate limits |
/ip-whitelist
|
manage |
—
|
IP whitelist |
/ip-whitelist/set
|
manage |
ip_whitelist
|
Update IP whitelist |
/low-balance-notification/toggle
|
manage |
—
|
Toggle low-balance alert |
| Endpoint | Scope | Body | Description |
|---|---|---|---|
/anti-fraud/rules
|
manage |
—
|
Anti-fraud rules |
/anti-fraud/toggle
|
manage |
—
|
Toggle anti-fraud |
/anti-fraud/rules/update
|
manage |
trust_rank, negative_rank?, whitelist?, blacklist?
|
Update anti-fraud rules |
| Endpoint | Scope | Body | Description |
|---|---|---|---|
/send
|
send |
idempotency_key, currency, amount, to, ip_address?, referral?
|
Send payout |
| Endpoint | Scope | Body | Description |
|---|---|---|---|
/faucet/create
|
admin |
faucet_name, faucet_domain, faucet_url
|
Create faucet |
/approval-cost
|
admin |
coin
|
Listing approval cost |
/faucet/request-approval
|
admin |
coin
|
Request listing approval |
Sending payouts.
The v2 send is the safe way to pay out: it requires an idempotency key and honors an optional per-key daily USD cap. It uses the same anti-fraud / balance / rate-limit path as the legacy send.
/send
send
Send a payout with idempotency and optional daily cap.
Body parameters
| Parameter | Type | Description |
|---|---|---|
| idempotency_key Required | string | Unique per logical payout. A retry with the same key never double-pays. |
| to Required | string | Recipient: email, username, or wallet address. |
| amount Required | integer | Amount in the coin's smallest unit (e.g. satoshis for BTC). |
| currency Required | string | Upper-case coin symbol, e.g. BTC, DOGE. |
| ip_address Optional | string | Recipient IP — recommended for anti-fraud. |
| referral Optional | string | Referral tag for your own reporting. |
Example request
curl -X POST https://faucetpay.io/api/v2/send \
-H "Authorization: Bearer YOUR_SCOPED_KEY" \
-H "Content-Type: application/json" \
-d '{"idempotency_key":"claim-8f3a1c2e","to":"user@example.com","amount":100,"currency":"BTC","ip_address":"203.0.113.4"}'
Example response
{
"success": true,
"message": "OK",
"data": {
"rate_limit_remaining": 0.00049900,
"currency": "BTC",
"balance": 49900,
"balance_bitcoin": 0.00049900,
"payout_id": 12834721,
"payout_user_hash": "3f9c1a2e6b7d0f5e8c4a9b2d1f6e0c8a7b5d2e91"
}
}
Webhooks.
Subscribe to payout events and receive HMAC-signed POSTs. Configure them from your faucet's Manage page — webhook management is session + 2FA only, so a scoped key can never register a delivery endpoint.
Event-driven
Subscribe to payout.sent and payout.failed events.
HMAC-signed
Every delivery includes an X-FaucetPay-Signature header with an HMAC-SHA256 of the body.
SSRF protection
Webhook URLs must be public HTTPS endpoints. Internal IPs are rejected.
Example delivery
POST https://your-site.example/webhooks/faucetpay
X-FaucetPay-Signature: sha256=4b0c…e91
{
"id": "9f2c1a…",
"event": "payout.sent",
"faucet_id": 1234,
"created_at": 1717365120,
"data": {
"to": "user@example.com",
"amount": 100,
"currency": "BTC",
"payout_id": "payout_9nq0xk2l",
"payout_user_hash": "3f9c…",
"message": "Payout completed successfully!"
}
}
Verify the signature
import crypto from 'node:crypto';
// rawBody = the exact bytes you received (verify BEFORE JSON.parse)
const signature = req.headers['x-faucetpay-signature']; // 'sha256=<hex>'
const expected =
'sha256=' + crypto.createHmac('sha256', WEBHOOK_SECRET).update(rawBody).digest('hex');
const ok =
signature &&
crypto.timingSafeEqual(Buffer.from(signature), Buffer.from(expected));
if (!ok) return res.status(401).end();
Errors.
v2 uses standard HTTP status codes plus a descriptive message in the envelope.
| Code | Tone | Meaning |
|---|---|---|
| 200 | Success | 200 OK |
| 400 | Warning | 400 Bad request |
| 401 | Error | 401 Unauthorized |
| 403 | Error | 403 Forbidden |
| 409 | Warning | 409 Conflict |
| 429 | Warning | 429 Too many requests |
Manage your faucet from any AI agent.
The FaucetPay MCP server lets an AI assistant (Cursor, Claude Code, Windsurf, …) read your faucet and tune settings over the Model Context Protocol. It's a thin client over the v2 API — read + manage only.
Thin layer
The MCP server is a thin wrapper over the v2 API — no extra state.
No money tools
The server exposes no payout tools. It can read and manage, but not send funds.
Nothing to install
The server runs remotely. Just point your AI assistant at the URL.
Connect & configure.
Add the FaucetPay MCP server to your AI assistant config. Point it at your faucet with a scoped read or manage key.
// ~/.cursor/mcp.json
{
"mcpServers": {
"faucetpay": {
"url": "https://mcp.faucetpay.io/mcp",
"headers": { "Authorization": "Bearer fpk_your_read_or_manage_key" }
}
}
}
Configuration
| Parameter | Type | Description |
|---|---|---|
| url Required | string | MCP server URL |
| Authorization Required | header | Scoped API key (read or manage scope) |
Tools.
Read-only and manage tools exposed by the MCP server.
Read tools
-
get_faucetGet faucet details -
get_balancesGet faucet balances -
get_balanceGet the current faucet balance for a coin. -
get_payoutsList recent payouts -
get_currenciesList supported currencies and their limits. -
check_addressCheck if an address is a registered FaucetPay user. -
get_daily_statsGet daily statistics -
get_user_statsGet user statistics -
get_transactionsList transactions -
get_ratelimitsGet rate limits -
get_low_balance_notificationGet low-balance settings
Manage tools
-
get_ip_whitelistGet IP whitelist -
set_ip_whitelistUpdate IP whitelist -
get_anti_fraudGet anti-fraud settings -
toggle_anti_fraudToggle anti-fraud -
update_anti_fraud_rulesUpdate anti-fraud rules -
update_faucet_settingsUpdate faucet settings -
set_ratelimitsSet rate limits -
toggle_low_balance_notificationToggle low-balance alert
Security & best practices.
Best practices for using the MCP server safely.
- Use a read or manage key — never a send key. This server exposes no payout tools.
- Set a short expiry. Give the key a lifetime so a stale config can't be abused forever.
- Revoke instantly if exposed. One click on the Manage page kills the key.
- Heed anti-fraud advisories. Disabling or weakening anti-fraud returns a warning.
Earn more
Monetize your faucet with the FaucetPay ad network.
Accept crypto payments in your store.
The Merchant API lets any website accept payments from FaucetPay users through a hosted checkout page. The buyer pays from their FaucetPay balance and the funds settle to your account instantly — no keys or server-side SDK required to get started.
Hosted checkout
You submit a plain HTML form; FaucetPay hosts the whole payment page. Nothing sensitive ever touches your server.
Any supported coin
Price in one currency and let the buyer pay with any coin FaucetPay supports — or pin the payment coin yourself.
Instant settlement
Payments move between FaucetPay balances, so they confirm instantly with no on-chain fees or waiting.
The payment form.
Checkout starts with a simple HTML form POSTed to the FaucetPay checkout endpoint. The buyer is taken to a FaucetPay-hosted page to review and confirm the payment.
Submit the form with a standard browser POST (not XHR) — the buyer must land on the hosted checkout page to confirm the payment.
| Parameter | Type | Description |
|---|---|---|
| merchant_username Required | string | Your FaucetPay username — the account that receives the payment. |
| item_description Required | string | Description of the item or service the buyer is paying for. |
| amount1 Required | string | Amount you want to receive, denominated in currency1. |
| currency1 Required | string | The pricing currency of your store (e.g. USDT, BTC, …). |
| currency2 Optional | string | The coin the buyer must pay with. Leave blank to let the buyer choose any supported coin. |
| custom Optional | string | An identifier passed back on the callback — use it for your order ID or user ID. |
| callback_url Optional | string | URL that receives the server-to-server POST callback once the payment completes. |
| success_url Optional | string | URL the buyer is redirected to after a successful payment. |
| cancel_url Optional | string | URL the buyer is redirected to if they cancel. |
Example HTML form
<form action="https://faucetpay.io/merchant/webscr" method="post"> <input type="hidden" name="merchant_username" value="YOUR_USERNAME"> <input type="hidden" name="item_description" value="PlayStation 5"> <input type="hidden" name="amount1" value="100"> <input type="hidden" name="currency1" value="USDT"> <input type="hidden" name="currency2" value=""> <input type="hidden" name="custom" value="order-4564211"> <input type="hidden" name="callback_url" value="https://your-site.com/ipn"> <input type="hidden" name="success_url" value="https://your-site.com/success"> <input type="hidden" name="cancel_url" value="https://your-site.com/cancel"> <input type="submit" name="submit" value="Pay with FaucetPay"> </form>
Callback & verification.
After a completed payment, FaucetPay POSTs a form-encoded callback to your callback_url with the payment details and a single-use verification token. Verify the token server-side before delivering the goods.
Example callback (IPN)
POST https://your-site.com/ipn Content-Type: application/x-www-form-urlencoded token=1a2b3c4d5e6f7a8b9c0d &transaction_id=87654321 &merchant_username=your_username &payer_username=buyer_username &amount1=100 ¤cy1=USDT &amount2=0.00105 ¤cy2=BTC &custom=order-4564211 &exchange_rate=95238.09
Verify the token
GET https://faucetpay.io/merchant/get-payment/{token}
{
"valid": true,
"transaction_id": "87654321",
"merchant_username": "your_username",
"payer_username": "buyer_username",
"amount1": "100",
"currency1": "USDT",
"amount2": "0.00105",
"currency2": "BTC",
"custom": "order-4564211"
}
Retry schedule
We expect that you respond to the callback request with an HTTP 200 OK response. If we don't receive a 200 response, our system will assume that the request has failed and will reattempt the callback based on the following schedule.
- 1st Callback: Immediately (After Payment)
- 2nd Callback: 5 Minutes Delay
- 3rd Callback: 15 Minutes Delay
- 4th Callback: 30 Minutes Delay
- 5th Callback: 60 Minutes Delay
- 6th Callback: 120 Minutes Delay
- 7th Callback: 240 Minutes Delay