Skip to main content
Every path below is relative to your base URL, and protected endpoints take an API key as a Bearer token.

Base URL

Examples on these pages use the Cloud host. Self-hosted, swap the origin and every request is otherwise identical. Delivery is the one path that differs: on Cloud it carries a bucket prefix, /b/{bucketId}/t/..., see your base URL.

Authentication

On Cloud, create keys in the dashboard at app.openinary.dev under Settings → API keys. A key is shown once and is pinned to a single bucket, which is why no endpoint takes a bucket ID. Either header works, Authorization: Bearer or x-api-key. Self-hosted, create them from the dashboard at /api-keys or through the API Keys API. In API-only mode the first key is printed to the server logs at startup. Every API-key endpoint also accepts a dashboard session cookie, which is how the dashboard calls storage and upload without minting a key for itself. These endpoints work on both Cloud and self-hosted, with the same request and response shapes. The pages that do not are marked Self-hosted only at the top and use https://media.example.com in their examples. For the full list of what Cloud does not have, see what differs on Cloud.

Endpoints

Rate limiting

Public routes are limited by IP: 100 requests per 60 seconds, tunable with PUBLIC_RATE_LIMIT_MAX and PUBLIC_RATE_LIMIT_WINDOW_MS. Every response carries X-RateLimit-Limit, X-RateLimit-Remaining and X-RateLimit-Reset. Most API-key endpoints sit outside that limiter, but POST /upload and GET /health/database do not, so a burst of uploads can be throttled even with a valid key. Those numbers are self-hosted. Cloud limits delivery only, 300 requests per 60 seconds per IP and 1,000 per account, and leaves upload, signing and storage calls unlimited. See Cloud rate limits.

Errors

JSON errors carry a short error label and a message:
The delivery routes /t/* and /authenticated/* return plain text, not JSON. Parsing every error body as JSON throws on exactly the routes your users hit most. Check Content-Type first.
Two endpoints add fields on top of that pair: delete returns a details object, and invalidate returns an errors array. Neither is a general envelope.