The API serves the same question-answering pipeline as the chat interface. Questions can be asked anonymously, with a member session, or with an API key. Responses are available as a complete JSON document or as a server-sent event stream.
Authentication
- Anonymous. The
/api/askand/api/searchendpoints require no authentication. The allowance is 20 questions per day per IP address. - Member. Signing in with an OIML SMART account at
/auth/loginraises the allowance to 300 questions per day and enables conversation synchronization, project memory and research mode. - API key. Machine callers authenticate with
Authorization: Bearer oiml_…. Each key carries its own daily limit, and an administrator issues keys.
The interactive reference
The complete interface is specified in the OpenAPI document in the publisher profile, and the console below renders that specification with live requests: every request shown can be edited and sent from this page against the production service. Requests to the anonymous endpoints need no key; requests to the keyed endpoints use the API key supplied above the console, which remains in the browser’s local storage and is sent nowhere except to the service itself.
The session mode sends the requests to the anonymous endpoints with this browser's signed-in cookie, so a signed-in member tests the interface with no credential handling at all. The token mode sends the pasted credential as the bearer token to the keyed endpoints; the credential is kept only in this browser's local storage and is sent nowhere except to the service itself.
Ask
Ask a question and receive a citation-grounded answer.
Asks a question over the OIML corpus and receives an answer with clause-level citations. The anonymous allowance is 20 questions per day per IP address. The request body and the response are identical to /v1/ask.
Response:documented under AskResponse in Schemas.
Request — edit and send
Identical to /api/ask, with authentication by API key and a per-key daily allowance. Streaming responses are available by setting stream to true, which returns a server-sent event stream whose first event is the reading, then the citations, then the answer tokens, and finally the completion marker.
Authentication:this endpoint requires an access token or an API key as the bearer credential.
Response:documented under AskResponse in Schemas.
Request — edit and send
Records a thumbs rating against the query hash, which the feedback triage clusters for review.
Request body
| query_hash * | string | |
| rating * | integer |
Request — edit and send
Search
Retrieve ranked clauses without generating an answer.
Retrieves the ranked clauses for a query without generating an answer. Each hit carries its document identifier, edition, clause anchor, status and a link into the rendered document.
Request body
| query * | string | The search text, at most 8000 characters. |
| k | integer | The number of hits to return. |
Request — edit and send
Identical to /api/search, with authentication by API key and a per-key daily allowance.
Authentication:this endpoint requires an access token or an API key as the bearer credential.
Request body
| query * | string | |
| k | integer |
Request — edit and send
Evidence
Provable absence certificates and answer verification.
Applies the deterministic verification battery to any answer, whether generated by this service or by another system: every quoted span must be contained verbatim in a passage retrieved for the query, and every object reference must resolve to a served object. A judged faithfulness score is reported separately and is labelled as judged.
Request body
| query * | string | The question the answer claims to answer. |
| answer * | string | The answer to verify. |
Request — edit and send
Authentication:this endpoint requires an access token or an API key as the bearer credential.
Request body
| query * | string | |
| answer * | string |
Request — edit and send
Research
Bounded iterative research over the corpus.
Identical to /v1/research, with authentication by the signed-in member's session cookie; research spend stays with signed-in members.
Request body
| query * | string | The research question. |
| max_iterations | integer | The iteration bound, at most 3. |
Request — edit and send
Runs a bounded iterative loop over the corpus. In each pass the service retrieves evidence, and an independent judge evaluates whether the evidence is sufficient and names what is missing; the next pass retrieves specifically for the missing parts, and the final answer is generated from the accumulated evidence. The response carries the answer, citations, typed blocks and the research metadata, including iterations, passages and elapsed time.
Authentication:this endpoint requires an access token or an API key as the bearer credential.
Request body
| query * | string | The research question. |
| max_iterations | integer | The iteration bound, at most 3. |
Request — edit and send
Conversations
The signed-in member's conversations: list, create, read, rename, delete, append messages and create shareable permalinks. These endpoints authenticate with the session cookie.
Request body
| title | string | The conversation's title, at most 120 characters. |
Request — edit and send
Request body
| title * | string | The new title, between 1 and 120 characters. |
Request body
| role * | string | |
| content * | string |
Request — edit and send
Memory
The signed-in member's personal memory notes, which the assistant consults in later conversations. At most ten notes of eight thousand characters each are kept.
Creates a note from a name and a content of at most 8000 characters. When the body carries the identifier of an existing note, that note is replaced instead and no new note is created. At most ten notes are kept per member.
Request body
| name * | string | The note's name |
| content * | string | The note's text |
| id | string | The identifier of the note to replace; when absent, a new note is created. |
Request — edit and send
Projects
The signed-in member's contexts: named groups of conversations with their attached files. A conversation may be filed into a context, and the retrieval is then scoped by the context's files.
The body selects the behaviour: a name alone creates a context; an identifier together with a name renames that context; a conversation identifier together with a context identifier (or null to unfile) moves the conversation into or out of the context. Filing a conversation into a context scopes its later retrieval to the context's files.
Request body
| name | string | The context's name, at most 64 characters; creates or renames. |
| id | string | The identifier of the context to rename; when absent, a new context is created. |
| conversation_id | string | The conversation to file; selects the move behaviour. |
| project_id | stringnull | The target context, or null to unfile the conversation. |
Request — edit and send
Deletes the context, detaches its files and returns its conversations to the general list.
Attaches a text file to the context named by project_id in the body. When the body carries the identifier of an existing file, that file is replaced instead and no new file is attached. At most ten files of 8000 characters are kept per context.
Request body
| project_id * | string | The context to attach the file to. |
| name * | string | The file's name |
| content * | string | The file's text |
| id | string | The identifier of the file to replace; when absent, a new file is attached. |
Request — edit and send
MCP
The Model Context Protocol server for agent ecosystems.
Serves the Model Context Protocol over streamable HTTP for agent ecosystems, behind the same authentication as the /v1 endpoints. The protocol follows JSON-RPC 2.0 with the 2025-06-18 revision. The tools are ask, which asks a question and returns the answer with its citations, and retrieve, which returns ranked passages.
Authentication:this endpoint requires an access token or an API key as the bearer credential.
Request body
| jsonrpc * | string | |
| id | object | The request identifier. |
| method * | string | |
| params | object | The method parameters; tools/call carries name and arguments. |
Request — edit and send
Service
Datasets, health and authentication.
Returns the credits the caller has left today — resolved by the same tiering as ask (anonymous by IP, member by session, key by its owner member's shared cap). 1 credit ≈ 1000 tokens of consumption; the UI's meter reads this.
The same balance, authenticated by session or key.
Authentication:this endpoint requires an access token or an API key as the bearer credential.
Lists the available corpora with their access status. The OIML publications and the OIML SMART models are open to everyone; the ISO/IEC corpus requires a role that is managed in the identity service.
Reports the key's own daily allowance consumption together with its seven-day request ledger. The identity is the presented credential itself, so a key can never read another key's usage.
Authentication:this endpoint requires an access token or an API key as the bearer credential.
Reports service identity and index version.
Reports whether the caller is signed in, together with the display name, the email and the estate roles when a session is present. The console uses this endpoint to state who is signed in.
Redirects to the estate's identity service with the OIDC authorization-code and PKCE parameters; the callback completes the sign-in and mints the session cookie.
The identity service's redirect target; completes the authorization-code exchange, mints the session cookie and returns the caller to the page they began from.
Request — edit and send
The same operation as the post, provided so that a plain link can end the session.
Experimental
The comparison-lane query endpoint, which retrieves from one named experimental corpus. These endpoints exist to support the measurement work and carry no stability promise.
Retrieves from a single named experimental corpus (the comparison levels of the annealment measurement) without touching the production index.
Request body
| lane * | string | The experimental corpus to query. |
| query * | string |
Request — edit and send
Identical to /api/lane, with authentication by API key and a per-key daily allowance.
Authentication:this endpoint requires an access token or an API key as the bearer credential.
Request body
| lane * | string | |
| query * | string |
Request — edit and send
Administration
Operational endpoints guarded by the administrator token, covering service statistics, the issuance and management of API keys, and the index-maintenance battery (enrichment, section units, vectors and figure captions).
Batches chunks through the contextual-enrichment lane, with the per-chunk contexts cached server-side. The default mode writes to the production index; callers that only want the generated contexts pass mode context.
Authentication:this endpoint requires an access token or an API key as the bearer credential.
Request body
| chunks | array | The chunks to enrich. |
| mode | string | |
| effort | string |
Request — edit and send
The operational alias of /v1/admin/enrich, which the ingestion tooling calls; the behaviour and the credential are identical.
Authentication:this endpoint requires an access token or an API key as the bearer credential.
Request body
| chunks | array | The chunks to enrich. |
| mode | string | |
| effort | string |
Request — edit and send
Generates a summary of each named top-level clause from its child chunks' excerpts, embeds it together with the table-of-contents path and upserts it as a navigation node, so that retrieval can descend from the summary to the quotable leaf clauses. Accepts at most six units per call; the credential and the batching mirror the enrichment driver.
Authentication:this endpoint requires an access token or an API key as the bearer credential.
Request body
| units * | array | The section units to write. |
Request — edit and send
Generates the precomputed answer to "what is this family and what changed between editions" from the registry rows and the successor graph, and stores it in KV; editionNote serves it beside the deterministic registry line on doc-scoped answers. Families need at least two editions. force regenerates.
Authentication:this endpoint requires an access token or an API key as the bearer credential.
Request body
| family * | string | The family key, for example R-60. |
| force | boolean |
Request — edit and send
The operational alias of /v1/admin/section; the behaviour and the credential are identical.
Authentication:this endpoint requires an access token or an API key as the bearer credential.
Request body
| units * | array |
Request — edit and send
The operational alias of /v1/admin/family-summary; the behaviour and the credential are identical.
Authentication:this endpoint requires an access token or an API key as the bearer credential.
Request body
| family * | string |
Request — edit and send
Embeds, upserts or reads index vectors by identifier through the binding lane, in batches of at most twenty identifiers; the binding is the credential, gated by the administrator token like the enrichment driver.
Authentication:this endpoint requires an access token or an API key as the bearer credential.
Request body
| mode | string | |
| ids | array | |
| vectors | array |
Request — edit and send
Fetches the named unit's figure asset from the object store, describes it with the vision-capable answer model and stores the description into the unit's payload. The operation is idempotent.
Authentication:this endpoint requires an access token or an API key as the bearer credential.
Request body
| unit_id * | string | The figure unit to caption. |
| context | string | Surrounding clause text, at most 400 characters, to steer the description. |
Request — edit and send
Scores an answer's faithfulness and relevancy against the passages it claims to rest on, with a model that took no part in generating the answer. The promotion gate and the evaluation harness call this lane.
Authentication:this endpoint requires an access token or an API key as the bearer credential.
Request body
| question * | string | The question |
| answer * | string | The answer |
| passages | array | The passages, each at most 600 characters. |
Request — edit and send
The operational alias of /v1/admin/judge; the behaviour and the credential are identical.
Authentication:this endpoint requires an access token or an API key as the bearer credential.
Request body
| question * | string | |
| answer * | string | |
| passages | array |
Request — edit and send
Authentication:this endpoint requires an access token or an API key as the bearer credential.
Reports the query volume by day and tier, the spend by model, the feedback counts, the answer-cache mix and the conversation count over a seven-day window.
Authentication:this endpoint requires an access token or an API key as the bearer credential.
Authentication:this endpoint requires an access token or an API key as the bearer credential.
Issues an API key carrying its own daily allowance. The plaintext key is returned once and the store holds its hash only.
Authentication:this endpoint requires an access token or an API key as the bearer credential.
Request body
| name * | string | The key's label. |
| day_limit | integer | The per-day allowance. |
Request — edit and send
Schemas
The shared request and response objects, referenced from the endpoints above.
| query | string | The question, at most 8000 characters. |
| licensed_standards | array | The caller's entitlement set: the licensed-standard keys this request may see, validated against the deployment's declared catalog. Absent or unknown keys mean the fail-closed default — an empty set — so licensed content never reaches an unentitled caller. Each key admits the chunks stamped with that standard's license and enables the machine verdicts computed from its condition sets. |
| stream | boolean | When true, the response is a server-sent event stream. The first event is the reading (how the service interpreted the question), then the citations, then the answer tokens, and finally the completion marker. |
| fresh | boolean | Regenerates the answer and skips the answer caches, so the response also carries the grounding passages in context. Evaluation callers use it to observe what the answer was built from. |
| ablate_stages | array | Research-only (TODO.sota/09): run the retrieval registry projected to these stage names (registry order preserved; unknown names are a 400). Requires the x-admin-token header — a request naming a configuration without it is a 403. Ablated answers bypass every answer cache read and write and echo the active configuration in the response's ablate field. |
| ablate_no_verdict | boolean | Research-only: skip the verdict engine (machine verdicts and condition-set evaluation); the answer model narrates from passages alone. Same admin credential and cache law as ablate_stages. |
| ablate_speculative | boolean | Research-only (TODO.sota/02 row 2): arm speculative draft-verify — the cheap model drafts an answer per diversified subset of the window in parallel, one strong call verifies every candidate against the full passages and produces the final answer. Same admin credential and cache law as ablate_stages. |
| ablate_route | string | Research-only: force the route (TODO.sota/05). fast drops the candidate-expansion lanes (hyde, multi-query, sub-query) and floors generation effort at low; deep keeps the full registry. adaptive (the default) lets the router decide from understanding's features. Same admin credential and cache law as ablate_stages. |
| lang | string | Forces the answer language, for example en or fr. |
| prev | string | The previous question, for conversational context. |
| history | array | Recent turns, for conversational context. |
| context | object | An application context, such as a certificate entity, that scopes the retrieval to the document the context names. |
| answer | string | The generated answer. |
| citations | array | The passages the answer rests on. |
| blocks | array | The typed objects the answer carries: tables, figures, condition-set verdicts, conformance verdicts and unit blocks. A verdict block's payload carries the machine evaluation — the verdict (pass, fail or void), one check per machine rule with its expression, the values bound from the question, and the individual result — plus, for condition-set membership, the matched severity set or the nearest set with the violated bands; aggregation verdicts carry the machine-computed count, minimum, maximum or interval lookup over a typed table payload. The verdict is computed server-side; clients render it as data. |
| model | string | The model that generated the answer. |
| query_hash | string | The hash of the question, used for feedback. |
| read | object | How the service read the question — the interpretation that steered retrieval. Present on fresh answers; absent on exact cache hits, which never re-ran understanding. |
| route | object | The adaptive route the ask rode (TODO.sota/05): fast (the registry minus the candidate-expansion lanes, generation effort floored at low) or deep (the full registry), with the features that fired — the telemetry the routing-accuracy analysis reads. |
| served_from | string | Present when the answer was served from the answer cache for an identical or similar earlier question. The cache stores the answer and never the passages. |
| quota | object | The remaining daily allowance. |
Streaming answers
Setting stream to true on either ask endpoint returns a server-sent event stream. The events carry the citations first, then the answer tokens as they are generated, and finally a completion event that names the model and carries the query hash. The chat interface uses this stream, and the JSON document returned by stream: false carries the same content as a complete object.
Entitlements and severity verdicts
Licensed standards deploy with a fail-closed entitlement scope. A
request carries its entitlement set in the licensed_standards field —
each key validated against the deployment’s declared catalog, and an
absent field meaning the empty set — so licensed chunks and their
machine verdicts never reach an unentitled caller.
Severity questions over the licensed test-method packages return a
machine-computed verdict block. Ask
Is 40 °C at 85 % RH a valid Test Cab severity per IEC 60068-2-78?
with "licensed_standards": ["std:iec-60068-2-78"] and the response
carries, in blocks, a verdict whose checks compare each stated
quantity against the set’s tolerance band in SI:
{
"type": "verdict",
"unit_id": "/condition/severity-cab-40-degc-85-rh",
"payload": {
"verdict": "pass",
"checks": [
{ "expression": "temperature within 40 degC ±2",
"values": { "stated": 40 }, "result": true },
{ "expression": "relative_humidity within 85 % ±3",
"values": { "stated": 85 }, "result": true }
],
"matched": ["/condition/severity-cab-40-degc-85-rh"]
}
}
An out-of-band combination returns verdict: "fail" with nearest
naming the closest severity set and the violated bands. The verdict is
computed server-side; the answer model narrates it and never recomputes
it. The same request without the entitlement set never sees the
licensed content.
Table aggregation verdicts
Questions whose answer is a table’s content — a count, a minimum or
maximum, or the cell an interval selects — return a computed block read
from the typed table payloads the model plane carries. Ask
After a 500 kg load change, how long must a class C load cell stabilise before the reading, per OIML R 60? and the response carries,
in blocks, the computed cell with the full matched row:
{
"type": "verdict",
"unit_id": "/table/loading_stabilisation_times",
"payload": {
"check": "lookup: class_cd = 30 s",
"operation": "lookup",
"value": 30,
"unit": "s",
"row": {
"load_change_gt": "100", "load_change_max": "1000",
"class_cd": "30", "class_b": "45", "class_a": "60"
}
}
}
The interval convention is the standards’ own: a row stated as
greater than 100 kg up to and including 1 000 kg is half-open, so
exactly 1 000 kg belongs to the lower row. Counts and extrema work the
same way — How many accuracy classes does OIML R 60-1 define? returns
count: accuracy_class = 4, computed over the distinct values of the
column, not counted from retrieved prose. The block is computed
server-side; the answer model presents it and cites the table’s clause.
Conformance verdicts
When a question names a machine-checkable model object, such as a constraint or a requirement with a numeric limit, the service binds the values in the question to the rule’s own parameters and executes the check deterministically. The answer opens with the computed verdict, and the blocks array carries an entry of type verdict whose payload contains the outcome, the evaluated check and the standard’s own word for a violation. When parameters are missing, the verdict is void and names exactly what is missing, because a verdict computed over guessed parameters would not be a verdict at all.
Provable absence
A refusal states that a search found nothing, which is a statement about the search. The absence endpoint instead enumerates the standard’s entire machine-readable model and reports how many nodes were examined and that none matched, which is a statement about the corpus. The response is an enumeration certificate that names its scope, and when the verdict is present, the response lists the matching nodes.
Verifying answers
The verify endpoint applies the deterministic verification battery to any answer, whether generated by this service or by another system. Every quoted span must be contained verbatim in a passage retrieved for the query, and every object reference must resolve to a served object. A judged faithfulness score is reported separately and is labelled as judged, because it is produced by a model and not by a mechanical check. Both the verify endpoint and this page’s probe accept two optional grounding inputs: the answer’s passages (judge against the grounding the answer was actually given, rather than a fresh retrieval — a different pipeline that returns different passages) and its typed blocks (machine-computed verdicts and aggregations, which the judge reads as the service’s own grounding). The judged lane also steers to the publication’s active edition and excludes superseded same-document candidates, so a 2021 answer is never judged against 2017 passages.
The Model Context Protocol server
The service speaks the Model Context Protocol over streamable HTTP at /mcp, which allows editors, agents and orchestrators to use the corpus through their existing tool interfaces. The protocol follows JSON-RPC 2.0 with the 2025-06-18 revision, and the tools it exposes are ask, which asks a question and returns the answer with its citations, and retrieve, which returns ranked passages.