---
name: foopixel
description: Upload image bytes to FooPixel and receive a public image URL. Use for agent-native image hosting; account settings remain in the signed-in account interface.
---

# FooPixel

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

## Safety and capability boundary

- Treat endpoint availability as deployment-specific; do not claim planned features are live.
- Anonymous uploads produce a public image URL with an expiry. Always preserve and report `expiresAt`.
- Some ownership and delivery settings are available only through the signed-in account interface.
- Do not attempt account-owner actions. Direct the user to the account interface when appropriate.

## Upload workflow

1. Read the image file as raw bytes and calculate its lowercase hexadecimal SHA-256 digest. Call `POST /v1/uploads` with `filename`, `contentType`, `byteSize`, and the required `checksumSha256` (anonymous maximum 5 MiB; JPEG, PNG, WebP, HEIC, or HEIF). Agents should omit `processing`; the server normalizes the image and applies the 2000px/20MP policy.
2. Make a direct `PUT` request to the returned `upload.url`, passing the returned `upload.headers` exactly. The server verifies the checksum before processing.
3. Call `POST /v1/uploads/{assetId}/complete` with JSON `{ "uploadToken": completionToken }` from the create response.
4. Use `asset.publicUrl` (`https://media.foopixel.com/a/{publicId}`) only after `processingStatus` is `ready`; public IDs are opaque and have no required prefix.
5. Include the expiry for anonymous assets. If an account URL is returned, provide it to the user rather than opening or submitting it.

Do not base64-encode image bytes. Do not send the file through an MCP tool as a data transport. The intended path is local bytes → direct HTTP `PUT` → completion request. Do not retry a `PUT` after its upload session has expired; create a new session.

## Request shape

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

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

Then:

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

## Account handoff

Some ownership and delivery settings are managed only through the signed-in account interface. Explain this limitation and direct the user to the relevant account page when it is available. Do not attempt these actions through undocumented endpoints.

## v1 endpoints

- `POST /v1/uploads`
- `POST /v1/uploads/{id}/complete`
- `GET /v1/assets/{id}`
- `GET /v1/assets`
- `GET` or `HEAD /a/{publicId}`

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