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

# Jev Decisions

> Call TypeSafe Jev for typed choices, scores, and yes/no probabilities.

## Overview

TypeSafe Jev is a decision model. Instead of generating prose, Jev answers named, typed questions about the state you provide:

* `choice` selects one named option and returns a probability for every option.
* `score` returns an expected score over an ordered rubric.
* `noul` returns the probability that a yes/no statement is true.

For new HTTP integrations, use the native `POST /api/v1/decisions` endpoint. If you already use the official TypeSafe SDK, point it at NanoGPT's `POST /api/v1/systemone` compatibility endpoint. Jev is also available through NanoGPT's OpenAI-compatible Chat Completions and Responses APIs and the Anthropic-compatible Messages API.

<Note>
  Jev returns calibrated probabilities, not generated text. Use a chat model when you need an explanation or other free-form response.
</Note>

## Models

| Model                 | Use                                                                             |
| --------------------- | ------------------------------------------------------------------------------- |
| `typesafe/jev-1.13`   | Pinned Jev 1.13 release for integrations that should not follow alias upgrades. |
| `typesafe/jev-latest` | Moving alias for the latest Jev release.                                        |

The System One compatibility endpoint also accepts the official SDK model names `jev-1.13` and `jev-latest`. Use the `typesafe/...` names on the native Decisions and OpenAI/Anthropic-compatible endpoints.

## Native Decisions API

### Endpoint

```text theme={null}
POST https://nano-gpt.com/api/v1/decisions
```

Authenticate with either `Authorization: Bearer YOUR_API_KEY` or `x-api-key: YOUR_API_KEY`.

### Example request

<CodeGroup>
  ```bash cURL theme={null}
  curl https://nano-gpt.com/api/v1/decisions \
    -H "Authorization: Bearer $NANOGPT_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{
      "model": "typesafe/jev-1.13",
      "state": {
        "ticket": "I was charged twice and need this fixed before Friday.",
        "customer_tier": "business"
      },
      "questions": {
        "route": {
          "type": "choice",
          "instructions": "Which team should handle this ticket?",
          "criteria": {
            "billing": "Payments, invoices, refunds, or duplicate charges",
            "technical": "Product behavior, bugs, or integrations",
            "sales": "Plans, pricing, or purchasing"
          }
        },
        "urgency": {
          "type": "score",
          "instructions": "How urgent is the ticket?",
          "criteria": [
            "No time pressure",
            "Can wait several days",
            "Needs attention within one business day",
            "Immediate action is required"
          ]
        },
        "needs_human_review": {
          "type": "noul",
          "instructions": "Does this ticket need human review?",
          "criteria": {
            "true": "A person should review the case",
            "false": "Automation can safely handle the case"
          }
        }
      },
      "user": "customer_123"
    }'
  ```

  ```javascript JavaScript theme={null}
  const response = await fetch("https://nano-gpt.com/api/v1/decisions", {
    method: "POST",
    headers: {
      Authorization: `Bearer ${process.env.NANOGPT_API_KEY}`,
      "Content-Type": "application/json",
    },
    body: JSON.stringify({
      model: "typesafe/jev-1.13",
      state: {
        ticket: "I was charged twice and need this fixed before Friday.",
        customer_tier: "business",
      },
      questions: {
        route: {
          type: "choice",
          instructions: "Which team should handle this ticket?",
          criteria: {
            billing: "Payments, invoices, refunds, or duplicate charges",
            technical: "Product behavior, bugs, or integrations",
            sales: "Plans, pricing, or purchasing",
          },
        },
        urgency: {
          type: "score",
          instructions: "How urgent is the ticket?",
          criteria: [
            "No time pressure",
            "Can wait several days",
            "Needs attention within one business day",
            "Immediate action is required",
          ],
        },
        needs_human_review: {
          type: "noul",
          instructions: "Does this ticket need human review?",
          criteria: {
            true: "A person should review the case",
            false: "Automation can safely handle the case",
          },
        },
      },
      user: "customer_123",
    }),
  });

  if (!response.ok) throw new Error(await response.text());
  const decision = await response.json();
  console.log(decision.answers);
  ```

  ```python Python theme={null}
  import os
  import requests

  response = requests.post(
      "https://nano-gpt.com/api/v1/decisions",
      headers={
          "Authorization": f"Bearer {os.environ['NANOGPT_API_KEY']}",
          "Content-Type": "application/json",
      },
      json={
          "model": "typesafe/jev-1.13",
          "state": {
              "ticket": "I was charged twice and need this fixed before Friday.",
              "customer_tier": "business",
          },
          "questions": {
              "route": {
                  "type": "choice",
                  "instructions": "Which team should handle this ticket?",
                  "criteria": {
                      "billing": "Payments, invoices, refunds, or duplicate charges",
                      "technical": "Product behavior, bugs, or integrations",
                      "sales": "Plans, pricing, or purchasing",
                  },
              },
              "urgency": {
                  "type": "score",
                  "instructions": "How urgent is the ticket?",
                  "criteria": [
                      "No time pressure",
                      "Can wait several days",
                      "Needs attention within one business day",
                      "Immediate action is required",
                  ],
              },
              "needs_human_review": {
                  "type": "noul",
                  "instructions": "Does this ticket need human review?",
                  "criteria": {
                      "true": "A person should review the case",
                      "false": "Automation can safely handle the case",
                  },
              },
          },
          "user": "customer_123",
      },
      timeout=30,
  )
  response.raise_for_status()
  print(response.json()["answers"])
  ```
</CodeGroup>

### Example response

```json theme={null}
{
  "id": "decision_...",
  "model": "typesafe/jev-1.13",
  "provider": "TypeSafe",
  "answers": {
    "route": {
      "type": "choice",
      "choice": "billing",
      "confidence": 0.97,
      "probabilities": {
        "billing": 0.97,
        "technical": 0.02,
        "sales": 0.01
      }
    },
    "urgency": {
      "type": "score",
      "score": 2.63,
      "confidence": 0.81,
      "legend": {
        "0": "No time pressure",
        "1": "Can wait several days",
        "2": "Needs attention within one business day",
        "3": "Immediate action is required"
      },
      "probabilities": {
        "0": 0.01,
        "1": 0.05,
        "2": 0.24,
        "3": 0.70
      }
    },
    "needs_human_review": {
      "type": "noul",
      "noul": 0.84
    }
  },
  "usage": {
    "input_tokens": 126,
    "output_tokens": 8
  }
}
```

`noul` is the probability of the `true` outcome. A `score` can be fractional because it is the expected value across the returned score distribution.

## Question types

| Type     | Required fields                                                            | Answer                                                                         |
| -------- | -------------------------------------------------------------------------- | ------------------------------------------------------------------------------ |
| `choice` | `instructions` and a non-empty `criteria` object                           | `choice`, `confidence`, and `probabilities` keyed by the supplied labels       |
| `score`  | `instructions` and 2-10 ordered `criteria` entries                         | Fractional `score`, `confidence`, `legend`, and `probabilities` keyed from `0` |
| `noul`   | `instructions`; optional `criteria.true` and `criteria.false` descriptions | `noul`, a probability from `0` to `1`                                          |

`instructions` and criterion descriptions can be strings, non-empty JSON objects, or non-empty arrays. A `choice` criterion may also be `null` when its label is self-explanatory. The top-level `state` can be a string, JSON object, or JSON array. Question names become keys in `answers`.

## Request fields

| Field        | Type                     | Required | Description                                                 |
| ------------ | ------------------------ | -------: | ----------------------------------------------------------- |
| `model`      | string                   |      Yes | `typesafe/jev-1.13` or `typesafe/jev-latest`.               |
| `state`      | string, object, or array |      Yes | Application state for Jev to evaluate.                      |
| `questions`  | object                   |      Yes | One or more named `choice`, `score`, or `noul` questions.   |
| `user`       | string                   |       No | Your end-user identifier, up to 256 characters.             |
| `session_id` | string                   |       No | Your session identifier, up to 256 characters.              |
| `trace`      | object                   |       No | Caller-supplied trace metadata.                             |
| `provider`   | object or null           |       No | Native Decisions routing controls. Usually omit this field. |

The native `provider` object can contain endpoint-level `order`, `only`, `ignore`, `allow_fallbacks`, `require_parameters`, `max_price`, `zdr`, and `data_collection` controls. These names describe native Decisions endpoints such as `TypeSafe`; they are not NanoGPT provider IDs. API-key provider restrictions and zero-data-retention requirements still apply.

## Official TypeSafe SDK

NanoGPT exposes `POST /api/v1/systemone` so the official TypeSafe JavaScript and Python SDKs can call Jev without changing their request types.

<CodeGroup>
  ```typescript JavaScript / TypeScript theme={null}
  // npm install @typesafe-ai/sdk
  import { choice, TypeSafeClient } from "@typesafe-ai/sdk";

  const client = new TypeSafeClient({
    apiKey: process.env.NANOGPT_API_KEY!,
    baseURL: "https://nano-gpt.com/api",
    defaultModel: "jev-latest",
  });

  const result = await client.systemOne({
    state: { ticket: "I was charged twice. Please fix this." },
    questions: {
      route: choice("Which team should handle this ticket?", {
        billing: null,
        technical: null,
        sales: null,
      }),
    },
  });

  console.log(result.answers.route.choice);
  ```

  ```python Python theme={null}
  # pip install typesafe-sdk
  import os
  from typesafe_sdk import Choice, TypeSafeClient

  with TypeSafeClient(
      api_key=os.environ["NANOGPT_API_KEY"],
      base_url="https://nano-gpt.com/api",
      model="jev-latest",
  ) as client:
      result = client.system_one(
          state={"ticket": "I was charged twice. Please fix this."},
          questions={
              "route": Choice(
                  instructions="Which team should handle this ticket?",
                  criteria={
                      "billing": None,
                      "technical": None,
                      "sales": None,
                  },
              ),
          },
      )

  print(result.choices["route"].choice)
  ```
</CodeGroup>

<Warning>
  The SDK's System One call is supported. The SDK's model-list method is not, because NanoGPT's `/api/v1/models` response uses the NanoGPT/OpenAI-compatible model-list shape rather than TypeSafe's model-list shape.
</Warning>

## OpenAI and Anthropic compatibility

Use these shapes when Jev must fit into an existing OpenAI- or Anthropic-compatible client. The answer object is returned as JSON text, so parse the returned string once.

### Chat Completions

```bash theme={null}
curl https://nano-gpt.com/api/v1/chat/completions \
  -H "Authorization: Bearer $NANOGPT_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "typesafe/jev-latest",
    "messages": [
      {"role": "user", "content": "I was charged twice. Please fix this."}
    ],
    "stream": false,
    "response_format": {
      "type": "questions",
      "questions": {
        "billing": {
          "type": "noul",
          "instructions": "Is this request about billing?"
        }
      }
    }
  }'
```

Parse `choices[0].message.content` as JSON.

### Responses API

```bash theme={null}
curl https://nano-gpt.com/api/v1/responses \
  -H "Authorization: Bearer $NANOGPT_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "typesafe/jev-latest",
    "input": "I was charged twice. Please fix this.",
    "stream": false,
    "store": false,
    "text": {
      "format": {
        "type": "questions",
        "questions": {
          "billing": {
            "type": "noul",
            "instructions": "Is this request about billing?"
          }
        }
      }
    }
  }'
```

Parse `output_text` as JSON. The same JSON text is also available in the assistant output item.

### Anthropic Messages

```bash theme={null}
curl https://nano-gpt.com/api/v1/messages \
  -H "x-api-key: $NANOGPT_API_KEY" \
  -H "anthropic-version: 2023-06-01" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "typesafe/jev-latest",
    "max_tokens": 128,
    "messages": [
      {"role": "user", "content": "I was charged twice. Please fix this."}
    ],
    "stream": false,
    "output_config": {
      "format": {
        "type": "questions",
        "questions": {
          "billing": {
            "type": "noul",
            "instructions": "Is this request about billing?"
          }
        }
      }
    }
  }'
```

Parse `content[0].text` as JSON. `max_tokens` is accepted for Anthropic SDK compatibility but does not change Jev's fixed typed output.

## Limitations

Jev requests are deliberately narrower than chat generation requests:

* Only non-streaming text input in `user` messages is supported on compatibility endpoints.
* System, developer, assistant, tool, image, audio, video, and file input is not supported.
* Tools, sampling controls, log probabilities, and reasoning generation controls are not supported.
* Output-token-limit fields are accepted where an SDK requires them, but they do not change Jev's fixed typed output.
* BYOK and accountless x402 payments are not supported.
* Standard NanoGPT or `X-Provider` provider pins are not supported. Use the native Decisions `provider` object only when you need endpoint-level routing controls.

Unsupported combinations return a `400` error instead of being silently ignored.


## OpenAPI

````yaml POST /v1/decisions
openapi: 3.1.0
info:
  title: NanoGPT API
  description: >-
    API documentation for the NanoGPT language, image, video, speech-to-text,
    and text-to-speech generation services
  license:
    name: MIT
  version: 1.0.0
servers:
  - url: https://nano-gpt.com/api
    description: NanoGPT API Server
security: []
paths:
  /v1/decisions:
    post:
      tags:
        - Decisions
      summary: Create typed decisions with TypeSafe Jev
      description: >-
        Evaluates application state with one or more typed Choice, Score, or
        Noul questions. Jev returns typed answers and calibrated probabilities
        rather than generated text.
      operationId: createDecision
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/DecisionsRequest'
      responses:
        '200':
          description: Typed decisions response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/DecisionsResponse'
        '400':
          description: Invalid state, questions, model, or unsupported parameter
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/DecisionsError'
        '401':
          description: Missing or invalid API key
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/DecisionsError'
        '429':
          description: Rate limit exceeded
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/DecisionsError'
      security:
        - bearerAuth: []
        - apiKeyAuth: []
components:
  schemas:
    DecisionsRequest:
      type: object
      additionalProperties: false
      required:
        - model
        - state
        - questions
      properties:
        model:
          type: string
          enum:
            - typesafe/jev-1.13
            - ~typesafe/jev-latest
            - typesafe/jev-latest
        state:
          description: Application state to evaluate.
          oneOf:
            - type: string
            - type: object
              additionalProperties: true
            - type: array
              items: {}
        questions:
          type: object
          minProperties: 1
          additionalProperties:
            oneOf:
              - $ref: '#/components/schemas/DecisionsChoiceQuestion'
              - $ref: '#/components/schemas/DecisionsScoreQuestion'
              - $ref: '#/components/schemas/DecisionsNoulQuestion'
        provider:
          description: >-
            Optional native Decisions endpoint-routing controls. These are not
            NanoGPT provider IDs.
          type:
            - object
            - 'null'
          additionalProperties: true
        session_id:
          type: string
          maxLength: 256
        trace:
          type: object
          additionalProperties: true
        user:
          type: string
          maxLength: 256
    DecisionsResponse:
      type: object
      required:
        - model
        - answers
        - usage
      properties:
        id:
          type: string
        model:
          type: string
        provider:
          type: string
        answers:
          type: object
          additionalProperties:
            oneOf:
              - $ref: '#/components/schemas/DecisionsChoiceAnswer'
              - $ref: '#/components/schemas/DecisionsScoreAnswer'
              - $ref: '#/components/schemas/DecisionsNoulAnswer'
        usage:
          type: object
          required:
            - input_tokens
            - output_tokens
          properties:
            input_tokens:
              type: integer
              minimum: 0
            output_tokens:
              type: integer
              minimum: 0
            cost:
              type: number
              minimum: 0
    DecisionsError:
      type: object
      required:
        - error
      properties:
        error:
          type: object
          required:
            - message
            - type
            - code
          properties:
            message:
              type: string
            type:
              type: string
            code:
              type: string
            param:
              type: string
    DecisionsChoiceQuestion:
      type: object
      required:
        - type
        - instructions
        - criteria
      properties:
        type:
          type: string
          const: choice
        instructions:
          $ref: '#/components/schemas/DecisionsStructuredDescription'
        criteria:
          type: object
          minProperties: 1
          additionalProperties:
            oneOf:
              - $ref: '#/components/schemas/DecisionsStructuredDescription'
              - type: 'null'
    DecisionsScoreQuestion:
      type: object
      required:
        - type
        - instructions
        - criteria
      properties:
        type:
          type: string
          const: score
        instructions:
          $ref: '#/components/schemas/DecisionsStructuredDescription'
        criteria:
          type: array
          minItems: 2
          maxItems: 10
          items:
            $ref: '#/components/schemas/DecisionsStructuredDescription'
    DecisionsNoulQuestion:
      type: object
      required:
        - type
        - instructions
      properties:
        type:
          type: string
          const: noul
        instructions:
          $ref: '#/components/schemas/DecisionsStructuredDescription'
        criteria:
          type: object
          required:
            - 'true'
            - 'false'
          properties:
            'true':
              $ref: '#/components/schemas/DecisionsStructuredDescription'
            'false':
              $ref: '#/components/schemas/DecisionsStructuredDescription'
    DecisionsChoiceAnswer:
      type: object
      required:
        - type
        - choice
        - confidence
        - probabilities
      properties:
        type:
          type: string
          const: choice
        choice:
          type: string
        confidence:
          type: number
          minimum: 0
          maximum: 1
        probabilities:
          type: object
          additionalProperties:
            type: number
            minimum: 0
            maximum: 1
    DecisionsScoreAnswer:
      type: object
      required:
        - type
        - score
        - confidence
        - legend
        - probabilities
      properties:
        type:
          type: string
          const: score
        score:
          type: number
          minimum: 0
        confidence:
          type: number
          minimum: 0
          maximum: 1
        legend:
          type: object
          additionalProperties: true
        probabilities:
          type: object
          additionalProperties:
            type: number
            minimum: 0
            maximum: 1
    DecisionsNoulAnswer:
      type: object
      required:
        - type
        - noul
      properties:
        type:
          type: string
          const: noul
        noul:
          type: number
          minimum: 0
          maximum: 1
    DecisionsStructuredDescription:
      description: >-
        A non-empty string, JSON object, or JSON array used to describe a
        question or outcome.
      oneOf:
        - type: string
          minLength: 1
        - type: object
          minProperties: 1
          additionalProperties: true
        - type: array
          minItems: 1
          items: {}
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
    apiKeyAuth:
      type: apiKey
      in: header
      name: x-api-key

````