> ## Documentation Index
> Fetch the complete documentation index at: https://docs.novita.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# JEV-27B-VL

## 1. Overview

This document describes how to use the **Decision Evaluation (Decide)** capability through the AutoTrust JEV-27B-VL native protocol.

Decision evaluation is not a chat, image, or video generation endpoint: a single request submits one piece of content to evaluate, `state`, and one question, `question`, and the endpoint synchronously returns the probability of each option for that question. The model supports mixing images into `state`, and is suited to scenarios that need a stable conclusion rather than free-form text, such as content moderation decisions, ticket routing, product categorization, and image-text consistency judgment.

The call flow is a single request-response; there is no need to create a task or poll:

1. Call the decision evaluation endpoint, specifying `model`, `kind`, `state`, and `question` in the request body (`choice` also requires `options`).
2. Read the probability of each option from the response `probabilities`, or read `choice` directly.
3. Read this request's token usage from the response `usage`.

Only one question can be asked per request. To ask multiple questions about the same content, call the endpoint separately for each.

### 1.1 Endpoint

| Capability | Endpoint |
| - | - |
| Decision Evaluation | `POST /v3/autotrust/v1/decide` |

The full address in the examples in this document is `https://api.novita.ai` plus the endpoint path in the table above, where `https://api.novita.ai` is the API domain you use.

### 1.2 Authentication

All requests must carry an API Key and specify the JSON content type:

```text theme={"system"}
Authorization: Bearer <YOUR_API_KEY>
Content-Type: application/json
```

### 1.3 Response Structure

On success, the HTTP status code is 200 and the conclusion is returned directly:

| Field | Type | Description |
| - | - | - |
| `kind` | string | Echoes the question type of the request. |
| `effective_kind` | string | The question type actually executed, usually the same as `kind`. |
| `options` | array | The list of options for this evaluation. For `noul` it is fixed to `["false", "true"]`, for `score` it is fixed to `["0", "1", "2", "3", "4", "5"]`, and for `choice` it is the `options` from the request. |
| `probabilities` | array | Probabilities corresponding one-to-one to `options`, in the same order, summing to 1. |
| `choice_index` | integer | The index in `options` of the highest-probability option. |
| `choice` | string | The highest-probability option. |
| `adaptation` | string | How options are read. It is `native` when there are no more than 16 options. |
| `protocol` | string | The upstream protocol version identifier. |
| `model` | string | The model that actually served this request, which is `autotrust/JEV-27B-VL`. |
| `usage.prompt_tokens` | integer | Number of input tokens, including image tokens; the billing basis. |
| `usage.completion_tokens` | integer | Number of output tokens. It is 1 when thinking is disabled. |
| `usage.total_tokens` | integer | The sum of the two items above. |
| `num_model_requests` | integer | The number of model calls the upstream executed to complete this request. It is 1 when thinking is disabled. |
| `elapsed_seconds` | number | Upstream processing time (seconds). |
| `thinking` | object | Returned only when thinking is enabled in the request; see 2.1. |

## 2. Decision Evaluation

Official parameter documentation: [autotrust/jev-27b-vl (inference.sh)](https://app.inference.sh/apps/autotrust/jev-27b-vl) · [autotrust/JEV-27B-VL model card](https://huggingface.co/autotrust/JEV-27B-VL) (the `POST /v1/decide` section)

### 2.1 Call Endpoint

```text theme={"system"}
POST https://api.novita.ai/v3/autotrust/v1/decide
```

Request fields:

| Field | Type | Required | Description |
| - | - | - | - |
| `model` | string | Yes | Fixed to `autotrust/jev-27b-vl`. |
| `kind` | string | Yes | Question type: `noul` (yes/no), `score` (0 to 5 rating), `choice` (single select from `options`). |
| `state` | string / object / array | No | The content to evaluate. It can be plain text, a JSON object, or an array mixing text and images (see below). Defaults to an empty string. |
| `question` | string | Yes | The question to judge. |
| `options` | array | Required for `choice` | 2 to 256 strings, the candidate options. Ignored for other types. |
| `thinking` | string | No | `off` (default, decision head only), `auto` (thinks only when the highest-probability option is below `threshold`), `on` (always thinks). `score` does not support `auto` or `on`. |
| `threshold` | number | No | The trigger threshold when `thinking=auto`, default 0.8. |
| `reasoning_effort` | string | No | Thinking effort: `xhigh` (default), `medium`, `low`. `high` is not accepted. |
| `think_budget` | integer | No | The maximum number of tokens to use for thinking; unbounded by default. |
| `return_reasoning` | boolean | No | When `true`, the response `thinking` object includes the reasoning text. |
| `strategy` | string | No | The reading strategy when a `choice` has more than 16 options: `single` (default), `tournament`, `permute`. |
| `debug` | boolean | No | When `true`, the response also includes the respective probability distributions for the decision head and thinking. |

**Passing images in `state`**: write `state` as an array, with text as strings and images as `{"image": "<URL or data URL>"}`; images are inserted at the position they appear. Images support `https://` public addresses or the `data:image/...;base64,...` form, up to 8 images. The larger the image, the more input tokens it consumes; a long edge of about 448 pixels is enough for most judgments.

```json theme={"system"}
"state": ["Product image: ", {"image": "https://example.com/item.jpg"}, "\nSeller title: Like-new wireless earbuds"]
```

**Thinking mode**: after `thinking` is enabled, the upstream calls the model for a round of reasoning in addition to the decision head, and fuses the two probability distributions with fixed weights. In this case `usage.completion_tokens` increases to the number of tokens used for thinking, `num_model_requests` is greater than 1, and the latency increases noticeably. The response contains an extra `thinking` object, including `mode`, `threshold`, `budget`, `used`, `think_tokens`, `think_seconds`, `finished_within_budget`, and, when `return_reasoning=true`, also the `reasoning` text.

A single request body is at most 64 MB. The endpoint is a synchronous call; without thinking, upstream latency is usually under 0.2 seconds, and with thinking it grows with `think_budget`, so set a sufficiently long read timeout for your client.

### 2.2 Request Examples

```bash theme={"system"}
curl -X POST 'https://api.novita.ai/v3/autotrust/v1/decide' \
  -H 'Authorization: Bearer <YOUR_API_KEY>' \
  -H 'Content-Type: application/json' \
  -d '{
    "model": "autotrust/jev-27b-vl",
    "kind": "choice",
    "state": "Customer: I was charged twice for a single coffee purchase.",
    "question": "Which team should handle this issue?",
    "options": ["billing", "shipping", "tech support"]
  }'
```

A yes/no judgment with an image:

```bash theme={"system"}
curl -X POST 'https://api.novita.ai/v3/autotrust/v1/decide' \
  -H 'Authorization: Bearer <YOUR_API_KEY>' \
  -H 'Content-Type: application/json' \
  -d '{
    "model": "autotrust/jev-27b-vl",
    "kind": "noul",
    "state": ["Photo: ", {"image": "https://example.com/photo.jpg"}],
    "question": "Is the main content of this image food or cooking?"
  }'
```

### 2.3 Response

On success, the conclusion is returned directly, with no need to query:

```json theme={"system"}
{
  "kind": "choice",
  "effective_kind": "choice",
  "options": ["billing", "shipping", "tech support"],
  "probabilities": [0.9970129415480892, 5.8849388422286644e-06, 0.002981173513068533],
  "choice_index": 0,
  "choice": "billing",
  "adaptation": "native",
  "protocol": "jev27-bare-v1",
  "model": "autotrust/JEV-27B-VL",
  "usage": {
    "prompt_tokens": 49,
    "completion_tokens": 1,
    "total_tokens": 50
  },
  "elapsed_seconds": 0.111,
  "num_model_requests": 1
}
```

How to read the conclusion for the three question types:

| `kind` | `options` | How to read the conclusion |
| - | - | - |
| `noul` | `["false", "true"]` | `probabilities[1]` is the probability of "yes"; close to 1 is a strong affirmative, close to 0 is a strong negative, and close to 0.5 is uncertain. Set a threshold in your code. |
| `score` | `["0", "1", "2", "3", "4", "5"]` | `choice` is the most likely score; you can also use `probabilities` weighted by index to get the expected score. |
| `choice` | the request's `options` | `choice` is the highest-probability option, and `probabilities` is in the same order as `options`. |

Use `probabilities` for threshold decisions; `choice` is only the highest-probability option and does not indicate confidence.

### 2.4 Billing

```text theme={"system"}
Request cost = input unit price × input tokens ÷ 1000000
```

* Only **input tokens** are billed, and the billed quantity is taken from the response `usage.prompt_tokens`, i.e. the number of input tokens actually counted by the upstream.
* Image tokens are counted as input tokens.
* Output tokens (`usage.completion_tokens`) are currently not billed, including tokens produced by enabling thinking mode.
* Failed requests, or responses that do not contain `usage`, are not charged.

The exact unit price is subject to the pricing page of the service you use.

## 3. Common Errors and Notes

Endpoint errors use the following structure:

```json theme={"system"}
{
  "code": 400,
  "reason": "INVALID_REQUEST_BODY",
  "message": "invalid request body",
  "metadata": {
    "trace_id": "0af7651916cd43dd8448eb211c80319c"
  }
}
```

| HTTP | reason | Common scenario | Suggested handling |
| - | - | - | - |
| 400 | `INVALID_REQUEST_BODY` | The request body is not valid JSON, exceeds 64 MB, or is rejected by upstream validation (such as a `choice` with fewer than 2 options, a missing `kind`, `reasoning_effort` set to `high`, or thinking enabled for `score`). | Fix the request based on `message`. |
| 400 | `MISSING_API_KEY` | The API Key is not provided. | Check the `Authorization` request header. |
| 403 | `NOT_ENOUGH_BALANCE` | Insufficient account balance. | Top up and retry. |
| 403 | `NOT_ENOUGH_KEY_BUDGET` | Insufficient API Key budget. | Adjust the budget limit for that key. |
| 403 | `NOT_ENOUGH_MEMBER_BUDGET` | Insufficient member budget. | Contact the team administrator to adjust the budget. |
| 404 | `FUSION_MODEL_NOT_FOUND` | `model` is not `autotrust/jev-27b-vl`. | Set `model` to `autotrust/jev-27b-vl` in the request body. |
| 404 | `PATH_NOT_FOUND` | The endpoint path or method is incorrect. | Use `POST /v3/autotrust/v1/decide`. |
| 429 | — | Too many requests. | Reduce the rate and use exponential backoff. |
| 500 | `INTERNAL` | The service is temporarily abnormal. | Contact technical support with `metadata.trace_id`. |

Other notes:

* The `model` in the request body is fixed to `autotrust/jev-27b-vl`; the `model` in the response is the upstream echo `autotrust/JEV-27B-VL`. Both refer to the same model.
* This endpoint and `POST /v3/decisions` (Jev 1.13) are two independent protocols: this endpoint asks one question per request and returns a probability array, while `/v3/decisions` asks multiple questions at once and returns an `answers` object. Do not mix their request bodies.
* Validation of fields such as `kind`, `options`, and `thinking` is performed by the upstream, and the error information is returned with the response; correct your request based on that information.
* Image URLs must be publicly accessible to the upstream and must not rely on an intranet, cookies, or a temporary login state; otherwise use an embedded data URL.
* The model's image judgment capability is zero-shot, and the official evaluation has not systematically measured its calibration on image scenarios; use image conclusions together with thresholds and business review.
* Errors returned by the upstream are converted to the platform error structure shown in the table above; when troubleshooting, provide `metadata.trace_id`.

## 4. Python Example

The following example uses the standard `requests` library to demonstrate one complete call.

```python theme={"system"}
import os

import requests


api_domain = os.environ["API_DOMAIN"]
api_key = os.environ["PLATFORM_API_KEY"]

payload = {
    "model": "autotrust/jev-27b-vl",
    "kind": "choice",
    "state": "Customer: I was charged twice for a single coffee purchase.",
    "question": "Which team should handle this issue?",
    "options": ["billing", "shipping", "tech support"],
}

response = requests.post(
    f"https://{api_domain}/v3/autotrust/v1/decide",
    headers={
        "Authorization": f"Bearer {api_key}",
        "Content-Type": "application/json",
    },
    json=payload,
    timeout=120,
)
response.raise_for_status()
result = response.json()

print(result["choice"])
print(dict(zip(result["options"], result["probabilities"])))
print("prompt tokens:", result["usage"]["prompt_tokens"])
```


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.