API for Developers
Access live yield data for the entire f(x) Protocol ecosystem — opportunities, TVL, APR/APY history, fxUSD price. Free tier available, no credit card required. Built-in x402 support for autonomous bots and AI agents.
Tiers
Choose the right plan for your integration.
| Anonymous | Free key | Pro key | x402 bot | |
|---|---|---|---|---|
| Rate limit | 30 req/min | 120 req/min | 600 req/min | Unlimited |
| Daily quota | — | 10 000 req | 100 000 req | Pay per call |
| Sparklines | ✗ | ✗ | ✓ | ✓ |
| 30-day stats | ✗ | ✗ | ✓ | ✓ |
| Price | Free | Free | Contact us | 0.001 USDC/call |
| Auth | None | X-Api-Key | X-Api-Key | X-PAYMENT |
| Ideal for | Browser | Builders | Production apps | Bots & agents |
Get a free API key
Register in seconds — no email verification, no credit card.
Authentication
Pass your key in the X-Api-Key header. All /api/v1/* routes require it.
# Free / Pro API key curl https://api.fxusd-observer.xyz/api/v1/opportunities \ -H "X-Api-Key: fxo_live_YOUR_KEY_HERE" # x402 per-call payment (bots / AI agents) curl https://api.fxusd-observer.xyz/api/v1/opportunities \ -H "X-PAYMENT: <base64url-encoded-x402-proof>"
If you call /api/v1/* without auth, the server returns a 402 Payment Required response describing your options:
{
"x402Version": 1,
"error": "Payment required. Options:\n 1. Get a free API key at /developers\n 2. Pay 0.001 USDC/call with x402 on base",
"accepts": [{
"scheme": "exact",
"network": "base",
"maxAmountRequired": "1000",
"payTo": "0x...",
"asset": "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
"maxTimeoutSeconds": 300
}]
}Endpoint reference
| Method | Endpoint | Description | Tiers |
|---|---|---|---|
| GET | /api/v1/opportunities | Full opportunity catalog with latest APR, APY, TVL. Pro adds sparklines + 30-day stats. | freeprox402 |
| GET | /api/v1/opportunities/{id} | Single opportunity by numeric ID or slug. Includes 90-day daily history. | freeprox402 |
| GET | /api/v1/stats | Aggregate KPIs: total TVL, best APR/APY, opportunity count, last sync. | freeprox402 |
| GET | /api/v1/fxusd-price | Current fxUSD price from on-chain oracle. | freeprox402 |
| GET | /api/v1/market-overview | Full market snapshot: TVL by protocol, top movers, fxUSD/fxSAVE KPIs. | freeprox402 |
| POST | /api/keys | Register a new free API key. Returns the full key once — keep it safe. | public |
| GET | /api/keys/{prefix} | Check key status, remaining daily quota, and total usage. | public |
| DELETE | /api/keys/{prefix} | Deactivate a key. Supply the full key as Authorization: Bearer <key>. | public |
Code examples
curl
# List all opportunities curl "https://api.fxusd-observer.xyz/api/v1/opportunities" \ -H "X-Api-Key: fxo_live_YOUR_KEY" # Get opportunity by slug curl "https://api.fxusd-observer.xyz/api/v1/opportunities/curve-usdc-fxusd" \ -H "X-Api-Key: fxo_live_YOUR_KEY" # Aggregate stats curl "https://api.fxusd-observer.xyz/api/v1/stats" \ -H "X-Api-Key: fxo_live_YOUR_KEY"
Python
import httpx
API_KEY = "fxo_live_YOUR_KEY"
BASE = "https://api.fxusd-observer.xyz/api/v1"
HEADERS = {"X-Api-Key": API_KEY}
with httpx.Client() as client:
# Opportunity list
opps = client.get(BASE + "/opportunities", headers=HEADERS).raise_for_status().json()
for opp in opps["items"]:
print(opp["name"], " APR=", opp["apr"], "% TVL=", opp["tvl_usd"])
# Check quota
prefix = API_KEY[:12]
quota = client.get("https://api.fxusd-observer.xyz/api/keys/" + prefix).json()
print("Remaining today:", quota["quota_remaining"], "/", quota["req_per_day"])JavaScript / TypeScript
const API_KEY = process.env.FXUSD_API_KEY; // fxo_live_...
const BASE = 'https://api.fxusd-observer.xyz/api/v1';
async function getOpportunities() {
const res = await fetch(BASE + '/opportunities', {
headers: { 'X-Api-Key': API_KEY },
next: { revalidate: 300 }, // Next.js ISR
});
if (!res.ok) throw new Error(await res.text());
const data = await res.json();
return data.items;
}
// Get highest-yield fxUSD opportunity
const opps = await getOpportunities();
const best = opps
.filter((o: any) => o.underlying === 'fxUSD')
.sort((a: any, b: any) => (b.apr ?? 0) - (a.apr ?? 0))[0];
console.log('Best fxUSD APR:', best?.apr, 'via', best?.name);x402 — Pay-per-call for bots & AI agents
No subscription, no sign-up. Pay 0.001 USDC per request on Base. Ideal for autonomous agents.
The x402 flow: the client calls without auth → receives a 402 with payment instructions → signs an EIP-3009 USDC authorization on Base → retries with X-PAYMENT: <proof>. The server verifies on-chain and returns X-PAYMENT-RESPONSE with a receipt.
Python (with coinbase-agentkit or x402-httpx)
# Using the x402-python client (pip install x402)
from x402.client import X402Client
from eth_account import Account
wallet = Account.from_key(os.getenv("PRIVATE_KEY"))
client = X402Client(wallet=wallet, network="base")
# The client handles the 402 → pay → retry loop automatically
opps = client.get("https://api.fxusd-observer.xyz/api/v1/opportunities").json()
print(f"Got {len(opps['items'])} opportunities (paid 0.001 USDC)")Payment details: Base mainnet · USDC 0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913 · 0.001 USDC (1 000 atomic units) per call. Compatible with any x402-compliant client (Coinbase AgentKit, AI SDKs, etc.).
Rate limits & error codes
| Code | Meaning | Action |
|---|---|---|
| 401 | Invalid or deactivated API key | Verify the key and that it has not been deactivated. |
| 402 | No auth supplied | Add X-Api-Key or X-PAYMENT header. Body contains x402 payment options. |
| 429 (per-min) | Per-minute rate limit exceeded | Back off and retry. Free: 120/min · Pro: 600/min. |
| 429 (daily) | Daily quota exceeded | Quota resets at midnight UTC. Consider Pro tier or x402. |
| 503 | Data not yet available | Backend sync in progress. Retry in 30 s. |
For Pro tier access, SLA inquiries, or bulk pricing contact hello@fxusd-observer.xyz. All data is sourced from on-chain contracts and third-party protocol APIs — not financial advice.