HTTP API¶
Everything under /_/api/v1, authenticated with a bearer token. A token is not a cookie: a cross-site request cannot borrow one, so these routes carry no CSRF protection and the browser UI's cookie does not work here. Two doors, one lock each.
Objects¶
List¶
| parameter | default | |
|---|---|---|
prefix |
none | only paths starting with it |
delimiter |
none | / folds the listing into folders |
cursor |
none | continue from next_cursor of the previous page |
limit |
100 | entries per page, at most 1000 |
Paging is by path rather than by offset. An object inserted while a client pages through would shift every later row under an offset, so a sync would silently skip one; a path cursor cannot.
With delimiter=/ the answer is a folder view: objects directly under the prefix, plus the folders below it. Both fill the same page and share the same cursor, so limit bounds objects and prefixes together and each entry is named exactly once across the pages. Treat next_cursor as opaque, since it may name either, and stop when it comes back null. Needs the read scope.
Upload or replace¶
The body is the bytes. 201 when the object is new, 200 when it replaced one.
| header | |
|---|---|
Content-Type |
stored and returned; guessed from the path when absent |
X-CDN-Cache-Control |
overrides the zone's caching header for this object |
Refused with 413 past CDN_MAX_UPLOAD_BYTES and 507 past a storage quota, in both cases before the body is transferred when the client declares a length. Needs write, and the zone must be a storage zone.
Describe¶
The body carries size, etag, content type, timestamps and the public URL. Needs read.
Delete¶
204, and 204 again for a path that is not there: a delete has to be safe to retry, and a client that timed out cannot know whether the first attempt landed. Needs delete.
Zones¶
Sign a URL¶
{"expires_in": 3600}, in seconds. Returns a URL carrying an expiry and a signature. Needs read. See Private links.
Purge¶
One of three bodies:
Answers {"purged": n}. Nothing is deleted: a storage zone's objects stay in S3 and a pull zone's stay at the origin. Needs purge.
For a token with a path prefix, {"all": true} means everything that token can reach.
Statistics¶
The body carries totals, a daily series, the busiest paths and a breakdown by outcome. Needs stats.
Status codes¶
400 |
a request the client can fix; the message says how |
401 |
no credential, or one that is not ours |
403 |
a credential without the scope, prefix or zone for this |
404 |
no such zone or object. Also what another tenant's zone answers, because whether it exists is not something to learn from the difference between two codes |
413 |
past CDN_MAX_UPLOAD_BYTES |
429 |
writing faster than the token's allowance; carries Retry-After |
507 |
past a storage quota |
Health¶
GET /_/health → {"status": "ok", "database": "ok"}
GET /_/health?deep=1 → also checks the object store
Unauthenticated. See Running it.