StateJar docs

Getting started

From a new account to a model that remembers, in seven steps — sign up, verify your address, make an API key, install the package, sign in from the terminal, remember and recall, and see your memory in the console. Each step has a recording of it running.

The short answer

Make an account with your e-mail address, install statejar, run statejar login once, then call ingest to store what a message says and recall to get the memory a question needs. recall gives you memory_context, which you put in front of your own model as its system message. Your code calls your model, and its key never reaches StateJar.

Every recording on this page is a real run of StateJar on one machine, in one throwaway account: the site at localhost:18173 and the API at 127.0.0.1:18100, where statejar.com has statejar.com and api.statejar.com. Each caption says when it was recorded and how.

1. Sign up

Open the sign-up page and enter your e-mail address, then choose Send me a code. StateJar e-mails you a one-time code. Your account is made only when you type that code in, so every account starts from an address that was proved.

The sign-up page: an address typed, Send me a code pressed, and the page saying a message is on its way
Sign up with your e-mail. The sign-up page of this site: an address typed, Send me a code pressed, and the page saying a message is on its way. Recorded 27 Oct 2026 in Chromium, on this site built from the same code, against a local StateJar server: every frame is a screenshot of the real page; waits for the server are shortened. Full size

If the sign-up page offers only a password, that server cannot send mail yet. Sign up with a password and go on to step 3.

2. Verify your e-mail

The message holds an 8-digit code that works for 10 minutes, once. Type it in and choose Create my account. You are signed in, and the account exists from this moment. The next page asks for a display name and the like, all optional.

The message with the code in a test inbox, the code typed on the sign-up page, and the account made
Verify your e-mail. The message the server sent, in a test inbox on the recording machine (the server sent it over SMTP to a mail receiver there, not to the internet), its code typed into the sign-up page, and the account made: the next page is the optional profile step. Recorded 27 Oct 2026 in Chromium, on this site built from the same code, against a local StateJar server: every frame is a screenshot of the real page; waits for the server are shortened. Full size

The recording reads the code from a test inbox on the same machine: the server sent the message over SMTP to a mail receiver there, not to the internet. Yours arrives in your own inbox. If it does not, look in the spam folder, or choose Send a new code.

3. Create an API key

A developer key is how your code calls StateJar from a server or CI. On API keys, under Developer API, give the key a name, choose how long it lives (7 days, 30 days, 1 year or never), and choose Generate key. The key is shown once: copy it into your secret store, or into STATEJAR_API_KEY. StateJar keeps only its SHA-256 hash.

The API keys page: a key named and generated, and the dialog that shows it once, the key blurred in the recording
Create an API key. The API keys page: a developer key named and generated, and the dialog that shows it once. The key is blurred in the recording. Recorded 27 Oct 2026 in Chromium, on this site built from the same code, against a local StateJar server: every frame is a screenshot of the real page; waits for the server are shortened. Full size

On your own machine you do not have to copy a key: step 5 stores one for you.

4. Install the package

pip install statejar

The package is the Python SDK and the statejar command. For JavaScript, npm install statejar gives you the Node SDK (Node 20.3 or later).

A new virtualenv, the statejar package installed, and statejar --version
Install the statejar package. A new virtualenv, then pip install of statejar 0.7.0 as built from StateJar's repository (taken from ~/dist, which the recording lists first), then statejar --version. From PyPI, pip install statejar installs the current release, 0.6.0, until 0.7.0 is published. Recorded 27 Oct 2026 against a local StateJar server; the output is real, with pauses over 3 s cut to 3 s. Full sizeThe recording (.cast)

5. Sign in from the terminal

statejar login
statejar whoami

statejar login prints a link with a code, opens it in your browser where it can, and waits. On that page, signed in, check the code and the device's name, and choose Approve. The terminal then receives a developer key for this machine. The key lasts a year, reaches only the memory API, and is stored in your keychain or in a file only you can read. Your password never goes through the terminal.

statejar login printing the link and its code, the approval arriving, then statejar whoami naming the account and the key's last four characters
Sign in from the terminal. statejar login prints the approval link with its code and waits. The code is approved on the site (the next recording), the terminal stores a key and prints its last four characters, and statejar whoami names the account. Recorded 27 Oct 2026 against a local StateJar server; the output is real, with pauses over 3 s cut to 3 s. Full sizeThe recording (.cast)
The approval page for the code the terminal printed, Approve pressed, and the key's last four characters shown
Approve the terminal's sign-in. The approval page for the code statejar login printed: the code and the device's name shown, Approve pressed, and the new key's last four characters and expiry. Recorded 27 Oct 2026 in Chromium, on this site built from the same code, against a local StateJar server: every frame is a screenshot of the real page; waits for the server are shortened. Full size

6. Remember and recall

ingest stores the facts a message states, as typed fields, never the message itself. recall returns the memory a question needs as memory_context. With no key in the code, the SDK uses the one statejar login stored.

from statejar import StateJar

# the key comes from `statejar login` or STATEJAR_API_KEY; one tag per conversation
sj = StateJar(session_tag="user-42")

sj.ingest("I'm Meera from Pune and I prefer email.")    # typed facts, no transcript
sj.ingest("My budget is ₹3,500.")

hit = sj.recall("What is my budget?", audit=True)       # what the question needs
print(hit["handle_used"])        # shm_… — a SHA-256 of the canonical state
print(hit["memory_context"])     # the system message for YOUR model, nothing else
The first-turn example run with python: the handle, then memory_context with the name, city, contact preference and budget
A first turn with the Python SDK. The first-turn example with the key statejar login stored, on statejar 0.7.0 as built from StateJar's repository (PyPI's 0.6.0 has the same calls): two messages in, one question out, then the handle and the memory_context your model gets, the whole state since it is small. The account already held these facts from the terminal, so nothing new is stored and the handle is the one statejar add printed. Recorded 27 Oct 2026 against a local StateJar server; the output is real, with pauses over 3 s cut to 3 s. Full sizeThe recording (.cast)

The same in JavaScript, with the key in STATEJAR_API_KEY:

import { StateJarClient } from "statejar";

const sj = new StateJarClient({
  baseUrl: process.env.STATEJAR_BASE_URL ?? "https://api.statejar.com/api/v1",
  // apiKey: STATEJAR_API_KEY is read automatically in Node (never in a browser)
});

const tag = "user-42";                     // one tag per conversation
await sj.ingest({ sessionTag: tag, text: "I'm Meera from Pune and I prefer email." });
await sj.ingest({ sessionTag: tag, text: "My budget is ₹3,500." });

const query = "What is my budget?";
const hit = await sj.recall({ sessionTag: tag, query, audit: true });
console.log(hit.handle_used);       // shm_…
console.log(hit.memory_context);    // the system message for your model
The same example in JavaScript, after npm install: the same handle and the same memory_context
A first turn with the Node SDK. npm install of the statejar package 0.3.0 as built from StateJar's repository (npm serves 0.2.1, which has the same calls), then the first-turn example in JavaScript, its key the one statejar login stored, read into STATEJAR_API_KEY. Same account and facts as the Python run, so it ends on the same handle. Recorded 27 Oct 2026 against a local StateJar server; the output is real, with pauses over 3 s cut to 3 s. Full sizeThe recording (.cast)

The handle (shm_…) is the SHA-256 of the stored facts, so the same facts give the same handle on any machine. That is why the Python and JavaScript runs end on the same handle. To put memory_context in front of Claude, OpenAI, Gemini or a model on your own machine, see any LLM provider.

7. See your memory in the console

The Dashboard counts your sessions, versions and disclosures, and lists the newest handles with the scope each came from. The Audit log lists every disclosure with its handle and the fields it sent. Replay on an entry re-derives the handle from the stored state and shows the exact facts the model was given.

The dashboard after the steps above, its newest handles, then the audit log with the newest disclosure replayed: byte-identical, and the facts it sent
Your memory in the console. The dashboard after the steps above, counting sessions, versions and disclosures and listing the newest handles with their scopes; then the audit log, its newest disclosure replayed: the handle re-derived from the stored state, byte-identical, and the facts that disclosure sent. Recorded 27 Oct 2026 in Chromium, on this site built from the same code, against a local StateJar server: every frame is a screenshot of the real page; waits for the server are shortened. Full size

Questions

This page as Markdown: /docs/getting-started.md