API providers
API provider guide
Sell your API by the call. Wrap an upstream URL as a Chest Gate, verify settlement on-chain, and keep reconciliation clean from day one.
Last updated May 12, 2026
This guide walks through wrapping your first upstream API as a paid Chest Gate, validating that a paid request settles on-chain in USDC, and setting up the reconciliation checks you'll run every month. About ten minutes end-to-end.
10-minute quickstart
Each step below has a verification check so you know you're set up correctly before moving on. Don't skip the discovery check in step two. It's the quickest way to catch a misconfigured deployment.
1. Deploy an endpoint
Open /dashboard/gates/new, fill in your endpoint URL and price, then sign the deploy transaction. The flow returns a deterministic slug. Save it. You'll use it in every subsequent call.
2. Verify discovery metadata
The well-known discovery endpoint is the canonical record for network, price, payTo, and the current split configuration. Agents and clients read it before every call, so this has to be correct.
curl "https://gate.chest.sh/g/<slug>/.well-known/chest.json" | jq3. Validate a paid call
A paid request works in two phases: the first request returns 402 Payment Requiredwith a challenge, and the retry carries X-Payment with a base64 payload. When the call settles, the response includes an X-Payment-Response header with the on-chain transaction reference.
# 1) challenge
curl -i "https://gate.chest.sh/g/<slug>/v1/resource"
# → 402 Payment Required
# 2) retry with X-Payment
curl -i "https://gate.chest.sh/g/<slug>/v1/resource" \
-H "X-Payment: <base64-payload>"
# → 2xx + X-Payment-Responseconst url = 'https://gate.chest.sh/g/<slug>/v1/resource'
const challenge = await fetch(url)
if (challenge.status !== 402) throw new Error('expected 402')
const paid = await fetch(url, {
headers: { 'X-Payment': '<base64-payload>' },
})
console.log(paid.status, paid.headers.get('X-Payment-Response'))import requests
url = "https://gate.chest.sh/g/<slug>/v1/resource"
# 1) challenge
r = requests.get(url)
assert r.status_code == 402
# 2) retry with payment
r = requests.get(url, headers={"X-Payment": "<base64-payload>"})
print(r.status_code, r.headers.get("X-Payment-Response"))Trust and accounting
Two references you'll reach for during month-end reconciliation.
Split math
10% is our default referrer rate, but merchants pick any value from 0–98.5% when they deploy, and can update it later from the dashboard or CLI. The numbers below assume the default.
For a 1.00 USDC paid call with the default split, settled amounts are:
| Party | Share | Amount (USDC) |
|---|---|---|
| Merchant | 88.5% | 0.885 |
| Referrer | 10.0% | 0.100 |
| Protocol | 1.5% | 0.015 |
Reconciliation checklist
- Export settled calls by date window from the dashboard.
- Cross-check each
distributeTxon the chain explorer. - Track and clear
distribute_failedrows separately.
Best practices
- Keep API keys and webhook secrets in server-side env vars only.
- Alert on
distribute_failedand retry quickly to avoid backlog drift. - Treat webhook deliveries as at-least-once, process them idempotently by
deliveryId.