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 /v1/models publishes the fee per 1M tokens, by tier.
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.
Both take a project API key and reference the mode by model — the
id from GET /v1/models (a ticker such as QRUM:STAN), not
the internal mode key.
/v1/tests is the Lab run the Builder launches: known-answer
questions graded against their answers, split across the tiers the mode permits, with optional
punch-up. You choose the questions per difficulty
(easy, medium,
hard), up to 100 each and 300 in total. Each question is priced at
the mode’s normal API price at 25% off, billed to the organization and
charged only for answered questions. Send
dry_run: true for the priced quote without launching. Up to 10
launches per organization per 24h. A connected app (OAuth) bills the person’s plan at
real cost instead.
POST /v1/tests
Authorization: Bearer <api_key>
{
"model": "QRUM:STAN",
"questions": { "easy": 10, "medium": 10, "hard": 10 },
"dry_run": true
}
{
"ok": true,
"dry_run": true,
"model": "QRUM:STAN",
"total_questions": 30,
"quote": { ... },
"billed_usd": ...,
"max_usd": ...,
"price_basis": "...",
"per_difficulty": { ... },
"price": { "lines": [ ... ], "discount_pct": 25, "max_total_usd": ... },
"note": "A maximum, not a bill: ..."
}
/v1/certify is the certification the Builder runs: a fixed 150-question
known-answer set, 50 each of easy, medium and hard, graded against their answers and
priced per question by depth at 25% off, charged only for questions answered.
Send dry_run: true for the quote and
punch_up: true to add the Builder’s punch-up once the certificate is
graded. The mode must already have a Marketplace listing. On completion the run pins the same public
card an in-app certification pins, and the finished batch carries
certification.pinned. Only the owning organization can certify. An API key
bills the organization; a connected app (OAuth) bills the person’s plan at real cost.
Up to 3 launches per organization per 24h.
POST /v1/certify
Authorization: Bearer <api_key>
{
"model": "QRUM:STAN"
}
{
"ok": true,
"batch_id": "…",
"model": "QRUM:STAN",
"total_questions": 150,
"billed_usd": ...,
"max_usd": ...,
"price_basis": "...",
"per_difficulty": { ... },
"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
scorecard once graded.
/api/mode-builder takes a session token, or a project API key issued
with the Can edit Modes scope (modes:write, granted at
issue by an owner or admin). A key’s save is always a draft, private and inactive, until
action: promote_draft re-validates and releases it. A key can never set the
price-override flag; that confirmation stays with a person in the Builder.