Same mode system, same certification, no canvas. Every field below is a key on the
mode config that /api/mode-builder writes and that
POST /v1/tests and POST /v1/certify
then measure. Steps are unlocked — set them in any order, in one call or six.
The visual builder is the same system with a different instrument. If you would rather see the deliberation as a map than as a body, use Mode Maker (subscriber) — it writes this identical object.
Identity and framing. name and ticker
are the only hard requirements on a create. mode_key is derived server-side from the name and
made unique — you do not set it, and it is permanent once the mode is published,
because it is what a deliberation call resolves against.
ticker_taken. Suggested from the name
(GET /api/mode-builder?suggest_ticker=<name>) and yours to
edit (?check_ticker= answers availability). Optional on a
PATCH: omit it to keep the stored one. It is not
mode_key and does not route.
Whether seats are filled dynamically per request or pinned to a fixed pool. Pinning trades
adaptability for reproducibility — certification cares about the latter. Every id is
validated server-side; an id that does not resolve is a hard 400,
never a silent fallback.
Two rules refuse a save. A new Mode must send pool_strategy; without
it the answer is 400 seat_selection_required, because a silent default
would pick for you. And "fixed" needs all six seats: three
engine_ids and three backup_engine_ids,
or 400 six_seats_required.
"dynamic" | "fixed". Required on a new Mode; an edit that omits it keeps the stored one.
tier_required, never defaulted. Optional on a
PATCH: omit it to keep the stored one. A floor, not a setting: the server
clamps it up to the highest tier any engine you picked actually requires.
Round ceiling and whether seats critique each other. The ceiling is a cap, not a target — the Judge exits early when the panel has converged, which is most of the time. The four depth presets are real named configurations, not a slider:
| deliberation_depth | max rounds | token scale | depth floor |
|---|---|---|---|
| light | 1 | 0.5× | — |
| standard | 2 | 1.0× | — |
| deep | 3 | 1.5× | 1 |
| exhaustive | 5 | 2.0× | 2 |
"gated" activates critique on harder questions only.
Per-mode overrides for the three non-seat roles. Leave them unset and the mode inherits
Quorum's current assignment, which moves as the field moves. Set one and it is pinned until
you change it — the server validates that the engine exists, is active, and covers every
input modality your own seats require, and returns 400 rather than
quietly substituting a different one.
Domain grounding — injected context and jurisdiction. This is where a mode stops being a parameter tweak and becomes a real product. It is listed here because the lever set is real and reviewable, and omitting it would misrepresent the shape of the config object. It accepts no fields today.
What the Marketplace shows, and what a customer is billed to call the mode through the API. Ingredients — provider families, round band, whether seats critique each other — are derived from the config above rather than written here, so you cannot claim a panel shape the mode does not run. Your own revenue share is not settable from this object at all: the payout weight is server-forced, permanently, whatever the request body contains.
description.
GET /api/mode-builder?price_preview=1&mode_id= returns the floor and the recommendation.
Publishing creates an org for payout tracking if you do not have one, sets the listing to
moderation_status: "pending", and returns the real
slug. Visibility is forced to public server-side and is never
read from the request.
Everything above, composed. This is the exact body /api/mode-builder
accepts — POST to create a draft (name
and ticker required),
PATCH with mode_id to update one.
Omitted keys keep their defaults.
This page composes the request body from the fields above. It does not send it — copy it into your own client, or use the visual builder if you would rather save from a UI.
These two are the real API surface, and unlike authoring they take a project API key. Both
reference the mode by model — the
api_model_id from GET /v1/models, not
the internal mode key.
/v1/tests is the metered run: you choose the buckets
(light, medium,
hard), up to 100 questions each and 300 in total, priced per
question at a 25% discount to the normal rate. Config stays editable across test runs. Send
dry_run: true to price a run without launching it. Up to 10
launches per organization per 24h.
POST /v1/tests
Authorization: Bearer <api_key>
{
"model": "quorum-standard",
"buckets": { "light": 10, "medium": 10, "hard": 10 },
"dry_run": true
}
{
"ok": true,
"dry_run": true,
"model": "quorum-standard",
"total_questions": 30,
"per_bucket": { ... },
"total_cost_usd": ...,
"estimated_minutes": 30
}
/v1/certify is the flat-price run: $50, a fixed
150-question set split 50/50/50 across the three buckets, judged pairwise. It writes the score
the Marketplace listing carries. Up to 3 launches per organization per 24h. A certified mode
whose config changes is no longer certified.
POST /v1/certify
Authorization: Bearer <api_key>
{
"model": "quorum-standard"
}
{
"ok": true,
"batch_id": "…",
"model": "quorum-standard",
"total_questions": 150,
"billed_usd": 50,
"status_url": "/v1/certify?batch_id=…"
}
Real, disclosed constraint, returned in the response rather than buried: the shared execution
engine processes roughly one question per minute per batch. A 150-question certification run
takes about two and a half hours, not seconds. Poll status_url
— GET /v1/certify?batch_id=… and
GET /v1/tests?batch_id=… both return progress, and the
certification verdict once status is completed.
Authoring writes to your account, so /api/mode-builder takes a
session token rather than a project API key. Deliberation, testing and certification take the key.