SeleStorage
SeleStorage
Zero egress fees on downloads, on every plan. Fair use applies, and request and operation limits still apply. See pricing.
The host below is a placeholder; use the host shown in your developer console.
SeleStorage stores files for your app behind a simple HTTPS API. Each account's files are isolated from every other account, and you only ever use a SeleTech API key.
Quickstart
- Create an API key in the console (shown once; copy it immediately).
- Upload a file, read it back, list, delete.
curl
export KEY=ssk_test_xxxxxxxxxxxxxxxxxxxxxxxx
export HOST=https://storage.example.invalid # placeholder until launch
curl -X PUT "$HOST/v1/objects/hello.txt" -H "Authorization: Bearer $KEY" -H "Content-Type: text/plain" --data-binary "hello"
curl "$HOST/v1/objects/hello.txt" -H "Authorization: Bearer $KEY"
curl "$HOST/v1/objects?prefix=he" -H "Authorization: Bearer $KEY"
curl -X DELETE "$HOST/v1/objects/hello.txt" -H "Authorization: Bearer $KEY"
TypeScript
const host = 'https://storage.example.invalid'; // placeholder until launch
const headers = { Authorization: `Bearer ${process.env.SELESTORAGE_KEY}` };
const body = new TextEncoder().encode('hello');
await fetch(`${host}/v1/objects/hello.txt`, { method: 'PUT', headers: { ...headers, 'Content-Type': 'text/plain', 'Content-Length': String(body.length) }, body });
const text = await (await fetch(`${host}/v1/objects/hello.txt`, { headers })).text();
const { objects } = await (await fetch(`${host}/v1/objects?prefix=he`, { headers })).json();
Authentication
Send Authorization: Bearer <key>. Keys start with ssk_live_ or ssk_test_. Test keys see a separate sandbox area and never touch live files. We store only a hash of each key, so a lost key cannot be recovered: create a new one. Each key has scopes: read, write and admin (admin includes the others and can create, rotate and revoke keys). Revoking a key or suspending an account takes effect on the very next request. Keep keys on your server; never put them in a mobile app or web page. Use signed URLs for those.
Endpoints
| Method and path | Scope | What it does |
|---|---|---|
PUT /v1/objects/{key} | write | Upload or replace. Content-Length is required. |
GET /v1/objects/{key} | read | Download. |
DELETE /v1/objects/{key} | write | Delete. |
GET /v1/objects?prefix=&limit=&cursor= | read | List keys under a prefix (up to 1000). |
GET /v1/usage | read | This month's usage and your plan limits. Not metered. |
POST /v1/signed-urls | read or write | Body {"method":"GET"|"PUT","key":"...","expires_in":300}. Returns a temporary URL (1 to 3600 seconds) you can hand to a browser or phone. |
POST /v1/keys, DELETE /v1/keys/{id}, POST /v1/keys/{id}/rotate | admin | Create, revoke, rotate. Rotation revokes the old key immediately. |
Object keys use / as a folder separator, up to 1024 characters. Keys with .., empty segments, backslashes or a leading / are rejected.
Pricing and egress
Zero egress fees on downloads, on every plan. Downloading your files never costs extra. This is subject to fair use, and request and operation limits still apply (see Limits).
Limits
| Plan | Storage | Writes / month | Reads / month | Requests / month | Max object |
|---|---|---|---|---|---|
| Free | 1 GB | 10,000 | 100,000 | 100,000 | 25 MB |
| Starter | 20 GB | 200,000 | 2,000,000 | 3,000,000 | 100 MB |
| Pro | 60 GB | 1,000,000 | 10,000,000 | 9,000,000 | 500 MB |
Limits are hard stops: when you reach one, requests that would exceed it fail with 429 quota_exceeded until the next month or a plan change. We never bill silently past a limit. Plans and prices are provisional: see Pricing.
Errors
Errors are JSON: {"error":{"code":"...","message":"..."}}.
| Status | Code | Meaning |
|---|---|---|
| 400 | invalid_key, invalid_prefix, invalid_request | The key, prefix or body is not valid. |
| 401 | invalid_api_key | Missing, wrong or revoked key. |
| 403 | insufficient_scope, tenant_disabled, invalid_signature, signed_url_expired | The key lacks the scope, the account is suspended, or a signed URL is bad or expired. |
| 404 | not_found | No such object. |
| 411 | length_required | Send Content-Length on uploads. |
| 413 | object_too_large | Over your plan's max object size. |
| 429 | quota_exceeded | A plan limit is reached. The body names the resource (storage, writes, reads, requests), the limit, your usage and your plan, and nothing is charged. |
| 503 | selestorage_disabled | The service is turned off. |