These docs describe DecideDB as designed. It isn't released yet, so names, URLs and endpoints may change.
Introduction
The Jev API is stateless: every call returns an answer and then it's gone. DecideDB keeps a record of everything. Your app still calls Jev itself; the DecideDB SDK copies each request and response to DecideDB in the background, so it never slows your app down.
- Log: every request and response is saved automatically.
- Browse: a web dashboard lets you search past decisions without SQL.
- Grade: tag a past decision good or bad once you know the real outcome.
The fastest way to start is DecideDB Cloud: nothing to run. Prefer to keep everything on your own servers? See Self-host.
Quickstart (Cloud)
1. Sign up and create an API key in the console. It starts with jdb_live_.
2. Install the SDK:
uv add decidedbNot on PyPI / npm yet. Until then, install straight from GitHub: uv add "decidedb @ git+https://github.com/SultanAlzoghaibi/JevDB#subdirectory=sdk/python"
3. Set your keys and point the SDK at DecideDB Cloud:
TYPESAFE_API_KEY=sk-… # Jev, from console.typesafe.ai
DECIDEDB_API_KEY=jdb_live_… # DecideDB, from your DecideDB console
DECIDEDB_URL=https://<decidedb-cloud-url>4. Call Jev through the DecideDB client, then open the console to see the decision. Full examples: Client SDK.
Where it goes in your project
Create the client once in its own small file and import it wherever you call Jev. That way keys, group_id and tags live in one place.
my-app/
├── .env # TYPESAFE_API_KEY, DECIDEDB_API_KEY, DECIDEDB_URL
├── pyproject.toml # dependency: decidedb
└── app/
├── main.py # your server / entry point
├── decidedb_client.py # ← create DecideDB(...) once here
└── tickets.py # from app.decidedb_client import decidedb
# decidedb.system_one(state=…, questions=…)from decidedb import DecideDB
# Keys and URL come from .env. One client for the whole app.
decidedb = DecideDB(group_id="support-bot", tags=["prod"])What gets logged
Each call becomes one row per question. Fields you filter on get their own columns; the full request and response are kept as JSONB so nothing is lost.
| Column | Type | Notes |
|---|---|---|
| id | text | Decision id: decidedb.id_of(response) |
| created_at | timestamptz | When the call started |
| question_type | text | noul, choice or score |
| answer | text | The typed answer, as text |
| confidence | real | 0 to 1 |
| latency_ms | integer | Jev round trip time |
| grade | text | good, bad or null |
| payload | jsonb | Full request and response |
Writes happen in the background after the response is sent, so logging never slows your app down. The trade-off: if your process is killed before flush(), the last few queued logs can be lost.
Question types
Jev supports three question types. DecideDB stores each one the same way, so they're all searchable.
| Type | Answers | Stored answer |
|---|---|---|
| Noul | Yes or no | yes / no |
| Choice | One option, with the full probability breakdown | The chosen option (breakdown in payload) |
| Score | A number on a scale | The number, e.g. 7.2 |
Grading
When the real outcome is known, send a grade for the request. You can grade minutes or weeks later, and grading again replaces the previous grade.
curl -X POST https://<decidedb-cloud-url>/api/decisions/<decision-id>/grade \
-H "Authorization: Bearer $DECIDEDB_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "grade": "good", "note": "customer accepted the refund" }'| Field | Required | Notes |
|---|---|---|
| grade | yes | "good" or "bad" |
| note | no | Free text, shown in the dashboard |
Dashboard
Open the console (or http://localhost:3000/console when self-hosting) to see every decision in a table, newest first.
- Search by text in the state or answer
- Filter by question type and by graded, ungraded, good or bad
- Click a row to see the full state, every answer and the raw JSON
- Grade a decision directly from its detail view
Self-host (alternative)
Want your data on your own machines? Run DecideDB yourself. You need Docker; Postgres runs in a container.
git clone https://github.com/SultanAlzoghaibi/JevDB.git decidedb
cd decidedb
docker compose up -d # Postgres
cd web && bun install && bun run db:migrate && bun run devThen point the SDK at your instance with DECIDEDB_URL=http://localhost:3000 (the SDK default). Everything else in these docs works the same.
Configuration
Self-hosting only. DecideDB Cloud is configured for you. Set these in web/.env.local.
| Variable | Default | Description |
|---|---|---|
| DATABASE_URL | (compose Postgres) | Postgres connection string |
| BETTER_AUTH_URL | http://localhost:3000 | Where the dashboard is served |
| DECIDEDB_RETENTION_DAYS | 30 | Delete logs older than this; 0 keeps forever |
| DECIDEDB_RETRIEVAL | off | Experimental retrieval, see below |
Retrieval Experimental
When enabled, DecideDB picks relevant graded examples from your history and adds them to a new request's state as few-shot context, aiming to improve accuracy.
This is unproven. Injected examples can help, hurt, or do nothing, so it's off by default. When it's on, the original state and the injected context are logged separately, so you can compare results with and without it.
Full guide, walkthrough and options: Retrieval (RAG).