Beezifi Storage API Docs
v1
OpenAPI JSON Home Dashboard →

API Reference

All systems operational
REST API  ·  JSON
API Version: v1
Base URL https://storage.beezifi.com/api

The Beezifi Storage API is a RESTful HTTP API. All request and response bodies are JSON unless you are uploading or downloading file content. Authentication uses API keys sent as request headers.

All API requests must be made over HTTPS. HTTP requests will be redirected to HTTPS.

Authentication

The API supports two authentication methods: API Keys (recommended for server-to-server) and JWT Bearer tokens (used by the dashboard).

API Key Authentication

Generate an API key from your dashboard under API Keys. Each key has an Access Key (prefix obj_) and a Secret Key shown only once at creation.

Send both on every request:

X-Api-Key: obj_a1b2c3d4
X-Api-Secret: your-secret-key-here

Bearer Token

Log in via POST /api/auth/login to receive a short-lived JWT (12 h). Include it in the Authorization header:

Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6Ikp...
Never expose your Secret Key in client-side code. Use API keys only on your server or backend functions.

Quick Start

Node.js / JavaScript

Install via npm: npm i node-fetch form-data or use the native fetch in Node 18+.

Python

Install via pip: pip install requests

HTTP / cURL

Any HTTP client works. Examples below use curl.

S3-Compatible

Coming soon — drop-in S3 SDK support with a compatibility layer.

Upload your first file

import { FormData } from 'node:stream';
import { readFileSync } from 'node:fs';

const BASE    = 'https://storage.beezifi.com/api';
const HEADERS = {
  'X-Api-Key':    'obj_your_access_key',
  'X-Api-Secret': 'your_secret_key',
};

// 1. Create a bucket
const bucket = await fetch(`${BASE}/buckets`, {
  method:  'POST',
  headers: { ...HEADERS, 'Content-Type': 'application/json' },
  body:    JSON.stringify({ name: 'my-bucket' }),
}).then(r => r.json());

// 2. Upload a file
const form = new FormData();
form.append('file', new Blob([readFileSync('./photo.jpg')]), 'photo.jpg');
form.append('key', 'photos/photo.jpg');

const obj = await fetch(`${BASE}/buckets/${bucket.id}/objects/upload`, {
  method:  'POST',
  headers: HEADERS,
  body:    form,
}).then(r => r.json());

console.log('Uploaded:', obj.objectKey);
import requests

BASE    = 'https://storage.beezifi.com/api'
HEADERS = {
    'X-Api-Key':    'obj_your_access_key',
    'X-Api-Secret': 'your_secret_key',
}

# 1. Create a bucket
bucket = requests.post(
    f'{BASE}/buckets',
    headers=HEADERS,
    json={'name': 'my-bucket'},
).json()

# 2. Upload a file
with open('photo.jpg', 'rb') as f:
    obj = requests.post(
        f'{BASE}/buckets/{bucket["id"]}/objects/upload',
        headers=HEADERS,
        data={'key': 'photos/photo.jpg'},
        files={'file': f},
    ).json()

print('Uploaded:', obj['objectKey'])
# 1. Create a bucket
curl -s -X POST https://storage.beezifi.com/api/buckets \
  -H "X-Api-Key: obj_your_access_key" \
  -H "X-Api-Secret: your_secret_key" \
  -H "Content-Type: application/json" \
  -d '{"name":"my-bucket"}'

# 2. Upload a file
curl -s -X POST https://storage.beezifi.com/api/buckets/BUCKET_ID/objects/upload \
  -H "X-Api-Key: obj_your_access_key" \
  -H "X-Api-Secret: your_secret_key" \
  -F "file=@photo.jpg" \
  -F "key=photos/photo.jpg"

Buckets

GET /buckets List all buckets

Returns all buckets belonging to your organization, sorted by creation date descending.

curl https://storage.beezifi.com/api/buckets \
  -H "X-Api-Key: obj_your_access_key" \
  -H "X-Api-Secret: your_secret_key"
const res     = await fetch(`${BASE}/buckets`, { headers: HEADERS });
const buckets = await res.json();

200Array of bucket objects

[{
  "id":         "a1b2c3d4-...",
  "name":       "my-bucket",
  "visibility": "private",
  "storageUsedBytes": 1048576,
  "createdAt":  "2026-01-15T10:00:00.000Z"
}]
POST /buckets Create a bucket
BodyTypeRequiredDescription
namestringrequiredUnique bucket name within your org. Lowercase letters, numbers, hyphens.
visibilitystringoptionalprivate (default) or public. Public buckets allow unauthenticated downloads.
curl -X POST https://storage.beezifi.com/api/buckets \
  -H "X-Api-Key: obj_your_access_key" \
  -H "X-Api-Secret: your_secret_key" \
  -H "Content-Type: application/json" \
  -d '{"name":"my-bucket","visibility":"private"}'
const bucket = await fetch(`${BASE}/buckets`, {
  method:  'POST',
  headers: { ...HEADERS, 'Content-Type': 'application/json' },
  body: JSON.stringify({ name: 'my-bucket' }),
}).then(r => r.json());

201Bucket object

PUT /buckets/:bucketId/policy Set bucket visibility
BodyTypeRequiredDescription
visibilitystringrequiredprivate or public
curl -X PUT https://storage.beezifi.com/api/buckets/BUCKET_ID/policy \
  -H "X-Api-Key: obj_your_access_key" \
  -H "X-Api-Secret: your_secret_key" \
  -H "Content-Type: application/json" \
  -d '{"visibility":"public"}'

Objects

GET /buckets/:bucketId/objects List objects in a bucket
QueryTypeRequiredDescription
prefixstringoptionalFilter objects by key prefix, e.g. images/
limitintegeroptionalMax results (default 100, max 1000)
offsetintegeroptionalPagination offset
includeDeletedbooleanoptionalInclude soft-deleted objects
curl "https://storage.beezifi.com/api/buckets/BUCKET_ID/objects?prefix=images/" \
  -H "X-Api-Key: obj_your_access_key" \
  -H "X-Api-Secret: your_secret_key"

200Paginated object list

{
  "total": 42,
  "objects": [{
    "id":          "...",
    "objectKey":  "images/photo.jpg",
    "sizeBytes":  204800,
    "contentType":"image/jpeg",
    "etag":       "d41d8cd9...",
    "createdAt":  "2026-01-15T10:00:00.000Z"
  }]
}
POST /buckets/:bucketId/objects/upload Upload an object

Upload a file using multipart/form-data. Maximum size is configurable (default 1 GB).

Form FieldTypeRequiredDescription
filefilerequiredThe file binary
keystringrequiredObject key (path), e.g. images/photo.jpg. Use / as a folder separator.
metadataJSON stringoptionalCustom key/value metadata as a JSON string
curl -X POST https://storage.beezifi.com/api/buckets/BUCKET_ID/objects/upload \
  -H "X-Api-Key: obj_your_access_key" \
  -H "X-Api-Secret: your_secret_key" \
  -F "file=@/path/to/photo.jpg" \
  -F "key=images/photo.jpg"
const form = new FormData();
form.append('file', fileBlob, 'photo.jpg');
form.append('key',  'images/photo.jpg');

const obj = await fetch(`${BASE}/buckets/${bucketId}/objects/upload`, {
  method:  'POST',
  headers: HEADERS,  // do NOT set Content-Type — let fetch set it with boundary
  body:    form,
}).then(r => r.json());
import requests

with open('photo.jpg', 'rb') as f:
    obj = requests.post(
        f'{BASE}/buckets/{bucket_id}/objects/upload',
        headers=HEADERS,
        data={'key': 'images/photo.jpg'},
        files={'file': ('photo.jpg', f, 'image/jpeg')},
    ).json()

201Uploaded object metadata

{
  "id":          "...",
  "objectKey":  "images/photo.jpg",
  "sizeBytes":  204800,
  "contentType":"image/jpeg",
  "etag":       "d41d8cd9..."
}
GET /buckets/:bucketId/objects/:objectKey Download an object

Streams the file content. The response Content-Type matches the uploaded file type. objectKey supports nested paths, e.g. images/folder/photo.jpg.

curl -O https://storage.beezifi.com/api/buckets/BUCKET_ID/objects/images/photo.jpg \
  -H "X-Api-Key: obj_your_access_key" \
  -H "X-Api-Secret: your_secret_key"

200File binary stream

DELETE /buckets/:bucketId/objects/:objectKey Delete an object

Soft-deletes the object. It can be recovered within your retention window using the /recover endpoint.

curl -X DELETE https://storage.beezifi.com/api/buckets/BUCKET_ID/objects/images/photo.jpg \
  -H "X-Api-Key: obj_your_access_key" \
  -H "X-Api-Secret: your_secret_key"

200{ "deleted": true }

GET /public/objects/:bucketId/:objectKey Public download (no auth)

Download an object without authentication. The bucket must have visibility: "public". Use this URL directly in <img>, <video>, or <a> tags.

# No headers needed — share this URL directly
https://storage.beezifi.com/api/public/objects/BUCKET_ID/images/photo.jpg
POST /buckets/:bucketId/signed-url Generate a signed URL

Generate a time-limited URL that grants temporary access to a private object — useful for sharing downloads without exposing your API key.

BodyTypeRequiredDescription
objectKeystringrequiredKey of the object to sign
expiresInintegeroptionalSeconds until expiry (default 3600, max 604800)
curl -X POST https://storage.beezifi.com/api/buckets/BUCKET_ID/signed-url \
  -H "X-Api-Key: obj_your_access_key" \
  -H "X-Api-Secret: your_secret_key" \
  -H "Content-Type: application/json" \
  -d '{"objectKey":"images/photo.jpg","expiresIn":3600}'

200{ "url": "https://storage.beezifi.com/..." }

API Keys

GET /auth/api-keys List API keys
curl https://storage.beezifi.com/api/auth/api-keys \
  -H "X-Api-Key: obj_your_access_key" \
  -H "X-Api-Secret: your_secret_key"
POST /auth/api-keys Create an API key
The secretKey is only returned once. Store it securely — it cannot be retrieved again.
BodyTypeRequiredDescription
labelstringrequiredHuman-readable label for this key, e.g. "Production server"
curl -X POST https://storage.beezifi.com/api/auth/api-keys \
  -H "X-Api-Key: obj_your_access_key" \
  -H "X-Api-Secret: your_secret_key" \
  -H "Content-Type: application/json" \
  -d '{"label":"Production server"}'

201New API key (secret shown once)

{
  "id":        "...",
  "accessKey": "obj_a1b2c3d4",
  "secretKey": "sk_live_...",   // save this — shown only once
  "label":     "Production server"
}

Usage

GET /usage/summary Get storage & bandwidth usage
curl https://storage.beezifi.com/api/usage/summary \
  -H "X-Api-Key: obj_your_access_key" \
  -H "X-Api-Secret: your_secret_key"

200

{
  "storageUsedBytes":    1073741824,
  "storageQuotaBytes":   26843545600,
  "bandwidthUsedBytes":  524288000,
  "bandwidthQuotaBytes": 107374182400,
  "objectCount":         1284,
  "bucketCount":         3
}

Errors

All errors return a JSON body with an error string and optional details.

{
  "error":     "Authentication required",
  "details":   null,
  "requestId": "cb34396e-dd46-49d3-b613-ceea53c41525"
}
StatusMeaning
400Bad request — missing or invalid parameters
401Unauthorized — missing or expired credentials
403Forbidden — valid credentials but insufficient permissions
404Not found — bucket or object does not exist
409Conflict — duplicate name or key
413Payload too large — file exceeds the upload size limit
429Rate limited — slow down requests
500Internal server error — something went wrong on our end
Every response includes a requestId you can share with support to help diagnose issues.