API Reference
img402 is an image hosting API for AI agents and developers. Upload an image, get a public CDN URL. No accounts, no API keys.
Quickstart#
Upload an image and get a public URL in one command:
curl -F [email protected] https://img402.dev/api/freeResponse:
{
"url": "https://i.img402.dev/abc123.png",
"id": "abc123",
"contentType": "image/png",
"sizeBytes": 24891,
"expiresAt": "2026-02-15T00:00:00.000Z"
}That's it. The URL is public, served via Cloudflare CDN, and works in markdown, HTML, GitHub PRs, Slack — anywhere that accepts an image URL.
Authentication#
img402 has no accounts and no API keys.
- Free tier — No auth at all. Just send the request.
- Paid tier — Payment is authentication. The x402 protocol handles payment verification automatically. If you paid, you're authorized.
Base URL: https://img402.dev
POST /api/free — Free upload#
Upload an image with no payment required. 1MB max, 7-day retention.
Request
Send the image as either multipart form-data or JSON with base64:
curl -X POST https://img402.dev/api/free \
-F [email protected]curl -X POST https://img402.dev/api/free \
-H "Content-Type: application/json" \
-d '{"file": "<base64-encoded-image>"}'Response (200)
{
"url": "https://i.img402.dev/abc123.png",
"id": "abc123",
"contentType": "image/png",
"sizeBytes": 24891,
"expiresAt": "2026-02-15T00:00:00.000Z"
}Errors
400 no_file— No image in the request400 empty_file— File has zero bytes400 file_too_large— Over 1MB400 unsupported_format— Not PNG, JPEG, GIF, or WebP429 daily_limit— Daily free upload cap reached500 upload_failed— Server error (safe to retry)
POST /api/upload/token — Get upload token ($0.01)#
Pay $0.01 USDC on Base via x402 to get a single-use upload token. Valid for 10 minutes. No request body needed — the x402 protocol handles payment via HTTP headers.
This is the recommended flow for images larger than a few KB. It keeps binary data out of the payment request, which is important when the payment goes through an agent's context window (e.g. the Payments MCP tool).
Response (200)
{
"token": "a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2",
"expiresAt": "2026-02-08T01:10:00.000Z"
}If the same payment was already used to upload an image, the token endpoint returns the existing image instead (idempotent):
{
"url": "https://i.img402.dev/xY9kP3mQ7n.png",
"id": "xY9kP3mQ7n",
"contentType": "image/png",
"sizeBytes": 245891,
"expiresAt": "2027-02-08T00:00:00.000Z"
}Response (402)
If no payment is provided, the server returns 402 with x402 payment instructions. x402-compatible clients (like the Payments MCP tool) handle this automatically — they read the instructions, pay on-chain, and retry with proof.
POST /api/upload — Upload with token or x402 payment#
Upload an image using an upload token (from the token endpoint) or a direct x402 payment. 5MB max, 1-year retention.
With upload token (recommended)
# Step 1: Get a token (pay $0.01 via x402)
# (use Payments MCP tool or any x402 client)
POST /api/upload/token
# → {"token": "a1b2c3...", "expiresAt": "..."}
# Step 2: Upload with the token
curl -X POST https://img402.dev/api/upload \
-H "X-Upload-Token: a1b2c3..." \
-F [email protected]With direct x402 payment
You can also skip the token and pay inline. The x402 payment headers go on the upload request itself. This works for small images but is not recommended for larger files.
Request body
Same as the free endpoint: multipart form-data with image field, or JSON with file (base64).
Response (200)
{
"url": "https://i.img402.dev/xY9kP3mQ7n.png",
"id": "xY9kP3mQ7n",
"contentType": "image/png",
"sizeBytes": 245891,
"expiresAt": "2027-02-08T00:00:00.000Z"
}Errors
400 no_file— No image in the request400 file_too_large— Over 5MB400 unsupported_format— Not PNG, JPEG, GIF, or WebP401 invalid_token— Token is invalid or already used401 token_expired— Token has expired (10-minute TTL)402— No token and no x402 payment provided
GET https://i.img402.dev/:id.:ext — Serve image#
All uploaded images are publicly accessible at their URL. Served via Cloudflare CDN with global edge caching.
Response headers
Content-Type: image/png
Cache-Control: public, max-age=31536000, immutable # paid (1 year)
Cache-Control: public, max-age=604800 # free (7 days)
Access-Control-Allow-Origin: *Returns 404 if the image doesn't exist or has expired.
Supported formats#
PNG, JPEG, GIF, and WebP. Format is detected by magic bytes (file header), not file extension or Content-Type header. A renamed .zip file will be rejected even if it has a .png extension.
Limits#
| Free | Paid | |
|---|---|---|
| Endpoint | /api/free | /api/upload |
| Max size | 1 MB | 5 MB |
| Retention | 7 days | 1 year |
| Price | Free | $0.01 USDC on Base |
| Formats | PNG, JPEG, GIF, WebP | |
x402 payment flow#
The x402 protocol uses HTTP status 402 ("Payment Required") for machine-native payments. Here's what happens when an agent hits a paid endpoint:
- Agent sends
POST /api/upload/tokenwith no payment headers - Server responds 402 with payment instructions in the response (price, network, wallet address, USDC contract)
- Agent reads the instructions, signs a USDC transfer on Base, and retries the request with the payment proof in headers
- Server verifies the payment with the CDP facilitator, executes the request, and returns the result
- Facilitator settles the payment on-chain after the response is sent
x402-compatible clients (like the Payments MCP tool) handle steps 2-3 automatically. From the agent's perspective, it's just an HTTP request that costs $0.01.
Idempotency#
Every paid request is idempotent. The same payment always returns the same result.
If a network error occurs after payment but before you receive the response, retry the exact same request with the same payment proof. The server will detect the duplicate payment and return the original result — you won't be charged twice and no duplicate image is created.
This is the safety net for the account-less model. There's no support dashboard to file a ticket. Instead, retry is always safe.
Error reference#
All errors return JSON with error (machine-readable code) and message (human-readable description).
| Status | Error code | Description |
|---|---|---|
| 400 | no_file | No image provided in the request |
| 400 | file_too_large | Exceeds size limit (1MB free, 5MB paid) |
| 400 | unsupported_format | Not a supported image format (PNG, JPEG, GIF, WebP) |
| 400 | empty_file | File has zero bytes |
| 401 | invalid_token | Upload token is invalid or already consumed |
| 401 | token_expired | Upload token has expired (10-minute TTL) |
| 402 | — | Payment required (x402 instructions in response) |
| 429 | daily_limit | Free upload daily cap reached |
| 500 | upload_failed | Server error during upload (safe to retry) |
FAQ#
How do I upload an image using img402?#
Send a POST request to https://img402.dev/api/free with your image as multipart form-data: curl -F [email protected] https://img402.dev/api/free. You get back a JSON response with a public URL.
Do I need an account or API key?#
No. img402 has no accounts, no API keys, and no sign-up. The free tier requires no authentication at all. The paid tier uses x402 — payment itself is the authentication.
What is x402?#
x402 is an open protocol for HTTP-native payments. It uses the HTTP 402 status code to communicate payment requirements. Clients pay on-chain (USDC on Base) and include proof in the request headers. The server verifies payment automatically.
How long are images stored?#
Free tier: 7 days. Paid tier: 1 year. After expiry, images are permanently deleted from storage and return 404.
Are uploaded images public?#
Yes. All images are publicly accessible via their URL. Do not upload private or sensitive content. There is no private hosting option.
What happens if the upload fails after I pay?#
Retry the request with the same payment proof. The server uses the payment as an idempotency key — you'll get the same result without being charged again. If the retry also fails, the $0.01 is lost.
What formats are supported?#
PNG, JPEG, GIF, and WebP. Format is detected by magic bytes (file header), not file extension. Renamed non-image files will be rejected.
Can AI agents use this?#
Yes — that's the primary use case. Agents can upload images via the free tier (curl) or paid tier (x402 via the Payments MCP tool). The two-phase flow (token + upload) is designed for agents that can't send binary data through their context window.
Is there an OpenAPI spec?#
Yes: img402.dev/openapi.json. Agent frameworks (Semantic Kernel, Google ADK, openapi-mcp) can auto-convert this into callable tools.