API reference
Upload once. Poll for approval. Serve only screened images.
Download the complete OpenAPI schemaAuthenticate your application
Create an application key in the dashboard. Send it as a bearer token on API requests. Keep it on your server. Each key can only access the images it uploaded.
Authorization: Bearer ih_YOUR_KEYUpload an image
Send a multipart request with a file and an optional public flag (defaults to true). JPEG, PNG and static WebP are accepted. A 202 response means the image is quarantined, not approved. All delivered images are metadata-free WebP.
curl "$IMAGEHOST_URL/api/v1/images" \
-H "Authorization: Bearer $IMAGEHOST_KEY" \
-F "[email protected]" \
-F "public=true"Wait for screening
Poll GET /api/v1/images/{id} every few seconds, with backoff. Use the url only when state is ready. Private images have no public URL; retrieve approved bytes through the authenticated content endpoint.
{
"id": "32-character-image-id",
"state": "pending",
"url": null
}This is a shortened response example. The schema documents all returned fields.
| State | Meaning |
|---|---|
| pending / scanning | Quarantined. No delivery or thumbnails. |
| ready | All mandatory checks passed. |
| blocked | Policy rejection. Bytes deleted. Cannot be released. |
| scan_error | No definitive verdict. Retry up to five times automatically. |
| expired | Quarantine exceeded 24 hours. Bytes deleted. |
Endpoints
| Method | Path | Permission |
|---|---|---|
| POST | /api/v1/images | images:write |
| GET | /api/v1/images | images:read |
| GET | /api/v1/images/{id} | images:read |
| GET | /api/v1/images/{id}/content | images:read |
| DELETE | /api/v1/images/{id} | images:delete |
| GET | /api/v1/stats | images:read |
| GET | /i/{id}.webp | Public, approved images only |
List queries: state, search, limit (1-100, default 25), offset. Statistics include a 14-day UTC series and current storage, including quarantine. Delivery counters measure responses started, not confirmed client downloads. Deleted images remain in historical usage totals.
Errors and limits
Errors use the envelope below. Status codes: 401 invalid credentials, 403 insufficient scope, 404 inaccessible image, 413 size limit, 415 invalid image, 422 invalid fields, 429 rate limit, 507 storage quota. A 429 includes Retry-After: 60. API keys allow 120 requests per minute, including polling. Upload requests must fit within the configured image limit plus 64 KiB of multipart overhead.
{"error": {"code": 403, "message": "API key lacks required scope"}}Responses include X-Request-ID. Public delivery is uncached so deletion takes effect on subsequent origin requests. Browser caches or downstream proxies under your control must respect Cache-Control: no-store. CORS is intentionally disabled; application integrations use server-to-server requests.
Administrative endpoints
Dashboard sessions are required for key creation and revocation, scanner configuration status, audit logs and scan retries. Mutations require an Origin header matching BASE_URL. API keys cannot administer the instance. See the schema for all administrative paths and request fields.