Quick start
Jers is a hosted API at https://api.getjers.com. There is nothing to install or run. Three steps.
1. A key
Write to ceyoualigator@gmail.com with a sentence about what you want to decide; you get a key and your starting credit. Keep it in JERS_API_KEY. Keys start with jj_live_; only their hash is stored.
2. A decision
curl -s https://api.getjers.com/v1/systemone \
-H "Authorization: Bearer $JERS_API_KEY" -H "Content-Type: application/json" \
-d '{
"state": {"message": "We were charged twice for September again. We just want the money back."},
"model": "jers-latest",
"questions": {
"route": {"type": "choice", "instructions": "Which team should handle this?",
"criteria": {"billing": "Charges and refunds", "support": "Product problems", "sales": "New licences"}},
"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"]}
}
}'
The answer, measured on 2026-09-23 through a gateway and product started from this repository (jers-latest resolved to jers, whose router picked the English checkpoint). engine.runtime, the engine's own metadata, is left out here; the engine adds fields of its own, such as action, which Jers passes through. The warning says that route has no option for a message that fits none of the three; add "other": "None of these" and it goes away:
{
"decision_id": "dec_02561a958a6ea3a255a69a71",
"model": "jers",
"engine": {
"name": "jers",
"checkpoint": "english"
},
"answers": {
"route": {
"type": "choice",
"choice": "billing",
"probabilities": {
"billing": 0.992,
"support": 0.005,
"sales": 0.002
},
"confidence": 0.955,
"action": {
"act_probability": 1.0
}
},
"refund": {
"type": "noul",
"noul": 0.897,
"confidence": 0.897,
"action": {
"act_probability": 1.0
}
},
"urgency": {
"type": "score",
"score": 1.671,
"legend": {
"0": "Can wait a week",
"1": "Should be handled today",
"2": "Blocking the customer now"
},
"probabilities": {
"0": 0.008,
"1": 0.313,
"2": 0.679
},
"confidence": 0.396,
"action": {
"act_probability": 1.0
}
}
},
"usage": {
"input_characters": 487,
"questions": 3,
"answers": 3,
"answers_billed": 3,
"engine_answers": 3,
"memory_lines_used": 0,
"memory_lines_seen": 0,
"engine_ms": 36.0,
"cached": false,
"state_tokens": 20,
"state_tokens_read": 20,
"state_truncated": false,
"input_tokens": 163,
"cost": 3e-05,
"currency": "USD",
"balance": 4.99994,
"gateway_ms": 37.1
},
"warnings": [
{
"code": "no_other_option",
"question": "route",
"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"
}
],
"reading": {
"route": {
"state_tokens": 20,
"read": 20,
"room": 480,
"chars_read": 86,
"truncated": false
},
"refund": {
"state_tokens": 20,
"read": 20,
"room": 478,
"chars_read": 86,
"truncated": false
},
"urgency": {
"state_tokens": 20,
"read": 20,
"room": 475,
"chars_read": 86,
"truncated": false
}
}
}
reading says how much of the state the engine read for each question (all of it here); decision_id is what you send back with POST /v1/feedback once you know the right answer.
3. A memory
Write what you know about the subject once, then name it in decisions:
curl -s https://api.getjers.com/v1/memory/remember -H "Authorization: Bearer $JERS_API_KEY" -H "Content-Type: application/json" \
-d '{"subject": "acme", "text": "ACME Logistics holds an enterprise contract; refunds for ACME go to the billing team within one business day.\nACME'\''s account is handled by the enterprise desk."}'
Add "subject": "acme" and "memory": {"compare": true} to the decision request. The answer gains a memory block: the lines used (hits), how many the engine read (lines_seen), the answer without memory, and what changed.
Python
The Python SDK is not on PyPI yet; this is how it reads once it is (the requests above work today).
from jers import JersClient, Choice, Noul, Score
with JersClient() as client:
r = client.system_one(
state={"message": "We were charged twice for September again."},
questions={"route": Choice("Which team should handle this?", {"billing": "Charges and refunds", "support": "Product problems"}),
"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, r.memory.lines_used, r.usage.cost)