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).
API access requires a Pro account.
/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/"
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.
https://cloudstorage.bar. All endpoints below are relative to it.status of "ok" or "error"./ (e.g. /Films/).link is a direct, streamable URL to the stored file.Each key is limited to 60 requests per minute (a 60-second sliding window). Every response includes:
| Header | Meaning |
|---|---|
X-RateLimit-Limit | Requests allowed per window. |
X-RateLimit-Remaining | Requests left in the current window. |
X-RateLimit-Reset | Unix 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.
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".
| Scope | Grants |
|---|---|
upload | POST /api/v1/upload |
import | POST /api/v1/import, /import/status, /import/cancel |
read | GET /api/v1/files, /api/v1/folders |
GET /api/v1/me works with any valid key. Grant only the scopes a key needs.
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." }
| HTTP | code | When |
|---|---|---|
| 400 | invalid_request | Missing/invalid parameter or body. |
| 401 | missing_auth | No/!malformed Authorization header. |
| 401 | invalid_key | Unknown or revoked key. |
| 401 | expired_key | Key past its expiry. |
| 403 | premium_required | Account is not Pro. |
| 403 | account_unavailable | Account missing or banned. |
| 403 | insufficient_scope | Key lacks the endpoint's scope. |
| 404 | not_found | Task or resource not found. |
| 413 | payload_too_large | Upload exceeds the size limit. |
| 429 | rate_limited | Per-key rate limit exceeded. |
| 503 | feature_disabled / unavailable | API off, or storage briefly unavailable. |
| 500 | server_error | Unexpected server error. |
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 } }
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 | ||
|---|---|---|
filename | required | Destination file name. |
path | optional | Destination 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/" }
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 }.
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).
Cancel a running import. Body: { "task_id": "video_1782..." }. Returns { "status": "ok" }, or 404 if the task is unknown.
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 }
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": [] } ] } ] } }
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.
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.
X-RateLimit-* headers, machine-readable error code, /api/v1/me, file-listing pagination metadata, and this reference + OpenAPI spec.