x402
Pay per request with USDC on Base via x402. Exact and Upto schemes, Permit2 for metered tools, when you still need an API key.
Use an API key and credits for most integrations. x402 lets you call paid /v1 routes without a key — pay USDC on Base, same JSON back.
Account routes (/v1/whoami, /v1/balance) and NL Ask (POST /v1/ask) always need an API key. They are not on the x402 rail.
Paid endpoints are also discoverable in the Coinbase x402 Bazaar catalog (HTTP and MCP).
How it works
- Call a paid endpoint without
x-api-key. - Read HTTP 402 and the
PAYMENT-REQUIREDheader (Base64 JSON — amount, network, pay-to, scheme). - Sign the payment (wallet or
@x402/fetch). - Retry the same request with
PAYMENT-SIGNATURE. - On success, use the JSON body as usual;
PAYMENT-RESPONSEis the settlement receipt.
Price matches the Starter pack list rate: $0.014 per credit. Metering is the same as the credits rail (including attempt floors on some search endpoints).
Optional: send a payment-identifier so retries stay idempotent.
Exact vs upto
The PAYMENT-REQUIRED challenge includes a scheme. Register both schemes on your buyer client so every paid route works.
| Scheme | When you see it | Buyer setup |
|---|---|---|
exact | Flat-price routes (most endpoints) | Sign each request. USDC uses EIP-3009 — no on-chain approve |
upto | Metered routes (e.g. list/search that charge per returned record) | Authorize a ceiling; settle charges only what was used. Needs a one-time Permit2 approve (below) |
If you only register ExactEvmScheme, metered/upto calls will fail after the payment challenge.
Routes that download or host media
Routes that copy media to our CDN charge for the files actually delivered, so the price depends on the request:
| Request | Options in the challenge | You pay |
|---|---|---|
No media asked for (no downloadMedia / hostMedia) | exact at the base price | The base price |
downloadMedia=true or hostMedia=true | upto first, then exact at the same maximum | upto: only what was downloaded or hosted. exact: the maximum |
GET /v2/instagram/media/{media}?include=files, GET /v1/tiktok/videos/download | upto first, then exact at the maximum | upto: the base price if no media was found, the full price otherwise. exact: the full price |
A buyer that registers only ExactEvmScheme keeps working on every one of these routes and pays the maximum, as it always has. Register UptoEvmScheme as well to pay only what a credit payer would be charged. @x402/fetch picks the first option your client supports, so an upto-capable client uses upto automatically.
These routes: Instagram posts (downloadMedia), post download, profile posts, reels and tagged posts (hostMedia); TikTok videos (downloadMedia), video download and profile videos (hostMedia); Facebook profile posts, reels and photos (hostMedia). Pay-per-request MCP tools follow the same rule.
One-time Permit2 approve
For upto on Base, your buyer wallet must approve the canonical Permit2 contract to spend USDC once:
- USDC (Base):
0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913 - Permit2:
0x000000000022D473030F116dDEE9F6B43aC78BA3
Call USDC.approve(Permit2, maxUint256) (or a large allowance) from the paying wallet. Exact / EIP-3009 routes do not need this. Standard x402 Permit2 setup — see the CDP / x402 buyer docs.
Distinguish HTTP 402
| Kind | How to tell | What to do |
|---|---|---|
| Credits | error.code = "insufficient_credits" (API key present) | Top up credits |
| x402 challenge | PAYMENT-REQUIRED header + error.code = "payment_required" | Pay USDC and retry |
| Settle failed | error.code = "payment_settlement_failed" | Not a successful response — retry only with a new payment if needed |
Do not treat every 402 as "out of credits." For walk-up pay, look for the PAYMENT-REQUIRED header. Full envelopes: Errors.
Try unpaid
curl -i "https://api.socialfetch.dev/v1/twitter/profiles/elonmusk"Expect 402 and a PAYMENT-REQUIRED header. The JSON body tells you to send an API key (most callers); the header is the x402 challenge.
Pay from Node
Install the official buyer helpers, then wrap fetch. Register Base (eip155:8453) and both Exact and Upto schemes.
npm install @x402/fetch @x402/evm viemimport { wrapFetchWithPayment, x402Client } from "@x402/fetch";
import { ExactEvmScheme } from "@x402/evm/exact/client";
import { UptoEvmScheme } from "@x402/evm/upto/client";
import { privateKeyToAccount } from "viem/accounts";
const signer = privateKeyToAccount(
process.env.EVM_PRIVATE_KEY as `0x${string}`,
);
const client = new x402Client()
.register("eip155:8453", new ExactEvmScheme(signer))
.register("eip155:8453", new UptoEvmScheme(signer));
const fetchWithPayment = wrapFetchWithPayment(fetch, client);
const res = await fetchWithPayment(
"https://api.socialfetch.dev/v1/twitter/profiles/elonmusk",
);
console.log(res.status, await res.json());
console.log(res.headers.get("PAYMENT-RESPONSE"));Keep the private key server-side. Prefer the official buyer quickstart for other languages (Go, Python, etc.).
MCP
MCP has two endpoints:
https://api.socialfetch.dev/mcp— OAuth orx-api-key. Tools bill credits on your account (whoami, balance, and NL Ask always need this endpoint). No credentials returns 401.https://api.socialfetch.dev/x402/mcp— anonymous walk-up. Paid tools challenge with x402; attach payment meta and settle in USDC (Exact + Upto, same Permit2 rule as HTTP).
Invalid Bearer or x-api-key returns 401 on either endpoint — no x402 fallback.
Further reading
- x402 protocol docs
- Buyer quickstart
- Payment identifier
- Coinbase x402 Bazaar
- Credits & billing — API key path
- Errors —
402envelopes
Agent Skills
Install the Social Fetch agent skill with npx skills — teach Cursor, Claude, and other agents to use llms.txt, MCP, POST /v1/ask, and real endpoints only.
n8n
Pull live social and web data into your n8n workflows — and AI agents — with a single verified node. No custom HTTP nodes, no glue code.