SDK reference for @zindexzero/sdk
This page covers the whole API for building on Zero. That includes chat, your private knowledge base, browser and mobile clients, the React hook, and account tools. It has no dependencies (it needs no other packages) and is fully typed. Every function below matches the package on npm.
Install
It runs on Node 18+ or any modern browser. It's plain ESM (modern JavaScript modules) with no dependencies.
npm i @zindexzero/sdkIn the browser, you can skip the install and load it from a CDN: https://esm.sh/@zindexzero/sdk (see Browser & mobile).
Get a key
You need a key to use the SDK. Without one, it does nothing, and only we give out keys. Sign up at zindexzero.org/start. Once we approve you, you can make keys from your account. New keys work right away, with a limit of 1,000 requests a month. You can turn a key off at any time.
| Field | Type | Description |
|---|---|---|
| ziz_live_… | secret | Server only. Gets everything: chat, the knowledge base, and premium models. |
| ziz_pub_… | publishable | Safe to put in a browser or mobile app. Chat only. It works only on the sites you list and stops at its monthly limit. |
| ZizHosted | proxy | Gets everything in an app that can't keep secrets. We keep your secret key on our server (see Browser & mobile). |
chat()
This is the main call. Pass a string, or a turn with attachments. You can also pass earlier turns. You get back the reply plus details about the call.
import { Ziz } from "@zindexzero/sdk";
const ziz = new Ziz({ apiKey: process.env.ZIZ_KEY! }); // ziz_live_…
// simplest form
const { text } = await ziz.chat("Summarize this contract");
// full turn: media (vision keys) + prior turns
const res = await ziz.chat(
{ text: "What's in this?", attachments: [{ type: "image", format: "png", data: b64 }] },
[{ role: "user", text: "earlier message" }],
);
console.log(res.modelId, res.escalated, res.usage);Response
| Field | Type | Description |
|---|---|---|
| text | string | The assistant's reply, in markdown. |
| modelId | string | The Bedrock model that answered this turn. |
| escalated | boolean | True when a bigger, pricier model (Sonnet or Opus) answered this turn. |
| usage | { inputTokens, outputTokens } | How many tokens (small chunks of text) went in and out. It never shows dollars. |
| retrieved? | number | How many pieces of your own documents were used. Only shows up on keys with RAG turned on. |
| searched? | true | Only shows up when the web search tool ran (first-party keys, meaning our own apps). |
| sources? | { title, url }[] | The web pages a search found, with repeats removed. Only https links. |
usage only counts tokens. It never shows cost. Your cost in dollars (with the +20% markup already added) comes from account.usage().
Knowledge base (RAG)
RAG means Zero looks things up in your own documents before it answers. On a secret key with RAG turned on, upload your documents. Chat then answers only from your account's content. Each account's documents sit behind their own access rights, so a lookup can never cross into another account's data.
// add text or a base64 file (pdf/docx/csv/xlsx/html/txt/md)
await ziz.docs.add({ text: "Internal policy…", title: "Policy" });
await ziz.docs.add({ file: { data: b64, format: "pdf", name: "handbook.pdf" } });
// list + delete
const { documents } = await ziz.docs.list(); // [{ docId, title, format, createdAt, chunks }]
await ziz.docs.delete(documents[0].docId);Browser & mobile
An app in a browser or on a phone can be picked apart, so it must never hold a ziz_live_ secret key. You have two safe choices:
1 · Publishable key (chat only)
import { Ziz } from "@zindexzero/sdk";
const ziz = new Ziz({ apiKey: "ziz_pub_…" }); // safe to ship; locked to your origins
const { text } = await ziz.chat("Hello");2 · Hosted proxy (all features)
A proxy is a server that passes your calls along. We keep your secret key on our server, and your app calls the proxy by its registered name (its slug). In a browser, the page's Origin(your site's address) decides who gets in. Native apps send an app token.
import { ZizHosted } from "@zindexzero/sdk";
const zh = new ZizHosted({ client: "acme" }); // browser: Origin is the gate
// const zh = new ZizHosted({ client: "acme", appToken: "hat_…" }); // native
const { text } = await zh.chat("Summarize my docs");
await zh.docs.add({ text: "Internal note…", title: "note" });From a CDN
<script type="module">
import { ZizHosted } from "https://esm.sh/@zindexzero/sdk";
const zh = new ZizHosted({ client: "acme" });
console.log(await zh.chat("hi"));
</script>React & React Native
useZero keeps track of the chat for you: the messages, sending, and status. It works with any client (Ziz, ZizHosted). React is a peer dependency, so you install React yourself.
import { useMemo } from "react";
import { ZizHosted } from "@zindexzero/sdk";
import { useZero } from "@zindexzero/sdk/react";
function Chat() {
const client = useMemo(() => new ZizHosted({ client: "acme" }), []);
const { messages, send, status, error, reset } = useZero(client);
// render messages; call send(text) on submit; status: "idle" | "sending"
}Account tools (server only)
Sign in with your ZiZ account to manage keys, features, personas, limits, usage, and your style profile from code. You don't need a dashboard. This code holds your account login, so never ship it in a browser bundle.
import { signIn } from "@zindexzero/sdk";
const account = await signIn({ email: process.env.ZIZ_EMAIL!, password: process.env.ZIZ_PW! });
const { keys } = await account.keys.list();
const { key } = await account.keys.create({ kind: "secret", label: "prod server" });
await account.keys.setFeature(key, { smart: true, vision: true });
await account.keys.setPersona(key, "You are Acme's warm, concise support agent.");
const { totalCostUsd } = await account.usage(); // +20% marked up server-side| Field | Type | Description |
|---|---|---|
| keys.list() | → { keys, provisioned? } | All your keys. The first call may also include your starter keys in full. You see those only once. |
| keys.create(opts) | → { key, view } | Make a key. You get the raw key only once, so save it right away. { kind: "secret" | "public", origins?, label? }. |
| keys.enable / disable / revoke | (keyId) | Turn a key on or off, or shut it down for good. |
| keys.addOrigin / removeOrigin | (keyId, origin) | Change which sites a public key works on. |
| keys.setFeature(keyId, flags) | { smart, vision, max, learn } | Turn premium models on or off for a secret key. |
| keys.setPersona / clearPersona | (keyId, persona) | Set the role and voice the assistant uses ("" clears it). We treat it as data, so it can't override safety rules. |
| caps.request(keyId, n, reason?) | → request | Ask us to raise a key's limit. You can't raise it yourself. |
| usage() | → { totalCostUsd, keys[] } | This month's cost, with our +20% markup already added on the server. |
| profile.get / set / clear | (style) | Read, edit, or clear the style guide Zero learned for your account. |
Type reference
ZizKeyView
This is how a key looks when your account tools list it. It never shows the raw key or its hash.
| Field | Type | Description |
|---|---|---|
| keyId | string | An id that never changes, used to manage the key. It is never the key itself or its hash (a scrambled copy). |
| kind | "secret" | "public" | Secret keys go on your server. Public keys go in a browser widget and only work on the sites you list. |
| status | "active" | "disabled" | A disabled key gets a 403 error on every call. |
| allowedOrigins | string[] | The sites (origins) a public key works on. Empty for secret keys. |
| quota / quotaUsed | number | null | Your monthly request limit and how much you've used. null means no limit. |
| smartEnabled | boolean | Uses Sonnet on hard turns (secret keys only). |
| visionEnabled | boolean | Uses Nova on image and document turns (secret keys only). |
| maxEnabled | boolean | Moves to Opus when Sonnet says a task is too hard for it (secret keys only, costs more). |
| learnEnabled | boolean | Learns the writing style used with this key. It adds to your cost. |
| persona | string | The role and voice the assistant uses for this key ("" if none). |
| createdAt | string | When the key was made, as an ISO-8601 timestamp. |
Errors
Both error types have a .url. Your app can use it to send the user to sign up or sign in again.
| Field | Type | Description |
|---|---|---|
| ZizNoKeyError | .url | The key was missing or wrong when you made the client. .url links to the sign-up page so your app can send the user there. |
| ZizApiError | .status, .url? | The API sent back a 401, 403, or other 4xx error. The key may be expired or disabled, over its limit, the wrong type, or used from a blocked site. .url is set when the key or sign-in failed. |
Limits & cost
Our server enforces these limits and has the final say. ZIZ_LIMITS holds a copy so your code can check them too.
| Field | Type | Description |
|---|---|---|
| maxAttachmentsPerTurn | 4 | Images or documents allowed per turn. |
| maxAttachmentBytes | 4,500,000 | Size limit per attachment after decoding (~4.5 MB). |
| maxHistoryTurns | 20 | Earlier turns you can include (text only). |
| maxMessageChars | 8,000 | Characters per message. |
Cost: chat().usage only counts tokens. Dollar amounts come only from account.usage() or GET /v1/portal/usage, with the +20% service fee already added. The SDK has no price list built in.
Start building
Installing takes one command, and a key takes a minute to make. The package README explains why it's built this way and how it keeps data safe.