Skip to content

The Client

Client is the single entry point to the SDK. You construct it once and use its three namespaces; they share one session, so signing in once unlocks all of them.

const client = new Client({ apiKey, baseUrl });
client.auth // who is signed in
client.kv // their private key/value data
client.storage // file storage
client.message // realtime + E2E messaging

When a user signs in, the client holds two things, with deliberately different lifetimes:

  • The session token — proves the user is authenticated to the accelerator. Cheap to persist; enough to authorize requests. Survives reloads via your sessionStore.
  • The identity — the derived secret + keypairs. Lets the client prove ownership, derive the at-rest encryption key, and run the messaging ratchet. It is never persisted by default — it’s re-derived from the password at login.

This split is why there are two distinct states after a page reload:

await client.auth.zk.restore(); // ✅ authenticated (token) — but locked
await client.auth.zk.unlock(pw); // ✅ now unlocked — can decrypt + message

A restored session can do anything that only needs the token. Reading encrypted storage or sending E2E messages needs the identity — so you either keep the user fully signed in (in memory) or unlock() with the password when they return.

CredentialHeaderScope
App key (mk_…)X-Muhkoo-KeyIdentifies your app — billing, metering, and which app a request belongs to.
Session tokenX-Muhkoo-SessionIdentifies the end user — authorizes their private data.

The client attaches both automatically. You set the app key once at construction; the session token is managed for you after login. See Identity & app keys.

The client is composed from primitives that remain exported for advanced use — AuthClient, PersonalSpaceClient, FileStorage, BroadcastChannel, EncryptedSession. You rarely need them directly; the client is the supported surface. Reach for a primitive only when you need control the client doesn’t expose.