Skip to main content
Dairo storage keeps your files in buckets. Upload an object once, then create a revocable link that a recipient can open without an API key — optionally behind a password, a use cap, or an expiry. Every account starts with a default bucket, so you can upload without creating anything first.

Buckets

A bucket is a named container for objects. List your buckets — the default bucket is seeded on first call, so the list is never empty — or create a named one. Each bucket reports its live usedBytes and objectCount.
Bucket names are unique per account (case-insensitive, up to 120 characters); creating a duplicate returns 409. The default bucket cannot be deleted. Deleting any other bucket archives it and soft-deletes its objects, so their bytes stop counting against your storage.

Upload an object

Uploading is a two-step handshake so bytes flow straight to storage, never through the API. First initiate the upload to get a time-boxed PUT URL, PUT your bytes to it, then finalize so Dairo verifies the true size and records the object.
1

Initiate — get an upload URL

cURL
The response is a PresignedUpload: { objectId, uploadUrl, method, headers, expiresInSeconds }. The URL is valid for 300 seconds.
2

PUT the bytes

Send the file directly to uploadUrl with the exact headers returned — they are part of the signature, and the upload is rejected without them.
cURL
3

Finalize — record the object

cURL
You get back a BucketObject with its verified bytes and a scanStatus. Dairo measures the stored bytes itself — a client-declared size is never trusted — and rejects the object with 429 if it would exceed your plan’s storage limit. Finalizing is idempotent: repeating the call returns the already-recorded object.
Objects are scanned before they can be shared. A freshly finalized object starts at scanStatus: "pending": you can still download it yourself, but creating a share link over it returns 409 until the verdict is clean. An infected or failed verdict blocks downloads for everyone, including you.

Download an object

Ask for a short-lived download URL, then fetch the bytes from it directly. The URL is valid for 3,600 seconds.
This URL is for you, not for recipients — it authenticates as you and expires on its own schedule. To hand a file to someone else, create a share link.

Share a single object

A share link turns one stored object into a revocable URL anyone can open — no API key needed. All three policy options are optional: The shareUrl (a /s/ share page) and downloadUrl (a direct /d/ download) are returned only at create time, so capture them from the response. Opening the share page spends nothing; each direct download counts one use.
When you want to hand out several files as a single link, create a share bundle: POST /v1/buckets/{bucketId}/share-links with an objectIds array — 1 to 50 distinct ids, all in the same bucket. The same password, maxUses, and expiresAt options apply, enforced on every file in the bundle.
The response is a share_bundle: one shareUrl landing page that lists every file, plus a per-file downloadUrl for each object.
Behind the landing page, each file is backed by its own share link over that object. Those per-file links appear in the object’s share-link list and can be revoked individually, exactly like links you create one at a time. List the links over an object, read a link’s open analytics, or revoke a link the moment it should stop working.
The opens response pairs an authoritative summary with the most recent open events. summary.servedOpens counts served downloads — the number measured against maxUses — while share-page views are logged but never consume a use. Each event carries openedAt, clientIp, userAgent, and an outcome such as served. After a revoke, every future open of the link’s share page or download URL returns 410 Gone. The same happens when a link expires or its use cap runs out.

Delete objects

Deleting an object removes its stored bytes and stops them counting against your storage. Delete one object, or up to 1,000 in a single call:
The batch response separates deleted ids from failed entries, each failure naming its id and reason.

Scopes

Listing buckets, objects, download URLs, share links, and open analytics requires buckets:read. Creating buckets, uploading, deleting, and minting or revoking share links require buckets:write. See scopes for how permissions attach to API keys.
  • Attachments — pull files off inbound mail and reference stored objects when sending.
  • MCP server — the list_storage and manage_storage tools for agents.
  • API reference — every buckets, objects, and share-link endpoint.