Skip to content

Core concepts & resources ​

This page is your mental model for the FluidCloud Partner API. It defines every resource your API key touches — Tenant, Space, Folder, File, Share, and Quota — and the fields you get back on each one. It also walks the File lifecycle, the rule that matters most for storage backends (quarantine-until-clean), and an optional convenience for addressing files by your own key (client_key).

Each resource has a full endpoint reference: see Spaces, Folders, Files, Uploads, Shares, and Quota. New here? Start with the Quickstart.


How the resources nest ​

FluidCloud is hierarchical. Everything you create lives inside your tenant, and the containment chain is fixed:

Tenant  (your workspace — implicit, comes from your API key)
└── Space        (a top-level bucket you create)
    └── Folder    (optional tree inside a Space; can nest)
        └── File  (a stored object: the bytes + metadata)
            └── Share  (a raw link that serves one File's bytes)
  • A Space belongs to your tenant.
  • A Folder belongs to one Space (and may have a parent Folder).
  • A File belongs to one Space, and optionally one Folder.
  • A Share points at exactly one File.
  • Quota is a single per-tenant view of your usage and limits.

All ids are UUID strings. All timestamps are ISO-8601 UTC (e.g. 2026-06-23T14:05:00Z).


Tenant ​

Your workspace. A tenant is the unit of isolation and billing — every Space, Folder, File, and Share you create lives inside it, and your subscription (and its storage / share-link limits) attaches here.

You do not pass a tenant id on requests and there is no "tenants" endpoint. Your API key is your tenant: every call is automatically scoped to the tenant that owns the key, and you can only ever see your own data. This is why cross-tenant ids return 404 Not Found rather than 403 — an id outside your tenant simply does not exist as far as your key is concerned (see Errors).

The closest thing to a "read my tenant" call is the Quota endpoint, which reports your tenant's usage and limits.

Team membership, seats, and roles are an account-level concern managed in the dashboard and are not exposed to API keys.


Space ​

A top-level bucket within your tenant. A Space is the natural place to separate one logical area of your integration from another — for example one Space per customer, per project, or per environment. Folders and Files always live inside a Space.

Requires the spaces:read / spaces:write scopes. Full reference: Spaces.

Fields you see:

FieldTypeNotes
idUUID stringThe Space id; use it as space_id when creating folders and files.
namestringDisplay name you chose.
created_atISO-8601 UTCWhen the Space was created.
updated_atISO-8601 UTCLast modification time.
json
{
  "id": "5b1f2c0a-9d4e-4a77-8c21-0f3a6b8e1d22",
  "name": "Customer ACME — production",
  "created_at": "2026-06-20T09:12:44Z",
  "updated_at": "2026-06-20T09:12:44Z"
}

Folder ​

An optional tree inside a Space. Folders organize Files. They are self-referential — a Folder can have a parent Folder, so you can build an arbitrarily deep tree. Files may sit directly in a Space (no folder) or inside a Folder.

Folders are soft-deletable: deleting a Folder marks it deleted (it stops appearing in listings) without immediately destroying its contents. See Organizing files and Deleting data.

Requires the folders:read / folders:write scopes. Full reference: Folders.

Fields you see:

FieldTypeNotes
idUUID stringThe Folder id.
space_idUUID stringThe Space this folder belongs to.
parent_idUUID string or nullParent folder, or null if it sits at the Space root.
namestringDisplay name.
created_atISO-8601 UTCWhen the folder was created.
updated_atISO-8601 UTCLast modification time.
json
{
  "id": "a77c9e10-2b44-4d8f-bb0e-7c5a1d9e3f04",
  "space_id": "5b1f2c0a-9d4e-4a77-8c21-0f3a6b8e1d22",
  "parent_id": null,
  "name": "renders",
  "created_at": "2026-06-21T11:30:02Z",
  "updated_at": "2026-06-21T11:30:02Z"
}

File ​

A stored object — the bytes plus their metadata. This is the core resource of the API. A File lives in a Space (and optionally a Folder), carries identifying metadata (name, MIME type, size, content hash), and tracks two pieces of state that gate what you can do with it: its scan status and its lifecycle state.

The API never proxies your bytes. You upload directly from your client to storage via a presigned URL, and you serve bytes to the public over a raw Share link — see Uploading and Raw links. The File row is the metadata record of that object.

Requires the files:read / files:write scopes. Full reference: Files.

Fields you see:

FieldTypeNotes
idUUID stringThe File id (FluidCloud's canonical handle).
space_idUUID stringOwning Space.
folder_idUUID string or nullOwning Folder, or null if at the Space root.
client_keystring or nullYour own logical key, if you supplied one on upload. See client_key.
original_namestringThe filename you uploaded.
mimestring or nullContent type, e.g. image/png.
sizeinteger or nullSize in bytes.
sha256string or nullSHA-256 of the content, once known.
scan_statusstringpending, clean, or infected — gates sharing/serving (see below).
created_atISO-8601 UTCWhen the File row was created.
updated_atISO-8601 UTCLast modification time.
json
{
  "id": "c3e9a1b6-7f20-4f15-9a4d-2e6b8c0f1a33",
  "space_id": "5b1f2c0a-9d4e-4a77-8c21-0f3a6b8e1d22",
  "folder_id": "a77c9e10-2b44-4d8f-bb0e-7c5a1d9e3f04",
  "client_key": "results/job-7/out.png",
  "original_name": "out.png",
  "mime": "image/png",
  "size": 482113,
  "sha256": "9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08",
  "scan_status": "clean",
  "created_at": "2026-06-22T08:01:19Z",
  "updated_at": "2026-06-22T08:01:27Z"
}

The File lifecycle ​

A File moves through scanning, then optionally soft-delete and permanent purge.

upload (presign → PUT → complete)
        │
        ▼
  scan_status = pending     ← virus scan runs automatically
        │
   ┌────┴────────────┐
   ▼                 ▼
 clean            infected
 (shareable)      (blocked — cannot be shared or served)
        │
        ▼
   soft-delete  ──restore──►  (back to live)
        │
        ▼
   permanent purge  (bytes + row destroyed; not recoverable)
  1. Upload. You start an upload, PUT the bytes straight to storage via the presigned URL, then complete the upload. The File row exists with scan_status: pending. See Uploading.
  2. Scan. Every uploaded file is automatically scanned for malware. While scanning, scan_status stays pending.
  3. Resolve. When scanning finishes the file becomes clean (safe to share and serve) or infected (permanently blocked from sharing and serving).
  4. Soft-delete / restore. Deleting a File marks it deleted — it leaves your listings but its bytes are retained for a grace window, so a delete is reversible by restoring it.
  5. Permanent purge. A purge destroys the bytes and the row. This is not recoverable. See Deleting data and Deletion.

Quarantine-until-clean ​

A File can only be shared or served once it has been scanned clean. This is the single most important rule for using FluidCloud as a file-link backend.

  • A freshly uploaded file is scan_status: pending.
  • If you try to create a share for it — or serve it — before scanning finishes (or if it came back infected), the API responds 409 Conflict (the file is not ready).
  • Once scan_status becomes clean, sharing and serving succeed.

Build your integration to wait for clean (poll the File, or retry the share on a 409 with backoff) before you publish a link. See the Uploading and Raw links guides for the polling pattern, and Errors for the 409 shape.


Share ​

A raw link that serves one File's bytes. A Share turns a clean File into a public URL that anyone with the link can open — served from the cookieless files domain, https://files.fluidadmin.com. A raw link looks like:

https://files.fluidadmin.com/s/<token>

The full token is returned once, at creation time — store it then, because it cannot be retrieved again. You can list and revoke shares afterward, but the link string itself is shown only on the create response. Creating a share counts against your tenant's share-link limit (see Quota).

A Share can only be created for a File whose scan_status is clean (otherwise 409, per quarantine-until-clean above). Requires the shares:read / shares:write scopes. Full reference: Shares; concepts and edge cases in Raw links.

Fields you see:

FieldTypeNotes
idUUID stringThe Share id.
file_idUUID stringThe File this link serves.
urlstringThe raw link https://files.fluidadmin.com/s/<token>. Returned only on the create response.
permissionstringview or download — how the bytes are served.
expires_atISO-8601 UTC or nullWhen the link stops working, or null for no expiry.
max_downloadsinteger or nullOptional cap on total downloads, or null for no cap.
download_countintegerHow many times the link has been served.
revokedbooleantrue once you revoke the link.
created_atISO-8601 UTCWhen the link was created.
updated_atISO-8601 UTCLast modification time.
json
{
  "id": "f0a4d2c8-3e51-4b9a-8d77-1c6e5b2f9a40",
  "file_id": "c3e9a1b6-7f20-4f15-9a4d-2e6b8c0f1a33",
  "url": "https://files.fluidadmin.com/s/Hk9_2pQ7zR4vXm1Lb0sN",
  "permission": "view",
  "expires_at": "2026-07-22T08:05:00Z",
  "max_downloads": null,
  "download_count": 0,
  "revoked": false,
  "created_at": "2026-06-22T08:05:00Z",
  "updated_at": "2026-06-22T08:05:00Z"
}

Known limitations to design around. A share-link password is accepted and stored but is not enforced at serve time — do not rely on it to gate access; use expires_at and max_downloads instead. And revoking a permanent (non-expiring) link does not take effect instantly: an already-cached copy can still serve from the edge for up to 3600 seconds (its max-age) after you revoke it. Both are covered in Security and Raw links.


Quota ​

Your tenant's usage and limits, in one read-only view. Before a big upload or a batch of shares, check Quota to know where you stand. Requires the quota:read scope. Full reference: Quota; guide: Quota and usage.

Fields you see:

FieldTypeNotes
bytes_usedintegerStorage you are currently using, in bytes.
bytes_limitintegerStorage allowance, in bytes. A generous pool comes with your plan.
links_usedintegerActive share links you have created.
links_limitintegerMaximum share links your plan allows.

A limit value of -1 means unlimited.

json
{
  "bytes_used": 18253611008,
  "bytes_limit": 1099511627776,
  "links_used": 412,
  "links_limit": 5000
}

These counters are FluidCloud's authoritative numbers and are checked synchronously on every write. Exceeding them returns 402 with detail equal to quota_exceeded (see Errors). Both an over-storage upload and an over-cap share return 402.


client_key — address a file by your own key ​

client_key is an optional convenience that lets you reference a File by your logical key instead of FluidCloud's file_id. This is ideal for a stateless backend: you don't have to persist FluidCloud's id alongside every object you store.

On upload, pass your own key (any string that makes sense to you):

text
client_key = "results/job-7/out.png"

Later, fetch that same File back by the key — without ever having stored its file_id — via files.resolve (GET /files/resolve). The resolver matches on your tenant and the key, and returns the most recent live match, so re-uploading under the same client_key supersedes the older object.

A few properties to keep in mind:

  • It is logical per tenant, not globally unique — two different tenants can use the same client_key with no collision.
  • A client_key is optional. Files you upload without one are addressed only by file_id (and client_key is null on the row).
  • Resolve returns the same File object shape shown above, so you can chain straight into sharing or deleting it.

See Files → resolve for the endpoint and the Uploading guide for setting it during upload.


Where to go next ​

FluidCloud API — part of the Fluidvip ecosystem.