storage.now API

File storage for humans and AI agents. Upload, organize, and share files via a simple REST API.

Base URL: https://storage.liteio.dev

FeatureDetail
Max file size100 MB (single PUT), unlimited via presigned URLs
AuthEd25519 challenge-response or magic link
StorageS3-compatible object storage (R2)
MetadataSQLite at edge (D1)
Soft deleteFiles go to trash first, permanent delete on empty

Authentication

All API routes (except registration, auth, and public pages) require a Bearer token or session cookie.

Register an Actor

POST /actors
Content-Type: application/json

{
  "actor": "a/my-agent",
  "public_key": "<base64url-ed25519-public-key>",
  "type": "agent"
}

// Response
{
  "actor": "a/my-agent",
  "created": true
}

Humans use u/name, agents use a/name. Agents must provide an Ed25519 public key.

Challenge-Response Auth

// Step 1: Get a challenge nonce
POST /auth/challenge
{"actor": "a/my-agent"}

// Response
{
  "challenge_id": "ch_...",
  "nonce": "abc123...",
  "expires_at": "2026-03-18T..."
}

// Step 2: Sign the nonce with your Ed25519 private key, then verify
POST /auth/verify
{
  "challenge_id": "ch_...",
  "actor": "a/my-agent",
  "signature": "<base64url-signature-of-nonce>"
}

// Response
{
  "access_token": "...",
  "expires_at": "2026-03-18T..."
}

// Step 3: Use the token
Authorization: Bearer <access_token>
POST /auth/magic-link
{"email": "alice@example.com"}

// Response
{"ok": true, "magic_link": "https://storage.liteio.dev/auth/magic/..."}

Opens a session in the browser. No password needed.

Logout

POST /auth/logout
GET /auth/logout

Ends the current session. Accepts both POST and GET (for link-based logout).

Files

Upload, download, and delete files using their path.

Upload a File

PUT /files/docs/readme.md
Authorization: Bearer <token>
Content-Type: text/markdown

<file bytes>

// Response (201 Created or 200 Updated)
{
  "id": "o_...",
  "path": "docs/readme.md",
  "name": "readme.md",
  "content_type": "text/markdown",
  "size": 1234,
  "created_at": 1710700000000
}

Parent folders are auto-created. Content-Type is auto-detected from extension if not provided. Max 100 MB.

Download a File

GET /files/docs/readme.md
Authorization: Bearer <token>

// Response: file bytes
// Headers: Content-Type, Content-Length, ETag, Last-Modified, Content-Disposition

Trashed files are not downloadable. Sets accessed_at on the file.

Delete a File

DELETE /files/docs/readme.md
Authorization: Bearer <token>

// Response
{"deleted": true}

Permanently deletes the file and its R2 object. To soft-delete, use POST /drive/trash instead.

File Metadata (HEAD)

HEAD /files/docs/readme.md
Authorization: Bearer <token>

// Response headers: Content-Type, Content-Length, Last-Modified

Folders

Folders are virtual metadata entries. Created automatically when uploading files, or explicitly.

Create a Folder

POST /folders
Authorization: Bearer <token>
Content-Type: application/json

{"path": "docs/reports"}

// Response (201)
{
  "id": "o_...",
  "path": "docs/reports/",
  "name": "reports",
  "created": true
}

Parent folders are auto-created. Returns created: false if already exists.

List Folder Contents

// List root
GET /folders
Authorization: Bearer <token>

// List subfolder
GET /folders/docs
Authorization: Bearer <token>

// Response
{
  "path": "docs/",
  "items": [
    {"name": "reports", "path": "docs/reports/", "is_folder": true, "starred": false, ...},
    {"name": "readme.md", "path": "docs/readme.md", "is_folder": false, "size": 1234, "starred": false, ...}
  ]
}

Items are sorted: folders first, then files alphabetically. Trashed items are excluded.

Delete a Folder

DELETE /folders/docs/reports
Authorization: Bearer <token>

// Response
{"deleted": true}

Folder must be empty. Delete or move files inside first.

Shares

Share files with other actors. Grant read or write access.

Create a Share

POST /shares
Authorization: Bearer <token>
Content-Type: application/json

{
  "path": "docs/readme.md",
  "grantee": "u/bob",
  "permission": "read"
}

// Response (201)
{
  "id": "sh_...",
  "path": "docs/readme.md",
  "grantee": "u/bob",
  "permission": "read",
  "created_at": 1710700000000
}

List Shares

GET /shares
Authorization: Bearer <token>

// Response
{
  "given": [...],    // shares you created
  "received": [...]  // shares granted to you
}

Revoke a Share

DELETE /shares/sh_abc123
Authorization: Bearer <token>

// Response
{"deleted": true}

Shared Files

// List files shared with you
GET /shared
Authorization: Bearer <token>

// Download a shared file
GET /shared/u%2Falice/docs/readme.md
Authorization: Bearer <token>

Presigned URLs

For large files or high-throughput scenarios, use presigned URLs to upload/download directly to object storage — bypassing the worker entirely. No file bytes pass through the API server.

Flow: Request a signed URL → PUT/GET directly to storage → Confirm upload (for writes).

Get Upload URL

POST /presign/upload
Authorization: Bearer <token>
Content-Type: application/json

{
  "path": "models/v3.bin",
  "content_type": "application/octet-stream",
  "expires": 3600
}

// Response
{
  "upload_url": "https://...signed-url...",
  "path": "models/v3.bin",
  "content_type": "application/octet-stream",
  "expires_in": 3600,
  "method": "PUT",
  "headers": {"Content-Type": "application/octet-stream"}
}

The signed URL is valid for expires seconds (default 1 hour, max 24 hours). After uploading, call /presign/complete to sync metadata.

Get Download URL

POST /presign/download
Authorization: Bearer <token>
Content-Type: application/json

{"path": "models/v3.bin", "expires": 3600}

// Response
{
  "download_url": "https://...signed-url...",
  "path": "models/v3.bin",
  "name": "v3.bin",
  "content_type": "application/octet-stream",
  "size": 47185920,
  "expires_in": 3600
}

No confirmation needed for downloads. The file must exist (verified against metadata before signing).

Confirm Upload

POST /presign/complete
Authorization: Bearer <token>
Content-Type: application/json

{"path": "models/v3.bin"}

// Response
{
  "id": "o_...",
  "path": "models/v3.bin",
  "name": "v3.bin",
  "content_type": "application/octet-stream",
  "size": 47185920,
  "created_at": 1710700000000
}

Call after a presigned upload succeeds. Verifies the file exists in storage, reads its actual size/type, and creates or updates the metadata record. Parent folders are auto-created.

Drive

Drive endpoints provide Google Drive-class file management features: star, rename, move, copy, trash, restore, search, and more. All require authentication.

Star / Unstar

PATCH /drive/star
Authorization: Bearer <token>
Content-Type: application/json

{"path": "docs/readme.md", "starred": 1}

// Response
{"path": "docs/readme.md", "starred": 1}

Set starred to 1 to star, 0 to unstar.

Rename

POST /drive/rename
Authorization: Bearer <token>
Content-Type: application/json

{"path": "docs/old-name.md", "new_name": "new-name.md"}

// Response
{
  "old_path": "docs/old-name.md",
  "new_path": "docs/new-name.md",
  "name": "new-name.md"
}

Renaming a folder cascades the path change to all children. R2 objects are copied to the new key and the old key is deleted.

Move

POST /drive/move
Authorization: Bearer <token>
Content-Type: application/json

{"paths": ["docs/readme.md", "images/logo.svg"], "destination": "archive/"}

// Response
{"moved": 2}

Moves files and folders to a new parent directory. Destination must end with / or be empty string for root. Folder moves cascade to all children.

Copy

POST /drive/copy
Authorization: Bearer <token>
Content-Type: application/json

{"path": "docs/readme.md"}

// Response
{
  "id": "o_...",
  "path": "docs/readme (copy).md",
  "name": "readme (copy).md"
}

Creates a duplicate file. Appends (copy) to the name, incrementing if needed. Folder copy is not supported.

Trash

POST /drive/trash
Authorization: Bearer <token>
Content-Type: application/json

{"paths": ["docs/readme.md", "images/"]}

// Response
{"trashed": 2}

Soft-deletes items by setting trashed_at. Folder trash cascades to all children. Trashed items are excluded from folder listings and search.

Restore

POST /drive/restore
Authorization: Bearer <token>
Content-Type: application/json

{"paths": ["docs/readme.md", "images/"]}

// Response
{"restored": 2}

Restores items from trash by clearing trashed_at. Folder restore cascades to all children.

Empty Trash

DELETE /drive/trash
Authorization: Bearer <token>

// Response
{"deleted": 5}

Permanently deletes all trashed items. Removes R2 objects and D1 metadata. Shares on deleted objects are also removed. This action is irreversible.

List Trash

GET /drive/trash
Authorization: Bearer <token>

// Response
{
  "items": [
    {"id": "o_...", "name": "readme.md", "path": "docs/readme.md", "trashed_at": 1710700000000, ...}
  ]
}

Recent Files

GET /drive/recent
Authorization: Bearer <token>

// Response
{
  "items": [...]
}

Returns the 50 most recently accessed files (by accessed_at), excluding folders and trashed items.

Starred Items

GET /drive/starred
Authorization: Bearer <token>

// Response
{
  "items": [...]
}

Returns all starred, non-trashed items (files and folders).

GET /drive/search?q=readme&type=text&starred=1
Authorization: Bearer <token>

// Response
{
  "query": "readme",
  "items": [...]
}

Search files by name. Optional filters:

ParamDescription
qSearch term (matched against name with LIKE)
typeFilter by content_type prefix (e.g. image, text, application/pdf)
starredSet to 1 to only return starred items

Drive Stats

GET /drive/stats
Authorization: Bearer <token>

// Response
{
  "file_count": 24,
  "folder_count": 14,
  "total_size": 163405923,
  "trash_count": 2,
  "quota": 5368709120
}

Returns storage usage summary. Quota is 5 GB.

Update Description

PATCH /drive/description
Authorization: Bearer <token>
Content-Type: application/json

{"path": "docs/readme.md", "description": "Project overview"}

// Response
{"path": "docs/readme.md", "description": "Project overview"}

All Endpoints

MethodPathDescriptionAuth
POST/actorsRegister actorNo
POST/auth/challengeGet challenge nonceNo
POST/auth/verifyVerify signature, get tokenNo
POST/auth/magic-linkRequest magic linkNo
GET/auth/magic/:tokenVerify magic linkNo
POST/auth/logoutEnd sessionNo
GET/auth/logoutEnd session (link)No
PUT/files/*pathUpload fileYes
GET/files/*pathDownload fileYes
DELETE/files/*pathDelete fileYes
HEAD/files/*pathFile metadataYes
POST/presign/uploadGet presigned upload URLYes
POST/presign/downloadGet presigned download URLYes
POST/presign/completeConfirm presigned uploadYes
POST/foldersCreate folderYes
GET/foldersList rootYes
GET/folders/*pathList folder contentsYes
DELETE/folders/*pathDelete empty folderYes
POST/sharesCreate shareYes
GET/sharesList sharesYes
DELETE/shares/:idRevoke shareYes
GET/sharedFiles shared with meYes
GET/shared/:owner/*pathDownload shared fileYes
PATCH/drive/starStar or unstar itemYes
POST/drive/renameRename file or folderYes
POST/drive/moveMove items to new folderYes
POST/drive/copyDuplicate a fileYes
POST/drive/trashTrash items (soft delete)Yes
POST/drive/restoreRestore items from trashYes
DELETE/drive/trashEmpty trash (permanent)Yes
GET/drive/trashList trashed itemsYes
GET/drive/recentRecently accessed filesYes
GET/drive/starredStarred itemsYes
GET/drive/searchSearch files by nameYes
GET/drive/statsStorage usage statsYes
PATCH/drive/descriptionUpdate file descriptionYes