# Jev API guide

> Use the Jev API with JSON, curl, Python and Node.js examples. Understand Choice, Score, Noul, context limits, authentication and bounded retries.

- Canonical HTML: https://omniakey.com/blog/jev-api-guide
- Markdown: https://omniakey.com/blog/jev-api-guide.md
- Published: 2026-09-28 (updated 2026-10-24)
- Author: Kiki, COO at OmniaKey
- Language: en
- Category: API setup
- Reading time: 11 min
- All posts: https://omniakey.com/blog/llms.txt

---

The **Jev API** evaluates text against questions you define and returns typed decisions. Send `state`, `model` and a `questions` map. Read `answers` under the same question IDs. There is no chat transcript to reconstruct and no free-form answer to parse.

This Jev API guide is for a first integration. For what the model does well, its limitations and pricing background, start with [Jev model explained](https://omniakey.com/blog/jev-model-explained).

> **Checked October 24, 2026.** The request and response contract comes from TypeSafe's documentation; the gateway route was checked against OmniaKey's implementation. Examples are illustrative and checked offline, not a new paid performance test. TypeSafe's limits and prices do not automatically describe a gateway account.

## Choose the endpoint and its matching API key

|Route|POST endpoint|Credential|
|-|-|-|
|OmniaKey|`https://api.omniakey.com/v1/alpha/search`|An OmniaKey API key with access to `jev-latest`|
|Direct TypeSafe|`https://api.typesafe.ai/v1/systemone`|A TypeSafe API key|

Both examples use `Authorization: Bearer ...` and the native Jev body. **Do not send an OmniaKey key to TypeSafe, or a TypeSafe key to OmniaKey.** The gateway endpoint is not `/v1/chat/completions`; replacing `state` with `messages` changes the contract.

Create a scoped key, check the [current Jev model route](https://omniakey.com/jev-latest), and set `OMNIAKEY_API_KEY` in your local environment. Keep keys out of browser code, source control and screenshots. General key setup is in the [API quick start](https://docs.omniakey.com/en/quick-start).

## Build a complete Jev JSON request

Save this as `jev-request.json`. It evaluates one support message for routing, frustration and urgency. The example uses English text; TypeSafe says English is currently strongest, so validate other languages on representative inputs.

```json
{
  "model": "jev-latest",
  "state": "My payouts have failed for three days. Please help me resolve this today.",
  "questions": {
    "department": {
      "type": "choice",
      "instructions": "Which team should handle this message?",
      "criteria": {
        "billing": "Payments, invoices, or refunds",
        "technical": "Bugs, outages, or integrations",
        "sales": "Pricing, upgrades, or new accounts"
      }
    },
    "frustration": {
      "type": "score",
      "instructions": "How frustrated is the customer?",
      "criteria": ["Calm", "Frustrated", "Very angry"]
    },
    "is_urgent": {
      "type": "noul",
      "instructions": "Does the message express a time-sensitive need?"
    }
  }
}
```

The IDs `department`, `frustration` and `is_urgent` join questions to answers. TypeSafe says those IDs are not used in inference: put the actual task in `instructions`, not only in the key name. A `state` can also be a JSON object or array containing text, such as a support record with named fields.

```bash
curl --fail-with-body https://api.omniakey.com/v1/alpha/search \
  -H "Authorization: Bearer $OMNIAKEY_API_KEY" \
  -H "Content-Type: application/json" \
  --data-binary @jev-request.json
```

For direct TypeSafe access, use `https://api.typesafe.ai/v1/systemone` with `$TYPESAFE_API_KEY` instead. Keep the JSON shape; verify the model names your account accepts.

## Understand Choice, Score and Noul responses

|Question|Define|Read from its answer|Interpretation|
|-|-|-|-|
|`choice`|A map of options to descriptions, up to 255 options|`choice`, `probabilities`, `confidence`|The chosen label plus the distribution across your options|
|`score`|An ordered rubric with 2–10 levels|`score`, `legend`, `probabilities`, `confidence`|A probability-weighted level, which may be fractional|
|`noul`|A yes/no question; optional `true` / `false` criteria|`noul`|Probability of yes between 0 and 1, not a Boolean|

The response also contains `model` and `usage.input_tokens` / `usage.output_tokens`. Record the resolved model ID when evaluating behavior: `jev-latest` currently points to `jev-1.14.0`, and an alias can move later. Pin `jev-1.14.0` if the version must stay fixed.

For a three-level rubric, a score of `1.05` would fall just above level 1; it would not mean 1.05 out of 100. Use the returned `legend`. A Noul value of `0.8` is a probability, not permission to execute an irreversible action. Choose thresholds using labeled examples from your application. `confidence` is derived from the distribution and is not a guarantee that a decision is correct.

The following complete response is an illustrative fixture, not an observed API result. Answer values and token counts are examples; actual results vary.

```json
{
  "model": "jev-1.14.0",
  "answers": {
    "department": {
      "type": "choice",
      "choice": "billing",
      "probabilities": {
        "billing": 0.88,
        "technical": 0.12,
        "sales": 0.0
      },
      "confidence": 0.81
    },
    "frustration": {
      "type": "score",
      "score": 1.05,
      "legend": {
        "0": "Calm",
        "1": "Frustrated",
        "2": "Very angry"
      },
      "probabilities": {
        "0": 0.0,
        "1": 0.95,
        "2": 0.05
      },
      "confidence": 0.92
    },
    "is_urgent": {
      "type": "noul",
      "noul": 0.8
    }
  },
  "usage": {
    "input_tokens": 320,
    "output_tokens": 72
  }
}
```

## Call the Jev API from Python or Node.js

These examples reuse `jev-request.json` and make one request. They print the typed answers rather than assuming an OpenAI `choices` response. Add the bounded retry policy below in a production client.

```python
import json
import os
import urllib.error
import urllib.request
from pathlib import Path

request = urllib.request.Request(
    "https://api.omniakey.com/v1/alpha/search",
    data=Path("jev-request.json").read_bytes(),
    headers={
        "Authorization": f"Bearer {os.environ['OMNIAKEY_API_KEY']}",
        "Content-Type": "application/json",
    },
    method="POST",
)
try:
    with urllib.request.urlopen(request, timeout=30) as response:
        result = json.load(response)
except urllib.error.HTTPError as error:
    raise SystemExit(f"Jev request failed: HTTP {error.code}") from None

print(result["model"])
print(json.dumps(result["answers"], indent=2))
```

```javascript
import { readFile } from 'node:fs/promises';

const key = process.env.OMNIAKEY_API_KEY;
if (!key) throw new Error('Set OMNIAKEY_API_KEY first');

const response = await fetch('https://api.omniakey.com/v1/alpha/search', {
  method: 'POST',
  headers: {
    Authorization: `Bearer ${key}`,
    'Content-Type': 'application/json',
  },
  body: await readFile('jev-request.json', 'utf8'),
  signal: AbortSignal.timeout(30_000),
});
if (!response.ok) throw new Error(`Jev request failed: HTTP ${response.status}`);

const result = await response.json();
console.log(result.model);
console.log(result.answers);
```

Use Python 3 or a Node.js version with built-in `fetch` and `AbortSignal.timeout`. These are plain HTTP examples, not a claim that an OpenAI SDK supports Jev's native schema. TypeSafe also publishes its own SDKs in the [official documentation](https://docs.typesafe.ai/api).

## Context limits, rate limits and billing

The current official model has **64K tokens for the entire request**, and a separate **32K limit for `state` plus the longest single question**. Both conditions must hold. Shorten irrelevant input and combine only questions that genuinely need the same state.

TypeSafe lists **250,000 tokens per second and 1,200 requests per minute**, with a warning that early-access limits can change. They are account throughput limits, not single-request speed measurements or a promise for your OmniaKey account. A gateway can impose additional limits.

Direct TypeSafe pricing is **$0.042 per million input tokens**, with output tokens free at the check date. Output usage is still returned. That does not mean all API use is free, nor that the gateway uses the same billing unit or price. Use the current model quote and your usage records for OmniaKey costs; see the [pricing and limits explanation](https://omniakey.com/blog/jev-model-explained).

OmniaKey’s current Jev catalog uses **per-request billing**. Check the current model quote and dashboard usage records before estimating gateway costs.

## Handle authentication, validation and retries

|Direct TypeSafe status|Check first|Action|
|-|-|-|
|`401`|Key belongs to this endpoint; Bearer header is present|Correct the credential; do not retry the same invalid key|
|`422`|Required fields, question type and `criteria` shape|Fix the field identified by the error|
|`429`|Account request or token limit|Honor `Retry-After` when present; use capped exponential backoff with jitter|
|`529`|Temporary provider overload|Retry with backoff and a finite attempt/time budget|

Those status meanings are documented for the direct API. A gateway can return its own authentication, validation or upstream error format. Also check the endpoint path and exact model ID when a route is unavailable. Keep keys and private request bodies out of diagnostics you share.

Separate the model request from downstream side effects: retrying a classification must not send a customer email or issue a refund twice. After repeated failures, return a visible failure or route for review. Do not silently turn a failed decision into a confident default.

## Frequently asked questions

### Is this the official Jev API documentation?

This is an OmniaKey Jev API guide. [TypeSafe's API reference](https://docs.typesafe.ai/api) owns the direct schema and [its model page](https://docs.typesafe.ai/models) owns direct prices and limits. The endpoint table above distinguishes the routes.

### Can I send images or ask Jev to write text?

Jev 1.14 accepts text by default and returns the typed decisions described above. Extract text from non-text assets first; image input in 1.14 sits behind an experimental header. Generating an explanation, image or video requires another model or application step.

### Should I use an alias or a versioned model ID?

An alias is convenient for exploration. For a deployed threshold-based workflow, evaluate a supported versioned ID and record the returned `model`; revalidate thresholds before changing versions. Gateway model availability can differ from the direct API.

## Sources

- [TypeSafe API reference](https://docs.typesafe.ai/api)
- [Models, prices, aliases and limits](https://docs.typesafe.ai/models)
- [Confidence](https://docs.typesafe.ai/confidence)
- [Jev 1.13 limitations](https://docs.typesafe.ai/model-jaggedness/jev-1.13)
