Docs
Get Started

Files API

Use these endpoints to upload, download, delete, and list the files in a bucket. A file is addressed by the bucket identifier and the file's name, called the key: /{bucket}/{key}. The address and the Basic authentication that every request uses are described in Authentication.

Unlike the bucket endpoints, these answer with the file itself or with plain JSON, without the message, status, and data wrapper. An error answer has the form {"error": "..."}. See Response formats.

The examples read your credential from two environment variables. Set them first:

export KUBERNS_ACCESS_KEY_ID="KBS..."
export KUBERNS_SECRET="your-secret-access-key"

Upload a file

PUT /{bucket}/{key}

Uploads a file to a bucket. The request body is the file's bytes, with nothing added around them: not JSON, and not a form.

Access: a read & write credential.

Parameters for "Upload a file"

Headers

Name Type Required Description
Authorization string Required Basic followed by your credential. See Authentication.
Content-Type string Optional The file's type, for example application/pdf. It is stored with the file and sent back when the file is downloaded.
Content-Length integer Required The size of the body in bytes, at most 5 GB (5,368,709,120 bytes). Your HTTP client sets it when you send bytes or a file.

Path parameters

Name Type Required Description
bucket string Required The bucket identifier, for example kb-product-assets-3f9a1c2b7d4e. It is not the bucket's name.
key string Required The name to give the file, with its folders, for example reports/2026/summary.pdf. Each slash (/) makes a folder, so you do not need to create the folders first. Names are case-sensitive. Use a name of 900 characters or fewer, with no backslash, no control characters, no //, and no . or .. between slashes. Create a folder, Get visibility, Set visibility, and Get a link answer 400 to a name that breaks these rules, so you could not share such a file. In the address, percent-encode each part of the name and keep the slashes between parts as they are. A space is %20, and a + is a plus sign, not a space.

HTTP status codes for "Upload a file"

Status When it happens
200 The file was uploaded.
400 The address ends with the bucket identifier and a slash, and has no file name: No object key given.
401 The credential is missing or wrong: Your credentials are missing or not valid.
402 Your account is in a grace period because your storage balance is unpaid, so uploads are paused: New uploads are paused because your storage balance is unpaid. Top up your credits to continue. Nothing is uploaded.
403 The credential is read-only: This credential is read-only.
403 The bucket identifier is not one of your active buckets. It may be mistyped, belong to another account, or name a bucket whose status is not ACTIVE: You do not have access to this bucket.
403 The address is the bucket identifier alone, with no slash and no file name: Buckets are managed from the Kuberns dashboard, not through this endpoint.
411 The request has no Content-Length: Content-Length is required.
413 The file is larger than 5 GB. The server in front of the gateway refuses it, so this answer does not use the {"error": "..."} form.
500 Kuberns could not check the credential: Something went wrong.
502 Storage could not complete the upload: The storage backend could not complete that request.

Code samples for "Upload a file"

Request example

cURL
BUCKET="kb-product-assets-3f9a1c2b7d4e"
KEY="reports/2026/summary.pdf"
 
curl -u "$KUBERNS_ACCESS_KEY_ID:$KUBERNS_SECRET" \
  -X PUT "https://gateway.kuberns.cloud/$BUCKET/$KEY" \
  -H "Content-Type: application/pdf" \
  --data-binary @summary.pdf
Python
import os
from urllib.parse import quote
 
import requests
 
BUCKET = "kb-product-assets-3f9a1c2b7d4e"
KEY = "reports/2026/summary.pdf"
 
with open("summary.pdf", "rb") as file:
    response = requests.put(
        f"https://gateway.kuberns.cloud/{BUCKET}/{quote(KEY)}",
        auth=(os.environ["KUBERNS_ACCESS_KEY_ID"], os.environ["KUBERNS_SECRET"]),
        headers={"Content-Type": "application/pdf"},
        data=file,
    )
response.raise_for_status()
 
print(response.json()["size"])
JavaScript
import { readFile } from "node:fs/promises";
 
const BUCKET = "kb-product-assets-3f9a1c2b7d4e";
const KEY = "reports/2026/summary.pdf";
 
const credentials = Buffer.from(
  `${process.env.KUBERNS_ACCESS_KEY_ID}:${process.env.KUBERNS_SECRET}`
).toString("base64");
const encodedKey = KEY.split("/").map(encodeURIComponent).join("/");
 
const response = await fetch(
  `https://gateway.kuberns.cloud/${BUCKET}/${encodedKey}`,
  {
    method: "PUT",
    headers: {
      Authorization: `Basic ${credentials}`,
      "Content-Type": "application/pdf",
    },
    body: await readFile("summary.pdf"),
  }
);
if (!response.ok) {
  throw new Error(`Upload failed: ${response.status}`);
}
const body = await response.json();
 
console.log(body.size);

Response

200 OK

Response
{
  "bucket": "kb-product-assets-3f9a1c2b7d4e",
  "key": "reports/2026/summary.pdf",
  "size": 48213
}

Warning: Uploading to a name that already exists replaces the file. The new file is private, even if the old one was public. To share it again, set its visibility to public.

Note: The 5 GB limit is for uploads through the API. The dashboard accepts files up to 1 GB.

Response fields for "Upload a file"

Field Type Description
bucket string The bucket identifier.
key string The file's name, as it is stored.
size integer The size of the file in bytes, taken from the Content-Length you sent.

Download a file

GET /{bucket}/{key}

Downloads a file. The body of the answer is the file's bytes.

Access: a read-only or read & write credential.

Parameters for "Download a file"

Headers

Name Type Required Description
Authorization string Required Basic followed by your credential. See Authentication.

Path parameters

Name Type Required Description
bucket string Required The bucket identifier, for example kb-product-assets-3f9a1c2b7d4e. It is not the bucket's name.
key string Required The file's name, with its folders, for example reports/2026/summary.pdf. Names are case-sensitive. Encode the name in the address as described for Upload a file.

HTTP status codes for "Download a file"

Status When it happens
200 The file's bytes are in the body.
401 The credential is missing or wrong: Your credentials are missing or not valid.
403 The bucket identifier is not one of your active buckets. It may be mistyped, belong to another account, or name a bucket whose status is not ACTIVE: You do not have access to this bucket.
404 The bucket has no file with this name: That file does not exist.
500 Kuberns could not check the credential: Something went wrong.
502 Storage could not complete the download: The storage backend could not complete that request.

Code samples for "Download a file"

Request example

cURL
BUCKET="kb-product-assets-3f9a1c2b7d4e"
KEY="reports/2026/summary.pdf"
 
curl --fail -u "$KUBERNS_ACCESS_KEY_ID:$KUBERNS_SECRET" \
  "https://gateway.kuberns.cloud/$BUCKET/$KEY" \
  -o summary.pdf
Python
import os
from urllib.parse import quote
 
import requests
 
BUCKET = "kb-product-assets-3f9a1c2b7d4e"
KEY = "reports/2026/summary.pdf"
 
with requests.get(
    f"https://gateway.kuberns.cloud/{BUCKET}/{quote(KEY)}",
    auth=(os.environ["KUBERNS_ACCESS_KEY_ID"], os.environ["KUBERNS_SECRET"]),
    stream=True,
) as response:
    response.raise_for_status()
    with open("summary.pdf", "wb") as file:
        for chunk in response.iter_content(chunk_size=1024 * 1024):
            file.write(chunk)
 
print("Saved summary.pdf")
JavaScript
import { createWriteStream } from "node:fs";
import { Readable } from "node:stream";
import { pipeline } from "node:stream/promises";
 
const BUCKET = "kb-product-assets-3f9a1c2b7d4e";
const KEY = "reports/2026/summary.pdf";
 
const credentials = Buffer.from(
  `${process.env.KUBERNS_ACCESS_KEY_ID}:${process.env.KUBERNS_SECRET}`
).toString("base64");
const encodedKey = KEY.split("/").map(encodeURIComponent).join("/");
 
const response = await fetch(
  `https://gateway.kuberns.cloud/${BUCKET}/${encodedKey}`,
  { headers: { Authorization: `Basic ${credentials}` } }
);
if (!response.ok) {
  throw new Error(`Download failed: ${response.status}`);
}
await pipeline(
  Readable.fromWeb(response.body),
  createWriteStream("summary.pdf")
);
 
console.log("Saved summary.pdf");

Response

200 OK

Response headers
Content-Type: application/pdf
Content-Length: 48213
ETag: "5d41402abc4b2a76b9719d911017c592"
Last-Modified: Sat, 17 Oct 2026 07:54:15 GMT

Response headers for "Download a file"

Header Description
Content-Type The type stored with the file when it was uploaded, for example application/pdf.
Content-Length The size of the file in bytes.
ETag A value that identifies the file's content, in double quotes. It changes when the file is replaced with different content.
Last-Modified When the file was last uploaded or replaced, as an HTTP date in GMT.

Get a file's details

HEAD /{bucket}/{key}

Returns a file's type, size, and time of last change without downloading the file, which also tells you that the file exists.

Access: a read-only or read & write credential.

Parameters for "Get a file's details"

Headers

Name Type Required Description
Authorization string Required Basic followed by your credential. See Authentication.

Path parameters

Name Type Required Description
bucket string Required The bucket identifier, for example kb-product-assets-3f9a1c2b7d4e. It is not the bucket's name.
key string Required The file's name, with its folders, for example reports/2026/summary.pdf. Names are case-sensitive. Encode the name in the address as described for Upload a file.

HTTP status codes for "Get a file's details"

Status When it happens
200 The file exists. Its details are in the headers.
400 The address ends with the bucket identifier and a slash, and has no file name.
401 The credential is missing or wrong.
403 The bucket identifier is not one of your active buckets. It may be mistyped, belong to another account, or name a bucket whose status is not ACTIVE.
404 The bucket has no file with this name.
500 Kuberns could not check the credential.
502 Storage could not complete the request.

A HEAD answer never has a body, so the error messages that the other endpoints return do not appear here. Only the status tells you what happened.

Code samples for "Get a file's details"

Request example

cURL
BUCKET="kb-product-assets-3f9a1c2b7d4e"
KEY="reports/2026/summary.pdf"
 
curl -I -u "$KUBERNS_ACCESS_KEY_ID:$KUBERNS_SECRET" \
  "https://gateway.kuberns.cloud/$BUCKET/$KEY"
Python
import os
from urllib.parse import quote
 
import requests
 
BUCKET = "kb-product-assets-3f9a1c2b7d4e"
KEY = "reports/2026/summary.pdf"
 
response = requests.head(
    f"https://gateway.kuberns.cloud/{BUCKET}/{quote(KEY)}",
    auth=(os.environ["KUBERNS_ACCESS_KEY_ID"], os.environ["KUBERNS_SECRET"]),
)
response.raise_for_status()
 
print(response.headers["Content-Length"])
JavaScript
const BUCKET = "kb-product-assets-3f9a1c2b7d4e";
const KEY = "reports/2026/summary.pdf";
 
const credentials = Buffer.from(
  `${process.env.KUBERNS_ACCESS_KEY_ID}:${process.env.KUBERNS_SECRET}`
).toString("base64");
const encodedKey = KEY.split("/").map(encodeURIComponent).join("/");
 
const response = await fetch(
  `https://gateway.kuberns.cloud/${BUCKET}/${encodedKey}`,
  { method: "HEAD", headers: { Authorization: `Basic ${credentials}` } }
);
if (!response.ok) {
  throw new Error(`Request failed: ${response.status}`);
}
 
console.log(response.headers.get("content-length"));

Response

200 OK

Response headers
Content-Type: application/pdf
Content-Length: 48213
ETag: "5d41402abc4b2a76b9719d911017c592"
Last-Modified: Sat, 17 Oct 2026 07:54:15 GMT

Response headers for "Get a file's details"

Header Description
Content-Type The type stored with the file when it was uploaded, for example application/pdf.
Content-Length The size of the file in bytes.
ETag A value that identifies the file's content, in double quotes. It changes when the file is replaced with different content.
Last-Modified When the file was last uploaded or replaced, as an HTTP date in GMT.

Delete a file

DELETE /{bucket}/{key}

Deletes a file permanently.

Access: a read & write credential.

Parameters for "Delete a file"

Headers

Name Type Required Description
Authorization string Required Basic followed by your credential. See Authentication.

Path parameters

Name Type Required Description
bucket string Required The bucket identifier, for example kb-product-assets-3f9a1c2b7d4e. It is not the bucket's name.
key string Required The file's name, with its folders, for example reports/2026/summary.pdf. Names are case-sensitive. Encode the name in the address as described for Upload a file.

HTTP status codes for "Delete a file"

Status When it happens
204 The file was deleted, or there was no file with this name. Both get the same answer, so you can repeat the request safely.
400 The address ends with the bucket identifier and a slash, and has no file name: No object key given.
401 The credential is missing or wrong: Your credentials are missing or not valid.
403 The credential is read-only: This credential is read-only.
403 The bucket identifier is not one of your active buckets. It may be mistyped, belong to another account, or name a bucket whose status is not ACTIVE: You do not have access to this bucket.
403 The address is the bucket identifier alone, with no slash and no file name: Buckets are managed from the Kuberns dashboard, not through this endpoint.
500 Kuberns could not check the credential: Something went wrong.
502 Storage could not complete the delete: The storage backend could not complete that request.

Code samples for "Delete a file"

Request example

cURL
BUCKET="kb-product-assets-3f9a1c2b7d4e"
KEY="reports/2026/summary.pdf"
 
curl -u "$KUBERNS_ACCESS_KEY_ID:$KUBERNS_SECRET" \
  -X DELETE "https://gateway.kuberns.cloud/$BUCKET/$KEY" \
  -w "%{http_code}\n"
Python
import os
from urllib.parse import quote
 
import requests
 
BUCKET = "kb-product-assets-3f9a1c2b7d4e"
KEY = "reports/2026/summary.pdf"
 
response = requests.delete(
    f"https://gateway.kuberns.cloud/{BUCKET}/{quote(KEY)}",
    auth=(os.environ["KUBERNS_ACCESS_KEY_ID"], os.environ["KUBERNS_SECRET"]),
)
response.raise_for_status()
 
print(response.status_code)
JavaScript
const BUCKET = "kb-product-assets-3f9a1c2b7d4e";
const KEY = "reports/2026/summary.pdf";
 
const credentials = Buffer.from(
  `${process.env.KUBERNS_ACCESS_KEY_ID}:${process.env.KUBERNS_SECRET}`
).toString("base64");
const encodedKey = KEY.split("/").map(encodeURIComponent).join("/");
 
const response = await fetch(
  `https://gateway.kuberns.cloud/${BUCKET}/${encodedKey}`,
  { method: "DELETE", headers: { Authorization: `Basic ${credentials}` } }
);
if (!response.ok) {
  throw new Error(`Delete failed: ${response.status}`);
}
 
console.log(response.status);

Response

204 No Content

Response headers for "Delete a file"

The body is empty, and the answer has no headers you need to read.

List files

GET /{bucket}/

Lists the files and folders directly inside a folder of a bucket, one level at a time. It does not list what is inside the folders it returns.

Access: a read-only or read & write credential.

Parameters for "List files"

Headers

Name Type Required Description
Authorization string Required Basic followed by your credential. See Authentication.

Path parameters

Name Type Required Description
bucket string Required The bucket identifier, for example kb-product-assets-3f9a1c2b7d4e. It is not the bucket's name. Keep the slash after it.

Query parameters

Name Type Required Description
folder string Optional The folder to list, for example reports or reports/2026. A / is added at the end if you leave it off. Leave it out to list the top of the bucket.
limit integer Optional The most entries to return in one page. Files and folders count together. Default: 100. The most is 1000: a larger number is lowered to 1000. A value that is not a whole number, or is less than 1, is ignored and the default is used.
page string Optional The next_page of the previous answer, to get the next page. It is not a page number. Send it exactly as you received it. It can contain /, +, and =, so let your HTTP client encode it as a query parameter. Leave it out for the first page.

HTTP status codes for "List files"

Status When it happens
200 The page is in the body. A bucket with no files answers 200 too.
400 page is not valid: That page is not valid. Use the next_page value from the previous response.
401 The credential is missing or wrong: Your credentials are missing or not valid.
403 The bucket identifier is not one of your active buckets. It may be mistyped, belong to another account, or name a bucket whose status is not ACTIVE: You do not have access to this bucket.
500 Kuberns could not check the credential: Something went wrong.
502 Storage could not complete the listing: The storage backend could not complete that request.

Code samples for "List files"

Request example

cURL
BUCKET="kb-product-assets-3f9a1c2b7d4e"
 
curl -G -u "$KUBERNS_ACCESS_KEY_ID:$KUBERNS_SECRET" \
  "https://gateway.kuberns.cloud/$BUCKET/" \
  --data-urlencode "limit=2"
Python
import os
 
import requests
 
BUCKET = "kb-product-assets-3f9a1c2b7d4e"
 
response = requests.get(
    f"https://gateway.kuberns.cloud/{BUCKET}/",
    auth=(os.environ["KUBERNS_ACCESS_KEY_ID"], os.environ["KUBERNS_SECRET"]),
    params={"limit": 2},
)
response.raise_for_status()
answer = response.json()
 
for folder in answer["folders"]:
    print(folder)
for file in answer["objects"]:
    print(file["key"], file["size"])
 
print("has_next:", answer["has_next"])
print("next_page:", answer["next_page"])
JavaScript
const BUCKET = "kb-product-assets-3f9a1c2b7d4e";
 
const credentials = Buffer.from(
  `${process.env.KUBERNS_ACCESS_KEY_ID}:${process.env.KUBERNS_SECRET}`
).toString("base64");
 
const params = new URLSearchParams({ limit: "2" });
const response = await fetch(
  `https://gateway.kuberns.cloud/${BUCKET}/?${params}`,
  { headers: { Authorization: `Basic ${credentials}` } }
);
if (!response.ok) {
  throw new Error(`List files failed with status ${response.status}`);
}
const answer = await response.json();
 
for (const folder of answer.folders) {
  console.log(folder);
}
for (const file of answer.objects) {
  console.log(file.key, file.size);
}
 
console.log("has_next:", answer.has_next);
console.log("next_page:", answer.next_page);

These samples ask for 2 entries at a time, so that the paging keys show up in the answer. Leave limit out to get up to 100 entries a page.

Response

200 OK

Response
{
  "bucket": "kb-product-assets-3f9a1c2b7d4e",
  "folder": "",
  "folders": [
    "invoices/"
  ],
  "has_next": true,
  "next_page": "1YsArNwnJgeAHhJPrz0DUmetRWnV9BHKt/RrOEl0yGjnZF0ZT60PMw6nGL9Skqm0SJw8Hsd0vAvQ=",
  "objects": [
    {
      "etag": "3bdaf5969285188ac756c339f69f5c79",
      "key": "logo.png",
      "last_modified": "2026-10-17T07:54:15Z",
      "size": 4
    }
  ]
}

Note: This is the first of two pages. The bucket holds invoices/, logo.png, notes.txt, and reports/, and the request asked for 2 entries. has_next is true, so there is more, and next_page is what you send to get it. The answer also repeats folder and next_page as prefix and next_token, the names the first version of the API used. Those names, and prefix and token in the request, still work, but use the new names in new code.

The paging keys

Key Where Example What it means
limit In your request 2 How many entries you want on this page. Files and folders count together.
folder In your request reports/2026 Which folder to list. Leave it out for the top of the bucket.
page In your request The next_page of the previous answer Which page to return. Leave it out for the first page. It is not a page number.
has_next In the answer true true when there is another page after this one. false on the last page.
next_page In the answer "1YsArNwn..." What to send as page to get the next page. null on the last page.

Get the next page

Send next_page back as page, with the same folder and limit. These samples ask for the first page and then for the second. The cURL sample needs jq.

cURL
BUCKET="kb-product-assets-3f9a1c2b7d4e"
 
FIRST=$(curl -s -G -u "$KUBERNS_ACCESS_KEY_ID:$KUBERNS_SECRET" \
  "https://gateway.kuberns.cloud/$BUCKET/" \
  --data-urlencode "limit=2")
PAGE=$(echo "$FIRST" | jq -r '.next_page')
 
curl -G -u "$KUBERNS_ACCESS_KEY_ID:$KUBERNS_SECRET" \
  "https://gateway.kuberns.cloud/$BUCKET/" \
  --data-urlencode "limit=2" \
  --data-urlencode "page=$PAGE"
Python
import os
 
import requests
 
BUCKET = "kb-product-assets-3f9a1c2b7d4e"
 
 
def list_page(page=None):
    params = {"limit": 2}
    if page:
        params["page"] = page
 
    response = requests.get(
        f"https://gateway.kuberns.cloud/{BUCKET}/",
        auth=(os.environ["KUBERNS_ACCESS_KEY_ID"], os.environ["KUBERNS_SECRET"]),
        params=params,
    )
    response.raise_for_status()
    return response.json()
 
 
first = list_page()
second = list_page(first["next_page"])
 
for folder in second["folders"]:
    print(folder)
for file in second["objects"]:
    print(file["key"], file["size"])
 
print("has_next:", second["has_next"])
JavaScript
const BUCKET = "kb-product-assets-3f9a1c2b7d4e";
 
const credentials = Buffer.from(
  `${process.env.KUBERNS_ACCESS_KEY_ID}:${process.env.KUBERNS_SECRET}`
).toString("base64");
 
async function listPage(page) {
  const params = new URLSearchParams({ limit: "2" });
  if (page) {
    params.set("page", page);
  }
 
  const response = await fetch(
    `https://gateway.kuberns.cloud/${BUCKET}/?${params}`,
    { headers: { Authorization: `Basic ${credentials}` } }
  );
  if (!response.ok) {
    throw new Error(`List files failed with status ${response.status}`);
  }
  return response.json();
}
 
const first = await listPage();
const second = await listPage(first.next_page);
 
for (const folder of second.folders) {
  console.log(folder);
}
for (const file of second.objects) {
  console.log(file.key, file.size);
}
 
console.log("has_next:", second.has_next);

The second answer has the rest. has_next is false and next_page is null, so this was the last page:

{
  "bucket": "kb-product-assets-3f9a1c2b7d4e",
  "folder": "",
  "folders": [
    "reports/"
  ],
  "has_next": false,
  "next_page": null,
  "objects": [
    {
      "etag": "4358b5009c67d0e31d7fbf1663fcd3bf",
      "key": "notes.txt",
      "last_modified": "2026-10-17T07:54:15Z",
      "size": 5
    }
  ]
}

These samples assume the first answer has has_next set to true. To handle any number of pages, use the loop below. See Pagination for more.

Read every page

These samples read every page of one folder and print the name of every file. The cURL sample needs jq.

cURL
BUCKET="kb-product-assets-3f9a1c2b7d4e"
FOLDER="reports"
PAGE=""
 
while true; do
  ANSWER=$(curl -s -G -u "$KUBERNS_ACCESS_KEY_ID:$KUBERNS_SECRET" \
    "https://gateway.kuberns.cloud/$BUCKET/" \
    --data-urlencode "folder=$FOLDER" \
    --data-urlencode "limit=100" \
    --data-urlencode "page=$PAGE")
 
  echo "$ANSWER" | jq -r '.objects[].key'
 
  [ "$(echo "$ANSWER" | jq -r '.has_next')" = "true" ] || break
  PAGE=$(echo "$ANSWER" | jq -r '.next_page')
done
Python
import os
 
import requests
 
BUCKET = "kb-product-assets-3f9a1c2b7d4e"
FOLDER = "reports"
 
page = None
 
while True:
    params = {"folder": FOLDER, "limit": 100}
    if page:
        params["page"] = page
 
    response = requests.get(
        f"https://gateway.kuberns.cloud/{BUCKET}/",
        auth=(os.environ["KUBERNS_ACCESS_KEY_ID"], os.environ["KUBERNS_SECRET"]),
        params=params,
    )
    response.raise_for_status()
    answer = response.json()
 
    for file in answer["objects"]:
        print(file["key"])
 
    if not answer["has_next"]:
        break
    page = answer["next_page"]
JavaScript
const BUCKET = "kb-product-assets-3f9a1c2b7d4e";
const FOLDER = "reports";
 
const credentials = Buffer.from(
  `${process.env.KUBERNS_ACCESS_KEY_ID}:${process.env.KUBERNS_SECRET}`
).toString("base64");
 
let page = null;
 
while (true) {
  const params = new URLSearchParams({ folder: FOLDER, limit: "100" });
  if (page) {
    params.set("page", page);
  }
 
  const response = await fetch(
    `https://gateway.kuberns.cloud/${BUCKET}/?${params}`,
    { headers: { Authorization: `Basic ${credentials}` } }
  );
  if (!response.ok) {
    throw new Error(`List files failed with status ${response.status}`);
  }
  const answer = await response.json();
 
  for (const file of answer.objects) {
    console.log(file.key);
  }
 
  if (!answer.has_next) break;
  page = answer.next_page;
}

To read the folders too, collect answer.folders on every page. To list the top of the bucket, leave folder out or set it to an empty string.

Response fields for "List files"

Field Type Description
bucket string The bucket identifier.
folder string The folder that was listed. It ends with /, or is an empty string for the top of the bucket.
folders array of strings The folders directly inside folder, each as a full path that ends with /, such as reports/2026/. An empty array when this page has none.
objects array of objects The files directly inside folder. An empty array when this page has none.
objects[].key string The file's full name, including its folders.
objects[].size integer The size of the file in bytes.
objects[].etag string A value that identifies the file's content. It is the ETag header of a download, without the double quotes.
objects[].last_modified string When the file was last uploaded or replaced, as an ISO 8601 time in UTC.
has_next boolean true when there is another page after this one. false on the last page.
next_page string or null Send it as page to get the next page. null on the last page.