# Create decision (Jev format)

> **Preview.** The same decision models in the System One format of TypeSafe Jev (`POST /v1/systemone`), for callers and tools migrating from Jev: `state` is any JSON value, `questions` is an object keyed by your own ids, and the question types are `noul` (yes or no), `choice` and `score`, with the options or levels in `criteria`. The answers come back under the same ids. Add `'calibration': 'raw'` to get uncalibrated probabilities.

Source: https://docs.serenityedge.ai/docs/api/edge/create-system-one-decision/

`POST https://api.serenityedge.ai/v1/systemone`

**Preview.** The same decision models in the System One format of TypeSafe Jev (`POST /v1/systemone`), for callers and tools migrating from Jev: `state` is any JSON value, `questions` is an object keyed by your own ids, and the question types are `noul` (yes or no), `choice` and `score`, with the options or levels in `criteria`. The answers come back under the same ids. Add `"calibration": "raw"` to get uncalibrated probabilities.

A question the model service cannot read is refused with HTTP 422, as Jev does; the error body is the same error object as on every other route. Access, billing (input tokens only), limits and the other errors are the same as on [Create decision](https://docs.serenityedge.ai/docs/api/edge/create-decision). See the [Decisions guide](https://docs.serenityedge.ai/docs/decisions#jev-compatible-route).

## Request body (`application/json`)

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `model` | string | yes | Id of the decision model, as on `POST /v1/decisions`. |
| `state` | any | yes | What the questions are about: any JSON value (a string, an object, an array). |
| `questions` | object | yes | The questions, keyed by ids of your choice, 1 to 256. The answers come back under the same ids. |
| `calibration` | string | no | `raw` returns the probabilities without calibration. Omit it for calibrated probabilities. Always `raw`. |
| `images` | array of string | no | Images the questions are about, read by `orion-compass-flash` and `d3` (at most 4 images, 8 MiB in total once decoded and 16 megapixels each). `orion-compass` refuses them with HTTP 422. At most 4 items. |

Example:

```json
{
  "model": "orion-compass",
  "state": {
    "ticket_id": 4821,
    "channel": "email",
    "message": "You charged my card twice for the same order last week. Refund the duplicate payment today or I will dispute it with my bank."
  },
  "questions": {
    "refund": {
      "type": "noul",
      "instructions": "Is the customer asking for a refund?"
    },
    "team": {
      "type": "choice",
      "instructions": "Which team should handle this ticket?",
      "criteria": {
        "billing": "Payments, charges and refunds",
        "shipping": "Delivery and tracking",
        "technical": "Bugs and sign-in problems"
      }
    },
    "urgency": {
      "type": "score",
      "instructions": "How urgent is this ticket?",
      "criteria": [
        "low",
        "medium",
        "high"
      ]
    }
  }
}
```

## Responses

### 200: One answer per question, under the question's id.

Body (`application/json`): `SystemOneResponse`

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `model` | string | yes | The versioned id of the model that answered. |
| `answers` | object | yes | One answer per question, under the question's id. |
| `usage` | object | yes |  |
| `usage.input_tokens` | integer | yes | Tokens the model read to answer, images included, billed at the input price. The state is read with each question, so the count grows with the number of questions. |
| `usage.output_tokens` | integer | yes | One per answer, as in Jev's format. Not billed. |
| `usage.text_tokens` | integer | no | Present only for a request with images: the text part of `input_tokens`, each image counted as its placeholder. |
| `usage.image_tokens` | integer | no | Present only for a request with images: the tokens the images expand to, over every question's read. Part of `input_tokens`: `text_tokens + image_tokens = input_tokens`. |
| `latency_ms` | number | no | Time the model service took to answer, in milliseconds. |
| `calibration` | SystemOneCalibration (object) | no |  |
| `calibration.applied` | boolean | no | `true` when the probabilities are calibrated; `false` when the request asked for `raw`. |
| `calibration.temperatures` | object | no | The temperature applied to each question type. |

### 400: The body is not a JSON object, or `model` is missing.

Body (`application/json`): `ErrorResponse`

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `error` | Error (object) | yes | OpenAI-style error object. |
| `error.message` | string | yes | Human-readable description of the problem. |
| `error.type` | string | yes | Error category. One of `invalid_request_error`, `authentication_error`, `permission_error`, `not_found_error`, `rate_limit_error`, `server_error`. |
| `error.code` | string or null | no | Machine-readable error code, when available. |
| `error.param` | string or null | no | The request parameter the error refers to, when applicable. |

### 401: Missing or invalid API key.

Body (`application/json`): `ErrorResponse`, the same fields as under 400.

### 403: The key is valid but cannot use the decision API (`permission_denied`). For now only Serenity Edge API keys can; keys from a Serenity Star account cannot yet.

Body (`application/json`): `ErrorResponse`, the same fields as under 400.

### 404: The model is not a decision model (`model_not_found`), or the route is not enabled yet and answers like an unknown path.

Body (`application/json`): `ErrorResponse`, the same fields as under 400.

### 413: The request body is larger than the gateway accepts (4 MB, or 12 MiB on `orion-compass-flash` and `d3`; `request_too_large`).

Body (`application/json`): `ErrorResponse`, the same fields as under 400.

### 422: The model service refused the questions or the state: an unknown question type, invalid `criteria`, too many options, images the model cannot read, or a state longer than the model's context (`code: context_length_exceeded`). The message says what to fix.

Body (`application/json`): `ErrorResponse`, the same fields as under 400.

### 429: Rate limit exceeded, or the service is temporarily at capacity for this model. Wait for the number of seconds in the `Retry-After` header before retrying.

Header `Retry-After`: Seconds to wait before retrying.

Body (`application/json`): `ErrorResponse`, the same fields as under 400.

### 500: Unexpected server error: the model service returned an unexpected response (`upstream_error`), the request got no answer within 600 seconds (`timeout`), or an error in the gateway. Retry with backoff.

Body (`application/json`): `ErrorResponse`, the same fields as under 400.

### 503: The model service is temporarily unavailable (`upstream_unavailable`). Retry later and check the status page at https://status.serenityedge.ai.

Body (`application/json`): `ErrorResponse`, the same fields as under 400.
