API reference · v1

One endpoint. A panel behind it.

Deliberation, as a call you can make from anywhere. Whatever you point at this endpoint gets several models arguing before it answers — in the editor you already work in, or inside the product you are building for someone else.

Quorum sends one prompt to several models at once, has them deliberate, and returns a single answer with a synthesis pass over their work. The transport is OpenAI-compatible: point base_url at https://www.quorum.dog/v1, set model, and your existing SDK code runs unchanged.

It is also slower than the single model you would otherwise call: 28.5s median, 88.2s at p90 (measured over 3,845 real deliberations, 2026-08-20). That is the trade the product is built on — seconds spent to lower the odds of being confidently wrong. It is a bad trade on most questions. The rest of this page is mostly about deciding, per request, which ones it is a good trade on.

Median latency
28.5s
p90 88.2s · n=3,845
Endpoints
6
plus 6 MCP tools
Pre-flight
$0
estimate is free
Compatibility
OpenAI
base_url + model

Two ways in, and they are different jobs

Both run the same deliberation. They differ in who the better answer is for, what you install, and whose provider account the seat calls land on.

Path one
Deliberation in your workflow

You are the one who benefits. The decision you were about to make alone — a schema, a migration strategy, a library choice — gets three frontier models disagreeing about it first.

  1. 01Add the Quorum MCP server to the editor or agent you already use.
  2. 02Your assistant gains six tools: deliberate, estimate, list_modes, get_receipt, certify_mode, run_test.
  3. 03Ask it to put something to the panel. The answer comes back with the receipt attached.
Whose keys
Quorum or yours. One developer has little to gain from managing f provider accounts, but the option is available.
Path two
Deliberation inside what you ship

Your users benefit, and they never hear the word Quorum. Your product’s AI feature answers from a panel instead of a single model, and you did not build the orchestration, the judging, or the receipts.

  1. 01Change base_url and model. Existing OpenAI SDK code runs unchanged.
  2. 02Call /v1/estimate first and route only the questions worth the wait to a panel.
  3. 03Pull /v1/receipts to show your own users what convened on their question.
Whose keys
Optionally your own. At product volume the spend, the rate limits and the provider relationship are already yours — BYOK moves the seat calls onto them.

Short answer on BYOK: it belongs to the second path. One developer using Quorum inside an editor has nothing to gain from routing seat traffic through their own provider accounts. A product shipping deliberation to its own users usually does. What BYOK does and does not move →

Quickstart

Two lines change. Send Idempotency-Key on every request — a deliberation costs real money and a retried POST should not run the panel twice.

Request
curl https://www.quorum.dog/v1/chat/completions \
  -H "Authorization: Bearer $QUORUM_API_KEY" \
  -H "Idempotency-Key: 8f2c1a90-..." \
  -H "Content-Type: application/json" \
  -d '{
    "model": "quorum-standard",
    "messages": [{"role":"user","content":"Which of these two contracts carries the renewal risk?"}]
  }'

Server-to-server only. A request arriving with a browser Origin header is rejected with browser_origin_not_allowed. That is why there is no in-browser playground on this page and will not be one: a playground would need a key in a browser.

The quorum object

Every response carries an additive quorum object alongside the OpenAI-shaped fields. It reports what actually happened rather than what was requested: how many rounds ran, whether the panel converged or hit its cap, and which model families saw the prompt.

Response
"quorum": {
  "request_id":    "req_8f2c1a90...",
  "rounds":        2,          // rounds actually run, not the cap
  "seats":         3,
  "converged":     true,       // false + capped:true means it ran out of rounds
  "capped":        false,
  "surcharge_usd": 0.0180,
  "billed_usd":    0.0417,
  "latency_ms":    27412,
  "engines":       ["anthropic", "google", "openai"]
}

Field values above are illustrative and taken from a real call shape. They are a schema reference, not a price: what a call costs you depends on the mode, the difficulty tier and the length of your prompt, and the only authoritative figure is the one on your own receipt.

converged: false with capped: true is the case worth handling: the panel was still disagreeing when it ran out of rounds. It is not an error, and the answer is still returned — but it is the signal that this question was genuinely contested, which is often more useful to log than the answer itself.

Architecture

Deciding which questions deserve a panel

The expensive question isn’t what deliberation costs. It’s which of these questions deserved it.

POST /v1/estimate answers the second one for free, before you spend anything on the first. It classifies a prompt with the same classifier the billed call uses and returns the price the billed call would charge — without running the panel and without touching your balance.

Most integrations put it immediately in front of a deliberation, where it works as a confirmation dialog: it fires only on turns you already decided to escalate, saves a little money, and changes nothing structurally. It is worth more at the top of your own router, where it fires on every turn and the escalation threshold is a number you own and move as your own evidence accumulates. We do not set it. You do.

Your agent’s control flow, per turn
User turn
POST /v1/estimate
free · sub-second · rate-limited
returns depth · difficulty_score · task_type · estimated_price_usd
depth = light AND difficulty_score < θ
— or —
estimated_price_usd > budget_remaining
Your existing single model
depth = deep OR difficulty_score ≥ θ
— or —
caller flagged this one high-stakes
POST /v1/chat/completions
28.5s median · 88.2s p90 · billed
response.quorum { rounds · converged · capped · engines }  →  GET /v1/receipts/:request_id for audit and attribution

What each returned field is a lever on

task_type
Domain routing. Most agents already have per-domain policy; this drops into it.
depth
light or deep. The coarse gate — light means do not escalate.
difficulty_score
0 to 1. The tunable threshold. You pick θ; you move it as your own outcome data arrives.
estimated_price_usd
The budget check, against a per-request or per-session ceiling you set.

difficulty_score is the one that matters. It is the field that makes this a control surface you own rather than a vendor feature you accept.

Four things to know before you wire it in

Free is not unmetered.
Estimate takes the same API key and the same rate-limit and concurrency ceilings as a billed call, and returns 429 with Retry-After on breach. An agent calling it on every turn needs its RPM sized for total turns, not for escalations. This is the single most likely cause of a bad first week in production.
It costs a round trip.
Sub-second, not zero. In a latency-sensitive loop, cache by prompt hash, or fire it concurrently with the cheap path and cancel whichever loses.
The classifier is a small model with a deterministic fallback.
A fast classifier, with a word-count and keyword heuristic that takes over when the model call fails. Both paths produce a score on the same scale by different means. Tune θ with a margin rather than against a boundary.
It does not return a time estimate.
The response carries no latency field today. Until it does, the timing half of the escalation decision has to come from the published p50/p90 above rather than from the response. This page will say so when that ships, and not before.

Modes, not models

The model string does not name an engine. It names a mode — a configuration of which engines sit in which seats, whether critique runs on every question or only hard ones, how many rounds, and which model judges and synthesises. Which engines that resolves to is ours to keep current; how deeply it deliberates is yours to choose.

quorum-standard
Three seats, gated critique — activates on harder questions, one to two rounds.
quorum-max
Frontier-only seats, critique on every question, deeper rounds. Slower and dearer by construction.

Entitlements are per-organisation, so this table is a hint and GET /v1/models is the answer. It returns what this key can call, with real pricing including any difficulty-tiered surcharge. Building your own mode and exposing it here: authoring a mode. How a mode’s performance is actually measured: Testing.

Endpoints

POST
/v1/chat/completions
Run a deliberation. OpenAI-compatible request and response.
GET
/v1/models
What this key can call, with real pricing. The source of truth.
POST
/v1/estimate
Classify and price a prompt without running it. Free.
GET
/v1/receipts/:request_id
Structured accounting for a past call. Transcript on opt-in.
POST
/v1/certify
Fixed 150-question certification run. $50 flat.
POST
/v1/tests
Configurable test run. 25% off, dry_run supported.

Receipts

GET /v1/receipts/:request_id returns the structured accounting for a past call: per-seat model and judge score, the difficulty and task-type signal that drove pricing, cost, latency, and mode_config_hash.

Aggregate metadata is the default. Full seat text requires ?include_transcript=true — a deliberate opt-in, because the transcript contains three models’ unsynthesised drafts and most systems should not be storing those by accident.

mode_config_hash is the field worth building on. It hashes the mode’s real configuration at the moment of the call, so you can prove the panel behind two answers was the same one — or detect that it wasn’t. Hosted models change under you without notice. This is how you find out.

Testing and certification

The same rig Quorum’s own Optimization Lab runs on, exposed as two endpoints. Both are blind and comparative: answers are anonymised and order-randomised before a judge panel sees them. What that rig currently says about Quorum’s own default mode, including where it loses, is on Testing.

POST /v1/certify

A fixed run, so results are comparable across modes: 150 questions, 3 judges, 2 repeats, $50 flat.

The verdict is a three-state ladder driven by the lower bound of a clustered 95% CI, not the point estimate — a mode that wins 58% of the time on a wide interval does not certify. That is deliberately conservative, and it is the reason a certification means anything.

POST /v1/tests

The configurable form: your own question buckets, judges and repeats. Bills at 25% off the mode’s normal price. Caps at 300 questions and 3 judge repeats.

dry_run: true prices a run without spending anything.

Both return a batch_id immediately and are polled. The shared execution engine runs about one question per minute, so a full 150-question certification takes roughly two and a half hours. Size your timeouts for that, not for an HTTP request.

MCP

The same capabilities are exposed as MCP tools, so an agent — or a person inside a tool that speaks MCP — can reach Quorum without an HTTP client.

deliberateestimatelist_modesget_receiptrun_testcertify_mode
Config
{
  "mcpServers": {
    "quorum": {
      "type": "http",
      "url": "https://www.quorum.dog/mcp",
      "headers": { "Authorization": "Bearer qk_..." }
    }
  }
}

Scope, stated plainly: the hosted server is live at https://www.quorum.dog/mcp and speaks stateless Streamable HTTP, so any client that supports remote MCP can point at it with your API key as the bearer token. It is not yet listed in any connector directory, and it has had no external callers — you would be the first. All six tools above are hosted; run_test and certify_mode joined the other four on 2026-08-22. Both spend real money — run_test bills per question at 25% off deliberate pricing and takes dry_run: true to price a run for nothing, and certify_mode commits $50 flat for 150 questions. A GET to that URL returns 405, which is correct rather than a fault.

Limits and errors

Concurrency
5 default
Requests/min
60 default
Per-call cost ceiling
yours to set

Every error carries a typed error.type, a stable error.code, and quorum.request_id — including errors thrown before a request had a body worth billing. An agent that reads code recovers; one that retries on any non-200 burns budget on a model_not_found.

401
invalid_api_key
Missing, wrong, or revoked key.
403
browser_origin_not_allowed
The request carried a browser Origin header.
404
model_not_found
No mode with that id is entitled to this key. Do not retry.
413
request_too_large
Input exceeds the ceiling. Cost scales faster than length — the prompt fans out.
429
rate_limit_exceeded
Per-key RPM. Retry-After is set. Also applies to estimate.
429
concurrency_limit_exceeded
Too many in flight for this organisation.
402
insufficient_balance
Prepaid balance would not cover the reservation.

One shape that surprises people: cost scales faster than input length, because the prompt fans out to every seat before anything comes back. A long document is not one long call, it is three or more.

Where your prompt goes

Deliberation means more than one company’s model sees the prompt. There is no version of this product where that is not true, so the answer is disclosure rather than reassurance: quorum.engines on every response names the model families that saw that call. Not a policy page, not a quarterly report — the response body, every time, without asking.

Two boundaries worth stating, because together they look like an inconsistency and are not. Provider brands are public. A mode’s gallery card names the providers it draws on — Anthropic, Google, OpenAI — because you should be able to read the ingredients before you buy. Specific model identifiers are not. They appear in quorum.engines, in a per-call record delivered to the caller who paid for that call, and nowhere on a public or shareable surface.

The third rule follows from both: the answer is Quorum’s. It is not decomposed into which engine wrote which paragraph, and no seat is labelled with a vendor’s name on anything you can print, export or share — a seat is a shape and a colour. That is a trademark position, not a modesty one.

Organisational data-handling, billing and compliance questions: /enterprise.

Bring your own keys

Live and self-serve today for OpenAI, Google, Groq and Bedrock, owner-only, configured from your organisation dashboard. Seat traffic then runs through your own provider accounts and your own provider billing.

Bedrock connects by cross-account IAM role ARN with an STS assume-role per request — Quorum never stores a long-lived AWS secret. Anthropic-direct is deliberately not offered; Claude runs via Bedrock.

The residual, stated rather than buried: orchestration always runs on Quorum’s keys. The judge and synthesis passes see the seats’ output. BYOK moves the seat calls, not the whole pipeline.

Authoring a mode

Authoring writes to your account, so it takes a signed-in session rather than a Bearer key — the price, the entitlement tier and the ownership record are all decided server-side. Deliberation calls take the key; creating the thing they call does not.

The builder is at Build a Mode. Once a mode is exposed to the API it is auto-entitled to your own org and appears in GET /v1/models.

Get a key

Create an organisation, add a prepaid balance, issue a key. No sales contact, no call, under a minute. The key is shown once.

Every new org gets a $10 credit to try the platform and see if it could help their organisation deliberate better, so your first calls run before you add a balance. Anything unused after 30 days is deducted.

Create your organisation Build a mode