Send a state and typed questions. Get typed answers with probabilities and confidence in one call, no text to parse. Name a subject, and Jers also uses what its memory knows, and shows you what that changed.
Runs on one machine, the one that runs the gateway: the engine and every subject's memory stay there, and nothing is sent to a third party. Input is free; you pay per answer. Built on an open engine (Apache-2.0), acknowledged on the models page.
Request · one question about one message
{
"state": "Hi, you charged me twice for September. Please send the second payment back.",
"questions": {
"refund": {
"type": "noul",
"instructions": "Is the customer asking for money back?"
}
},
"model": "jers-english"
}
Answer · from the gateway, shortened
{
"model": "jers-english",
"engine": {
"checkpoint": "english"
},
"answers": {
"refund": {
"type": "noul",
"noul": 0.934,
"confidence": 0.934,
"action": {
"act_probability": 1.0
}
}
},
"warnings": [],
"usage": {
"answers": 1,
"answers_billed": 1,
"cost": 1e-05,
"currency": "USD"
}
}
Three question types: Choice picks an option, Score places the state on ordered levels, Noul says how likely a statement is true. Every answer carries probabilities, so your code branches, sorts and routes on numbers.
A subject is whatever you decide about: a customer, a user, a player, a device, a case. Write what you know once. Every decision that names the subject shows which lines it used, and can show the answer without them. Forgetting is verified.
Every number on this site was measured and says where. The documentation has a page of what the engine gets wrong, with the measurements, and the examples say when the memory changed nothing.
One request, one response. Code keeps the control flow; Jers answers the judgments inside it.
robust, windows, derive and valueswhen holds and the facts derive computedwindows one pass per windowdecision_id for POST /v1/feedback, which feeds the quality report and calibration| Question type | Ask it when | You get back |
|---|---|---|
| Choice | the answer is one of a set of options (add other) | choice, probabilities per option, confidence |
| Score | the answer is a position on ordered levels, each written as a situation | score, probabilities per level, legend, confidence |
| Noul | the answer is yes or no | noul, the probability of yes, and confidence |
Three of the twenty-five on the examples page. Switch tabs; every answer came from the gateway, shortened for the page.
A department with an other option, a refund check and an urgency score, about one message.
Request
{
"state": "Hi, you charged me twice for September. Please send the second payment back.",
"questions": {
"route": {
"type": "choice",
"instructions": "Which team should handle this?",
"criteria": {
"billing": "Charges, invoices and refunds",
"support": "Product problems",
"sales": "New licences and upgrades",
"other": "None of these"
}
},
"refund": {
"type": "noul",
"instructions": "Is the customer asking for money back?"
},
"urgency": {
"type": "score",
"instructions": "How urgent is this?",
"criteria": [
"Can wait a week",
"Should be handled today",
"Blocking the customer now"
]
}
},
"model": "jers-english"
}Answer
{
"model": "jers-english",
"engine": {
"checkpoint": "english"
},
"answers": {
"route": {
"type": "choice",
"choice": "billing",
"probabilities": {
"billing": 0.954,
"support": 0.027,
"sales": 0.009,
"other": 0.01
},
"confidence": 0.834,
"action": {
"act_probability": 1.0
}
},
"refund": {
"type": "noul",
"noul": 0.934,
"confidence": 0.934,
"action": {
"act_probability": 1.0
}
},
"urgency": {
"type": "score",
"score": 1.557,
"legend": {
"0": "Can wait a week",
"1": "Should be handled today",
"2": "Blocking the customer now"
},
"probabilities": {
"0": 0.016,
"1": 0.411,
"2": 0.573
},
"confidence": 0.318,
"action": {
"act_probability": 1.0
}
}
},
"warnings": [],
"usage": {
"answers": 3,
"answers_billed": 3,
"cost": 3e-05,
"currency": "USD"
}
}The subject is a pump. Its memory says anything above 75 C must be looked at the same day, and the reading is 78 C. Watch the answer: the line alone does not move it, because the engine does not compare numbers. Then derive compares the reading with the limit in code and hands the engine one sentence that says so, and the action changes to a ticket.
With the technician's line only
{
"model": "jers-english",
"engine": {
"checkpoint": "english"
},
"answers": {
"action": {
"type": "choice",
"choice": "ignore",
"probabilities": {
"ignore": 0.397,
"log": 0.199,
"ticket": 0.203,
"stop": 0.201
},
"confidence": 0.037,
"action": {
"act_probability": 1.0
}
}
},
"warnings": [
{
"code": "no_other_option",
"question": "action",
"message": "add an option such as other or none_of_these, so a state that fits nothing is not forced into the least bad option"
},
{
"code": "memory_number_rule",
"message": "the memory line \"Pump-13 had a bearing failure in June at 80 C; anything above 75 C on pump-13 mu\" compares numbers; the engine reads the words, not the arithmetic. Use a rule with a condition, or derive"
}
],
"usage": {
"answers": 1,
"answers_billed": 1,
"cost": 1e-05,
"currency": "USD"
},
"memory": {
"subject": "pump-13",
"lines_used": 1,
"lines_seen": 1,
"hits": [
{
"text": "Pump-13 had a bearing failure in June at 80 C; anything above 75 C on pump-13 must be looked at the same day."
}
],
"without_memory": {
"action": {
"type": "choice",
"choice": "ignore",
"probabilities": {
"ignore": 0.494,
"log": 0.207,
"ticket": 0.127,
"stop": 0.171
},
"confidence": 0.106,
"action": {
"act_probability": 1.0
}
}
},
"changes": {
"action": {
"answer_changed": false,
"with": "ignore",
"without": "ignore",
"top_probability_with": 0.397,
"top_probability_without": 0.494
}
}
}
}With the limit checked in code
{
"model": "jers-english",
"engine": {
"checkpoint": "english"
},
"answers": {
"action": {
"type": "choice",
"choice": "ticket",
"probabilities": {
"ignore": 0.108,
"log": 0.146,
"ticket": 0.706,
"stop": 0.04
},
"confidence": 0.354,
"action": {
"act_probability": 1.0
}
}
},
"warnings": [
{
"code": "no_other_option",
"question": "action",
"message": "add an option such as other or none_of_these, so a state that fits nothing is not forced into the least bad option"
}
],
"usage": {
"answers": 1,
"answers_billed": 1,
"cost": 1e-05,
"currency": "USD"
},
"derived": {
"limit": true
},
"memory": {
"subject": "pump-13",
"lines_used": 1,
"lines_seen": 1,
"hits": [
{
"text": "Pump-13 had a bearing failure in June."
}
]
}
}derive in the request or a memory rule with when, and keep in memory what a person knows, in words. The documentation measures it.An opt-out line was written for the subject, then forgotten with a verified removal, before this decision. The answer uses only what is left.
Request
{
"state": {
"task": "A launch mail is ready for all Fabrikam contacts, including Anna Berg."
},
"subject": "fabrikam-demo",
"memory": {
"compare": true
},
"questions": {
"send": {
"type": "noul",
"instructions": "Should this mail be sent as planned?"
}
},
"model": "jers-english"
}Answer
{
"model": "jers-english",
"engine": {
"checkpoint": "english"
},
"answers": {
"send": {
"type": "noul",
"noul": 0.627,
"confidence": 0.627,
"action": {
"act_probability": 1.0
}
}
},
"warnings": [],
"usage": {
"answers": 1,
"answers_billed": 1,
"cost": 1e-05,
"currency": "USD"
},
"memory": {
"subject": "fabrikam-demo",
"lines_used": 1,
"lines_seen": 1,
"hits": [
{
"text": "Anna Berg is the marketing contact at Fabrikam."
}
],
"without_memory": {
"send": {
"type": "noul",
"noul": 0.753,
"confidence": 0.753,
"action": {
"act_probability": 1.0
}
}
},
"changes": {
"send": {
"with": 0.627,
"without": 0.753,
"shift": -0.1258,
"answer_changed": false
}
}
}
}| Subject | Lines you would write | Decisions that use them |
|---|---|---|
| a customer account | contract terms, who handles it, past incidents | which team, how urgent, escalate or not |
| a user of your app | preferences, opt-outs, plan | send this mail, show this offer |
| a player in a game | deeds, reputation, quests done | how a character treats them |
| a device or machine | normal ranges, last service, known faults | alert, ticket, stop |
| a case or claim | what is already known, who asked to be told | next step, escalate |
POST /v1/memory/remember {"subject": "acme", "text": "ACME holds an enterprise contract; refunds go to billing within one business day."}
POST /v1/memory/rules {"subject": "acme", "when": "open_tickets >= 3", "text": "Escalate ACME to a person."}
POST /v1/systemone {"state": ..., "questions": ..., "subject": "acme", "values": {"open_tickets": 4}, "memory": {"compare": true}}
POST /v1/memory/forget {"subject": "acme", "concept": "enterprise contract"} → verified_forgotten: true
POST /v1/memory/delete {"subject": "acme"}
when, checked in code at every decision on the request's values and the state's fields, with an optional expiry: the engine does not compare numbers or dates. A stop-loss rule took the stop answer from 0.11 (at −10, not fired) to 0.80 (at −30, fired).lines_seen and the warnings say when some were left out. With placebo on, Jers also answers with a neutral line, so you see what the words did: on the escalation case the answer with the real line was 0.62 higher than with a neutral line naming the same subject.Measured, and written up on the rules in memory and memory pages.
Jev is TypeSafe AI's System One model. Jers speaks the same request and answer shape on purpose, so code written for one runs against the other with a new base URL and a model name. What differs:
| Jev | Jers | |
|---|---|---|
| Memory | none; every request is stateless | a memory per subject, with recall evidence, comparison and verified forgetting |
| Where it runs | their cloud | the machine that runs the gateway (yours, if you host it); nothing is sent to a third party |
| Price | per input token, output free | input free; per answer and per memory line written |
| The engine | their own model | an open engine, named with its checkpoint in every answer |
| Speed and cost claims | multiples against language models | measured numbers only, and where they were measured |
The state and the questions cost nothing, however long. You pay per answer and per memory line written. Each question answered is one answer, times the work you ask for: each option order with robust, each window with windows, twice with placebo. usage.answers_billed shows it.
Every priced request is one line in your ledger; GET /v1/usage shows credit, spending and the last requests, and the totals always agree. When credit is used up, decisions answer 402 until it is topped up. A failed request is never charged.
Current prices come with your key. Rate limits are per key, with a Retry-After header when you go over.
Write to ceyoualigator@gmail.com with a sentence about what you want to decide. You get a key, the gateway address, and the current prices.
export JERS_API_KEY=jj_live_...
export JERS_BASE_URL=https://your-gateway.example
curl -s $JERS_BASE_URL/v1/systemone \
-H "Authorization: Bearer $JERS_API_KEY" -H "Content-Type: application/json" \
-d '{"state": "You charged me twice for September. Please send the second payment back.",
"questions": {"refund": {"type": "noul", "instructions": "Is the customer asking for money back?"}}}'
from jers import JersClient, Choice, Noul, Score
with JersClient() as client: # reads JERS_API_KEY, JERS_BASE_URL
r = client.system_one(
state={"message": "We were charged twice for September again.", "account": "ACME Logistics"},
questions={
"route": Choice("Which team should handle this?", {"billing": "Charges and refunds", "support": "Product problems", "other": "None of these"}),
"refund": Noul("Is the customer asking for money back?"),
"urgency": Score("How urgent is this?", ["Can wait a week", "Should be handled today", "Blocking the customer now"]),
},
subject="acme", memory={"compare": True})
print(r.answers["route"].choice, r.answers["route"].confidence)
print(r.answers["refund"].noul, r.answers["urgency"].score)
print(r.memory.lines_used, r.memory.changes, r.usage.cost)
Also: a TypeScript client (JavaScript and TypeScript) and an MCP server with a Claude Code plugin (Claude and MCP).
Then the five-minute guide, the examples and the cookbooks.