# FooPixel API

> Foundation release — examples describe the current contract. Check the launch gates before relying on a deployment.

FooPixel's anonymous uploader accepts JPEG, PNG, WebP, HEIC, and HEIF image bytes and returns a public image URL after processing. Anonymous input is limited to 5 MiB, a 2000px maximum width, and a 20MP decoded/output pixel area. Anonymous URLs expire. Uploaded images are validated, processed, and may be moderated before becoming publicly available.

Some ownership and delivery settings are available only through the signed-in account interface. API clients must not attempt account-owner actions.

## Quickstart

### 1. Create an upload session

Agents omit `processing`; the server normalizes the image under the anonymous 2000px/20MP policy. A browser that has already resized and optimized to WebP may send `processing: {"mode":"client","maxWidth":2000,"optimized":true}`. HEIC/HEIF originals omit `processing` and are normalized by the server.

```http
POST https://api.foopixel.com/v1/uploads
Content-Type: application/json

{"filename":"cover.webp","contentType":"image/webp","byteSize":184220,"checksumSha256":"<64 lowercase hex characters>"}
```

The response includes an asset identifier, upload instructions, an expiry, and the completion value required below. `checksumSha256` is required and verified against the uploaded bytes.

### 2. Put the bytes directly

Read the local file as raw bytes and make a `PUT` to `upload.url`. Use the returned headers exactly. Do not base64-encode the file or send it through an MCP tool as data transport: the upload path is deliberately direct.

```bash
curl -X PUT "$upload.url" \
  -H "Content-Type: image/webp" \
  -H "Content-Length: 184220" \
  --upload-file ./cover.webp
```

### 3. Complete with the one-time token

```bash
curl -X POST "https://api.foopixel.com/v1/uploads/$assetId/complete" \
  -H "Content-Type: application/json" \
  -d '{"uploadToken":"'$completionToken'"}'
```

The response includes an asset and its `processingStatus`. Only a `ready` asset is publicly deliverable. The image URL is `https://media.foopixel.com/a/{publicId}`. Uploaded images are validated, processed, and may be moderated before delivery.

## Account features

Some ownership and delivery settings are available only through the signed-in account interface. API clients must not attempt account-owner actions.

## Routes

- `POST /v1/uploads` — create a direct upload session (anonymous: 5 MiB maximum, JPEG/PNG/WebP/HEIC/HEIF; account policy may allow up to 20 MiB).
- `POST /v1/uploads/{id}/complete` — validate `{ "uploadToken": "..." }` and complete the uploaded bytes.
- `GET /v1/assets/{id}` — read account asset metadata.
- `GET /v1/assets` — list assets visible to the authenticated account.
- `GET` / `HEAD /a/{publicId}` — stream or inspect the public image.

The machine-readable contract is [`/openapi/openapi.yaml`](/openapi/openapi.yaml).

## Authentication

Authenticated asset-management requests use a FooPixel API key in the `Authorization: Bearer` header. Anonymous uploads use the values returned by the upload API and do not require that header. Never expose an API key in a browser or commit it.

## Errors

Errors are always nested under `error` and include `code`, `message`, and `requestId`:

```json
{
  "error": {
    "code": "invalid_request",
    "message": "The request could not be completed.",
    "requestId": "req_01JX8W9W"
  }
}
```

## Foundation notes

Account features, image variants, the MCP server, and paid tiers are not live today. Current content checks are not a complete safety system, and FooPixel should not be used as the only copy of important media.
