# Quick start

Jepela is a hosted API at `https://api.jepela.com`. There is nothing to install or run. Three steps.

## 1. A key

Create an account at [app.jepela.com](https://app.jepela.com/#register) and choose your region. Confirm your email address, then pay by card under Billing to start at once (the account is approved as soon as the payment goes through), or wait for Jepela to approve it; then you create your keys in the console. Keep it in `JEPELA_API_KEY`. Keys start with `jj_live_`; only their hash is stored.

## 2. A decision

```bash
curl -s https://api.jepela.com/v1/systemone \
  -H "Authorization: Bearer $JEPELA_API_KEY" -H "Content-Type: application/json" \
  -d '{
    "state": {"message": "We were charged twice for September again. We just want the money back."},
    "model": "jepela-latest",
    "questions": {
      "route":   {"type": "choice", "instructions": "Which team should handle this?",
                  "criteria": {"billing": "Charges and refunds", "support": "Product problems", "sales": "New licences"}},
      "refund":  {"type": "noul",   "instructions": "Is the customer asking for money back?"},
      "urgency": {"type": "score",  "instructions": "How urgent is this?",
                  "criteria": ["Can wait a week", "Should be handled today", "Blocking the customer now"]}
    }
  }'
```

The answer, measured on 2026-09-23 through a gateway and product started from this repository (`jepela-latest` resolved to `jepela`, whose router picked the English checkpoint). `engine.runtime`, the engine's own metadata, is left out here; the engine adds fields of its own, such as `action`, which Jepela passes through (its `act_probability` was 1.0 on every recorded answer and tells you nothing; see the [API reference](api.md)). The warning says that `route` has no option for a message that fits none of the three; add `"other": "None of these"` and it goes away:

```json
{
 "decision_id": "dec_02561a958a6ea3a255a69a71",
 "model": "jepela",
 "engine": {
  "name": "jepela",
  "checkpoint": "english"
 },
 "answers": {
  "route": {
   "type": "choice",
   "choice": "billing",
   "probabilities": {
    "billing": 0.992,
    "support": 0.005,
    "sales": 0.002
   },
   "confidence": 0.955,
   "action": {
    "act_probability": 1.0
   }
  },
  "refund": {
   "type": "noul",
   "noul": 0.897,
   "confidence": 0.897,
   "action": {
    "act_probability": 1.0
   }
  },
  "urgency": {
   "type": "score",
   "score": 1.671,
   "legend": {
    "0": "Can wait a week",
    "1": "Should be handled today",
    "2": "Blocking the customer now"
   },
   "probabilities": {
    "0": 0.008,
    "1": 0.313,
    "2": 0.679
   },
   "confidence": 0.396,
   "action": {
    "act_probability": 1.0
   }
  }
 },
 "usage": {
  "input_characters": 487,
  "questions": 3,
  "answers": 3,
  "answers_billed": 3,
  "engine_answers": 3,
  "memory_lines_used": 0,
  "memory_lines_seen": 0,
  "engine_ms": 36.0,
  "cached": false,
  "state_tokens": 20,
  "state_tokens_read": 20,
  "state_truncated": false,
  "input_tokens": 163,
  "cost": 3e-05,
  "currency": "USD",
  "balance": 4.99994,
  "gateway_ms": 37.1
 },
 "warnings": [
  {
   "code": "no_other_option",
   "question": "route",
   "message": "add an option such as other or none_of_these, so a state that fits nothing is not forced into the least bad option"
  }
 ],
 "reading": {
  "route": {
   "state_tokens": 20,
   "read": 20,
   "room": 480,
   "chars_read": 86,
   "truncated": false
  },
  "refund": {
   "state_tokens": 20,
   "read": 20,
   "room": 478,
   "chars_read": 86,
   "truncated": false
  },
  "urgency": {
   "state_tokens": 20,
   "read": 20,
   "room": 475,
   "chars_read": 86,
   "truncated": false
  }
 }
}
```

`reading` says how much of the state the engine read for each question (all of it here); `decision_id` is what you send back with `POST /v1/feedback` once you know the right answer.

## 3. A memory

Write what you know about the subject once, then name it in decisions:

```bash
curl -s https://api.jepela.com/v1/memory/remember -H "Authorization: Bearer $JEPELA_API_KEY" -H "Content-Type: application/json" \
  -d '{"subject": "acme", "text": "ACME Logistics holds an enterprise contract; refunds for ACME go to the billing team within one business day.\nACME'\''s account is handled by the enterprise desk."}'
```

Add `"subject": "acme"` and `"memory": {"compare": true}` to the decision request. The answer gains a `memory` block: the lines used (`hits`), how many the engine read (`lines_seen`), the answer without memory, and what changed.

## Python

```bash
pip install "git+https://github.com/jepelasweden/jepela#subdirectory=sdk/python"
```

```python
from jepela import JepelaClient, Choice, Noul, Score

with JepelaClient() as client:
    r = client.system_one(
        state={"message": "We were charged twice for September again."},
        questions={"route": Choice("Which team should handle this?", {"billing": "Charges and refunds", "support": "Product problems"}),
                   "refund": Noul("Is the customer asking for money back?"),
                   "urgency": Score("How urgent is this?", ["Can wait a week", "Should be handled today", "Blocking the customer now"])},
        subject="acme", memory={"compare": True})
    print(r.answers["route"].choice, r.answers["route"].confidence, r.memory.lines_used, r.usage.cost)
```
