Quota & usage
Every FluidCloud partner account draws on one storage pool and one share-link allowance, both set by your subscription. Your app reads its current usage and limits from a single endpoint — GET /api/v1/quota — so you can show a meter, pre-flight a large upload, or decide when to free space before you hit a wall.
This page covers reading your quota, interpreting the numbers, and handling the 402 quota_exceeded you get when an action would cross a cap.
- Base URL:
https://api-cloud.fluidvip.com/api/v1 - Scope required:
quota:read
The two limits
FluidCloud meters two things:
| Counter | What it measures |
|---|---|
Storage (bytes_used / bytes_limit) | Total bytes stored across all your files. A file counts toward this pool from upload until it is fully deleted (soft-deleted files still occupy storage until purge). |
Share links (links_used / links_limit) | The number of live share links you currently hold. Revoking a link frees a slot. |
Both are read from the same response. A limit value of -1 means unlimited for that counter (treat any negative value as unlimited).
Your subscription (the Elite tier that includes API access) sets these limits: storage is a generous pool, and a share-link count limit applies. You never set limits via the API — you read them here and the values reflect your plan.
Read your quota
GET /api/v1/quota returns your storage and link usage, the limits, and a brief per-app breakdown.
Response shape
{
"bytes_used": 18253611008,
"bytes_limit": 107374182400,
"links_used": 42,
"links_limit": 500,
"by_app": [
{ "app": "fluidcloud", "bytes": 18253611008, "files": 1207 }
]
}| Field | Type | Meaning |
|---|---|---|
bytes_used | integer | Bytes currently stored. |
bytes_limit | integer | Storage cap in bytes. -1 = unlimited. |
links_used | integer | Live share links you hold right now. |
links_limit | integer | Share-link cap. -1 = unlimited. |
by_app | array | Per-source breakdown of your storage footprint (reporting only — see below). |
The authoritative numbers — the ones enforced on every upload and every new share link — are bytes_used / bytes_limit and links_used / links_limit.
Examples
curl
curl https://api-cloud.fluidvip.com/api/v1/quota \
-H "X-API-Key: fck_live_..."Python (pip install fluidcloud)
from fluidcloud import FluidCloud
fc = FluidCloud(api_key="fck_live_...")
usage = fc.quota.get()
print(f"{usage.bytes_used} / {usage.bytes_limit} bytes")
print(f"{usage.links_used} / {usage.links_limit} share links")TypeScript (npm install fluidcloud)
import { FluidCloud } from "fluidcloud";
const fc = new FluidCloud({ apiKey: "fck_live_..." });
const usage = await fc.quota.get();
console.log(`${usage.bytes_used} / ${usage.bytes_limit} bytes`);
console.log(`${usage.links_used} / ${usage.links_limit} share links`);Computing headroom
Because -1 means unlimited, always check the sign before you subtract:
def bytes_remaining(usage) -> float:
if usage.bytes_limit < 0:
return float("inf") # unlimited
return usage.bytes_limit - usage.bytes_used
def links_remaining(usage) -> float:
if usage.links_limit < 0:
return float("inf") # unlimited
return usage.links_limit - usage.links_usedconst bytesRemaining = (u: { bytes_used: number; bytes_limit: number }) =>
u.bytes_limit < 0 ? Infinity : u.bytes_limit - u.bytes_used;
const linksRemaining = (u: { links_used: number; links_limit: number }) =>
u.links_limit < 0 ? Infinity : u.links_limit - u.links_used;Use this to pre-flight a batch upload (sum the file sizes and compare against storage headroom) or to decide whether you can mint another share link.
Per-app breakdown (by_app)
by_app splits your storage footprint by the product that stored each file (app, bytes, files). It is reporting only — a computed breakdown that never gates an upload — so use it for dashboards and attribution, not for enforcement decisions. For a partner using FluidCloud purely as a storage backend, this list is typically a single fluidcloud entry; you can ignore it if you only care about the totals above.
Limits are enforced synchronously
Quota is checked at the moment of the action, against the live counters — not on a delayed billing cycle. Two actions are gated:
- Storing bytes. Starting an upload checks
bytes_used + sizeagainstbytes_limit. If it would exceed the cap, the request is refused up front — before any bytes are signed for or sent. - Creating a share link. Minting a link checks
links_usedagainstlinks_limit. If you are already at the cap, the request is refused.
When either check fails you get 402 with the JSON body:
{ "detail": "quota_exceeded" }This is synchronous and deterministic: if the call returns 200, the action fit within your limits; if it returns 402 quota_exceeded, nothing was stored or created. There is no partial state to clean up.
Releasing space is also immediate. Deleting a file returns its bytes to the pool and revoking a share link frees a link slot, so a retry after cleanup can succeed right away. See Deleting data.
Handling quota_exceeded
Catch the 402 where you upload or share, free space (or links), and retry — or surface an upgrade prompt to your own users. The SDKs raise a typed QuotaExceededError so you can branch on it directly.
Python
from fluidcloud import FluidCloud
from fluidcloud.errors import QuotaExceededError
fc = FluidCloud(api_key="fck_live_...")
try:
result = fc.files.upload(
space_id=space_id,
path="results/job-7/out.png",
data=open("out.png", "rb"),
)
except QuotaExceededError:
usage = fc.quota.get()
print(f"Over cap: {usage.bytes_used} / {usage.bytes_limit} bytes")
# free space (delete old files), then retry — or prompt the user to upgradeTypeScript
import { FluidCloud, QuotaExceededError } from "fluidcloud";
const fc = new FluidCloud({ apiKey: "fck_live_..." });
try {
await fc.files.upload({
spaceId,
path: "results/job-7/out.png",
data: fileBlob,
});
} catch (err) {
if (err instanceof QuotaExceededError) {
const usage = await fc.quota.get();
console.warn(`Over cap: ${usage.bytes_used} / ${usage.bytes_limit} bytes`);
// free space, then retry — or prompt the user to upgrade
} else {
throw err;
}
}With raw HTTP, branch on the status code and the detail string:
# A 402 with {"detail": "quota_exceeded"} means you are over a cap.
# Free space or links, then retry the original call.For the full list of statuses and how each SDK maps them to typed errors, see Errors.
Patterns
- Pre-flight large or batch uploads. Read the quota once, sum your intended upload sizes, and skip the round trip if you have no headroom — you avoid a guaranteed
402. - Show a live meter. Poll
GET /api/v1/quotaon a sensible cadence (it counts against the per-key request limit — see Rate limits) and renderbytes_used / bytes_limitandlinks_used / links_limit, drawing any negative limit as "Unlimited". - Free space proactively. When storage headroom runs low, delete files you no longer need before the next upload rather than after a failure. See Deleting data.
- Recycle link slots. If you are near the share-link cap, revoke links you no longer serve to reclaim slots before minting new ones.
Related
- Errors — the full status table and the
402 quota_exceededcontract. - Deleting data — free storage and share-link slots.
- Rate limits — request budgets, including for polling this endpoint.
- Quota reference — the endpoint's full schema.