Developers

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.

Overview

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.

Base URL
https://faucetpay.io/api/v1
Authentication

Send your api_key with every request.

Pass your faucet's api_key in the api_key field of every POST body.

Never expose your api_key
Shipping the key to the browser or a public repo is the #1 cause of drained faucets.
1 Open the Faucet owner dashboard and pick a faucet.
2 In Manage → API & Webhooks, reveal or regenerate the key.
3 Store the key in your backend secrets manager, not in a repo.
Quick start

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&currency=BTC"
Format

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.

Request application/x-www-form-urlencoded
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
Response application/json
{
  "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
Endpoints

The API surface

Five endpoints cover every faucet-owner scenario: send payouts, verify users, check balances, list history and introspect the coin list.

POST /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&currency=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"
}
POST /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&currency=BTC"

Example response

{
  "status": 200,
  "message": "This address belongs to a FaucetPay user.",
  "payout_user_hash": "3f9c1a2e6b7d0f5e8c4a9b2d1f6e0c8a7b5d2e91"
}
POST /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&currency=BTC"

Example response

{
  "status": 200,
  "message": "OK",
  "currency": "BTC",
  "balance": 49900,
  "balance_bitcoin": 0.00049900
}
POST /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&currency=BTC"

Example response

{
  "status": 200,
  "message": "OK",
  "rewards": [
    {
      "to":     "user@example.com",
      "amount": 100,
      "date":   "02-05-26 21:12:00 GMT"
    }
  ]
}
POST /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" }
  ]
}
Reference

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
Reference

Supported coins.

Every coin active on FaucetPay is available for payouts.

Bitcoin
BTC
Active
Ethereum
ETH
Active
Tether
USDT
Active
Litecoin
LTC
Active
Dogecoin
DOGE
Active
Bitcoin Cash
BCH
Active
Dash
DASH
Active
DigiByte
DGB
Active
Tron
TRX
Active
Zcash
ZEC
Active
Solana
SOL
Active
BNB
BNB
Active
Feyorra
FEY
Active
USD Coin
USDC
Active
Reference

Rate limits.

Limits are applied per faucet api_key and keep both your integration and our network healthy.

Live keys

60 / min

Per-faucet api_key. Burst up to 120 tolerated.

Burst tolerance

Burst window

Short bursts above the limit are tolerated for up to 2 seconds.

Reference

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.

Open help desk
Scoped-key API (v2)

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.

Base URL
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 '{}'
Scoped-key API (v2)

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.

1 Faucet owner → Manage your faucet → Scoped API keys.
2 Create key, tick the minimum scopes the tool needs, copy it once.
3 Store it server-side; revoke instantly from the same page if exposed.
read

Read balances, payouts, statistics, currencies, settings, and anti-fraud status.

send moves money / account

Make payouts — moves real funds. Keep server-side only.

manage

Change faucet settings, rate limits, IP whitelist, and anti-fraud rules.

admin charges listing fee

Create a faucet and request listing approval. Cannot delete faucets.

Legacy keys still work
Your existing faucet api_key continues to work on v1 endpoints.
Scoped-key API (v2)

Endpoints.

Every v2 endpoint uses Bearer auth and returns the standard envelope.

Read
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
Management
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
Anti-fraud
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
Send
Endpoint Scope Body Description
/send send idempotency_key, currency, amount, to, ip_address?, referral? Send payout
Admin
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
Scoped-key API (v2)

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.

Idempotency is mandatory
Every /send requires an idempotency key. A retry with the same key never double-pays.
Daily payout cap
When you mint a send key you can set a daily payout cap. Exceeding it returns a 429 and the payout is not made.
POST /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"
  }
}
Scoped-key API (v2)

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();
Verify before you trust
Recompute the HMAC over the raw request body with your webhook secret and constant-time compare it to the header.
Scoped-key API (v2)

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
MCP server

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.

Built-in guidance
The server ships agent instructions, a security-review prompt, and a monetization prompt.
MCP server

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)
MCP server

Tools.

Read-only and manage tools exposed by the MCP server.

read

Read tools

  • get_faucet Get faucet details
  • get_balances Get faucet balances
  • get_balance Get the current faucet balance for a coin.
  • get_payouts List recent payouts
  • get_currencies List supported currencies and their limits.
  • check_address Check if an address is a registered FaucetPay user.
  • get_daily_stats Get daily statistics
  • get_user_stats Get user statistics
  • get_transactions List transactions
  • get_ratelimits Get rate limits
  • get_low_balance_notification Get low-balance settings
manage

Manage tools

  • get_ip_whitelist Get IP whitelist
  • set_ip_whitelist Update IP whitelist
  • get_anti_fraud Get anti-fraud settings
  • toggle_anti_fraud Toggle anti-fraud
  • update_anti_fraud_rules Update anti-fraud rules
  • update_faucet_settings Update faucet settings
  • set_ratelimits Set rate limits
  • toggle_low_balance_notification Toggle low-balance alert
Prompts & resources
Slash-style prompts faucetpay_security_review and faucetpay_monetization_setup ship with the server for on-demand help.
MCP server

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.

Open ad network
Merchant API

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.

Enable merchant payments first
Apply for a merchant account from your FaucetPay dashboard before going live. Payments are received under your FaucetPay username.
Merchant API

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.

POST https://faucetpay.io/merchant/webscr

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>
Pinning the payment coin
If currency2 is set, the buyer can only pay with that exact coin. When blank, the buyer picks any supported coin and FaucetPay converts at the current exchange rate.
Merchant API

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
&currency1=USDT
&amount2=0.00105
&currency2=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
Never trust the callback alone
Anyone can POST fake data to your callback URL. Always confirm the payment by calling the verify endpoint with the received token — it returns the authoritative payment record and each token works exactly once. Retries back off for up to several hours, so keep your endpoint idempotent using the custom field.