# What is Jev? The decision model explained for developers

> Jev answers a question with typed probabilities, not text: moderation, intent, proof of payment. Real calls, thresholds and cost in credits.

- Published: 2026-10-12
- Author: Gael — Tchavi founder
- Canonical: https://tchavi.com/en/blog/what-is-jev-decision-model

---


Jev is a model that writes nothing. You give it a text and a question with options, and it returns one probability per option. That is all, and it is what makes it useful: you have no text to parse, and you set the threshold at which your code acts.

On Tchavi it is called `jev-1.13` and it runs on the `/v1/decisions` endpoint. I ran five messages through it: shop listings, a support message and a proof of payment. The results, thresholds and costs are below. If you are still deciding whether you need a gateway at all, start with [what an AI API gateway is](https://tchavi.com/en/blog/what-is-an-ai-api-gateway).

## In short

- **Tchavi, an OpenAI-compatible AI API gateway you pay for with mobile money, gives access to Jev**, TypeSafe's decision model, on `/v1/decisions` with the same key as everything else.
- A **decision** is a text plus typed questions: a choice between labels, a score on a scale, or a yes/no probability. The answer always has that shape.
- Use it to classify, moderate, route or check a yes/no. Avoid it whenever you want written text.
- Cost on Tchavi: 0.09 credits per thousand input tokens, output free. My calls cost between 0.035 and 0.044 credits each, about KES 0.003 at October 2026 rates.
- Latency measured in October 2026: 298 to 575 ms per call.

## What a decision is

When you ask a chat model to "answer only yes or no", you then parse a word, and sometimes the model adds an apology or a sentence. With Jev you declare the shape of the answer in the request, and the answer comes back in that shape.

There are three question types:

| type     | what you ask                       | `criteria`                       | what you get                                  |
| -------- | ---------------------------------- | -------------------------------- | --------------------------------------------- |
| `choice` | pick between labels                | label mapped to its definition   | `choice`, `confidence`, `probabilities`       |
| `score`  | place on an ordered scale          | an array, from lowest to highest | continuous `score`, `legend`, `probabilities` |
| `noul`   | how likely is it that this is true | none                             | a number between 0 and 1                      |

You name the questions as you like, and `answers` comes back keyed by your names. You can ask several in one call: the text is sent once.

On Tchavi, the text to judge (`state`) is a string or a JSON object. I only tested text and JSON, so I say nothing about images here.

## One request, one answer

Here is an online shop listing that looks like a scam. The code is plain `fetch`, no SDK (the published SDK has no decisions client):

```javascript
const response = await fetch('https://tchavi.com/api/v1/decisions', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
    Authorization: `Bearer ${process.env.TCHAVI_API_KEY}`,
  },
  body: JSON.stringify({
    model: 'jev-1.13',
    // Measured call, so the text and labels are the French ones I tested.
    // Gloss: "Brand-new sealed iPhone 15 Pro Max, only 40,000 F! Send 10,000 F
    // by MoMo to reserve it, I deliver tomorrow. Message me on WhatsApp, not here."
    state:
      'Annonce : « iPhone 15 Pro Max neuf sous scellé, 40 000 F seulement ! Envoie 10 000 F par MoMo pour réserver, je livre demain. Écris-moi sur WhatsApp, pas ici. »',
    questions: {
      verdict: {
        type: 'choice',
        instructions: 'Que doit faire la modération avec cette annonce ?', // what should moderation do with this listing?
        criteria: {
          publier: 'annonce normale, rien à signaler', // publish: normal listing
          refuser: 'produit interdit ou arnaque évidente', // reject: banned product or obvious scam
        },
      },
      arnaque: {
        type: 'noul',
        instructions: 'Cette annonce ressemble-t-elle à une arnaque ?', // does this look like a scam?
      },
    },
  }),
});

const result = await response.json();
console.log(result.answers);
console.log('credits:', response.headers.get('x-credits-used'));
```

All my tests were in French, with French WhatsApp-style messages for a fictional shop, so the examples keep their French labels (`publier` = publish, `refuser` = reject, `arnaque` = scam). I did not test English or Swahili messages, so I have no results to show for them.

The answer I got:

```json
{
  "model": "jev-1.13.0",
  "answers": {
    "verdict": {
      "type": "choice",
      "choice": "refuser",
      "confidence": 0.96,
      "probabilities": { "publier": 0.02, "refuser": 0.98 }
    },
    "arnaque": { "type": "noul", "noul": 0.92 }
  },
  "usage": { "input_tokens": 426, "output_tokens": 53 }
}
```

The cost is not in the JSON but in the `X-Credits-Used` header: 0.039 credits here. For all the fields, see the [decisions reference](https://tchavi.com/en/docs/decisions).

Two details matter. The `confidence` of a `choice` measures the model's certainty about its pick, and it can differ a little from the probability of the winning label (0.96 against 0.98 here). And a `noul` question has no `confidence`, only the number.

## Five real calls

Measured in October 2026, through Tchavi, on a test instance at public prices. Every message is invented. Latency is the round trip from my machine, one call at a time: treat it as an order of magnitude.

| case                                                                    | Jev's answer                                                       | latency | credits |
| ----------------------------------------------------------------------- | ------------------------------------------------------------------ | ------- | ------- |
| normal listing (wax dress, 12,000 F, pickup in Cotonou)                 | `publier` 1.00; scam 0.23                                          | 575 ms  | 0.037   |
| suspicious listing (iPhone at 40,000 F, MoMo deposit, WhatsApp contact) | `refuser` 0.98; scam 0.92                                          | 298 ms  | 0.039   |
| furious support message (broken parcel, threat to post on Facebook)     | `reclamation` (complaint) 1.00; urgency 2.75 of 3; escalation 0.85 | 316 ms  | 0.044   |
| MoMo screenshot text: 25,000 FCFA to Boutique Ama, order of 25,000 F    | payment complete 0.95                                              | 301 ms  | 0.035   |
| same screenshot, but 2,500 FCFA sent                                    | payment complete 0.05                                              | 422 ms  | 0.035   |

The third case shows why asking several questions at once pays off: the intent (`reclamation`), the urgency on a scale (a score of 2.75 reads between "urgent" and "critical", closer to "critical": the probability is 0.75 on "critical" and 0.25 on "urgent") and whether a human is needed, for 0.044 credits.

The fourth and fifth cases check a proof of payment from its text. I passed an object in `state` with the expected order (amount, payee) and the customer's message. Jev compares the two: 0.95 when the amount matches, 0.05 when it is ten times too low. Be careful about what that proves: it reads text that a customer can fake. To credit an account, never trust a screenshot: the money must arrive through a webhook from the operator, as it does on Tchavi. What Jev can do is sort which screenshots to look at by hand. (M-Pesa confirmations and other operator messages were not tested; the amounts above are the French-language MoMo style I measured.)

## Thresholds instead of a yes or no

A probability lets you decide how much risk you accept. The simplest scheme has three outcomes: act, hold, reject.

```javascript
function moderate(answers) {
  const scam = answers.scam.noul; // the question is named "scam" in this example
  if (scam >= 0.8) return 'reject'; // the iPhone case: 0.92
  if (scam <= 0.3) return 'publish'; // the wax dress: 0.23
  return 'needs_review'; // the middle goes to a human queue
}
```

With my two listings, the dress passes (0.23) and the iPhone is rejected (0.92). The values 0.8 and 0.3 are my choice for this example, not a rule: tune them on your own data.

How do you set them? Take 50 to 100 messages you have already judged by hand, run them through Jev, and see from which value you start getting it wrong. If rejecting a good listing is expensive (a seller who leaves), raise the reject threshold and send more cases to the human queue. If letting a scam through costs more, lower the reject threshold.

On a `choice`, `confidence` plays the same role: below, say, 0.7, you hand over instead of acting. In a test of 40 support messages that I ran through Jev, the 38 answers with a confidence of 0.9 or higher were all correct.

## When to use it, and when to avoid it

Jev fits when the answer is a list of options or a number:

- **Classification**: intent of a message, category of a ticket, language or topic.
- **Moderation**: a listing, a comment, a review, with a threshold you tune.
- **Routing**: which team, what urgency, is a human needed.
- **Yes/no checks**: does the message contain a refund request, does the receipt match the order.

It does not fit when you want text: a reply to a customer, a summary, a translation, code. It does not stream and does not write, and `/v1/chat/completions` rejects it with a `400` error (the reverse too: a chat model sent to `/v1/decisions` is rejected). The classic setup combines both: Jev decides, a chat model writes.

## What it costs on Tchavi

`jev-1.13` is billed at 0.09 credits per thousand input tokens, and output is free. Top-ups start at KES 250, and KES 1,000 buys about 13,204 credits at October 2026 rates, so one credit is roughly KES 0.0757.

One thing to know: your questions are expanded into the prompt before the model reads them. My texts were one or two lines, and the count showed between 384 and 480 input tokens. With a short `state`, the cost depends mostly on the questions, not on the text. At 0.035 to 0.044 credits per call, a thousand decisions come to 35 to 44 credits, about KES 2.65 to 3.33. On my test of 40 support messages, the average was 0.0436 credits per message: 3,000 credits (about KES 227) then pay for roughly 69,000 classifications.

Prices are the catalogue's and can change; the [model page](https://tchavi.com/en/m/typesafe/jev-1.13) shows the current rate.

## FAQ

### Is Jev an LLM?

No. It does not produce text: it returns probabilities for questions you define. It differs from a chat model by its guaranteed answer shape, not by a prompt trick.

### Do I need an SDK to call it?

No. It is a plain JSON POST request: `fetch`, `curl` or `requests` is enough. I only used `fetch` for these tests.

### What should I do when confidence is low?

Do not let your code act. Send the case to a human or, if the cost allows, to a bigger chat model. It is the same principle as the thresholds above.

### How many questions can I ask in one call?

Several: I asked up to three in the same call. Each question adds to the billed prompt, so the cost goes up with their number.

### Can I rely on Jev to validate a payment?

Not on its own. It judges a text that someone can make up. A credit must come from a confirmation by the operator, not from a screenshot. Jev is for sorting.

### Does it work on English or Swahili messages?

I do not know: all my tests were French messages, and I did not test English or Swahili. Test it on your own messages before relying on it, as described in the thresholds section.

[create your account and top up KES 250](https://tchavi.com/en/register?next=%2Fdashboard%2Fbilling%3Famount%3D250%26currency%3DKES%26from%3Dblog-jev-explained-en)

> _This article is part of the series "Building an AI product from Africa". Tchavi is an OpenAI-compatible AI API gateway: one key gives access to over 100 text, image, audio and video models, and you pay for it with mobile money, no bank card ([countries and operators](https://tchavi.com/en/docs/payments)). More guides on [the blog](https://tchavi.com/en/blog). Follow us: [LinkedIn](https://www.linkedin.com/company/tchavi) and [X](https://x.com/tchaviai)._

