# Decisions API reference

The Decisions API answers questions about a piece of context with typed answers from options you define, plus a probability for every option. One endpoint, three question types. Use it for classification, routing, moderation, scoring and choosing an agent's next action.

- Base URL: `https://api.decisionsapi.cc`
- Auth: `Authorization: Bearer $DECISIONS_API_KEY` (keys start with `dk_live_`). Keep the key on the server, never in browser or mobile code.
- Billing: 1 credit per call with up to 4,000 input tokens, however many questions it asks. Failed calls are free.
- Human docs: https://decisionsapi.cc/docs

## POST /v1/decisions

```bash
curl https://api.decisionsapi.cc/v1/decisions \
  -H "Authorization: Bearer $DECISIONS_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "context": "Charged twice for my March invoice, please refund one.",
    "questions": {
      "team": {
        "type": "choice",
        "options": {
          "billing": "Payments, invoices, refunds",
          "technical": "Bugs, errors, integrations",
          "sales": "Plans, pricing, upgrades"
        }
      },
      "priority": {
        "type": "score",
        "question": "How soon does this need a human reply?",
        "options": ["whenever", "today", "within the hour", "right now"]
      },
      "refund_requested": {
        "type": "yes_no",
        "question": "Is the customer asking for money back?"
      }
    }
  }'
```

Response:

```json
{
  "id": "dec_a245cc31fc4f48d4939f",
  "model": "decisions",
  "answers": {
    "team": {
      "choice": "billing",
      "confidence": 0.97,
      "probabilities": { "billing": 0.97, "technical": 0.02, "sales": 0.01 }
    },
    "priority": {
      "choice": "today",
      "confidence": 0.73,
      "probabilities": { "whenever": 0.04, "today": 0.8, "within the hour": 0.1, "right now": 0.06 },
      "score": 1.18
    },
    "refund_requested": { "answer": true, "probability": 0.99 }
  },
  "usage": { "input_tokens": 412, "credits": 1 }
}
```

### Request fields

| Field | Type | Notes |
|---|---|---|
| `context` | string, object or array of strings | Required. What the decision is about: text, JSON (an event, a record, agent state) or a list of messages. |
| `questions` | object | Required. 1 to 32 questions, keyed by a name you choose (letters, digits, `_ . -`). Answers come back under the same names. |
| `questions.*.type` | `choice`, `score` or `yes_no` | Required. |
| `questions.*.options` | object or string[] | `choice`: object of option → plain-language description (or a list of option names), 2 to 255 options. `score`: ordered list, lowest first, 2 to 10 levels. Not used by `yes_no`. |
| `questions.*.question` | string | Required for `yes_no`. Optional framing for `choice` and `score`. |
| `instructions` | string | Optional policy text applied to every question. |
| `model` | string | Optional. `decisions` (default) or `decisions-latest`. |

### Answer fields

| Type | Fields |
|---|---|
| `choice` | `choice` (one of your options), `confidence` (0–1), `probabilities` (every option, sums to 1) |
| `score` | same as `choice`, plus `score`: expected position on the scale, 0 = first option |
| `yes_no` | `answer` (boolean), `probability` (probability of yes) |

`confidence` is how certain the model is; use it for thresholds and send low-confidence cases to a person.

## GET /v1/balance

```bash
curl https://api.decisionsapi.cc/v1/balance -H "Authorization: Bearer $DECISIONS_API_KEY"
# {"key_prefix":"dk_live_ab12","credits":4999}
```

## Errors

Body: `{"error": {"type": "...", "message": "...", "param": "..."}}`. Every response has an `x-request-id` header.

| Status | type | Meaning |
|---|---|---|
| 400 | `invalid_request` | Body failed validation. `param` names the field. Don't retry unchanged. |
| 401 | `unauthorized` | Missing or invalid API key. |
| 402 | `insufficient_balance` | No credits left. Top up at https://decisionsapi.cc/pricing |
| 413 | `context_too_large` | Context and questions exceed the per-request limit. |
| 429 | `rate_limited` | Too many requests. Retry after the `Retry-After` header. |
| 503 | `overloaded` | Temporarily over capacity. Retry with backoff after `Retry-After`. |
| 5xx | `server_error` | Safe to retry with exponential backoff. |

## Integration guidance

- Wrap the call in one function (for example `decide(context, questions)`) that reads the key from the `DECISIONS_API_KEY` environment variable, sets a 10 s timeout, and retries 429/503/5xx with exponential backoff (max 3 tries).
- Make options mutually exclusive and describe each in plain words. Add an escape hatch such as `"none": "None of the above apply"`.
- Ask several narrow questions in one request instead of one broad question with many options. It costs the same single credit.
- Read `confidence` and route answers below a threshold (start around 0.7) to a human or a fallback path.
- Log `id` with each decision for debugging and support.
