Base URL
Everything, the API and the CDN, is served from one host:https://app.openinary.dev, and is not an API.
Authentication
Send your API key on every request, either header works:Endpoints
Delivery
string
required
Your bucket’s ID. It’s the
/b/…/ segment of the url returned by
POST /upload, and visible on any asset in the dashboard.string
Comma-separated parameters, e.g.
w_400,h_400,c_fill,f_webp. Identical syntax
to self-hosted, see Image
transformations and Video
transformations.string
required
Storage path of the file, e.g.
products/photo.jpg.Upload
multipart/form-data.
file
required
The file to upload. Repeat the field to send several in one request.
string
Destination folder, e.g.
products/2026. Defaults to the bucket root. Ignored
when a signature is present, the signature carries its own folder.string
A presigned token from
POST /upload/sign. Use this instead of an API key for
browser uploads.Response
path may
end in .jpg. A name that already exists is de-duplicated (photo (1).jpg),
always trust the returned path over the one you sent.
The self-hosted
transformations field (prewarming variants at upload time) is
not supported on Cloud. It’s ignored, and variants are generated on the
first request instead.Presigned uploads
string
Folder the upload is scoped to. Derive it from the authenticated user, never
from the browser.
number
default:"300"
Lifetime in seconds, clamped to 1–3600. Keep it short, 60–300 is plenty.
Response
Storage
GET /storage?path= — list one folder level
GET /storage?path= — list one folder level
GET /storage/folders — every folder path in the bucket
GET /storage/folders — every folder path in the bucket
GET /storage/{path}/metadata — size and timestamps
GET /storage/{path}/metadata — size and timestamps
PATCH /storage/{path} — rename in place
PATCH /storage/{path} — rename in place
Body:
{ "name": "new-name.jpg" }, a bare name, no slashes. Works on files
and folders. Returns { "success": true, "path": "products/new-name.jpg" }.POST /storage/{path}/move — move to another folder
POST /storage/{path}/move — move to another folder
Body:
{ "destination": "archive/2025" }. An empty or missing body moves the
item to the bucket root. Works on files and folders.POST /storage/{path}/copy — duplicate a file
POST /storage/{path}/copy — duplicate a file
No body. The copy is named
photo copy.jpg, de-duplicated if that already
exists. Files only.DELETE /storage/{path} — delete a file or folder
DELETE /storage/{path} — delete a file or folder
Deletes the original and its cached transform variants. Deleting a folder
deletes everything under it. Storage usage is credited back.
GET /storage/stats — bucket footprint
GET /storage/stats — bucket footprint
POST /storage/stats/recalculate recomputes them from
storage; POST /storage/cache/clear empties the bucket’s transform cache
(204), after which variants are regenerated on demand.GET /download/{path} — fetch the stored original
GET /download/{path} — fetch the stored original
Authenticated download of the untransformed file, with
Range support.
Public delivery goes through /b/{bucketId}/t/… instead.Paths are URL-encoded in the request and compared as stored, so
products/Marée.jpg becomes /storage/products/Mar%C3%A9e.jpg.Video processing
A video transformation is queued rather than run inline. The first request for a transformed video returns202 with a JSON body while it encodes.
string
One of
pending · running · completed · error · not_found.number
0 to 100.
GET /queue/events is a Server-Sent Events stream of the same job updates, for
when polling is the wrong shape.
A video URL carrying no parameters is never transcoded, it streams the stored
file (with range requests, so seeking works) and costs no processing minutes.
Errors
A
402 tells you which allowance ran out:
feature is one of storage_mb · image_transformations ·
video_processing_seconds · cdn_requests. Over the transformation quota,
already-cached assets keep being served, only new work is refused. See Plans and
limits.
Rate limits
Both answer
429. They exist to stop abuse, not to shape normal traffic, if you
expect to run against them, get in touch before you do.
Not available on Cloud
These self-hosted endpoints have no Cloud equivalent today:/authenticated/s--{sig}/…signed delivery URLs/api-keys/*, keys are managed in the dashboard/queue/stats,/queue/worker/stats,/queue/jobs, job retry/cancel/invalidate/{path}, usePOST /storage/cache/clear, or delete the asset/download-folder,/download-zip/health