bucketpilot/Docs

Buckets & objects

List buckets and search their indexed objects.

List buckets

GET /v1/buckets returns every bucket in the key's workspace:

bash
curl https://bucketpilot.io/api/v1/buckets \
  -H "Authorization: Bearer $BUCKETPILOT_KEY"
json
{
  "buckets": [
    {
      "id": 12,
      "name": "prod-data",
      "awsBucketName": "acme-prod-data",
      "region": "us-east-1",
      "provider": "aws",
      "objectCount": 48210,
      "totalSizeBytes": 734003200000,
      "indexStatus": "ready",
      "indexedObjectCount": 48210,
      "lastIndexedAt": "2026-07-15T04:12:09.000Z",
      "createdAt": "2026-03-02T18:30:11.000Z"
    }
  ]
}

GET /v1/buckets/{id} returns one bucket in the same shape. provider is the hosting cloud — aws, r2 (Cloudflare R2), or gcs (Google Cloud Storage); R2 buckets report region auto.

Search objects

GET /v1/buckets/{id}/objects reads the search index (metadata only — key, size, storage class; never file contents), so the bucket must be indexed first. Results are paged.

ParameterTypeDescription
searchstringText match on the key; * and ? work as wildcards (reports/*.csv).
prefixstringLimit to keys under a prefix.
storageClassstringe.g. STANDARD, GLACIER, DEEP_ARCHIVE.
page, pageSizeintegerPagination — default 50, max 200 per page.
sortBystringkey, size, or lastModified.
sortDirstringasc or desc.
bash
curl "https://bucketpilot.io/api/v1/buckets/12/objects?search=*.parquet&sortBy=size&sortDir=desc" \
  -H "Authorization: Bearer $BUCKETPILOT_KEY"
python
import requests

resp = requests.get(
    "https://bucketpilot.io/api/v1/buckets/12/objects",
    params={"search": "*.parquet", "sortBy": "size", "sortDir": "desc"},
    headers={"Authorization": f"Bearer {KEY}"},
)
for obj in resp.json()["objects"]:
    print(obj["key"], obj["size"])
json
{
  "objects": [
    {
      "key": "events/2026/06/day-30.parquet",
      "size": 52428800,
      "lastModified": "2026-07-01T00:14:55.000Z",
      "etag": "\"9b2cf535f27731c974343645a3985328\"",
      "storageClass": "STANDARD",
      "contentType": "application/octet-stream"
    }
  ],
  "page": 1,
  "pageSize": 50,
  "totalCount": 1284
}

Download objects

POST /v1/buckets/{id}/objects/download returns a short-lived presigned URL — your download comes straight from your own S3, BucketPilot never proxies the bytes. Send the object key in the body; expiresIn (seconds, 60–86400, default 3600) and versionId are optional.

bash
curl -X POST https://bucketpilot.io/api/v1/buckets/12/objects/download \
  -H "Authorization: Bearer $BUCKETPILOT_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "key": "reports/2026/june.csv", "expiresIn": 600 }'
json
{
  "downloadUrl": "https://acme-prod-data.s3.us-east-1.amazonaws.com/reports/2026/june.csv?X-Amz-...",
  "key": "reports/2026/june.csv",
  "expiresAt": "2026-07-16T10:24:03.000Z"
}

The URL carries Content-Disposition: attachment, so fetching it saves the file rather than rendering it.

Trigger indexing

Needs a read/write key. POST /v1/buckets/{id}/index starts (or resumes) building the search index — the same operation as Index this bucket in the app, with the same guardrails: it returns 403 INDEX_LIMIT_REACHED if your plan's indexed-object allowance is used up, 409 LARGE_BUCKET for very large scan-mode buckets (pass ?force=true to scan anyway, or switch the bucket to daily inventory indexing in the app), and 409 if an index job is already running. Add ?fresh=true to rebuild from scratch instead of resuming a checkpoint.

bash
curl -X POST "https://bucketpilot.io/api/v1/buckets/12/index" \
  -H "Authorization: Bearer $BUCKETPILOT_KEY"

Returns 202 { "status": "indexing" }; poll GET /v1/buckets/{id} for indexStatus to become ready.

Object metadata, tags & versions

Read a single object's details live from your storage — no index needed:

  • GET /v1/buckets/{id}/objects/metadata?key=… — size, content type, etag, last-modified, storage class, version id, and any user metadata. Add &versionId=… for a specific version.
  • GET /v1/buckets/{id}/objects/tags?key=… — the object's tag set.
  • GET /v1/buckets/{id}/objects/versions?prefix=… — object versions and delete markers (pass maxKeys ≤ 1000, and keyMarker/versionIdMarker from the previous page to continue).
bash
curl "https://bucketpilot.io/api/v1/buckets/12/objects/metadata?key=reports/2026/june.csv" \
  -H "Authorization: Bearer $BUCKETPILOT_KEY"

Upload objects (read/write key)

Uploading is two steps, so the bytes go straight to your storage and never through BucketPilot. Needs a read/write key.

  1. 1.POST /v1/buckets/{id}/objects/upload with the target key (and optional contentType) returns a short-lived presigned uploadUrl.
  2. 2.PUT your file to that URL.
  3. 3.POST /v1/buckets/{id}/objects/confirm with the same key so BucketPilot indexes it — now it shows up in listings and cost.
bash
# 1. get a presigned upload URL
UP=$(curl -s -X POST https://bucketpilot.io/api/v1/buckets/12/objects/upload \
  -H "Authorization: Bearer $BUCKETPILOT_KEY" -H "Content-Type: application/json" \
  -d '{ "key": "reports/2026/july.csv", "contentType": "text/csv" }')

# 2. PUT the bytes to the returned uploadUrl
curl -X PUT -T ./july.csv -H "Content-Type: text/csv" "$(echo "$UP" | jq -r .uploadUrl)"

# 3. confirm so it's indexed
curl -X POST https://bucketpilot.io/api/v1/buckets/12/objects/confirm \
  -H "Authorization: Bearer $BUCKETPILOT_KEY" -H "Content-Type: application/json" \
  -d '{ "key": "reports/2026/july.csv" }'

Delete, copy, folders, tags & storage class (read/write key)

All need a read/write key. Each keeps the search index in sync automatically.

  • DeletePOST /v1/buckets/{id}/objects/delete with { "keys": ["a.txt", "b/c.txt"] } (up to 1000). Returns { deleted, errors }.
  • Copy / movePOST /v1/buckets/{id}/objects/copy with { "sourceKey", "destinationKey", "move": false } (same bucket; set move: true to delete the source).
  • Create folderPOST /v1/buckets/{id}/folders with { "name": "invoices", "prefix": "2026/" }.
  • Set tagsPUT /v1/buckets/{id}/objects/tags with { "key", "tags": [{ "key": "team", "value": "finance" }] } (replaces the whole set).
  • Change storage classPUT /v1/buckets/{id}/objects/storage-class with { "key", "storageClass": "GLACIER_IR" } (STANDARD, STANDARD_IA, ONEZONE_IA, INTELLIGENT_TIERING, GLACIER, GLACIER_IR, DEEP_ARCHIVE, REDUCED_REDUNDANCY).
bash
curl -X POST https://bucketpilot.io/api/v1/buckets/12/objects/delete \
  -H "Authorization: Bearer $BUCKETPILOT_KEY" -H "Content-Type: application/json" \
  -d '{ "keys": ["tmp/old.log", "tmp/older.log"] }'

A read-only key on any of these returns 403 READ_ONLY_KEY.

© 2026 BucketPilot