Objects
Objects are :storage.Object nodes uniquely identified by (bucket_id, path). The path is a flat string but the conventional /-separator lets clients render a folder tree on top.
Upload
Two surfaces: POST creates (409 on conflict), PUT upserts. Body is the raw bytes; Content-Type sets the stored MIME.
# Single-shot create curl -X POST -H "Authorization: Bearer $TOKEN" \ -H "Content-Type: image/png" \ --data-binary @alice.png \ http://localhost:7474/storage/v1/object/avatars/alice.png # Upsert (replaces if it exists) curl -X PUT ...same headers... \ http://localhost:7474/storage/v1/object/avatars/alice.png
For files larger than the configured upload_chunk_size (default 5 MiB) use the TUS resumable endpoint - see the Resumable Uploads page.
Download
Authenticated downloads via GET /storage/v1/object/{bucket}/{path}; public buckets also expose GET /storage/v1/object/public/{bucket}/{path}. Both honour Range headers so video and audio players can seek.
HEAD
HEAD /storage/v1/object/{bucket}/{path} returns the metadata headers (Content-Length, Content-Type, ETag, X-Content-SHA256) without streaming the body - ideal for existence checks.
Copy / move
# Copy across buckets
curl -X POST -H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"source_bucket": "avatars",
"source_path": "alice.png",
"dest_bucket": "thumbnails",
"dest_path": "alice.png"
}' \
http://localhost:7474/storage/v1/object/copy
# Rename within a bucket
curl -X POST .../storage/v1/object/move -d '{
"source_bucket": "avatars", "source_path": "old.png",
"dest_bucket": "avatars", "dest_path": "new.png"
}'List
POST /storage/v1/object/list/{bucket} with an optional prefix, limit, offset, and sort. Defaults to limit: 100, capped at 1000.
curl -X POST -H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"prefix":"users/","limit":50,"sort_by":"created_at","order":"desc"}' \
http://localhost:7474/storage/v1/object/list/avatarsDelete
DELETE /storage/v1/object/{bucket}/{path}. The backend blob is released automatically when the last :storage.Object referencing its content hash is removed (refcount cleanup).