KV storage
Key-value namespaces for config, sessions, feature flags and cached answers, read and written over HTTPS.
Create a namespace and a token
- Open KV in the dashboard sidebar and choose New namespace. Give it a name; apps use its id (kvns_…).
- Under KV tokens choose New token. Copy it right away: it is shown only once, and Rimbra keeps only a hash and the last few characters.
- Add the token to your application as a secret variable, for example RIMBRA_KV_TOKEN, and the namespace id as RIMBRA_KV_NAMESPACE.
Read and write
Send the token as Authorization: Bearer. Values are raw bytes in the request and response body, so text, JSON and binary all work. Keys go in the path, URL-encoded, so a key like user/42 becomes user%2F42.
bash
KV=https://api.rimbra.app/api/kv/v1/namespaces/$RIMBRA_KV_NAMESPACE
# Write a value that expires in an hour
curl -X PUT "$KV/values/session:abc?ttl=3600" \
-H "Authorization: Bearer $RIMBRA_KV_TOKEN" \
--data-binary '{"user":42}'
# Read it (404 when missing or expired)
curl "$KV/values/session:abc" -H "Authorization: Bearer $RIMBRA_KV_TOKEN"
# Delete it
curl -X DELETE "$KV/values/session:abc" -H "Authorization: Bearer $RIMBRA_KV_TOKEN"From Node
js
const KV = `https://api.rimbra.app/api/kv/v1/namespaces/${process.env.RIMBRA_KV_NAMESPACE}`;
const auth = { Authorization: `Bearer ${process.env.RIMBRA_KV_TOKEN}` };
export async function kvGet(key) {
const res = await fetch(`${KV}/values/${encodeURIComponent(key)}`, { headers: auth });
return res.ok ? res.text() : null;
}
export async function kvSet(key, value, ttlSeconds) {
const q = ttlSeconds ? `?ttl=${ttlSeconds}` : "";
await fetch(`${KV}/values/${encodeURIComponent(key)}${q}`, { method: "PUT", headers: auth, body: value });
}Endpoints
All paths start with /api/kv/v1/namespaces/{namespace_id}.
| Request | What it does |
|---|---|
| GET /values/{key} | The value as raw bytes. Metadata comes back in the X-Kv-Metadata header and the expiry (unix seconds) in X-Kv-Expiration. |
| PUT /values/{key} | Write the request body as the value. Optional ?ttl=seconds or ?expiration=unix-time, and X-Kv-Metadata with up to 1 KB of JSON. |
| DELETE /values/{key} | Remove the key. Deleting a key that does not exist is not an error. |
| GET /keys?prefix=&cursor=&limit= | Keys in order with size, expiry and metadata, up to 1,000 a page. When complete is false, pass the returned cursor for the next page. |
| POST /bulk | Up to 10,000 writes and deletes at once: {"put":[{"key","value","base64","ttl","expiration","metadata"}],"delete":["key"]}. Writes are all-or-nothing. |
| GET /api/kv/v1/namespaces | Your namespaces with their key counts and size. |
Limits
- Keys: up to 512 bytes of UTF-8. Values: up to 25 MB. Metadata: up to 1 KB of JSON.
- Expiry: at least 60 seconds away. Expired keys read as missing at once and are cleared within minutes.
- Reads and writes are counted per UTC day; a list counts as a read, and each item in a bulk request as one write.
- What you store in KV counts toward your plan’s storage, the same pool as application files and databases.
| Plan | Namespaces | Reads a day | Writes a day |
|---|---|---|---|
| Free | 1 | 100,000 | 1,000 |
| Launch | 10 | 1,000,000 | 1,000,000 |
| Pro | 50 | 10,000,000 | 10,000,000 |
| Scale | 200 | 100,000,000 | 100,000,000 |
How it stores your data
KV lives in Rimbra’s own database in the region, so a read right after a write always sees it, and a bulk write lands all at once or not at all. It is backed up with the rest of your workspace.
Your apps on Rimbra reach the API over the same network, so reads are fast. For values your app reads on every request, keep a short in-memory cache in front of it.
