# Consensus Room — AI/LLM reference

> Consensus Room (https://consensusroom.com) is a hosted multi-AI debate service: one question is debated in structured rounds by a panel of 2–5 LLMs (Claude, GPT, Gemini, Grok, Kimi, Qwen, Mistral, budget open models), and a moderator model returns a synthesis with consensus scores. This document specifies the Panel API (v1) for agents and programmatic clients.

## Access / setup

Consensus Room is SaaS — there is nothing to install.

1. Create an account at `https://consensusroom.com/register.html` (email+password or Google sign-in).
2. Add balance (menu → "Add credit"; Lemon Squeezy checkout, packs $5–$100). API calls that use paid models require positive balance; premium models require ≥ $1.00.
3. Create an API key at `https://consensusroom.com/api-keys.html`. The full key (`cr_live_` + 64 hex chars, 72 chars total) is shown exactly once at creation. Up to 10 active keys per account; keys can be revoked there.

## Configuration

Client-side configuration is a single value:

| Item | Value |
|---|---|
| Base URL | `https://consensusroom.com/api/v1` |
| Auth header | `Authorization: Bearer cr_live_...` (required on every request) |
| Content type | `application/json` |

There are no other client-configurable settings. Missing/invalid key → `401 {"error":{"code":"missing_api_key"|"invalid_api_key"}}`.

## API quickstart

Start a debate and block until the result (real request/response, abbreviated content):

```bash
curl -s "https://consensusroom.com/api/v1/debates?wait=120" \
  -H "Authorization: Bearer cr_live_..." \
  -H "Content-Type: application/json" \
  -d '{
    "question": "Event sourcing or CRUD for a microservice architecture? One paragraph.",
    "panelists": [
      {"key": "gpt",    "model": "gpt-4o-mini",       "role": "custom:Pragmatic systems architect"},
      {"key": "claude", "model": "claude-haiku-4-5",  "role": "skeptic"}
    ],
    "rounds": 1
  }'
```

Response (`200` when finished within `wait`; fields abbreviated):

```json
{
  "id": 696,
  "status": "DONE",
  "question": "Event sourcing or CRUD ...",
  "rounds": 1,
  "synthesis": "**Sentez**\n\nMikroservis mimarisi tasarımında ...",
  "messages": [
    {"round": 1, "panelist": "gpt", "content": "...", "model": "gpt-4o-mini-2024-07-18",
     "inputTokens": 187, "outputTokens": 338, "chargedUsd": 0.000346},
    {"round": 2, "panelist": "moderator", "content": "...", "model": "claude-haiku-4-5-20251001", "...": "..."}
  ],
  "totalTokens": 2731,
  "totalChargedUsd": 0.0046
}
```

`synthesis` is the final moderator message (Markdown, in the language of the question). It contains sections for merged ideas, disagreements, at least one rejected idea, an action list, per-panelist contribution summary, and a "Konsensüs"/consensus score list (1–5 per main idea). There is no separate machine-parseable JSON synthesis format yet — parse the Markdown or use the full `messages` array.

## Endpoints

| Method + path | Purpose |
|---|---|
| `GET /api/v1/models` | Panelist groups, per-model prices, available roles |
| `POST /api/v1/debates` | Start a debate. `202 {"id":N,"status":"RUNNING"}`, or with `?wait=<seconds>` (max 120) blocks and returns the full result (`200`) |
| `GET /api/v1/debates/{id}` | Status + transcript + synthesis. Statuses: `RUNNING`, `DONE`, `FAILED` |
| `GET /api/v1/debates/{id}/stream` | Server-sent events live stream (see below) |

### POST /api/v1/debates body

| Field | Type | Required | Constraints |
|---|---|---|---|
| `question` | string | yes | ≤ 4000 chars; debate language follows the question's language |
| `panelists` | array | yes | 2–5 entries of `{key, model, role}` |
| `panelists[].key` | string | yes | A panelist group key from `GET /models` (e.g. `claude`, `gpt`, `gemini`, `or-deepseek`, `orx-x-ai`) |
| `panelists[].model` | string | recommended | Must belong to that group (for `or-*`/`orx-*` keys the model must have the group's vendor prefix). Omitted → group default |
| `panelists[].role` | string | no | One of the roles from `GET /models` (`optimist`, `skeptic`, `finance`, `customer`, `lawyer`, `engineer`, `marketer`, `pro`, `con`) or `custom:<free text>` (≤160 chars; separators `, = \|` and newlines are stripped) |
| `rounds` | int | no | 1–3, default 2. Round 1 = independent ideas, round 2 = cross-critique, round 3 = refinement; synthesis always follows |
| `moderator` | string | no | Key of one of the chosen panelists; default = first panelist |
| `webhookUrl` | string | no | `http(s)` URL. On completion Consensus Room POSTs `{"id":N,"status":"DONE"|"FAILED"}` (no content — fetch details via API). The POST is not signed |

### SSE stream events

`GET /debates/{id}/stream` emits JSON events: `{"type":"message_start","panelist":...,"name":...,"round":N,"model":...}`, `{"type":"delta","panelist":...,"text":"..."}`, `{"type":"message_end",...}`, `{"type":"status","value":"SYNTHESIS"}`, `{"type":"usage","panelist":...,"inputTokens":N,"outputTokens":N,"chargedUsd":X,"totalChargedUsd":X}`, `{"type":"notice","code":...}`, `{"type":"done"}`. The connection closes when the debate finishes.

### Errors

Errors use standard HTTP codes with a JSON body; the machine-readable code is in `message`:

| HTTP | code | Meaning |
|---|---|---|
| 400 | `question_required`, `question_too_long`, `min_two_panelists`, `max_panelists`, `invalid_model`, `invalid_webhook_url` | Validation failure |
| 401 | `missing_api_key`, `invalid_api_key` | Auth failure |
| 402 | `insufficient_balance` | Paid models selected with $0 balance |
| 402 | `min_balance_premium` | Premium (non-budget) model selected with balance < $1.00 |
| 404 | `not_found` | Debate does not exist or belongs to another account |
| 429 | `daily_quota` | Over 500 debate-start requests per account per day |

## Pricing facts

- Charge per message = model provider list price × 1.5 (OpenRouter-routed models additionally include a 1.055 processing-fee factor in the base cost). Charged amounts are returned per message (`chargedUsd`) and per debate (`totalChargedUsd`) and deducted from the account balance as the debate runs.
- `GET /models` returns per-model `inputPerM`/`outputPerM` (USD per 1M tokens, base cost before the 1.5 factor) plus `cheap`/`free` flags. Typical debate costs: 2 budget models × 1 round ≈ $0.005–0.02; 3 panelists incl. one premium × 2 rounds ≈ $0.10–0.40.
- No subscription. The free one-time trial exists only in the web UI, not in the API.

## Architecture facts that affect integration

- Debates are asynchronous; typical wall time 30 s – 3 min depending on rounds/models. `wait` caps at 120 s — for `rounds:3` or 5 panelists prefer async + polling, SSE, or `webhookUrl`.
- The service is single-region (eu-central-1). Debate transcripts persist indefinitely and remain fetchable by `id` under the owning account.
- A failed panelist does not fail the debate: its message contains an error marker `[[err:rate_limited|daily_quota|provider|credits]]` and the debate continues with the remaining panelists. `status:"FAILED"` occurs only when the whole run fails.
- Rate limit: 500 debate starts per account per day. Balance is the effective cost cap; there is no per-debate hard cost limit beyond panelist/rounds/question caps.
- API-created debates appear in the owner's web UI history; follow-up questions and share links are currently web-UI-only features.

## Status / limitations

- Panel API v1 is new (2026-08). Stable parts: auth, `models`, `debates` create/get, SSE. Not yet available: structured JSON synthesis format, signed webhooks, follow-up rounds via API, MCP server (planned).
- Model lists are fetched live from providers and change without notice; call `GET /models` rather than hard-coding model ids. Group keys (`claude`, `gpt`, `or-*`, `orx-*`) are stable.

## Links

- Product: https://consensusroom.com
- Sign-up: https://consensusroom.com/register.html
- API keys: https://consensusroom.com/api-keys.html
- Site summary (llms.txt convention): https://consensusroom.com/llms.txt
- This document: https://consensusroom.com/documentation.ai.md
