Skip to main content
ApolloMessagingClient is the browser-safe client for end-user messaging. It authenticates with your publishable key, exchanging it for a short-lived access token internally — the agent comes from the key, never from request bodies.
All methods are async, fully typed, and throw typed errors on failure. Request and response models are exported under the Apollo namespace.
Want to see the responses before you write code? Every call on this page is a button in the Apollo Agent Tester — paste your publishable key and try sends, streams, traces and channels against your own agent.

Send a message

Omit thread_id to start a new conversation, or pass it to continue one.
When the agent surfaces entities — products, bookings, search results — the reply carries them as cards. Each card holds the same entity in two self-contained representations, so you pick what fits your stack: a ready-to-render JSX string for React, or structured JSON for any other framework — see Cards for the full shape.
title, capability, and instance are optional and may be null — read them defensively. Pass structured data the caller should not have to state — the signed-in user, the account in view, what your systems already know — as agent_variables: a flat Record<string, unknown> whose keys are the context variables the agent’s program declares. Attach an image for the agent to reason over with image_url:
Send requests also accept an optional runtime_version — an advanced build pin for the turn; normally omit it.

Stream a message

streamMessage is the streaming transport: one HTTP call per turn that returns the reply as an async-iterable stream of Server-Sent Events — token deltas while the agent works, then the complete message, then ready-made follow-up suggestions. It takes the same request body and auth as sendMessage, leaves you no connection to keep alive, and resumes after a drop without re-running the turn:
Ready-made follow-up prompts arrive automatically as the suggestions frame after the terminal message — render them as tappable chips, no extra call needed. Its data carries followup_suggestions alongside the thread_id and interaction_id it belongs to. (Runtime v1 agents don’t emit this frame; their followup_suggestions ride on the message itself.) To resume a dropped stream without re-running the turn, reconnect with the last seq you saw:

Rerun an interaction

Regenerate a previous interaction — with the original or edited text — on a new thread branched from the original. Both interaction_id and text are required:

Read a conversation

A thread lives on the runtime that created it, so the transcript read names that runtime — pass the runtime version your agent runs on as runtime_version (sending resolves it automatically; see Threads and runtime versions):
Any value outside the 1.x family selects runtime v2 — it doesn’t have to match the thread’s exact build. Threads of runtime v1 agents take no selector: listMessages(threadId) reads them as is.

Traces

Every interaction’s reasoning trace — what the agent understood, which sources it relied on, what it decided. The shape follows the runtime the agent runs on, and trace.runtime says which one you got:
Apollo.Trace is a discriminated union — Apollo.Trace.V1 (Apollo.RuntimeV1Trace with runtime: "v1") or Apollo.Trace.V2 (Apollo.RuntimeV2Trace with runtime: "v2") — so the if narrows it. The runtime v2 sections are typed too (Apollo.RuntimeTraceFact, Apollo.RuntimeTracePassage, and the sources, citations_used, decided, checks and answer item types under Apollo.RuntimeV2Trace).
Requires SDK 3.4.0 or later. Earlier versions type Trace as the runtime v1 shape only and don’t know include_trace or the thread_id argument.
With the reply, in one request. Set include_trace: true on sendMessage / streamMessage / rerun; the reply carries the same object as message.trace_info. Off by default — a trace can be large. On a stream it rides the final message event:
Paging a long thread. threadTrace takes page[size], page[after] / page[before], and sort_by / sort_order in its second argument and returns { results, meta, links }:
Errors. A runtime v2 interaction read without thread_id throws Apollo.BadRequestError (the message says to pass it, or to use include_trace on the send); a thread that belongs to another agent than the key’s throws Apollo.NotFoundError. Both carry the standard error envelope in error.body.

Welcome message and follow-up suggestions

Called without a context, generateFollowupSuggestions returns the agent’s configured static suggestions.

Client context

After the first exchange (or an explicit getContext() call), the client knows which agent and organization its key resolves to:

Channels (WhatsApp and SMS)

Start an outbound conversation on a channel with channels.initiateThread. Pass 'sms' or 'whatsapp' as the channel. phone_number is the recipient (who receives the opener). sender_id is not that phone number. It is the MongoDB ObjectId of a sender record you already connected in the Playground. If you connected a specific phone number through the Playground (SMS or WhatsApp), copy that sender’s ObjectId and pass it as sender_id. The SDK then starts the conversation from that connected number. Without sender_id, the platform default sender is used instead. The response includes from when a specific sender was used, so you can confirm which connected number the opener was sent from.
WhatsApp is the same call. Template fields apply to WhatsApp only; text is used for SMS and ignored by WhatsApp.

Method reference

Every method also accepts a final requestOptions argument (timeoutInSeconds, maxRetries, abortSignal, extra headers) — see Best practices.