Skip to main content
Preview endpoint, integration testing only. POST /api/chat/v3 is enabled per API key under a written testing agreement. Request text is sent to the model provider and recorded in Vera’s tracing system, and the endpoint carries no availability or stability commitment.
This is not the /api/chat/v2 event format. /api/chat/v2 emits Vera’s own flat event vocabulary (thread-info, data-references, data-search-steps). /api/chat/v3 emits the AI SDK UI message stream, which has different frame types and a different terminator. Do not reuse a v2 parser. The frame shape is a preview contract and may change; the x-vercel-ai-ui-message-stream header carries its version.

Transport

Content-Type: text/event-stream. Each frame is one JSON object:
The stream ends with a literal sentinel, which is not JSON:
Parse every data: line except [DONE], and treat [DONE] as end-of-stream. Every frame carries a top-level type.

Response headers

Reconnecting a dropped stream

Every answer is saved in a thread under your partner account, so any of your API keys can reach it. Vera keeps generating when your connection drops, so you can pick the answer back up:
Reconnecting replays an answer; it does not ask anything. To ask a follow-up in the same thread, POST again with thread_id set to this id. Reconnecting after a follow-up resumes the latest answer in that thread (see the tool guide).

Frame catalog

Message and step envelope

start, start-step, finish-step, finish, abort start opens the assistant message, finish closes it. The agent runs a bounded loop, so a single answer contains several start-step / finish-step pairs: one per model call. abort appears instead of finish when the run was cancelled.
The messageId on start is the id Vera saves this answer under, inside the thread named by x-thread-id. The non-streaming lane returns the same pair as thread_id and message_id. To quote a request in a support request, use the x-vera-request-id header.

text-start / text-delta / text-end

The answer. Concatenate every delta with the matching id to build the Markdown answer. The id is text-1 for the first block of a turn, text-2 for the next, and so on.
Text deltas carry Vera’s citation markup verbatim, and so does the non-streaming answer: both modes return the same text for the same question. See Resolving a citation below for the tag grammar.

tool-input-available

The agent called a tool you can render. toolCallId names the tool and its position in the turn, as <toolName>-<n>: the first medcalc call of a turn is medcalc-1, the second is medcalc-2. The output frame that may follow carries the same id, so you can attribute a payload without keeping any mapping of your own. For patientHandout and priorAuth, input is the deliverable: the model authors the document as the tool’s arguments and writes no answer text. It arrives trimmed to the fields documented for that tool.
For medcalc, the one card tool, input is empty: what the model asked for is its own working, and the payload follows on tool-output-available.
A toolName of stop, also with an empty input, means Vera declined the request on content-policy grounds. No answer text follows and nothing about the reason is sent. Neither retrieve nor drug ever appears: they do their work on the model channel, and what they found reaches you as data-sources and answer text. A drug the answer relied on arrives as a drug reference whose title is its name.

tool-output-available

A card tool returned. output is the payload documented for that tool in the API reference, trimmed at every depth: the monograph, the evidence and everything Vera’s own clients do not render are removed before the frame leaves the server. The frame carries toolCallId but not toolName; the id names the tool, and matches the tool-input-available frame that announced it. A card tool announced there can end without an output frame: when the lookup fails, or returns something the documented payload cannot describe, nothing is sent for it and the answer text stands on its own.

data-sources

Sources the answer may cite. One frame is emitted per search the agent runs, carrying the sources that search surfaced. A search that re-surfaces a paper an earlier one already sent will send it again, identically, so accumulate into a map keyed by sourceId rather than appending to a list. sourceId is what a cite index resolves against. A frame is not tied to the step it arrives in. Sources are written when a background lookup that attaches their evidence grade returns, which is usually a step later than the search that produced them, so do not group sources by step or wait for a step to close before rendering. A reference carries what a citation renders and links with, and no more. sourceId and kind are always present. kind says what the source is: a paper (journal article or guideline) carries title, firstAuthor, journal, year, its doi when it has one, which is the only identifier to link out with, and isGuideline; a drug and a calculator each carry only their name as title. isGuideline is a paper field and is absent on every other kind, as is evidenceStrength, which is present when the paper has a graded level of evidence (Very High, High, Moderate, Low). The evidence text, journal tiering and Vera’s internal scoring never leave the server, nor does the provider metadata the model attaches to a part.

data-suggestions

Follow-up questions, emitted once near the end of a completed answer.
Sent only when the request set suggestions: true, on both the streamed and the collected lane.

error

Terminal stream failure. The text is a failure class plus the request id, deliberately generic.

Resolving a citation

A grounded claim is wrapped in a tag whose index names the evidence behind it:
index is one or more sourceId-spanNo pairs: comma-separated for several sources, .. for a range, and the spanNo after the dash identifies the passage within that source. Read the number before the dash and look it up by sourceId in the references you accumulated from data-sources; the span number is Vera-internal and safe to discard. A self-closing tag (/>) carries no claim of its own and cites the sentence it trails. <calculator index="12"/> marks where a calculator card belongs and resolves by sourceId the same way. Every id Vera cites was announced on a data-sources frame in the same response, or, on a follow-up, in an earlier response in the same thread. Ids are numbered across the whole thread and never reused, so keep the references from earlier answers and resolve against all of them. A lookup that still misses means the model invented the index, so drop that tag rather than render an unresolvable citation.

Block tags around the answer

The answer can also carry a block tag that wraps a whole passage and marks what kind of statement it is. These are not citations and carry no index: they open and close around prose you render normally.
Strip the tag and keep its contents. A tag you do not recognise should be stripped the same way — the list can grow — and never rendered as literal text.

Frames Vera does not send to partners

These exist in the underlying protocol and are filtered out before the stream reaches you. Do not build against them; if one appears, report it.

Parsing example

Prefer a single JSON payload

Set stream: false and Vera returns one body once the answer is complete. answer carries the same citation markup the stream does, resolvable against references exactly as above:
The request id is on the x-vera-request-id header, not in the body. An agentic turn can take a couple of minutes, so allow a generous client timeout on this path.

Follow-up questions on this path

Send "suggestions": true and the body carries a suggestions object alongside answer:
It is off by default. Generating them is a second model call made after the answer is already finished, so on this path you wait for it and on the streaming path you do not.

Agentic tools

Choosing which tools the agent may use.

API reference

Full request and response schemas.