SDKsTypeScript

Streaming messages

Stream new messages in a conversation in real time over Server-Sent Events using the TypeScript SDK.

Stream new messages in a conversation in real time over Server-Sent Events. The flow has two steps. First the SDK issues a single-use, short-lived ticket from the stream-ticket endpoint. Then it opens a GET to the message-stream endpoint with that ticket as a query parameter and Accept: text/event-stream. The stream is authenticated by the ticket rather than the bearer key, so your API key never travels on the long-lived connection and the stream can be opened from a browser. stream() does both steps for you and yields messages as they arrive.

const controller = new AbortController();

for await (const message of bimpe.conversations.messages.stream(agentId, conversationId, {
  signal: controller.signal,
})) {
  console.log(message.role, message.message);
}

Each yielded value is a StreamMessageEvent with id, conversation_id, role, message, message_type, and created_at. The server also emits periodic heartbeat events to hold the connection open; the SDK consumes those internally and never yields them, so the loop only ever sees real messages.

Reconnection

On a dropped connection the SDK reconnects on its own. It remembers the id of the last message it handed you and resumes from there using after, so you neither miss a message nor see one twice. The reconnect budget counts consecutive failures and resets to zero every time a message is delivered, so a stream that flows for hours and then blips still gets a full set of retries rather than one exhausted long ago. Reconnects use the same backoff-with-jitter policy as the rest of the SDK.

Options

OptionDescription
afterReplay messages created after a message id or ISO-8601 timestamp; also used internally on resume
reconnectRe-open when the server closes the stream; default true; set to false to stop iteration on close
maxRetriesMaximum consecutive reconnect attempts before giving up; default 5
signalAn AbortSignal to stop the stream; breaking out of the loop also stops it

The async iterable never rejects on a normal close; it just ends.

Stream ticket

The ticket step is exposed on its own if you want to open the stream yourself. The ticket is single-use and expires after expires_in seconds.

const { ticket, expires_in } = await bimpe.conversations.messages.streamTicket(agentId, conversationId);

On this page