client.kv
See the Storage guide for usage and
patterns. For files, use client.storage.
Methods
Section titled “Methods”set(collection, id, value, opts?)
Section titled “set(collection, id, value, opts?)”set<T>(collection: string, id: string, value: T, opts?: { encrypt?: boolean }): Promise<void>Stores value under collection/id. Encrypted at rest by default; pass
{ encrypt: false } to store plaintext. Needs an unlocked identity for
encrypted writes.
get(collection, id)
Section titled “get(collection, id)”get<T>(collection: string, id: string): Promise<T | null>Returns the value (transparently decrypted) or null if absent.
delete(collection, id)
Section titled “delete(collection, id)”delete(collection: string, id: string): Promise<boolean>Removes the key; resolves to whether it existed.
list(collection)
Section titled “list(collection)”list(collection: string): Promise<string[]>Returns the ids in a collection (not values). The server filters by the
collection and returns its keys a page at a time, which list follows to the
end; a collection of up to 1,000 keys is one request. There is no server-side
query on values — filter client-side after fetching (see
Querying).
keys(prefix?)
Section titled “keys(prefix?)”keys(prefix?: string): Promise<string[]>Returns the full keys (todos/t1, not t1) in the signed-in user’s space
that start with prefix, or every key when it is omitted. Values are not
fetched. The space is shared by every app the user signs into, so expect keys
you did not write: the VFS’s vfs/…, version control’s
vcs/…, and the SDK’s own chat-keys and space-keys/….
on(event, handler)
Section titled “on(event, handler)”on(event: "change", handler: (e: StorageChangeEvent) => void): () => voidSubscribes to the realtime change feed for the signed-in user (across devices).
Returns an unsubscribe function. Requires a WebSocket global.
interface StorageChangeEvent<T = unknown> { collection: string; id: string; type: "set" | "delete"; data: T | null; // decrypted value on "set"; null on "delete"}query(...)
Section titled “query(...)”Reserved. Server-side query is intentionally unsupported (encrypted-at-rest);
calling it throws. Use list() + client-side filtering.
Offline
Section titled “Offline”In a browser, client.kv is offline-aware (see client.offline).
set and delete write the local cache first. If the server can’t be reached the
write is queued and replayed on reconnect (delete then resolves true
optimistically). A response from the server — including a refusal — is never
queued: it throws. get falls back to the cache only when the server is
unreachable, and keys / list merge the server’s keys with un-synced local
ones.
Errors
Section titled “Errors”| Message contains | Meaning |
|---|---|
not signed in | No active session — sign in first. |
identity | Encrypted op needs an unlocked identity — login() or unlock(). |
HttpError | The server refused the request; carries status and body. |
PaymentRequiredError | A set was refused for payment (paid-only app on a Free user, or a past-due payment) — see Errors. delete still works. |
no \WebSocket` global` | on() needs a WebSocket (browsers; Node 22+ or a shim). |