Skip to content

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.

  1. Sign in at https://cloud.fluidvip.com with an account that has an active subscription (API access is included with the Elite tier).
  2. Open Settings → Developer → API keys.
  3. Create a key and copy it. A key looks like fck_live_... (production) or fck_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:

bash
export FLUIDCLOUD_API_KEY="fck_live_..."

An active subscription is required. If your plan does not include API access, calls return 403 with detail.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

bash
pip install fluidcloud

TypeScript / JavaScript

bash
npm install fluidcloud

3. 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

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

ts
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.

bash
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_key so 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 -1 means unlimited).
  • Deleting data — trash, restore, and permanent deletion.
  • Errors and Rate limits — status codes, the detail body, typed SDK errors, and the Retry-After header on 429.
  • SDK references: Python · TypeScript.

FluidCloud API — part of the Fluidvip ecosystem.