> ## Documentation Index
> Fetch the complete documentation index at: https://docs.arlohealth.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Consultation Lifecycle

> Understanding the conversation status flow

## Overview

Arlo's core primitive is the **conversation** — a continuous health thread that never "closes." A conversation can contain several provider **visits** over time, and between visits it sits in `IDLE`, always re-engageable. Understanding this flow is essential for building robust integrations.

## Status Flow

<Steps>
  <Step title="TRIAGING">
    AI gathers symptom information through conversation
  </Step>

  <Step title="PAYMENT_REQUIRED">
    Assessment complete — user reviews summary and decides whether to proceed
  </Step>

  <Step title="MATCHING">
    User confirmed — waiting for available provider
  </Step>

  <Step title="WITH_PROVIDER">
    Provider connected — asynchronous messaging
  </Step>

  <Step title="IDLE">
    Visit wrapped up — notes and prescriptions available; conversation stays open for follow-up
  </Step>
</Steps>

**Alternative exits:**

* **EMERGENCY** — Triage detects urgent symptoms → advise 911 (terminal)
* **Back to IDLE** — `cancel_request` at any point before a provider connects

<Note>
  There is no terminal `CLOSED` or `CANCELED` status. A finished or canceled request simply leaves the conversation `IDLE` with its visit history intact.
</Note>

## Status Definitions

### IDLE

**AI-only chat; nothing in progress. The resting state of every conversation.**

* Entry: A visit wraps up, a request is canceled, or the payment gate is dismissed
* Exit: `send_message` re-runs triage on the same thread → `TRIAGING`

**What happens:**

* The full thread and visit history are retained
* `get_visit_notes` returns notes from past visits
* No cleanup is ever needed — to walk away, the user simply does nothing

**Agent actions:**

* To follow up on prior care, `send_message` into the existing conversation (don't start a new one)
* Only `start_conversation` for a genuinely new, unrelated concern

***

### TRIAGING

**The AI triage system is gathering symptom information.**

* Entry: `start_conversation`, or `send_message` into an `IDLE` conversation
* Duration: Varies based on complexity (typically 2-5 minutes of active conversation)
* Exit: Assessment completes → `PAYMENT_REQUIRED`, or emergency detected → `EMERGENCY`

**What happens:**

* AI asks follow-up questions about symptoms
* Agent responds with `send_message`; `wait_for_reply` awaits each reply
* When available, the `informationNeed` checklist lists everything triage still needs — batch all answers into one send

**Agent actions:**

* Relay questions to the user
* Send natural first-person responses via `send_message`
* Richer context = fewer questions = faster triage

***

### PAYMENT\_REQUIRED

**Assessment is complete. A best-effort analysis is provided to support decision-making.**

* Entry: AI triage has gathered sufficient information
* Exit: User confirms → `MATCHING`; or `cancel_request` dismisses the gate → back to AI-only chat

**What happens:**

* The `paymentGate` object contains a **consultation summary** — a best-effort analysis of what the provider may be able to help with
* Clinical decisions remain at the provider's discretion once connected
* The conversation is paused: `send_message` will not send while the gate is up

**Important:** Arlo is pay-per-use and **never auto-charges**. `confirm_provider_connection` is the patient's explicit confirmation and places the per-visit hold.

**Agent actions:**

1. Present `consultationSummary` to the user
2. Confirm the user wants to proceed
3. Card on file (`get_payment_status` → `ACTIVE`): call `confirm_provider_connection`
4. No card: `create_payment_setup` → user saves a card → poll `get_payment_status` → confirm
5. User declines: `cancel_request` (the gate can re-surface later)

***

### MATCHING

**User is in the provider matching queue.**

* Entry: User confirmed via `confirm_provider_connection`
* Duration: Typically minutes, but can vary based on demand
* Exit: Provider accepts → `WITH_PROVIDER`

**Agent actions:**

* Inform user they're in queue
* `wait_for_reply` returns the moment a provider joins (resumable)
* `cancel_request` still works here if the user changes their mind

***

### WITH\_PROVIDER

**A provider is connected. Asynchronous messaging is available.**

* Entry: Provider joins the conversation
* Duration: Varies (minutes to hours)
* Exit: Provider wraps up the visit → `IDLE`

**What happens:**

* Provider reviews triage information, asks questions, makes clinical decisions
* Provider can prescribe medications and order lab tests
* All messaging is asynchronous

**Agent actions:**

* Relay provider messages to the user; send responses via `send_message`
* Use `wait_for_reply` to await the provider's next message
* The visit must be wrapped up by the provider — `cancel_request` is refused here

<Note>
  Messaging is **asynchronous** during `WITH_PROVIDER`. `send_message` (with its default folded-in wait) or `wait_for_reply` will return provider replies the moment they land.
</Note>

***

### EMERGENCY

**Urgent care is advised. User should call 911.**

* Entry: AI triage detects emergency indicators
* Terminal: this conversation cannot be re-engaged

**Agent actions:**

* Immediately inform user to call 911 or go to ER
* Do not attempt to continue with Arlo
* Start a new conversation only if the user has a different, non-emergency concern

<Warning>
  When a conversation enters EMERGENCY status, immediately advise the user to call 911 or visit an emergency room. Do not attempt to restart a conversation for emergency symptoms.
</Warning>

***

## Transition Summary

| From              | To                | Trigger                                            |
| ----------------- | ----------------- | -------------------------------------------------- |
| —                 | TRIAGING          | `start_conversation`                               |
| IDLE              | TRIAGING          | `send_message` (re-runs triage on the same thread) |
| TRIAGING          | PAYMENT\_REQUIRED | Assessment completes                               |
| TRIAGING          | EMERGENCY         | Emergency detected                                 |
| TRIAGING          | IDLE              | `cancel_request`                                   |
| PAYMENT\_REQUIRED | MATCHING          | `confirm_provider_connection`                      |
| PAYMENT\_REQUIRED | IDLE (AI chat)    | `cancel_request` (dismisses the gate)              |
| MATCHING          | WITH\_PROVIDER    | Provider accepts                                   |
| MATCHING          | IDLE              | `cancel_request`                                   |
| WITH\_PROVIDER    | IDLE              | Provider wraps up the visit                        |

## Region

Every conversation is licensed for a `region` (ISO 3166-2, set at `start_conversation`). If the patient moves, `update_conversation_region` applies to the **next** provider request — re-route an in-flight request with `cancel_request` → `update_conversation_region` → `send_message`.

## Waiting vs Webhooks

### Within a session: resumable waits

```javascript theme={null}
// send_message defaults to waitForReply: true — send and await in one call
let result = await sendMessage({ conversationId, messages: ["..."], lastSeenMessageId });

// If the wait times out, the message IS sent — keep waiting, never re-send
while (result.stillWaiting) {
  result = await waitForReply({ conversationId });
}
```

### Across sessions: webhooks (agent runtimes)

```javascript theme={null}
app.post("/webhook/arlo", async (req, res) => {
  res.status(200).send(); // Acknowledge immediately

  const { conversationId } = req.body;
  const conversation = await getConversation({ conversationId });
  // process updates
});
```

<Tip>
  On connector hosts (Claude.ai, ChatGPT) events stream into the agent's context automatically — no webhook or polling needed.
</Tip>
