Quick answer
Use POST https://api.typesafe.ai/v1/systemone with a Bearer API key. Send model, state and a questions object. Read the matching keys in answers; a Noul result is answers.<id>.noul, not a generated text response.
1. Prepare access and a small test case
Open the official TypeSafe console and check that your account has access. Create your API key there, then store it as TYPESAFE_API_KEY in your server environment. The official quick start also provides a Playground for experimenting before writing code.
Choose a short, unambiguous example first. For a billing ticket, separate the destination team, urgency and refund intent. These are different judgments; combining them into a single broad prompt makes it harder to inspect which part failed.
- The example below uses Node.js 18 or later and its built-in fetch.
- Keep the key on your server. A VITE_ environment variable or a script embedded in a webpage would expose it to visitors.
- Access and billing belong to your TypeSafe account; this community website cannot issue keys.
2. Send a server-side JavaScript request
This original example follows the documented request shape. Save it as quickstart.mjs and run it on your server after setting the environment variable. It logs decisions and token usage; it does not issue a refund or contact a customer.
The endpoint and field names were checked against the official documentation on September 20, 2026. We did not run a paid inference request, so no particular prediction or latency is promised.
// Run on your server with Node.js 18+; never expose this key in browser code.
const apiKey = process.env.TYPESAFE_API_KEY;
if (!apiKey) throw new Error('Set TYPESAFE_API_KEY first');
const response = await fetch('https://api.typesafe.ai/v1/systemone', {
method: 'POST',
headers: {
Authorization: `Bearer ${apiKey}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
model: 'jev-latest',
state: 'My invoice lists the same purchase twice. Please refund the duplicate charge.',
questions: {
team: {
type: 'choice',
instructions: 'Which team should handle this request?',
criteria: {
billing: 'Charges, invoices, and refunds',
technical: 'Bugs and integration problems',
other: 'Requests outside the listed categories',
},
},
urgency: {
type: 'score',
instructions: 'How time-sensitive is the request?',
criteria: ['No stated deadline', 'A stated deadline', 'An immediate service outage'],
},
refund: {
type: 'noul',
instructions: 'Does the customer explicitly request a refund?',
},
},
}),
});
if (!response.ok) {
throw new Error(`TypeSafe request failed: HTTP ${response.status}`);
}
const { answers, usage } = await response.json();
console.log({
team: answers.team.choice,
confidence: answers.team.confidence,
urgency: answers.urgency.score, // Three levels: 0 to 2, including fractions.
refundProbability: answers.refund.noul,
inputTokens: usage.input_tokens,
});
// Select automation thresholds on your own evaluation data before taking action.
3. Read each primitive correctly
Score levels start at zero. Three criteria give a range from 0 to 2, and fractional scores are valid. Writing labels such as ‘1 = low’ does not change the underlying array positions.
Noul does not have a separate confidence field. A value near 0 means a strong no; a value near 1 means a strong yes. For Choice and Score, confidence summarizes the distribution and is not interchangeable with the winning option’s probability.
| Primitive | Use it for | Read from the answer |
|---|---|---|
| Choice | One category from named alternatives | choice, probabilities, confidence |
| Score | A position on an ordered rubric | score, legend, probabilities, confidence |
| Noul | Whether a specific statement is true | noul, between 0 and 1 |
4. Diagnose failures before retrying
Avoid retrying every failure in a tight loop. Bound the number of retries, handle timeouts and retain a manual fallback. Do not log raw customer content or API keys merely to debug a routing failure.
| HTTP status | Next check |
|---|---|
| 401 | Check the API key and Authorization header. |
| 422 | Inspect the validation response; check model, state and the questions map. |
| 429 | Reduce concurrency and retry with backoff. |
| 529 | The service is overloaded; retry later with backoff. |
5. Decide when automation is appropriate
Build a labeled set containing ordinary tickets, ambiguous wording and requests outside your categories. Review wrong assignments as well as abstentions. Choose thresholds based on the cost of errors in that workflow; a threshold copied from a demo is only a hypothesis.
Keep model-version information with your evaluation results. Recheck the same cases when a model or rubric changes. A correctly typed answer can still select the wrong team, and confidence does not replace authorization for the action your application takes.
Common questions
Is /v1/decide the Jev endpoint?
The documentation checked for this guide specifies /v1/systemone. Use that endpoint and the documented questions object.
Can I call Jev directly from a React component?
Use a backend to hold the API key. The public browser bundle must not contain your TypeSafe credentials.
Do I need an SDK?
No. The HTTP API works with fetch or cURL. TypeSafe also documents Python and JavaScript SDKs.
Sources & verification
Examples and explanations are editorial guidance. Current official documentation and account terms take precedence.