Quickstart
Go from nothing to a public, hotlinkable file URL in a few minutes. You will get an API key, install a FluidCloud SDK, create a space, upload a file as public, and print its permanent public_url.
This is the fastest path. For the concepts behind it, read concepts.md; for the full method list, see the API reference.
1. Get an API key
API keys are created in the FluidCloud dashboard, not through the API.
- Sign in at https://cloud.fluidvip.com with an account that has an active subscription (API access is included with the Elite tier).
- Open Settings → Developer → API keys.
- Create a key and copy it. A key looks like
fck_live_...(production) orfck_test_...(testing). It is shown once — store it as a secret.
Your key carries a fixed set of scopes (spaces, folders, files, shares, and quota — read and write, plus quota:read). That is everything the steps below need. See authentication.md for how the key is sent and security.md for handling it safely.
Keep the key in an environment variable rather than in source:
export FLUIDCLOUD_API_KEY="fck_live_..."An active subscription is required. If your plan does not include API access, calls return
403withdetail.error = "feature_not_in_plan". See errors.md.
2. Install an SDK
The SDKs send your key in the X-API-Key header automatically and hide the multi-step upload flow (presign → direct PUT → complete) behind a single call. Or you can call the REST API directly with curl.
Python
pip install fluidcloudTypeScript / JavaScript
npm install fluidcloud3. Create a space, upload a public file, print the URL
A space is a top-level container for your files (see concepts.md). You create one, upload into it with public=true, and read back a permanent public_url.
The production API base is https://api-cloud.fluidvip.com/api/v1. Public file bytes are served from the cookieless raw-link domain https://files.fluidadmin.com, so a public_url looks like https://files.fluidadmin.com/s/<token>.
Python
from fluidcloud import FluidCloud
fc = FluidCloud(api_key="fck_live_...") # base_url defaults to production
# 1. Create a space
space = fc.spaces.create("Brand Assets")
# 2. Upload a file and mint a permanent public hotlink
asset = fc.files.upload("logo.png", space_id=space.id, public=True)
# 3. Print the stable URL — drop it straight into an <img src="...">
print(asset.public_url)
# -> https://files.fluidadmin.com/s/<token>files.upload accepts a filesystem path, raw bytes, or an open binary file object. With public=True the SDK runs the upload, then mints a permanent public link and sets it on asset.public_url.
TypeScript
import { FluidCloud } from "fluidcloud";
import { readFileSync } from "node:fs";
const fc = new FluidCloud({ apiKey: "fck_live_..." }); // baseUrl defaults to production
// 1. Create a space
const space = await fc.spaces.create("Brand Assets");
// 2. Upload a file and mint a permanent public hotlink
const bytes = readFileSync("logo.png");
const asset = await fc.files.upload(bytes, space.id, {
name: "logo.png",
public: true,
});
// 3. Print the stable URL
console.log(asset.public_url);
// -> https://files.fluidadmin.com/s/<token>In the browser, pass a File or Blob instead of reading from disk — files.upload handles either.
curl
The SDKs collapse three calls into one. With curl you do them by hand: create the space, initiate the upload to get a presigned URL, PUT the bytes directly to storage, complete the upload, then mint a public share.
API="https://api-cloud.fluidvip.com/api/v1"
KEY="$FLUIDCLOUD_API_KEY"
# 1. Create a space -> capture its id
SPACE_ID=$(curl -s -X POST "$API/spaces" \
-H "X-API-Key: $KEY" \
-H "Content-Type: application/json" \
-d '{"name":"Brand Assets"}' | jq -r .id)
# 2. Initiate the upload -> get a presigned PUT URL
SIZE=$(wc -c < logo.png)
INIT=$(curl -s -X POST "$API/uploads/initiate" \
-H "X-API-Key: $KEY" \
-H "Content-Type: application/json" \
-d "{\"original_name\":\"logo.png\",\"content_type\":\"image/png\",\"size\":$SIZE,\"space_id\":\"$SPACE_ID\"}")
FILE_ID=$(echo "$INIT" | jq -r .file_id)
KEY_PATH=$(echo "$INIT" | jq -r .key)
UPLOAD_URL=$(echo "$INIT" | jq -r .upload_url)
# 3. PUT the bytes directly to storage (no API key on this request)
curl -s -X PUT "$UPLOAD_URL" \
-H "Content-Type: image/png" \
--data-binary @logo.png
# 4. Complete the upload
curl -s -X POST "$API/uploads/complete" \
-H "X-API-Key: $KEY" \
-H "Content-Type: application/json" \
-d "{\"file_id\":\"$FILE_ID\",\"key\":\"$KEY_PATH\",\"original_name\":\"logo.png\",\"mime\":\"image/png\",\"size\":$SIZE,\"space_id\":\"$SPACE_ID\"}"
# 5. Mint a permanent public link -> read its url
curl -s -X POST "$API/shares" \
-H "X-API-Key: $KEY" \
-H "Content-Type: application/json" \
-d "{\"file_id\":\"$FILE_ID\",\"expires_in_days\":null}" | jq -r .url
# -> https://files.fluidadmin.com/s/<token>The presigned PUT in step 3 goes directly from your client to storage — the API never proxies your bytes. The full upload flow (including multipart for large files) is documented in guides/uploading.md and reference/uploads.md.
A note on timing: scanned before it serves
Every uploaded file is automatically scanned before it can be shared or served. In the snippets above, minting the public link succeeds immediately because small uploads are typically scanned by the time you ask. If you mint or serve a link before the file is confirmed clean, the API returns 409 (the file is not ready). Retry once scan_status is clean. This quarantine-until-clean behavior is covered in concepts.md and guides/raw-links.md.
What next
- Uploading files — paths, bytes, streams, large/multipart uploads, and setting your own
client_keyso you can fetch a file later without storing FluidCloud's id. - Raw links — permanent public hotlinks vs. expiring signed links, and how
https://files.fluidadmin.com/s/<token>URLs behave. - Organizing files — folders, moving, and renaming inside a space.
- Quota and usage — read your storage pool and share-link limits (a value of
-1means unlimited). - Deleting data — trash, restore, and permanent deletion.
- Errors and Rate limits — status codes, the
detailbody, typed SDK errors, and theRetry-Afterheader on429. - SDK references: Python · TypeScript.