Documentation
Getting started
Create an account and copy your key from the dashboard. Send it with every request:
Authorization: Bearer hk_live_...A key is shown once, when it is created. Keep it server-side; never ship it in browser code.
Asking for a decision
POST https://7aasm.com/v1/systemone follows the Jev contract. Send a state and your questions:
state: a string, a JSON object, or a list of strings.questions: an object keyed by names you choose. Each question has a type:choicepicks one key fromcriteria(key → description, up to 255).noulis yes/no and returns the probability of yes. Optionalcriteria:{"true": …, "false": …}.scoreplaces the case on an ordered scale of 2 to 10 levels.
policy(optional): your rules in plain words. The model follows them before its own judgment.
{
"state": "My parcel arrived broken and I want my money back today",
"questions": {
"team": {"type": "choice", "instructions": "Which team handles this?",
"criteria": {"refunds": "Refunds", "parcels": "Damaged parcels", "login": "Sign-in"}},
"angry": {"type": "noul", "instructions": "The customer is angry"},
"level": {"type": "score", "instructions": "How upset",
"criteria": ["Calm", "Annoyed", "Furious"]}
},
"policy": "Damaged parcels go to the parcels team"
}Reading the answer
{
"model": "hasm-cloud/haiku",
"answers": {
"team": {"type": "choice", "choice": "parcels", "confidence": 0.85, "grade": "decided",
"probabilities": {"refunds": 0.08, "parcels": 0.9, "login": 0.02}, "expected_accuracy": 0.97},
"angry": {"type": "noul", "noul": 0.93, "grade": "decided"},
"level": {"type": "score", "score": 1.9, "level": 2, "confidence": 0.84, "grade": "likely",
"legend": {"0": "Calm", "1": "Annoyed", "2": "Furious"}}
},
"usage": {"input_tokens": 612, "output_tokens": 88, "quota_left": 998},
"elapsedMs": 1412,
"hasm": {"request_id": "…", "memory": null, "examples_used": 3,
"calibration": {"team": {"threshold": 0.72, "learned": true, "verdicts": 140, "accuracy": 0.96}}}
}Every answer carries a grade that tells your code what to do with it:
decided: the answer's probability clears the question's threshold and nothing calls for a person. Act on it.likely: the best answer, but confirm it before acting.review: Hasm is not sure. It still returns its best candidate as a hint, with"abstained": true; a person decides.
p_answer is the probability of the answer given — what the grade gates on: a “no” at p(yes) = 0.3 is a 70% answer. confidence is computed from the shape of the distribution with Jev's formulas. expected_accuracy is the accuracy you have actually measured on answers given at that probability. hasm.escalation flags sensitive topics such as money.
Consistency and memory
- Consistency: the same case with the same questions returns the same answer, instantly, from memory, until you correct something or change the questions.
hasm.memoryis"exact". - Corrections stick: once you correct a case, that exact case returns your answer, without calling the model.
- Learning from the first correction: your closest corrected cases ride along as worked examples.
hasm.examples_usedsays how many.
Self-calibration
You never pick thresholds. For each question, Hasm compares the probability it gave with the outcome of every confirmation and correction, then picks the lowest threshold at which answers have met your target accuracy (95% by default; change it in settings).
- Every question starts at a default threshold and switches to a learned one after at least 30 verdicts.
- Accuracy is judged by its plausible lower bound, not the raw rate, so a few lucky verdicts cannot switch automation on.
- If the model turns over-confident on a question, its threshold rises on its own; when it proves itself, the threshold comes down.
GET /v1/accuracyreturns the measured accuracy and the threshold in force for every question.
Accuracy tips
- Use descriptive option keys such as
refunds, never bare numbers. - One judgment per question. Build compound decisions in your code from several questions.
- Describe each option the way you would brief a new colleague.
- Confirm the right answers and correct the wrong ones. Both measure accuracy; corrections alone cannot.
Question sets
Instead of sending the questions with every request, save them once under a name and send just "contract": "support_v1". Calibration and learning run per set.
PUT /v1/contracts/support_v1 {"description": "...", "policy": "...", "questions": {...}}
GET /v1/contracts
DELETE /v1/contracts/support_v1
GET /v1/templates
POST /v1/contracts/from-template/triageConfirmations and corrections
POST /v1/confirm {"request_id": "..."}
POST /v1/feedback {"request_id": "...", "question": "team", "human_answer": "refunds"}
GET /v1/accuracyEvery 20 new verdicts on a saved set, a small model per question retrains automatically, is tested on cases it has not seen, and goes live only if it performs. It then decides the recurring cases itself, faster and cheaper.
Ready-made tools
Every tool on the Tools page works from the API too: send its fields and up to 100 items, and each item comes back with a plain verdict plus the typed answers.
GET https://7aasm.com/v1/tools
POST https://7aasm.com/v1/tools/scam-check
{"fields": {}, "items": ["Your card is suspended, update your details at this link"]}On the page itself you can drop files (PDF, Word, Excel, CSV, ZIP) or screenshots and photos; the model reads the picture into text, which is then decided like any text. Images are downscaled, stripped of metadata (location, device) and never stored.
For agents: an MCP server and a Python SDK ship in sdk/python: claude mcp add hasm -e HASM_KEY=… -- python -m hasm_sdk.mcp_server. The full schema is at openapi.json.
Each result carries verdict, tone (ok, warn, bad, info), sure and a request_id, so you confirm or correct it like any decision.
Code samples
Python
import httpx
r = httpx.post("https://7aasm.com/v1/systemone",
headers={"Authorization": "Bearer hk_live_..."},
json={"state": "...", "contract": "support_v1"}).json()
team = r["answers"]["team"]
if team["grade"] == "decided":
route(team["choice"])
else:
queue_for_review(r["hasm"]["request_id"])JavaScript
const r = await fetch("https://7aasm.com/v1/systemone", {
method: "POST",
headers: { "Authorization": "Bearer hk_live_...", "content-type": "application/json" },
body: JSON.stringify({ state: "...", contract: "support_v1" })
}).then(res => res.json());curl
curl https://7aasm.com/v1/systemone \
-H "Authorization: Bearer hk_live_..." \
-H "content-type: application/json" \
-d '{
"state": "My parcel arrived broken and I want my money back today",
"questions": {
"team": {"type": "choice", "instructions": "Which team handles this?",
"criteria": {"refunds": "Refunds", "parcels": "Damaged parcels", "login": "Sign-in"}},
"angry": {"type": "noul", "instructions": "The customer is angry"}
}
}'Limits
- Up to 255 options per question, 2 to 10 score levels, and up to 64 questions per request depending on your plan.
- Up to 512 KB per request, 1,200 requests per minute per key, and a 5-second budget per decision.
- Balance: each decision draws its price from your prepaid balance (a decision from your memory is free). When it runs out the API returns
402with the top-up link, andGET /v1/usagegives the balance, prices and this month's usage per service. "classification": "confidential"means the text never reaches an external model. For secret data, use the on-premises edition.