Overview
A conversation is a continuous health thread that never “closes.” It can contain several provider visits over time, and anIDLE conversation can always be re-engaged with send_message (which re-runs triage on the same thread). These tools manage the full lifecycle: starting, reading, waiting for replies, stopping a provider request, retrieving visit notes, and updating the care region.
start_conversation
Open a new health conversation with Arlo. Triggers AI triage and can lead to one or more provider visits over time. Arlo connects patients with licensed clinicians who can diagnose, treat, prescribe, order labs, and refer.Start NEW vs. continue EXISTING
This tool opens a brand-new conversation. To continue an existing conversation — even one that looks finished — usesend_message instead; messaging an idle conversation re-runs triage on the same thread. Call list_conversations first if you’re unsure whether a relevant conversation already exists. Only start a new conversation for a genuinely new, unrelated concern.
Parameters
The live tool description and the
REGION_NOT_SUPPORTED payload carry the current list of regions Arlo serves — read them at call time instead of hardcoding a list. See Service regions.Context Message Format
Write in the first person, as the patient speaking — the message is delivered to the care team as if the patient typed it themselves. Never third person (“The user has…”, “Patient reports…”). For a child or dependent, stay first person from the account holder’s perspective (“My daughter has had a fever since yesterday…”).Fast-ack behavior
This tool returns as soon as the conversation is created — it does not block for the first triage reply. Callwait_for_reply with the returned conversationId to await Arlo’s response.
Returns
list_conversations
List the user’s ongoing health conversations. Use this to find an existing conversation to continue before starting a new one.Parameters
Returns
Pagination
Conversations come back newest-activity-first. WhenhasMore is true, the result also includes nextCursor and nextPageInstructions:
beforeTimestamp and beforeId. The cursor rides on lastActivityAt (the last message, as epoch seconds) with the conversation id as tie-breaker — not on updatedAt.
If the patient is now in a different state than a conversation’s
region, call update_conversation_region before requesting a provider in it.get_conversation
Get the current status and messages of a conversation: itsstatus, region, the active provider visit (if any), and a summary of past visits.
Parameters
Delta reads
When your agent is woken by a webhook or resumes a loop, pass the id of the newest message it already saw assinceMessageId — only newer messages are returned (with newMessagesSince carrying the count), so a long thread doesn’t re-enter your context on every wake. The read gate is satisfied either way. If the id isn’t found in the fetched window, the normal message window is returned with sinceNotFound: true.
The read gate
Call this before everysend_message. send_message enforces a read-first rule — it refuses unless you’ve pulled the latest conversation state since its last update (or since your previous send). Calling this tool with includeMessages: true marks the conversation as read for your session. Alternatively, pass lastSeenMessageId to send_message to skip the extra round-trip.
Statuses
There is no terminal
CLOSED/CANCELED status. A finished or canceled request simply leaves the conversation IDLE with its visit history intact.Returns
Key fields:The payment gate
Whenstatus is PAYMENT_REQUIRED, paymentGate carries everything you need to ask the patient to confirm:
Every gate is approved the same way: relay
consultationSummary, then call start_visit_payment once the patient wants to proceed and hand them the paymentUrl. Arlo never auto-charges.
The informationNeed checklist
WhileTRIAGING, the result carries the shortlist of what Arlo would most like to learn next, so you can gather it all and answer in one send_message:
The checklist is computed per triage turn, and
informationNeedAsOfMessageId is the AI message it was computed on. If you have already answered items since that message, don’t re-collect them — the next triage reply recomputes the list.
When the patient’s own message is the newest on the thread, the checklist is withheld (it would list items they may have just answered) and
informationNeedNote explains why. Wait for the next triage reply.Message Types
Agent runtimes
Nothing streams into your context between turns, so this tool is your source of truth. Register a webhook once so Arlo wakes you (notifications carry no clinical content), then call this on wake withsinceMessageId to read what changed.
Widget hosts
On hosts that render the Arlo consultation widget, new events stream into your context between turns under theArlo Consultation Widget header. Read that before answering anything that depends on current state, and don’t re-render the full message thread as text — the UI displays it. Use this tool as the fallback (no widget content present, omittedEarlierEvents > 0, or as the read gate before send_message).
wait_for_reply
Wait for the next reply or update in a conversation.start_conversation returns as soon as the conversation exists, so call wait_for_reply to await the first triage reply. send_message folds this same wait in by default; use wait_for_reply to keep waiting after it returns stillWaiting, or to await a provider who is messaging on their own schedule.
It is a resumable wait you can loop on: call it, and if it returns stillWaiting, call it again to keep waiting. What it waits for depends on the conversation’s current status — the AI’s triage reply while TRIAGING, a provider connecting while MATCHING, or the provider’s next message while WITH_PROVIDER.
Parameters
Wait windows
The wait window is a host capability. Connector hosts (Claude.ai, ChatGPT) abort tool calls around 60s, so they get one ~55s window per call. Agent runtimes get ~240s by default and can ask for up to 600s viamaxWaitSeconds — provided the connection can be kept warm: send a progressToken with the call or declare the logging capability at initialize (Arlo emits a keepalive every ~12s). Clients that do neither are capped at 300s. stillWaiting results include waitedSeconds so you can decide whether to resume the wait or end the turn and rely on your webhook.
Returns
A wait returns one of these shapes. Most also carrynote, nextStep, and nextStepArgs — the suggested follow-up call, ready to pass straight through.
Reply events
reply (and each entry of replies[]) is one inbound message or visit event, never the patient’s own message:
While
TRIAGING, a reply can also carry informationNeed and informationNeedAsOfMessageId — the same checklist get_conversation returns. When a reply arrives, the conversation is marked read for your session.
Triage completed — payment required
Every consultation passes through this transition. The gate is inlined, so you don’t need aget_conversation round-trip before asking the patient to confirm:
paymentGate.consultationSummary, then call start_visit_payment when the patient agrees and hand them the paymentUrl. Once they approve the hold on Stripe’s page, the conversation moves to MATCHING on its own; await the provider with wait_for_reply. Arlo never auto-charges.
Provider joined
Timed out
stillWaiting: false with a note means the current status has nothing pending to wait for (IDLE, PAYMENT_REQUIRED, or EMERGENCY) — don’t loop. At the payment gate the next step is start_visit_payment, not a wait.cancel_request
Stop the conversation’s current attempt to connect with a provider and return it to AI-only chat. This does not end the conversation: the thread stays open and the user can re-engage anytime withsend_message.
Behavior by status
Parameters
Returns
action is payment_gate_dismissed when a PAYMENT_REQUIRED gate was declined, or provider_connection_canceled when a MATCHING request was pulled back and its hold released.
To fully walk away, the user can simply do nothing — an
IDLE conversation requires no cleanup.get_visit_notes
Get clinical notes from a conversation’s provider visits. A conversation can have several visits over time, each with its own note; this returns the notes across all of them, grouped per visit.Parameters
Returns
Notes exist per provider visit, not per conversation — the conversation itself never closes. A visit only has notes once the provider has closed it out with one, so check
pastVisits[].hasNotes from get_conversation before calling, and expect notes: [] with hasNotes: false otherwise.update_conversation_region
Change the region (state) a conversation is licensed for. Use when the patient is now physically somewhere different than when the conversation was started.Parameters
Timing
This updates the conversation’s region for the next provider request. It does not re-route a request already in flight:- If the conversation is
IDLE: change the region, thensend_messageto start a new request in the new region. - If the conversation is
MATCHINGorPAYMENT_REQUIREDand the user has actually moved: callcancel_requestfirst, thenupdate_conversation_region, thensend_message.