# System One Decision API Contract

Each deployment exposes a high-throughput, non-autoregressive decision engine
compatible with the System One API standard. The engine binds to `127.0.0.1`
on a configured port (default `8787` or assigned deployment port).

The API key is provided during deployment creation and validated via standard
HTTP Bearer authentication.

## `POST /v1/systemone`

Send JSON with a Bearer API key:

```http
POST /v1/systemone HTTP/1.1
Host: 127.0.0.1:8787
Authorization: Bearer zv_live_…
Content-Type: application/json

{
  "state": "Customer: My card was swallowed by the ATM dispenser.",
  "questions": {
    "intent": {
      "type": "choice",
      "instructions": "Route to the appropriate support department:",
      "criteria": {
        "card_swallowed": "ATM card swallowed or retained by machine",
        "atm_support": "General ATM transaction support and inquiries",
        "declined_cash": "Card declined during cash withdrawal attempt"
      }
    }
  }
}
```

### Request Schema

| Field | Type | Description |
| :--- | :--- | :--- |
| `state` | `string \| object \| null` | Context or conversation turn. Objects and strings are formatted into context tokens automatically. |
| `questions` | `map<string, Question>` | Map of unique decision keys to question specifications. |
| `questions.<key>.type` | `string` | Question type: `"choice"`, `"bool"`, or `"boolean"` (default `"choice"`). |
| `questions.<key>.instructions` | `string` | Prompt or routing instructions for this specific decision. |
| `questions.<key>.criteria` | `map<string, string>` | Map of candidate option identifiers to their semantic descriptions (2–10 candidates). |
| `questions.<key>.options` | `list<string>` | Alternative plain-string candidate list (2–10 candidates) if semantic criteria are not needed. |

Successful response (`200 OK`):

```json
{
  "model": "ZEV",
  "answers": {
    "intent": {
      "type": "choice",
      "choice": "card_swallowed",
      "confidence": 0.9412,
      "probabilities": {
        "card_swallowed": 0.9412,
        "atm_support": 0.0486,
        "declined_cash": 0.0102
      }
    }
  },
  "usage": {
    "input_tokens": 58,
    "output_tokens": 0
  }
}
```

### Response Schema

| Field | Type | Description |
| :--- | :--- | :--- |
| `model` | `string` | The active model identifier handling inference. |
| `answers` | `map<string, Answer>` | Decision results keyed by question identifier. |
| `answers.<key>.type` | `string` | Question type (e.g. `"choice"`). |
| `answers.<key>.choice` | `string` | The winning candidate key selected by the model. |
| `answers.<key>.confidence` | `float` | Calibrated probability of the winning candidate (`0.0`–`1.0`). |
| `answers.<key>.probabilities`| `map<string, float>` | Full softmax probability distribution across all submitted candidates. |
| `usage.input_tokens` | `integer` | Total context, question, and candidate tokens processed. |
| `usage.output_tokens` | `integer` | Output tokens generated (always `0` for single-pass non-autoregressive scoring). |

## Additional Endpoints

- **`POST /`**: Default System One endpoint for low-latency agent harnesses.
- **`POST /v3/compat/v1/systemone`**: Opper AI gateway-compatible compatibility route.
- **`GET /health`**: Health check returning `{"status": "ok"}`.
- **`GET /metrics`**: Server telemetry JSON including median latency, request throughput, and token statistics.
- **`GET /v1/models`**: Active model metadata and capabilities.

## Errors

Errors return standard HTTP status codes with a JSON payload `{"error": "<description>"}`:
- `400 Bad Request`: Malformed JSON or candidate count out of range (must be 2–10 choices).
- `401 Unauthorized`: Missing or invalid Bearer key.
- `413 Payload Too Large`: Context tokens exceed sequence length limit.
- `500 Internal Server Error`: Engine or inference failure.
