A REST API for object storage: create buckets, upload objects into them (flat or in folders), and share what's inside — as a permanent public link, a time-limited signed link, or an authenticated download. JSON in, JSON out; multipart for uploads.
Base URLhttps://buckets.cloudvantage.com.ng/bucketaas
Auth header
AuthToken
Request format
JSON · multipart/form-data
Response format
application/json
Rate limit
70 req / min
Powers every Try it panel below — expand one on any endpoint to send a real request from this page. Stored only in this browser (localStorage); never sent anywhere but your own requests. Only works when this page is served from the API's own origin — cross-origin previews will show a network error instead of a response.
Walkthrough
Quickstart
Four calls to go from credentials to a shareable link.
Get an auth token
Exchange your CloudVantage account email and password for a key. Every authenticated call below sends it back as an AuthToken header — prefixed with the literal word Bearer, a space, then the key.
Every protected endpoint reads a custom AuthToken request header — not the standard Authorization header. There's no session or cookie state on this API; each request stands alone.
⚠
The value still needs a Bearer prefix. Only the header name is non-standard — its value is Bearer <key>, the same convention as Authorization: Bearer. Sending the bare key without Bearer in front of it fails with an error like {"statuscode": "01", "statusmessage": "API token is required"}, which reads like a missing-token error even though a token was sent.
#
Two token endpoints, one shape./tokens/generate-token mints a new key pair; /tokens/get-token returns the account's existing one. Both accept the same email / password body and return the same shape. Pick whichever matches your flow — most integrations only ever need generate-token.
Authentication
Tokens
Both endpoints below are unauthenticated — they're how you obtain the AuthToken everything else requires.
POST/tokens/generate-tokenNo auth
Authenticates with email and password and mints a new AuthToken.
Name for the new bucket, unique within the project's zone.
public
boolean
optional
Default false. Makes the bucket itself publicly readable when true — every object placed in it stays public even if uploaded with expires_in_hours set.
tier
string
optional
Storage tier for the bucket, e.g. Basic — see List bucket tiers for the available options.
Lists every object in a bucket, including folder contents — objects inside a folder are nested under that folder's children array rather than listed flat.
Uploads a single file to the root of a bucket. We queue the actual upload and return immediately — poll status_url (see Check upload status) to confirm it finished.
Query string
Field
Type
Required
Description
expires_in_hours
integer
optional
Pass this param empty (?expires_in_hours=) to publish the object permanently. Omit the param entirely, or give it a number, to keep the object private — the number itself isn't enforced as a real expiry.
Body — multipart/form-data
Field
Type
Required
Description
file
file
required
The file to upload.
◐
Private by default. Without ?expires_in_hours=, the file is read back through the authenticated object, download, or stream endpoints using your AuthToken — the same route the response's object_url already points at. There's no request-body flag for going public; it's query-string only.
⚠
A public bucket makes every object in it public. If the bucket itself was created with public: true, objects uploaded into it are always public, regardless of expires_in_hours.
{ "statusmessage": "No file provided", "statuscode": "01" }
A private upload (the default — no expires_in_hours param) returns the same shape minus share_token/public_url. Oversized files return 400 too, e.g. {"statusmessage": "Image/PDF file size exceeds the limit of 20 MB", "statuscode": "01"} — see Limits.
Uploads several files to the root of a bucket in one call — same public/private contract as single upload, applied to every file in the batch. We queue each file individually and return immediately, with its own task_id/status_url per file (see Check upload status).
Query string
Field
Type
Required
Description
expires_in_hours
integer
optional
Pass this param empty (?expires_in_hours=) to publish every file in the batch permanently. Omit the param entirely, or give it a number, to keep them all private — the number itself isn't enforced as a real expiry.
Body — multipart/form-data
Field
Type
Required
Description
files
file[]
required
Repeat the files field for each file in the batch.
◐
Private by default — same as single upload: every file stays private unless you pass ?expires_in_hours=<empty>, which gives each one its own share_token/public_url. A bucket created with public: true makes them all public regardless.
Checks the background upload task returned by Upload object's task_id/status_url.
Response fields
Field
Description
status
PENDING, STARTED, RETRY, SUCCESS, or FAILURE. PENDING covers both "still running" and "unknown task_id" — there's no way to tell those apart until a result exists.
result
Present once status is SUCCESS or FAILURE. Its nested success field is the real signal — the task itself finishes without raising even when the upload fails, so check result.success, not just status.
A failed upload still reports status: "SUCCESS" (the task ran to completion) with result: {"success": false, "message": "..."} describing what went wrong — e.g. "project not found" or "local bucket not found".
This route always responds 200. If the object can't be retrieved, the error payload is returned as the downloaded content instead of a normal JSON error — check the content-type/size to confirm you received the real file.
Folders group objects under a path prefix within a bucket. Folder uploads share the same public/private mechanism as the root create-object/create-objects endpoints — a share_token/public_url pair, controlled by expires_in_hours.
Uploads a file into a folder. Same public/private contract as Upload object.
Query string
Field
Type
Required
Description
expires_in_hours
integer
optional
Pass this param empty (?expires_in_hours=) to publish the object permanently. Omit the param entirely, or give it a number, to keep it private — the number itself isn't enforced as a real expiry.
Body — multipart/form-data
Field
Type
Required
Description
file
file
required
The file to upload.
◐
Private by default — same as Upload object: the response only includes a share_token/public_url when you pass ?expires_in_hours=<empty>. A bucket created with public: true makes it public regardless.
Uploads several files into a folder in one call — same public/private contract as single folder upload, applied to every file in the batch. Unlike the root Upload multiple objects, this runs synchronously: the response only returns once every file has finished uploading, with one entry per file (no task_id/polling needed).
Query string
Field
Type
Required
Description
expires_in_hours
integer
optional
Pass this param empty (?expires_in_hours=) to publish every file in the batch permanently. Omit the param entirely, or give it a number, to keep them all private.
Body — multipart/form-data
Field
Type
Required
Description
files
file[]
required
Repeat the files field for each file in the batch.
◐
Private by default — same as single folder upload: every file stays private unless you pass ?expires_in_hours=<empty>, which gives each one its own share_token/public_url. A bucket created with public: true makes them all public regardless.
{
"statusmessage": "File 'april.pdf': Image/PDF file size exceeds the limit of 20 MB",
"statuscode": "01"
}
If a single file in the batch fails to upload, its entry has an error field instead of object_url/share_token/public_url — the rest of the batch still completes. A private batch (the default — no expires_in_hours param) returns the same per-object shape minus share_token/public_url.
401 if AuthToken is missing. Like Download object, this route always responds 200 — a failed lookup comes back as the error payload in place of file content.
401 if AuthToken is missing. Otherwise the storage's status and body are passed through.
Try it
Public sharing
Public sharing
Objects uploaded via Upload object or Upload multiple objects with an empty expires_in_hours query param get a share_token and a ready-to-use public_url in the response. These two routes serve that token — no AuthToken, ever.
Errors are JSON. Most carry an error field; some — especially the token endpoints — use the upstream statuscode / statusmessage pair instead ("00" means success).
Status
Meaning
Typical body
400
Missing or invalid input — e.g. no file on an upload, or a missing email/password.
70 per minute, per account (and per anonymous IP on unauthenticated routes)
Video uploads
100 MB — .mp4, .mov, .avi, or any video/* content type
Image / PDF uploads
20 MB — .jpg, .jpeg, .png, .gif, .webp, .svg, .pdf, or any image/* content type
Oversized uploads return 400 with a statusmessage naming the limit that was hit. Exact limits are configured per deployment and may differ from the defaults above.