## Evaluation endpoint

```
POST https://api.typesafe.ai/v1/systemone
Authorization: Bearer <API_KEY>
Content-Type: application/json
```

## Request body

The top-level shape of every request. Each entry in the `questions` map is a typed question you name.

### Parameters

#### state

- **Type:** string | object | array  
- **Required:** Yes  
- The content to evaluate. A plain string for text, or structured data (object/array) for things like chat logs, records, or the current state of your application. See [State](https://docs.typesafe.ai/concepts/state) for formats and best practices.

#### model

- **Type:** string  
- **Required:** Yes  
- The model that handles the request. Use "jev-latest", TypeSafe’s flagship model. See [Models](https://docs.typesafe.ai/models) for the available models and aliases.

#### questions

- **Type:** map<string, Question>  
- **Required:** Yes  
- A map of typed [Question](https://docs.typesafe.ai/api#question-types) objects. You choose each key; answers come back under the same keys.

### Example request

```json
{
  "state": "Help! My payouts have been failing for 3 days.",
  "model": "jev-latest",
  "questions": {
    "is_urgent": {
      "type": "noul",
      "instructions": "Does this convey urgency?"
    }
  }
}
```

## Question types

### Noul

A yes/no question. Returns the probability the answer is yes.

#### Parameters

- **type:** "noul"  
- **Required:** Yes

- **instructions:** string | object | array  
- **Required:** Yes  
- The yes/no question to evaluate.

- **criteria:** object  
- **Optional:** Optional descriptions of what a yes and a no mean.

### Example request

```json
{
  "state": "Help! My payouts have been failing for 3 days.",
  "model": "jev-latest",
  "questions": {
    "is_urgent": {
      "type": "noul",
      "instructions": "Does this convey urgency?",
      "criteria": {
        "true": "Explicitly time-sensitive",
        "false": "No urgency expressed"
      }
    }
  }
}
```

### Choice

Picks one option from a set you define. Returns the chosen option and the full probability distribution.

#### Parameters

- **type:** "choice"  
- **Required:** Yes

- **instructions:** string | object | array  
- **Required:** Yes

- **criteria:** map<string, string | null>  
- **Required:** A map of option to rubric description; use null when an option needs no extra detail.

### Example request

```json
{
  "state": "Help! My payouts have been failing for 3 days.",
  "model": "jev-latest",
  "questions": {
    "department": {
      "type": "choice",
      "instructions": "Which team should handle this?",
      "criteria": {
        "billing": "Payments, invoicing, refunds",
        "technical": "Bugs, outages, integrations",
        "sales": "Pricing, upgrades, new accounts"
      }
    }
  }
}
```

### Score

Rates the state along a rubric you define. Returns a probability-weighted value across your levels.

#### Parameters

- **type:** "score"  
- **Required:** Yes

- **instructions:** string | object | array  
- **Required:** Yes

- **criteria:** array  
- **Required:** An ordered array of level descriptions. You must include at least two levels.

### Example request

```json
{
  "state": "Help! My payouts have been failing for 3 days.",
  "model": "jev-latest",
  "questions": {
    "frustration": {
      "type": "score",
      "instructions": "How frustrated is the customer?",
      "criteria": ["Calm", "Frustrated", "Very angry"]
    }
  }
}
```

## Response body

One answer per question, returned under the same ids you provided.

### Example response

```json
{
  "model": "jev-latest",
  "answers": {
    "is_urgent": {
      "type": "noul",
      "noul": 0.92
    }
  },
  "usage": { "input_tokens": 312, "output_tokens": 48 }
}
```

## Answer types

### Noul answer

#### Parameters

- **type:** "noul"  
- **Required:** Yes

- **noul:** number  
- **Required:** The yes/no answer on a scale from 0 (no) to 1 (yes).

### Example response

```json
{
  "model": "jev-latest",
  "answers": {
    "is_urgent": {
      "type": "noul",
      "noul": 0.92
    }
  },
  "usage": { "input_tokens": 312, "output_tokens": 48 }
}
```

### Choice answer

#### Parameters

- **type:** "choice"  
- **Required:** Yes

- **choice:** string  
- **Required:** The highest-probability option.

- **probabilities:** map<string, number>  
- **Required:** Every option mapped to its probability (floats that sum to 1).

### Example response

```json
{
  "model": "jev-latest",
  "answers": {
    "department": {
      "type": "choice",
      "choice": "technical",
      "probabilities": { "billing": 0.08, "technical": 0.85, "sales": 0.07 },
      "confidence": 0.82
    }
  },
  "usage": { "input_tokens": 312, "output_tokens": 48 }
}
```

### Score answer

#### Parameters

- **type:** "score"  
- **Required:** Yes

- **score:** number  
- **Required:** The probability-weighted answer across the levels; can land between levels.

- **legend:** map<string, string>  
- **Required:** Each level number mapped back to its description.

- **probabilities:** map<string, number>  
- **Required:** Each level (string key) mapped to its probability (floats that sum to 1).

### Example response

```json
{
  "model": "jev-latest",
  "answers": {
    "frustration": {
      "type": "score",
      "score": 1.6,
      "legend": { "0": "Calm", "1": "Frustrated", "2": "Very angry" },
      "probabilities": { "0": 0.05, "1": 0.3, "2": 0.65 },
      "confidence": 0.78
    }
  },
  "usage": { "input_tokens": 312, "output_tokens": 48 }
}
```

## Errors

Errors use standard HTTP status codes with a JSON body describing what went wrong.

| Status | Meaning |
| --- | --- |
| `401 Unauthorized` | Missing or invalid API key. Check the `Authorization` header. |
| `422 Unprocessable Entity` | The request body failed validation — for example a missing required field or a malformed question. The body details the offending field. |
| `429 Too Many Requests` | You have exceeded your rate limit. Back off and retry after a short delay. |
| `529 Overloaded` | TypeSafe is temporarily overloaded. Retry after a short delay. |

### Handling rate limits

When you receive a `429 Too Many Requests` or `529 Overloaded` response, retry the request with exponential backoff instead of retrying immediately. Our client SDKs handle this automatically, so no extra handling is needed if you use one of our SDKs with its default retry policy.
