FOR DEVELOPERS

One request to upload.
Zero to serve.

REST API for files. No SDK, no buckets, no egress fees. Globally distributed. Claude and ChatGPT connected over MCP.

terminal
# upload
$ curl -X POST /files/uploads \
    -H "Authorization: Bearer $TOKEN" \
    -d '{"path":"assets/logo.svg"}'

# share it
$ curl -X POST /files/share \
    -d '{"path":"assets/logo.svg"}'
→ /s/k7f2m · expires 24h
QUICKSTART

30 seconds to first upload

1
Get a token
Register with your Ed25519 key or email. Returns a bearer token.
POST /auth/challenge → POST /auth/verify
2
Upload a file
Initiate upload, PUT to presigned URL, confirm.
POST /files/uploads → PUT <signed-url> → POST /files/uploads/complete
3
Share it
Generate a time-limited link. Anyone can access it, no auth needed.
POST /files/share → GET /s/:token
THE API

Everything under /files

One resource namespace. Standard HTTP methods. Paths are your filesystem.

Store

POST /files/uploads
GET /files/{path}
HEAD /files/{path}
DEL /files/{path}

Organize

GET /files?prefix=
GET /files/search?q=
POST /files/move
GET /files/stats

Share

POST /files/share
GET /s/:token
That’s the whole API. Full reference →
ANY LANGUAGE

No SDK. Just HTTP.

# initiate upload
curl -X POST https://storage.liteio.dev/files/uploads \
  -H "Authorization: Bearer $TOKEN" \
  -d '{"path":"data/config.json","content_type":"application/json"}'

# download (follows 302 redirect)
curl -L https://storage.liteio.dev/files/data/config.json \
  -H "Authorization: Bearer $TOKEN"
// initiate upload, then PUT to the presigned URL
const { upload_url } = await fetch("https://storage.liteio.dev/files/uploads", {
  method: "POST",
  headers: { Authorization: `Bearer ${TOKEN}` },
  body: JSON.stringify({ path: "data/config.json" }),
}).then(r => r.json());

await fetch(upload_url, { method: "PUT", body: file });
import requests

# initiate upload
res = requests.post(
    "https://storage.liteio.dev/files/uploads",
    headers={"Authorization": f"Bearer {TOKEN}"},
    json={"path": "data/config.json"},
)
upload_url = res.json()["upload_url"]

# upload directly to object store
requests.put(upload_url, data=file_bytes)
// initiate upload
body := strings.NewReader(`{"path":"data/config.json"}`)
req, _ := http.NewRequest("POST",
    "https://storage.liteio.dev/files/uploads", body)
req.Header.Set("Authorization", "Bearer "+token)

resp, _ := http.DefaultClient.Do(req)
// parse upload_url from response, PUT file there
MCP PROTOCOL

Your files in Claude and ChatGPT.

8 MCP tools built in. Connect once, then read, write, search, and share files from any MCP client.

"Save this as report.md"storage_write
"What files do I have?"storage_list
"Find all CSV files"storage_search
"Share the report"storage_share
"How much space am I using?"storage_stats
"Move it to /work"storage_move
Claude
Settings → Integrations → Add
https://storage.liteio.dev/mcp
ChatGPT
Settings → Connected apps
https://storage.liteio.dev/mcp
claude.ai
Save the meeting notes as notes/2025-03-20.md
Done! Saved notes/2025-03-20.md (4.2 KB)
What files do I have in notes/?
Your notes/ folder has 3 files:
• 2025-03-20.md · 4.2 KB
• 2025-03-18.md · 2.1 KB
• ideas.txt · 890 B
Share the latest one
Here’s your link:
storage.liteio.dev/s/m9x2k
Expires in 24 hours.
ARCHITECTURE

Direct transfer. No proxy.

File bytes never touch our servers. Auth is inline, data goes direct to the object store.

Your App
curl · fetch · CLI
HTTPS
API Server
Auth + presign · <50ms
Presigned
Object Store
Durable · zero egress cost
Inline auth Token verification before presigning. Sub-millisecond overhead.
Direct transfers Clients upload and download directly via presigned URLs. No proxy bandwidth.
Metadata layer File index, sessions, and shares in SQLite. Fast reads, strong consistency.
USE CASES

Drop it into any stack.

FRONTEND

App file uploads

Get a presigned URL from the API, upload from the browser to the object store. No server proxy. Works with React, Vue, Svelte, vanilla JS.

DEVOPS

CI/CD artifacts

Push build outputs, deploy bundles, and test reports from GitHub Actions or any CI. One curl per artifact. Scoped API keys for each pipeline.

MCP

AI workflows

Let Claude or ChatGPT save research, code snippets, and generated files directly to your storage. Search and share them by asking.

SECURITY

Secure by default. No passwords stored.

Ed25519 auth Public key challenge-response. No shared secrets.
Scoped API keys Path-prefix restrictions. sk_* format, 90-day TTL.
Signed share links Time-limited URLs. 60s to 7 days. Auto-expire.
OAuth 2.0 + PKCE Standard flow for third-party apps. Dynamic client registration.
Rate limiting Per-endpoint sliding window. Auth: 10/min. Uploads: 100/min.
Audit logging Every action logged with actor, resource, and timestamp.

Start building.

One request to upload. Zero egress to serve. MCP connection in a minute.

# Storage Developer Guide Base URL: https://storage.liteio.dev Storage is a file storage API. Upload a file in one HTTP request, serve it globally with zero egress fees. No SDK required — every endpoint is plain HTTP with JSON. ## Quickstart Three steps from zero to your first uploaded file. ### 1. Get a token Register with your Ed25519 public key or request a magic link via email. Both return a bearer token.
bash # Ed25519 key auth curl -X POST https://storage.liteio.dev/auth/challenge \ -H "Content-Type: application/json" \ -d '{"actor":"your-username","public_key":"base64-ed25519-pubkey"}' # Then verify the signature curl -X POST https://storage.liteio.dev/auth/verify \ -H "Content-Type: application/json" \ -d '{"actor":"your-username","signature":"base64-signature"}'
### 2. Upload a file Initiate the upload to get a presigned URL, PUT the file bytes there, then confirm.
bash # Step 1: Initiate curl -X POST https://storage.liteio.dev/files/uploads \ -H "Authorization: Bearer $TOKEN" \ -H "Content-Type: application/json" \ -d '{"path":"assets/logo.svg","content_type":"image/svg+xml"}' # Step 2: Upload to the presigned URL returned in step 1 curl -X PUT "$UPLOAD_URL" \ -H "Content-Type: image/svg+xml" \ --data-binary @logo.svg # Step 3: Confirm curl -X POST https://storage.liteio.dev/files/uploads/complete \ -H "Authorization: Bearer $TOKEN" \ -H "Content-Type: application/json" \ -d '{"path":"assets/logo.svg"}'
### 3. Share it Generate a time-limited public link. Anyone with the link can download — no auth required.
bash curl -X POST https://storage.liteio.dev/files/share \ -H "Authorization: Bearer $TOKEN" \ -H "Content-Type: application/json" \ -d '{"path":"assets/logo.svg","ttl":86400}' # Response: { "url": "https://storage.liteio.dev/s/k7f2m", "expires_at": 1711065600000 }
## API Surface Everything lives under /files. Standard HTTP methods. Paths are your filesystem. ### Store
MethodEndpointDescription
POST/files/uploadsInitiate a file upload (returns presigned PUT URL)
POST/files/uploads/completeConfirm upload after PUT completes
GET/files/{path}Download a file (302 redirect to presigned URL)
HEAD/files/{path}Get file metadata without downloading
DELETE/files/{path}Delete a file or folder
### Organize
MethodEndpointDescription
GET/files?prefix={folder}List files in a folder
GET/files/search?q={query}Search files by name
POST/files/moveRename or move a file
GET/files/statsGet total file count and bytes used
### Share
MethodEndpointDescription
POST/files/shareCreate a temporary public link (default: 1h, max: 7d)
GET/s/{token}Access a shared file (no auth required)
### Authentication
MethodEndpointDescription
POST/auth/challengeRequest an Ed25519 challenge nonce
POST/auth/verifyVerify signature and get session token
POST/auth/magicSend a magic link to an email address
POST/auth/registerRegister a new account with Ed25519 public key
POST/auth/logoutInvalidate current session
### API Keys
MethodEndpointDescription
POST/auth/keysCreate a scoped API key
GET/auth/keysList all API keys
DELETE/auth/keys/{id}Revoke an API key
## Code Examples ### curl
bash # Upload a file curl -X POST https://storage.liteio.dev/files/uploads \ -H "Authorization: Bearer $TOKEN" \ -H "Content-Type: application/json" \ -d '{"path":"data/config.json","content_type":"application/json"}' # Download (follows 302 redirect) curl -L https://storage.liteio.dev/files/data/config.json \ -H "Authorization: Bearer $TOKEN"
### JavaScript
javascript // Initiate upload, then PUT to the presigned URL const { upload_url } = await fetch("https://storage.liteio.dev/files/uploads", { method: "POST", headers: { Authorization: `Bearer ${TOKEN}` }, body: JSON.stringify({ path: "data/config.json" }), }).then(r => r.json()); await fetch(upload_url, { method: "PUT", body: file });
### Python
python import requests res = requests.post( "https://storage.liteio.dev/files/uploads", headers={"Authorization": f"Bearer {TOKEN}"}, json={"path": "data/config.json"}, ) upload_url = res.json()["upload_url"] requests.put(upload_url, data=file_bytes)
### Go
go body := strings.NewReader(`{"path":"data/config.json"}`) req, _ := http.NewRequest("POST", "https://storage.liteio.dev/files/uploads", body) req.Header.Set("Authorization", "Bearer "+token) resp, _ := http.DefaultClient.Do(req) // Parse upload_url from JSON response, then PUT file there
## MCP Protocol Storage has 8 MCP tools built in. Connect once, then read, write, search, and share files from any MCP client. ### Available Tools
ToolDescription
storage_readRead a file's contents
storage_writeWrite or overwrite a file
storage_listList files in a folder
storage_searchSearch files by name
storage_shareCreate a temporary public link
storage_moveMove or rename a file
storage_deleteDelete a file
storage_statsGet storage usage statistics
### Connect Claude 1. Open Settings > Integrations 2. Click Add custom connector 3. Enter URL: https://storage.liteio.dev/mcp 4. Authorize with your email ### Connect ChatGPT 1. Open Settings > Connected apps 2. Click Add app > Add by URL 3. Enter URL: https://storage.liteio.dev/mcp 4. Sign in with your email ### Connect Claude Desktop Add to your claude_desktop_config.json:
json { "mcpServers": { "storage": { "command": "npx", "args": ["-y", "mcp-remote", "https://storage.liteio.dev/mcp"] } } }
## Architecture
Your App ──HTTPS──> API Server ──Presigned URL──> Object Store (R2) (auth + sign) (durable, zero egress)
File bytes never touch the API server. Your app sends an authenticated request, the API returns a presigned URL in under 50ms, and your app uploads or downloads directly to the object store. - Inline auth — Token verification happens before presigning. Sub-millisecond overhead. - Direct transfers — Clients upload and download directly via presigned URLs. No proxy bandwidth. - Metadata layer — File index, sessions, and shares stored in SQLite. Fast reads, strong consistency. ## Security - Ed25519 auth — Public key challenge-response. No shared secrets. - Scoped API keys — Path-prefix restrictions. sk_* format, 90-day TTL. - Signed share links — Time-limited URLs, 60 seconds to 7 days, auto-expire. - OAuth 2.0 + PKCE — Standard flow for third-party apps. Dynamic client registration. - Rate limiting — Per-endpoint sliding window. Auth: 10/min. Uploads: 100/min. - Audit logging — Every action logged with actor, resource, and timestamp. ## Links - API Reference - CLI Documentation - Pricing - Developer Guide (human view)