API reference
This page describes what every Storage Buckets endpoint has in common: the address, how you authenticate, the access levels, the response formats, and the headers. The parameters, status codes, and examples of each endpoint are on the pages linked in Endpoints.
Base URL
https://gateway.kuberns.cloudEvery request goes to this address, which is the same for every account. Use HTTPS only. Your credential travels in a header on every request, so a request over plain HTTP would send it where anyone on the network can read it.
The address is path-style: the bucket goes in the path and never in the host name. The management endpoints start with /buckets. The file endpoints start with the bucket identifier.
Authentication
Every endpoint uses HTTP Basic authentication with a credential. The access key ID is the username and the secret access key is the password:
Authorization: Basic base64(<access-key-id>:<secret>)Most HTTP clients build this header for you. With cURL, use -u:
export KUBERNS_ACCESS_KEY_ID="KBS..."
export KUBERNS_SECRET="your-secret-access-key"
curl -u "$KUBERNS_ACCESS_KEY_ID:$KUBERNS_SECRET" https://gateway.kuberns.cloud/bucketsA credential belongs to your account and works for every bucket you own. It cannot be limited to one bucket.
Where credentials come from
You create credentials in the dashboard, under Buckets → Credentials. The secret is shown once, when you create the credential. See Credentials for the steps.
The API cannot create, list, or delete credentials, and a credential cannot create another one. The consequence is that deleting a credential in the dashboard cuts off everything that credential could do. It stops working on the next request.
A missing or wrong credential
A request gets 401 Unauthorized when the Authorization header is missing or cannot be read, when the access key ID does not exist, when the secret is wrong, or when the credential has been deleted. All of these get the same answer, so the API cannot be used to find out which access key IDs exist.
{
"error": "Your credentials are missing or not valid."
}The answer also carries the header WWW-Authenticate: Basic realm="kuberns-storage".
Access levels
A credential has one of two access levels, chosen when you create it. The level cannot be changed afterwards. See Access levels for how to choose.
| Access level | What it can do |
|---|---|
| Read only | List and get buckets, list files, download a file, get a file's details, get visibility, and get a link. |
| Read & write | Everything a read-only credential can do, and create and delete buckets, create folders, upload and delete files, and set visibility. |
A read-only credential can get a link because a link only lets someone read the file. It cannot change anything.
A read-only credential that calls an endpoint needing read & write gets 403 Forbidden, and nothing is changed:
{
"error": "This credential is read-only."
}The secret is checked first, so a wrong secret still gets 401. The endpoint list shows which access level each endpoint needs.
Response formats
The API answers in three JSON shapes. Which one you get depends on the endpoint and on what went wrong, so write your client to handle all of them. Four cases are shown below. Formats 1 and 4 are the same shape, one for success and one for a refusal.
Two terms are used below. The management endpoints are the ones under /buckets: they create, list, get, and delete buckets, create folders, and handle visibility and links. The file endpoints are the ones at /{bucket}/{key}: they upload, download, delete, and list files.
Format 1: success from the management endpoints
{
"message": "Bucket fetched successfully.",
"status": 200,
"data": {
"bucket": "kb-product-assets-3f9a1c2b7d4e",
"public_id": "05f8ebb3-5e3d-494f-b251-4ef2937f49c9",
"name": "product-assets",
"aws_region": "ap-south-1",
"status": "ACTIVE",
"status_message": null,
"size_bytes": 5242880,
"object_count": 12,
"usage_synced_at": "2026-10-17T07:54:12.778541Z",
"created_at": "2026-10-17T07:54:09.901564Z"
}
}message is a short sentence about the result. status repeats the HTTP status. data holds the result, and is {} when there is nothing to return, as for Delete a bucket and Create a folder.
Format 2: errors from authentication, access levels, and the file endpoints
{
"error": "That file does not exist."
}This is a single string under error. It is used for:
- A missing or wrong credential (
401), on every endpoint, and a read-only credential (403), on every endpoint that needs read & write. - Every error from the file endpoints, such as
403You do not have access to this bucket.,404That file does not exist., and411Content-Length is required. - A
502withCould not reach the platform.on the management endpoints, when the request could not be completed.
Format 3: validation errors from the management endpoints
{
"status": 400,
"timestamp": "2026-10-17T07:54:12.981958",
"error": "Bad Request",
"detail": {
"name": [
"Use 3-40 lowercase letters, numbers and hyphens."
]
}
}The management endpoints answer this way when the body you sent is not valid. detail is an object. Each key is the name of a field that was not valid, and its value is a list of messages. error is the name of the HTTP status, not a message, and timestamp has no time zone.
The same shape is used for failures the endpoint did not expect, and then detail is a string. A 403 with Storage buckets are available on paid plans. is what an account on the free trial gets, and a 500 has Something went wrong. Please try again later or contact support if the issue persists.
Format 4: refusals from the management endpoints
{
"message": "You already have a bucket with this name.",
"status": 400,
"data": {}
}This is the shape of format 1 with an error status and an empty data. The management endpoints use it when the request is well formed but cannot be done: a name you already used, a bucket that does not exist, or a file that does not exist.
Which endpoints answer in which format
| Endpoint | Success | Errors |
|---|---|---|
| Create a bucket | Format 1 | Format 2: 401, 403, 502. Format 3: name not valid. Format 4: every other refusal. |
| List buckets | Format 1 | Format 2: 401, 502. Format 4: 400. |
| Get a bucket | Format 1 | Format 2: 401, 502. Format 4: 404. |
| Delete a bucket | Format 1 | Format 2: 401, 403, 502. Format 4: 404, 400. |
| Create a folder | Format 1 | Format 2: 401, 403, 502. Format 3: folder_path not valid. Format 4: 404, 400. |
| Get visibility | Format 1 | Format 2: 401, 502. Format 4: 404, 400. |
| Set visibility | Format 1 | Format 2: 401, 403, 502. Format 3: body not valid. Format 4: 404, 400. |
| Get a link | Format 1 | Format 2: 401, 502. Format 3: body not valid. Format 4: 404, 400. |
| Upload a file | Its own body: bucket, key, size |
Format 2. |
| Download a file | The file's bytes | Format 2. |
| Get a file's details | Headers only, no body | The status only, because a HEAD response has no body. |
| Delete a file | 204, no body |
Format 2. |
| List files | Its own body: bucket, folder, folders, objects, has_next, next_page |
Format 2. |
Any management endpoint can also answer in format 3 for a 500, or for the free-trial 403 described above.
What to read in a response
Read the HTTP status first. It tells you what kind of problem it is, in every format. Then read the message, which is in a different field in each format: message in formats 1 and 4, detail in format 3, and error in format 2. In code, take message if it is there, then detail, then error.
See Errors and troubleshooting for what to do about each status.
Warning: The same problem can come back in different formats. A bucket that is not yours gets
403You do not have access to this bucket.in format 2 from the file endpoints, and404Bucket not found.in format 4 from the management endpoints. A bucket identifier that does not exist gets the same answer as one that is not yours. A file that does not exist gets404in format 2 from Download a file, and400in format 4 from Get a link. Read the status first, then find the message as described above.
Common headers
| Header | Where it applies | What to send |
|---|---|---|
Authorization |
Every request, on every endpoint. | Basic followed by the base64 of <access-key-id>:<secret>. See Authentication. |
Content-Type |
Requests with a JSON body: Create a bucket, Create a folder, Set visibility, and Get a link. | application/json. |
Content-Type |
Upload a file. | The file's type, such as image/png. Optional. It is stored with the file and returned when the file is downloaded. Download a file and Get a file's details answer with the stored type. |
Content-Type |
Every JSON response. | application/json. |
Content-Length |
Upload a file. | Required. Your HTTP client sets it when you send bytes or a file. Without it the answer is 411 with Content-Length is required. |
Content-Length |
Download a file and Get a file's details responses. | The file's size in bytes. |
Endpoints
| Endpoint | Method and path | Access | What it does |
|---|---|---|---|
| Create a bucket | POST /buckets |
Read & write | Creates a bucket in your account. |
| List buckets | GET /buckets |
Read-only or read & write | Lists your buckets, with a summary of your storage. |
| Get a bucket | GET /buckets/{bucket} |
Read-only or read & write | Returns one bucket. |
| Delete a bucket | DELETE /buckets/{bucket} |
Read & write | Permanently deletes a bucket and every file in it. |
| Create a folder | POST /buckets/{bucket}/folders |
Read & write | Creates an empty folder. |
| Upload a file | PUT /{bucket}/{key} |
Read & write | Uploads a file, or replaces the file with the same name. |
| Download a file | GET /{bucket}/{key} |
Read-only or read & write | Returns a file's bytes. |
| Get a file's details | HEAD /{bucket}/{key} |
Read-only or read & write | Returns a file's headers without the file. |
| Delete a file | DELETE /{bucket}/{key} |
Read & write | Permanently deletes a file. |
| List files | GET /{bucket}/ |
Read-only or read & write | Lists the files and folders directly inside a path. |
| Get visibility | GET /buckets/{bucket}/visibility |
Read-only or read & write | Tells you whether a file is public or private, and returns a link to it. |
| Set visibility | PUT /buckets/{bucket}/visibility |
Read & write | Makes a file public or private. |
| Get a link | POST /buckets/{bucket}/url |
Read-only or read & write | Returns one link to a file, permanent if it is public and temporary if it is private. |
Access is the lowest access level that can call the endpoint. {bucket} is the bucket identifier, and {key} is the file's name, such as reports/2026/summary.pdf.
More
- Limits: the sizes and counts the API enforces.
- Pagination: how to page through a long list of files.
- Rate limits: how many requests you can make.
- Changelog: what changed in the API and when.
- Errors and troubleshooting: what each error means and what to do about it.
- Code examples: ready-made Python and JavaScript clients.
- Use buckets from your application: the basics, from your first request.