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:

bash
curl -F [email protected] https://img402.dev/api/free

Response:

json
{
  "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.

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:

Multipart (recommended)
curl -X POST https://img402.dev/api/free \
  -F [email protected]
JSON (base64)
curl -X POST https://img402.dev/api/free \
  -H "Content-Type: application/json" \
  -d '{"file": "<base64-encoded-image>"}'

Response (200)

json
{
  "url": "https://i.img402.dev/abc123.png",
  "id": "abc123",
  "contentType": "image/png",
  "sizeBytes": 24891,
  "expiresAt": "2026-02-15T00:00:00.000Z"
}

Errors

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)

json
{
  "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):

json
{
  "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)

bash
# 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)

json
{
  "url": "https://i.img402.dev/xY9kP3mQ7n.png",
  "id": "xY9kP3mQ7n",
  "contentType": "image/png",
  "sizeBytes": 245891,
  "expiresAt": "2027-02-08T00:00:00.000Z"
}

Errors

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#

FreePaid
Endpoint/api/free/api/upload
Max size1 MB5 MB
Retention7 days1 year
PriceFree$0.01 USDC on Base
FormatsPNG, 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:

  1. Agent sends POST /api/upload/token with no payment headers
  2. Server responds 402 with payment instructions in the response (price, network, wallet address, USDC contract)
  3. Agent reads the instructions, signs a USDC transfer on Base, and retries the request with the payment proof in headers
  4. Server verifies the payment with the CDP facilitator, executes the request, and returns the result
  5. 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).

StatusError codeDescription
400no_fileNo image provided in the request
400file_too_largeExceeds size limit (1MB free, 5MB paid)
400unsupported_formatNot a supported image format (PNG, JPEG, GIF, WebP)
400empty_fileFile has zero bytes
401invalid_tokenUpload token is invalid or already consumed
401token_expiredUpload token has expired (10-minute TTL)
402Payment required (x402 instructions in response)
429daily_limitFree upload daily cap reached
500upload_failedServer 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.