Skip to content
esc

Search pages and sections. Try a tool name, an error code, a route.

↑↓ navigate↵ openesc close

API reference · Data plane

Files

Upload, list, delete, and serve files. A file is authorized exactly like a row: visibility: "private" behaves like a row on the prive preset, "public" like a row on the partage preset.

Host: https://proj-<id>.manybases.com · Key: pk_ with X-Session, or sk_. The first three routes also exist for an account key under /v1/projects/:pid/files…; the fourth has no mirror, on purpose.

POST/v1/files?name=<name>&visibility=<private|public>
BodyThe file bytes, raw, with their Content-Type and a Content-Length
Effect201 { data: { file } }. visibility defaults to private
GET/v1/files
Body—
Effect200 { data: { files: [file] }, cursor } — cursor pagination as everywhere
DELETE/v1/files/:id
Body—
Effect200 { data: { id, deleted: true } }. Every link to the file stops working immediately
GET/v1/files/:id/content?exp=…&sig=…
Body—
EffectThe file itself, with its Content-Type. No key: the signed URL is the authority

The file object: { id, name, size, content_type, visibility, url, created_at }. size is in bytes, url is the absolute signed URL to the content. Nothing else — neither the storage key, nor the bucket, nor the owner.

Uploading#

  • The body is the file, raw, not multipart. The name goes in ?name=, the type in Content-Type.
  • A declared length is required. Content-Length is checked before the first byte: a declaration above 25 MB answers 413 payload_too_large immediately, and the transfer is then held to exactly the declared length — a client that lies fails its transfer instead of moving the cap. A chunked upload without a length is refused with 400 validation_error. From a browser, pass a Blob, File, ArrayBuffer or Uint8Array, not a stream.
  • The 25 MB cap is a property of the store: no object above it enters, whatever the route.
  • Idempotency-Key is ignored here: two uploads of the same file create two files with two ids. Uniqueness is yours to hold, through the name you choose.
  • The file is written under owner_id of the session; an sk_ or ak_ upload has no owner.

Whoever holds a file URL can read the file, with no sign-in. The URL is signed by Manybases and served by Manybases, never by the object store, and the API re-reads the file's record before serving the first byte.

  • A private URL carries an expiry (exp), one hour by default. Ask for a fresh one by listing the files again.
  • A public URL carries a signature but no expiry: it does not stop on its own. Deleting the file is the only way to take a public link back.
  • Either way, deleting the file revokes every link at once: a URL that served 200 a second ago answers 403 after the deletion.

Sizes and quotas#

25 MB per file. File storage is counted account-wide, across all projects, against the plan's quota (500 MiB on Free, 10 240 MiB on Builder); above it, writes answer 402 quota_exceeded. Downloads never cost anything — there are no egress fees.

What deletion of a person does#

When an end user is deleted (by themselves or by the account owner), every file they uploaded goes with them — the object and its record, public files included, because a public URL has no expiry and would otherwise outlive its owner.