How a decide request is shaped
A decide call asks for typed answers, not a paragraph. This page is the contract this website actually implements. The copy-ready samples live on the API reference. The meter is on credits and keys.
One route, three spellings
Send JSON to POST /v1/decide. The same body is accepted at POST /v1/systemone and at POST /api/decide. The last of those is the path the playground uses. All three run the same auth, the same meter, and the same upstream call. The browser does not talk to Impossibl. The server holds IMPOSSIBL_API_KEY and posts state and questions to the upstream POST /v1/systemone. If that key is missing, the route returns 503 with code not_configured, and the playground can label a run as an Offline demo. The offline demo does not load weights.
The body is a JSON object of at most 100,000 bytes. Larger bodies return 413. A body that is not JSON, or a JSON array at the top level, returns 400. Two fields do the work. state is required. It may be a string, an object, or an array. A support ticket is usually an object with a sender, a subject, and a body. A one-line note can be a string. There is no separate system prompt on this API. Instructions live on each question.
questions must be a non-empty object. Each key is an id you choose, such as department or churn_risk. The value is one question of type choice, score, or noul. The model answers every question in that map in one forward pass. It does not write prose back. Choice returns a label and a probability per option. Score returns an expected level on an ordered rubric. Noul returns P(true), from 0 to 1.
Choice, score, and noul
A choice question needs instructions and a criteria object. The keys are the labels you want back. The values are short glosses, so the label is not only a code. The support-triage tool uses this shape for department: billing for invoices, payments, and refunds; technical for bugs, outages, and errors; account for login, access, and profile; other for everything else. The answer has type choice, a choice string, and probabilities for those labels. It may also include confidence and answer_confidence. Those two numbers are not the same statistic. On choice and score, the upstream README defines confidence as 1 minus normalized entropy, and answer_confidence as the maximum class probability. The calibration guide is the longer note, including why a Jev confidence formula does not transfer.
Do not treat action.act_probability as a signal. The upstream note on issue 185 puts that head at AUROC 0.30 against 0.77 for confidence, on 396 labelled decisions. This site's demo sets act_probability to null so a copied JSON shape is not mistaken for that head.
A score question uses an ordered list in criteria, not a map. Urgency on the support-triage tool is not urgent, soon, today, critical. The answer includes score, a legend from index to label, and probabilities. The score is a position on that rubric. It is not a free-text severity essay.
A noul question is a yes or no. It has instructions and no label list. noul is P(true). Churn risk on the same tool asks whether the user threatens to cancel or leave. Refund requested asks whether the user explicitly requests a refund. A value near 1 means the model assigns a high probability to the statement. It is still a probability. You decide what to do with it. The free way to turn probabilities into allow, review, or block is POST /v1/gate, described below and in the support-triage guide.
You can mix the three types in one questions object. That mix is the product. A ticket can return a department, an urgency, a churn flag, and a refund flag together. If you need a written reply to the customer, this call will not draft it. Use a chat model for the sentence, and use decide for the labels. The model-router tool on the tools page exists for that split: a lane of decide, chat, or human.
curl https://laya-model.com/v1/decide \
-H "Authorization: Bearer laya_YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{
"state": {
"ticket": "I was charged twice and nobody has replied for 3 days.",
"channel": "email"
},
"questions": {
"route": {
"type": "choice",
"instructions": "Where should this go?",
"criteria": { "billing": "money", "bug": "broken", "account": "login" }
},
"urgency": {
"type": "score",
"instructions": "How urgent is this?",
"criteria": ["routine", "today", "urgent"]
},
"escalate": { "type": "noul", "instructions": "Escalate to a human now?" }
}
}'Model aliases on this gateway
An optional model string selects a checkpoint. This gateway maps english and laya to convaiinnovations/laya, and multilingual and laya-multilingual to convaiinnovations/laya-multilingual. The string typed-decisions is accepted too, and it resolves to convaiinnovations/laya, the same id as english. It does not switch this hosted API onto the fine-tuned checkpoint that the model card scores at 0.766. That figure belongs to laya-typed-decisions after training. The bases on that benchmark are 0.362 and 0.352. See fine-tune before you quote 0.766 as the score of a default call.
If you omit model, the server sends IMPOSSIBL_MODEL, or convaiinnovations/laya when that setting is empty. An unknown model string is forwarded as you wrote it. The local Router() in the Apache-2.0 package can send Han text to the multilingual checkpoint and keep short English text on the English checkpoint. This gateway does not add that routing on top of the model id. If you want the multilingual checkpoint, pass model as multilingual. Score questions on that checkpoint have a position bias, tracked upstream as issue 131. The Chinese routing and router versus one checkpoint guides are about the local package, not about an automatic host-side router.
What comes back, and what it costs
A successful body includes model, answers, usage with input_tokens and output_tokens, timing.infer_ms, and request_id when the upstream sends one. A routing object is included when the upstream returns one. This site adds billing. billing.mode is key, session, or anon. The cost is in micro-dollars. A signed-in account also gets the balance after the call.
Only input tokens are billed: 1,000 tokens at $0.0004, and at least one unit per call. Output tokens are free. The account is held for an estimate, then settled on upstream usage.input_tokens. A failed call refunds the hold. If the balance cannot cover the estimate, the route returns 402. Packs and the monthly grant are in the credits guide.
A laya_ key in the Authorization header bills the Google account that created the key. A signed-in browser session bills the same balance. There is no email and password form. An anonymous caller may use the free runs configured by ANON_FREE_RUNS, default 1, counted by the laya_anon cookie. When that allowance is spent, the route returns 401.
A missing, unknown, or revoked key is 401. Exceeding the account rate, or the hourly or daily input-token cap, is 429. If the upstream does not answer within 120 seconds, the route returns 504 and refunds the hold. The numbers for those caps, and how packs change the rate, are in the credits guide rather than repeated here.
Batch, templates, and the gate
POST /v1/batch/decide takes states, an array, and one shared questions object. The limit is 20 states. Each state is metered on its own. The same key, session, or anonymous allowance applies. If one item fails, the route stops and returns that error together with the results it already collected.
The tools are the same contract with the questions filled in. POST /v1/support/triage accepts the tool's fields, or a full state plus questions if you want to override the template. At least one field must be non-empty. Email triage, the prompt guard, scam spotting, and the rest share the prepaid balance. The path for each tool is on its page and in the API reference.
POST /v1/gate is not a model call. It applies a local policy to answers you already have and returns allow, review, or block, plus reasons. It does not contact the upstream, does not spend tokens, and does not require a key. The default confidence floor is 0.55. Pass policy.min_confidence to change it. The gate reads a numeric confidence on each answer. For a noul answer that has no confidence field, it uses the larger of noul and one minus noul. It does not read answer_confidence unless you copy that number into confidence yourself. Choice rules can name labels to allow, review, or block. Noul rules can set review_above and block_above. The strictest decision wins.
Do not put secrets in state that you would not send to an inference host. The prompt text is not written into the usage ledger. That ledger stores the route, the input-token count, the cost, and the time. The text does go upstream to produce the answer. Revoke a key from the account page if it leaks. For a full ticket from the tool page through a gate, read the support-triage guide.