Cloud Storage
Home

API Reference

Upload files, import from links and video sites, and read your folders and files programmatically. The API is JSON over HTTPS, authenticated with a Bearer key. Version 1 (stable).

Quickstart Authentication Conventions Rate limits Scopes Errors Endpoints OpenAPI spec

Quickstart

API access requires a Pro account.

  1. In the web app open your profile menu and choose API Keys. Create a key, pick its scopes, and copy it. The full key is shown once — store it securely.
  2. Verify it with a request to /api/v1/me:
curl -H "Authorization: Bearer YOUR_KEY" \
     "https://cloudstorage.bar/api/v1/me"

Upload a file:

curl -H "Authorization: Bearer YOUR_KEY" \
     --data-binary @movie.mp4 \
     "https://cloudstorage.bar/api/v1/upload?filename=movie.mp4&path=/Films/"

Authentication

Send your key in the Authorization header on every request:

Authorization: Bearer csb_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxx

Keys look like csb_live_…. We store only a one-way hash of your key, so it cannot be recovered — if you lose it, revoke it and create a new one. A request with a missing, invalid, revoked, or expired key returns 401; a non-Pro account returns 403 with code: "premium_required". You can hold up to 10 keys at once.

Base URL & conventions

  • Base URL: https://cloudstorage.bar. All endpoints below are relative to it.
  • Every response is JSON with a top-level status of "ok" or "error".
  • Timestamps are ISO 8601 in UTC. Folder paths always start and end with / (e.g. /Films/).
  • A returned link is a direct, streamable URL to the stored file.

Rate limits

Each key is limited to 60 requests per minute (a 60-second sliding window). Every response includes:

HeaderMeaning
X-RateLimit-LimitRequests allowed per window.
X-RateLimit-RemainingRequests left in the current window.
X-RateLimit-ResetUnix epoch second when a slot frees.

Over the limit returns 429 with code: "rate_limited" and a Retry-After header (seconds). Back off and retry.

Scopes

Each key carries a set of scopes, chosen at creation (default: all three). A request to an endpoint outside the key's scopes returns 403 with code: "insufficient_scope".

ScopeGrants
uploadPOST /api/v1/upload
importPOST /api/v1/import, /import/status, /import/cancel
readGET /api/v1/files, /api/v1/folders

GET /api/v1/me works with any valid key. Grant only the scopes a key needs.

Errors

Errors return a non-2xx status and a body with a stable, machine-readable code you can branch on without parsing messages:

{ "status": "error", "code": "insufficient_scope",
  "message": "This API key is missing the 'upload' scope." }
HTTPcodeWhen
400invalid_requestMissing/invalid parameter or body.
401missing_authNo/!malformed Authorization header.
401invalid_keyUnknown or revoked key.
401expired_keyKey past its expiry.
403premium_requiredAccount is not Pro.
403account_unavailableAccount missing or banned.
403insufficient_scopeKey lacks the endpoint's scope.
404not_foundTask or resource not found.
413payload_too_largeUpload exceeds the size limit.
429rate_limitedPer-key rate limit exceeded.
503feature_disabled / unavailableAPI off, or storage briefly unavailable.
500server_errorUnexpected server error.

Endpoints

GET /api/v1/me

Who the key belongs to, its scopes and expiry, the live rate-limit window, and account limits. Requires only a valid key.

{ "status": "ok", "username": "alice", "plan": "pro",
  "key": { "id": "...", "name": "My script",
           "scopes": ["upload","import","read"],
           "key_prefix": "csb_live_ab12cd...", "key_last4": "wxyz",
           "created_at": "2026-06-25T10:00:00+00:00", "expires_at": null },
  "rate_limit": { "limit": 60, "remaining": 59, "reset": 1782326145, "window_seconds": 60 },
  "limits": { "upload_max_bytes": 2147483648 } }
POST /api/v1/upload scope: upload

Streams the raw request body into storage. Pass the file bytes as the body, the name as filename, and an optional destination path (default /). Max size is your account limit (see /api/v1/me).

Query
filenamerequiredDestination file name.
pathoptionalDestination folder, default /.
curl -H "Authorization: Bearer YOUR_KEY" \
     --data-binary @movie.mp4 \
     "https://cloudstorage.bar/api/v1/upload?filename=movie.mp4&path=/Films/"

{ "status": "ok", "tracking_id": "1782...", "file_name": "movie.mp4",
  "size": 734003200, "link": "https://share.cloudstorage.bar/1782.../movie.mp4", "folder": "/Films/" }
POST /api/v1/import scope: import

Starts an asynchronous import from a URL and returns a task_id to poll. type: "auto" (default) detects whether the URL is a direct file or a supported video page. Video imports use a per-title folder (path is ignored for them).

curl -H "Authorization: Bearer YOUR_KEY" -H "Content-Type: application/json" \
     -d '{ "url": "https://www.youtube.com/watch?v=...", "type": "auto",
           "video": { "quality": "1080", "subtitles": true } }' \
     "https://cloudstorage.bar/api/v1/import"

{ "status": "ok", "type": "video", "task_id": "video_1782..." }

Body fields: url (required), type (auto|file|video), path and filename (file imports), and video: { quality: "best" | "audio" | a max height like "1080", subtitles, thumbnail }.

GET /api/v1/import/status scope: import

Poll an import by its task_id. Poll every few seconds until state is terminal.

curl -H "Authorization: Bearer YOUR_KEY" \
     "https://cloudstorage.bar/api/v1/import/status?task_id=video_1782..."

{ "status": "ok",
  "task": { "id": "video_1782...", "type": "video", "state": "running", "progress": "42%" } }

state is one of running, completed, failed, cancelled. When complete: file imports include link; video imports include folder (then list it with /api/v1/files).

POST /api/v1/import/cancel scope: import

Cancel a running import. Body: { "task_id": "video_1782..." }. Returns { "status": "ok" }, or 404 if the task is unknown.

GET /api/v1/files scope: read

List files and immediate subfolders at path (default /), 50 files per page. Page with offset; has_more is true when another page may exist. Subfolders are returned only on the first page.

curl -H "Authorization: Bearer YOUR_KEY" \
     "https://cloudstorage.bar/api/v1/files?path=/Films/&offset=0"

{ "status": "ok", "path": "/Films/", "folders": ["2026"],
  "files": [ { "name": "movie.mp4", "size": 734003200,
               "link": "https://share.cloudstorage.bar/1782.../movie.mp4",
               "uploaded_at": "2026-06-25T10:00:00+00:00" } ],
  "limit": 50, "next_offset": 1, "has_more": false }
GET /api/v1/folders scope: read

The complete nested folder tree (structure only). Read a folder's contents with /api/v1/files.

{ "status": "ok",
  "tree": { "name": "", "path": "/",
            "folders": [ { "name": "Films", "path": "/Films/",
                           "folders": [ { "name": "2026", "path": "/Films/2026/", "folders": [] } ] } ] } }

Managing keys

Keys are created, listed, and revoked from the API Keys panel in the web app (these management endpoints use your web session, not a Bearer key). A key can be revoked at any time and stops working immediately. Set an expiry at creation if you want it to lapse automatically.

Versioning & changes

The current version is v1, served under /api/v1/. We add fields and endpoints without bumping the version; any breaking change would ship under a new version prefix. New response fields may appear over time — ignore unknown fields.

  • 2026-06-25 — v1: per-key scopes, X-RateLimit-* headers, machine-readable error code, /api/v1/me, file-listing pagination metadata, and this reference + OpenAPI spec.

Legal

ImpressumPrivacy PolicyCookie PolicyTerms of ServiceAcceptable UseSub-processorsSecurityDMCACookie settings

© Cloud Storage. All rights reserved.