API reference

Every REST endpoint, the MCP tools, the receipt fields and the error codes.

Base URL and auth

https://www.quorum.dog/v1

Send the key as Authorization: Bearer <key>. Keys start with qk_live_ or qk_test_. The API is server to server: a request carrying a browser Origin header returns 403 browser_origin_not_allowed.

API keys always bill your organization's API account. Each API-key call has a ceiling on its bill: the higher of $2.00 and the price of the Mode being called, unless the API key carries its own ceiling. Only Quorum sets a key's own ceiling. A request can lower the ceiling for one call with quorum.max_cost_usd. Calls from a connected app on a plan pay real cost and have no per-call ceiling.

Endpoints

Method and pathPurposeCost
POST /v1/chat/completionsRun a Mode and return one answer.Billed.
POST /v1/estimateClassify a prompt and quote the Mode's surcharge for it without running it.Free.
GET /v1/modelsList the Modes this key can call, with pricing.Free.
GET /v1/receipts/{request_id}Read the accounting for a past call.Free.
POST /v1/tests, GET /v1/tests?batch_id=Launch or poll a Lab run on known-answer questions.Billed per question.
POST /v1/certify, GET /v1/certify?batch_id=Launch or poll the certification run.Billed per question.
POST /mcpThe MCP server, 13 tools.Per tool.

Every model field takes a Mode ticker in the form COMPANY:MODE, for example QRUM:STAN for Standard Mode. model is required on every call.

POST /v1/chat/completions

curl -sS https://www.quorum.dog/v1/chat/completions \
  -H "Authorization: Bearer $QUORUM_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  --max-time 300 \
  -d '{
    "model": "QRUM:STAN",
    "messages": [{"role": "user", "content": "Should we use RLS or app-layer authz?"}],
    "quorum": { "max_cost_usd": 1.00 }
  }'

Request fields:

FieldTypeMeaning
modelstring, requiredMode ticker.
messagesarray, required{ role, content } objects. role is user, system or assistant.
tierstringexperience (Express), plus (Foundation) or pro (Frontier). Which engine tier fills the seats for this call. An API key accepts any of the three, up to pro. The default is plus. The Mode decides whether a panel convenes.
quorum.max_cost_usdnumberCeiling on this call's bill, for API-key calls. It can lower the key's ceiling and cannot raise it.
streambooleantrue returns 400 stream_not_supported.

Headers: Idempotency-Key makes a retry safe. Send a new key for each request and the same key only when you retry that request. If you omit it, one is derived from your organization, key, model and messages, so an identical repeat question is a retry.

A replay matches on the key alone. A key reused with a different request returns the first request's answer, when that request succeeded, and runs nothing new. While the first call is still running, a retry with the same key returns 409 request_in_progress; wait and retry.

A repeat of a call that succeeded replays the stored answer with quorum.replayed: true and bills nothing. The replayed quorum block holds request_id, replayed, mode, a note, and seats_answered and answer_truncated when they were recorded. It does not hold converged, remaining_friction, contested_passage, deliberation or billed_usd. Check replayed first and read the other fields with a default. A call that ended capped is not replayed: a retry with the same key runs again and bills again.

Response:

{
  "id": "…",
  "object": "chat.completion",
  "created": 1790000000,
  "model": "QRUM:STAN",
  "choices": [
    { "index": 0, "message": { "role": "assistant", "content": "…" }, "finish_reason": "stop" }
  ],
  "usage": {
    "prompt_tokens": 41,
    "completion_tokens": 612,
    "total_tokens": 653,
    "completion_tokens_details": { "reasoning_tokens": null }
  },
  "quorum": {
    "request_id": "…",
    "mode": "QRUM:STAN",
    "rounds": 1,
    "seats": 3,
    "seats_answered": 3,
    "converged": true,
    "remaining_friction": null,
    "contested_passage": null,
    "best_seat_rationale": "…",
    "best_seat_judged_by": "llm",
    "deliberation": [],
    "capped": false,
    "surcharge_usd": 0.05,
    "platform_fee_usd": 0.004,
    "cap_credit_usd": 0,
    "billed_usd": 0.10,
    "latency_ms": 26418,
    "engines": ["<seat model id>", "<seat model id>", "<seat model id>"],
    "substitutions": [],
    "persisted": true
  }
}

finish_reason is stop or length. length means the answer was cut off. The values in the sample are illustrative.

quorum fields:

FieldMeaning
request_idId for the receipt endpoint.
modeThe Mode ticker that ran.
roundsRounds of the seats answering. One pass of the seats is one round.
seats, seats_answeredSeats convened and seats that answered. seats_answered < seats means the panel was smaller than the one that convened.
convergedfalse when the seats did not settle on one position. null when no judge read the round, as on the express lane. Absent on a replay.
remaining_frictionfactual_conflict when the judge flagged a factual conflict between seats, otherwise null. Absent on a replay.
contested_passageAn object { seat, quote, why }: the seat, the passage it quoted and why it is contested. null when no single passage carried the split. Absent on a replay.
best_seat_rationale, best_seat_judged_byWhich seat won and why. judged_by is express_lane, heuristic or llm.
deliberationOne entry per round.
divergence_first_round, divergence_final_roundThe judge's divergence score at the first and the last round. null when no judgment was recorded.
cappedtrue when the call went over its ceiling and cap_credit_usd is above 0. The deliberation ran in full and the answer is whole. A capped call is not replayed, so a retry runs again and bills again.
surcharge_usd, platform_fee_usd, billed_usdThe Mode's surcharge, the platform fee and the total billed. billed_usd is absent on a replay.
cap_credit_usdThe amount over the call ceiling, credited back. A call that goes over its ceiling is charged in full: tokens, seat fees and the Quorum surcharge. The amount over the ceiling is then credited back as a cap credit, so you pay the ceiling. billed_usd is the token charge plus platform_fee_usd plus surcharge_usd, minus cap_credit_usd. 0 on a call under the ceiling. Absent on a replay.
latency_msEnd to end.
enginesThe model ids of the seats that ran.
substitutionsSeats that ran a backup engine, and what ran instead. [] when the panel ran as assigned.
seats_unavailable, staff_unavailablePresent when a seat or a staff engine could not run, with the reason.
replayedtrue on an idempotent replay. Present only then.

A deliberation runs several models. Set the client timeout to 300 seconds.

POST /v1/estimate

Same request body as chat completions. Free. The response:

{
  "request_id": "…",
  "model": "QRUM:STAN",
  "mode": "QRUM:STAN",
  "depth": "medium",
  "difficulty_score": 0.61,
  "task_type": "analysis",
  "estimated_price_usd": 0.10,
  "billed_usd": 0,
  "deliberation_value": {
    "verdict": "likely_helps",
    "reason": "multi_step_conclusion",
    "basis": "hypothesis",
    "evidence": "…"
  },
  "timing_ms": { "total": 912, "classify": 874 }
}

The values in the sample, including timing_ms, are illustrative. estimated_price_usd is the Mode's surcharge for the classified depth. The bill for the real call adds a token charge and the platform fee.

deliberation_value.verdict is likely_helps, likely_hurts or unknown. See the escalation router.

GET /v1/models

Returns { "object": "list", "data": [...] }. Each entry has id (the ticker), quorum.name, quorum.description, quorum.use_when, quorum.pricing (q_surcharge_usd, q_surcharge_by_depth, q_surcharge_express_usd), quorum.provider_families and quorum.includes_deliberation.

GET /v1/receipts/{request_id}

Returns { "ok": true, "receipt": {...} }. Add ?include_transcript=true to include each seat's text. A request id from another organization returns 404 receipt_not_found.

A call that never convened a panel, such as an estimate or a call that ended before a seat fired, returns 200 with { "ok": true, "request_id": "...", "status": "...", "receipt_available": false, "reason": "..." } and no receipt key. Check receipt_available before reading receipt.

Top level of receipt:

FieldMeaning
request_id, mode, statusIdentity and outcome.
billed_usd, token_charge_usd, q_surcharge_usd, cap_credit_usdWhat the call billed and its parts: billed_usd is the token charge, the seat fees and the surcharge, minus cap_credit_usd. cap_credit_usd is null when no credit was recorded, which is not the same as $0.00.
prompt_tokens, completion_tokensToken counts.
rounds, seat_countRounds fired and seats convened.
payerWho paid.
laneexpress when one engine answered on its own, panel otherwise. null when no seat row was recorded.
difficulty_score, task_type, hallucination_risk, minority_insight_likelyThe classifier's read of the prompt.
best_seatmodel_used and judge_score of the winning seat.
seatsOne entry per seat, below.
staffThe judge, synthesis and grounding engines.
seats_unavailable, staff_unavailableEach entry is { role, reason }.
latency_ms, created_at, completed_atTiming.

Each entry in seats:

FieldMeaning
roleThe seat.
model_used, original_modelThe engine that answered and, on a substitution, the one it replaced.
fallback_usedtrue when the seat ran its backup.
judge_score, is_best_seatThe judge's score and whether this seat won.
round_numberThe round.
tokens_in, tokens_out, latency_ms, started_at, ended_atUsage and timing.
sourceWhich source served the call.
real_cost_usdWhat the call cost at the source.
fee_rateThe platform fee rate. The default is 5% on Quorum's keys and 0.5% on your own key.
fee_usdreal_cost_usd times fee_rate.

A staff engine that could not run shows as unavailable: reason. The fee applies to API calls only, on the source's real billed cost; never on plan usage.

Lab and certification

POST /v1/tests runs known-answer questions against a Mode you can call and returns a batch_id and a status_url. Send dry_run: true for a quote. POST /v1/certify runs the certification for a Mode your organization owns. The Mode must be listed in the Marketplace to launch, and a dry_run on an unlisted Mode returns its quote with requires_listing: true. Both are billed per question to the organization, accept Idempotency-Key, and are polled with GET and batch_id. The same operations are the run_test and certify_mode MCP tools.

MCP tools

The server is at https://www.quorum.dog/mcp. It has 13 tools. Setup is in Connect Quorum to your tools. The loop is estimate, deliberate, get_receipt, act.

ToolWhat it does
deliberateSends your question to a panel of models and returns where they agree and where they split.
list_modesLists the Modes you can call, with their prices and the providers behind them.
estimateQuotes the Mode's surcharge for the question and says whether a panel is likely to help, free of charge. The bill adds the token charge and the platform fee.
get_receiptShows which model sat in each seat of a past deliberation, with judge scores, cost and latency.
run_testRuns a Lab test of a Mode on questions with known answers, graded the way the Mode Builder grades.
certify_modeStarts the certification run for a Mode, the same run the Mode Builder starts.
list_enginesLists the engines you can put in a Mode's seats, up to the tier your plan or key allows.
validate_modeChecks a Mode spec against the rules a save runs and reports what would fail.
ask_genieAsks the Mode Maker Genie about one of your Modes: where its results are thin, what to test next and at what price, and whether it is ready to certify.
approve_quoteApproves a price the Genie quoted and launches that run once, at no more than the quoted price.
genie_propose_modeDescribe what a Mode is for and the Genie designs all of it, checked against the save rules and priced.
save_modeSaves a Mode spec through the same save the Mode Maker uses.
list_modePublishes a released Mode to the Marketplace, as the Publish button in the Mode Builder does.

deliberate takes model, messages, and optionally max_cost_usd and tier. estimate takes model and messages. get_receipt takes request_id. A connected app signed in to a plan pays real cost with no API surcharge. max_cost_usd applies to API-key calls.

Convene a panel for judgement calls: a consequential assumption, options close enough that the numbers no longer separate them, a diagnosis you cannot check, a decision you will have to defend, or a "what have I missed" check. Use a single model for lookups, syntax, formatting, conversions, arithmetic and anything you need reproduced word for word.

Errors

Every error has the OpenAI shape plus a quorum block.

{
  "error": { "message": "Rate limit exceeded for this API key.", "type": "rate_limit_error", "code": "rate_limit_exceeded", "param": null },
  "quorum": { "request_id": null }
}

Branch on error.code. Messages can change.

CodeHTTPRetryMeaning
invalid_api_key401NoMissing, malformed or unknown key.
revoked_api_key401NoThe key expired or was revoked.
invalid_oauth_token401NoA connected app's access token was refused. The message gives the reason. Sign in again.
org_suspended403NoThe organization's access is suspended.
browser_origin_not_allowed403NoThe request carried a browser Origin header.
insufficient_scope403NoThe key lacks the scope for this endpoint or Mode.
invalid_model400Nomodel is missing or not a string. Returned by /v1/estimate, /v1/tests and /v1/certify.
invalid_messages400Nomessages is missing or empty. /v1/chat/completions also returns it when model is missing.
invalid_tier400Notier is not experience, plus or pro.
invalid_max_cost_usd400Noquorum.max_cost_usd is not a positive number.
stream_not_supported400NoThe request had stream: true.
context_length_exceeded413NoThe prompt is over 8000 tokens.
model_not_found404NoNo Mode with that ticker is available to you. Call GET /v1/models.
tier_not_permitted403NoConnected apps only. The requested tier or Mode is above the signed-in plan.
mode_not_permitted403NoThe organization is not entitled to that Mode.
mode_not_published403NoThe Mode has not been published.
lab_not_available403NoThe :LAB version is open to its author, team and invited users.
request_in_progress409WaitA call with this Idempotency-Key is still running.
missing_request_id400NoThe receipt call had no id.
receipt_not_found404NoNo receipt for that id under your organization.
method_not_allowed405NoWrong HTTP method for the path.
verification_required402NoThe activation allowance is used. Activate the organization.
insufficient_balance402NoThe organization's balance is too low. On /v1/tests and /v1/certify it also covers a used quota, a suspended organization or missing billing; the message names the reason.
quota_exceeded402NoThe monthly quota is used.
no_billing_configured402NoThe organization has no billing set up.
plan_limit_reached402NoA connected app's plan limit is used up. Top up Turbo or wait for the reset.
rate_limit_exceeded429YesRequests per minute for this key. Honor Retry-After.
concurrency_limit_exceeded429YesToo many calls in flight for the organization.
too_many_concurrent_requests429YesToo many deliberations in flight for one person on a connected app.
classification_failed502Yes/v1/estimate could not classify the prompt. Not billed.
service_unavailable503YesA check could not complete. Try again.
mode_unavailable503YesNo seat the Mode approved can run right now. Not billed.
upstream_provider_error502YesThe deliberation failed. Not billed.
mode_resolution_mismatch502YesThe Mode that ran was not the Mode requested. Not billed.
internal_error500YesA fault on our side. Retry with the same Idempotency-Key.
price_unavailable400NoThe Mode has no API price set for the question bands in the run.
mode_not_owned403NoLab and certification run on Modes you own or can edit.
launch_refused400NoThe launcher refused the run. The message says why.
listing_required400NoThe Mode is not listed yet. Certification needs a listing.
invalid_punch_up400Nopunch_up is not true or false.
invalid_questions400No/v1/tests: questions is missing or is not an object like {"easy": 2, "medium": 1}.
invalid_difficulty400No/v1/tests: a questions key is not easy, medium or hard.
invalid_bucket400No/v1/tests: a legacy buckets key is not light, medium or hard.
invalid_question_count400No/v1/tests: a count is not a whole number in the allowed range. The message gives the range.
too_many_questions400No/v1/tests: the counts add up to more than one run allows. The message gives the cap.
invalid_tiers400No/v1/tests: tiers is not a non-empty list drawn from free, plus and pro. experience is accepted as another name for free.
missing_batch_id400NoA poll had no batch_id.
batch_not_found404NoNo run for that batch_id under your organization.
provider_unavailable409WaitA provider the run needs is unavailable. Try later.
idempotency_key_reused422NoThe key was used with a different body. Send a new key.
reconciliation_required409NoAn earlier attempt with this key stopped mid-charge. Retry with a new key.
test_launch_limit_exceeded429YesThe organization reached its daily Lab launch limit. Retry-After: 3600.
certify_launch_limit_exceeded429YesThe organization reached its daily certification launch limit. Retry-After: 3600.
cost_unreadable502YesThe deliberation could not be recorded. Not billed.

MCP tool calls that fail return a result with isError: true. The text of the result is JSON in one of three shapes.

Tools that forward to the REST API (deliberate, list_modes, estimate, get_receipt, run_test, certify_mode) return the REST error object, with the HTTP status beside it. request_id and quorum appear only when the API sent them.

{
  "http_status": 404,
  "error": { "message": "Unknown model: ACME:NOPE", "type": "invalid_request_error", "code": "model_not_found", "param": null }
}

The tools Quorum answers itself (list_engines, validate_mode, ask_genie, approve_quote, genie_propose_mode, save_mode, list_mode) return error.code and error.message. Extra detail, such as refusals or retry_after_seconds, sits in quorum.

{
  "http_status": 409,
  "error": { "code": "quote_already_used", "message": "Request failed (quote_already_used)." },
  "quorum": { "quote": { "status": "launched" } }
}

upstream_unreachable and a tool that fails before it can answer (internal_error) return a plain string: { "error": "upstream_unreachable", "detail": "..." }. Branch on error.code when error is an object and on error when it is a string.

These failures arrive outside the tool result, as a JSON-RPC error or an HTTP status:

The REST codes above come back unchanged through the forwarding tools. The server adds these:

CodeHTTPRetryMeaning
oauth_unavailable503YesSign-in is temporarily unavailable.
gate_check_failed503YesThe usage check failed. Try again.
not_configured500NoThe server is not configured for this call.
upstream_unreachablenoneYesThe MCP server could not reach the API.
name_taken409Nosave_mode or list_mode: your organization already has a Mode with that name.
ticker_taken409Nosave_mode: the ticker is in use. The error carries no suggestion. Each ticker_taken entry that validate_mode lists in refusals, and in quorum.refusals of mode_invalid, carries suggested_ticker.
batch_too_large413NoA batch carried more than 8 calls to the tools Quorum answers itself. The extra calls did not run. Send them in a separate request.
engines_unavailable503YesThe engine list could not be read. genie_propose_mode returns it as 503, or as 422 when no engine list was available to build the proposal from.
mode_not_found404NoNo Mode by that name that you own or your organization has.
draft_required400Nosave_mode always saves a draft. Pass release: true to release it.
mode_invalid422Nosave_mode: the spec failed validate_mode. Nothing was saved. quorum.refusals lists why.
invalid_request400Nosave_mode or list_mode: the save endpoint refused the request and sent no code of its own.
forbidden403Nosave_mode or list_mode: the key or sign-in cannot change that Mode.
test_key_not_allowed403Nosave_mode or list_mode: a test key cannot change Modes. Use a live key.
mode_not_allowed403Nosave_mode or list_mode: the key is limited to named Modes. It cannot create a Mode or change one outside its list.
org_required400Nosave_mode or list_mode: the person has no organization yet. Modes are saved and listed inside one.
org_owner_missing409Nosave_mode: the key's organization has no owner to own a new Mode.
name_too_short400Nosave_mode: the name is too short. The message gives the minimum.
name_too_long400Nosave_mode: the name is too long. The message gives the maximum.
name_bad_chars400Nosave_mode: use letters, numbers, spaces and - ' & . , only.
name_edge_punctuation400Nosave_mode: a name cannot start or end with punctuation.
name_reserved400Nosave_mode: the name is reserved. Choose another.
description_bad_chars400Nosave_mode: the description contains <, > or a control character.
price_below_floor400Nosave_mode: a price is under the Mode's floor. quorum.floor_usd and quorum.recommended_usd carry the numbers.
pricing_unavailable503Yessave_mode: the price floor could not be read. Nothing was saved, or with release: true, nothing was released.
validation_unavailable503Yessave_mode with release: true: the draft could not be checked against the engine list. Nothing was released.
save_unavailable503Yessave_mode: saving Modes is unavailable. Nothing was saved.
draft_pending409Nosave_mode: the Mode has a draft that was never released. Release it with mode_id and release: true, then save again.
draft_changed409Yessave_mode with release: true: the draft changed while it was being released. Release again.
no_draft409Nosave_mode with release: true: the Mode has no draft to release.
draft_unvalidated409Nosave_mode with release: true: the draft has no saved spec. Save it again, then release.
mode_not_released409Nolist_mode: the Mode was saved as a draft and never released. Release it with save_mode, then list it.
listing_rejected409Nolist_mode: the listing was rejected in review.
listing_delisted409Nolist_mode: the listing was taken down.
listing_changed409Yeslist_mode: the listing changed while it was being written. List again.
listing_read_failed503Yeslist_mode: the current listing could not be read.
published_version_uncertified409Nolist_mode: the published version is not the certified one. Certify the published version, or publish the certified one, then list.
ticker_required400Nosave_mode: the Mode needs a four-letter ticker.
ticker_invalid400Nosave_mode: a ticker is exactly four letters, A to Z.
conflict409Nosave_mode or list_mode: the save endpoint reported a conflict with the Mode as stored.
save_failedvariesMaybesave_mode or list_mode: the save endpoint failed with no code of its own. The HTTP status is the endpoint's.
suffix_not_supported400NoThe Genie reads a Mode as it stands. Drop the :LAB or @version suffix.
genie_unavailable502YesThe Genie could not answer. Not billed.
too_few_engines422Nogenie_propose_mode: the proposal could not fill every seat from the engines open to you.
no_proposal502Yesgenie_propose_mode: the Genie answered without a proposal. Ask again.
chat_history_required503Noapprove_quote: Genie quotes need chat history, which is not switched on. Use run_test or certify_mode.
invalid_batch_id400Noask_genie with batch_id: the id is not a run id.
status_unavailable503YesThe run status could not be read.
invalid_quote_id400Noapprove_quote: quote_id is not a quote id.
quote_not_found404Noapprove_quote: no quote with that id under your key or sign-in.
quote_already_used409Noapprove_quote: the quote was already approved.
quote_expired410Noapprove_quote: the quote expired. Ask ask_genie for a new one.
payer_mismatch403Noapprove_quote: the quote bills to the plan or the organization the call does not. Approve it where it was quoted.
approval_not_recorded503YesThe approval could not be saved to the chat, so nothing launched or charged. Approve again.
quote_read_failed503Yesapprove_quote: the quote could not be read.
launch_failed502Yesapprove_quote: the run could not be confirmed as started. Approve the same quote again, from an API key or a connected app; it returns that run if it started and never launches twice.
requoted409Noapprove_quote: the price rose above what you approved. Nothing launched. When a new quote could be made, quorum.quote carries it; otherwise ask ask_genie for one.

approve_quote also passes on the /v1/tests or /v1/certify code that refused the launch, such as insufficient_balance or listing_required. A refusal with no code of its own comes back as launch_refused, and http_status is the status the launch answered with, or 502 when it gave none. That status can be 200 when the launch answered without a run id.

save_mode and list_mode pass on the save endpoint's own code. The codes it can send are in the table above and in the validation codes below. When it sends a status with no code, the tool uses invalid_request (400), invalid_api_key (401), forbidden (403), mode_not_found (404), conflict (409) or save_failed.

Validation codes

save_mode with release: true checks the stored draft again before it releases it. A draft that no longer passes returns the check's own code as error.code, usually with HTTP 400, and the message says what to fix. validate_mode reports the same codes in body.error of each entry in refusals. A check with no code of its own, such as a round count out of range, returns invalid_request with the reason in the message.

AreaCodes
Seatssix_seats_required duplicate_seat_engine seat_engine_not_found seat_engine_above_tier single_family_row seat_selection_required seats_ambiguous engine_unavailable
Seat rows by tierseats_by_tier_invalid seat_tier_unknown seat_tiers_not_contiguous seats_by_tier_needs_fixed seat_tiers_min_tier_mismatch seat_tiers_below_staff tier_required
Staffstaff_role_unknown staff_auto_not_allowed staff_tiers_shape staff_tier_unknown staff_tier_is_lowest staff_backup_without_primary staff_backup_same_as_primary staff_engine_above_tier
System Modessystem_mode_seats system_mode_seats_untiered system_mode_tier_dropped
Auto seatsauto_needs_fixed_pool auto_seats_mixed auto_rows_differ_by_tier auto_seat_backup auto_picked_needs_backup family_diversity_invalid family_diversity_needs_auto
Other settingsfidelity_retired fidelity_inert invalid_value
Listing and pricedescription_too_long use_when_invalid use_when_too_long price_required price_override_not_allowed ticker_required ticker_invalid org_required

price_override_not_allowed (400) means the spec sets api_commercial.price_override_acknowledged. That confirmation is for a person in the Builder. An API key or a connected app may set any price at or above the floor without it, so drop the field. validate_mode lists it first in refusals, and save_mode returns it inside mode_invalid's quorum.refusals.

Quote refusal values

ask_genie with a quote answers successfully even when it cannot price the run. The result then carries quote_unavailable in place of quote, set to one of these values or to the /v1/tests or /v1/certify error code that refused the price.

ValueMeaning
invalid_specThe run spec is not valid. Fix it and ask again.
mode_not_ownedA run billed to your plan launches only on a Mode you own.
chat_history_requiredGenie quotes need chat history, which is not switched on. Use run_test or certify_mode.
quote_not_storedThe quote could not be saved. Ask again.
quote_failedThe quote could not be made. Ask again.

Limits

LimitDefaultScope
Requests per minute60Per API key
Concurrent requests5Per organization
Input tokens8000Per request
Cost per callthe higher of $2.00 and the price of the Mode being called, unless the API key carries its own ceilingPer API-key call

A key can be given higher request and concurrency limits, and a different input limit. rate_limit_exceeded and concurrency_limit_exceeded send Retry-After in seconds.