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

# Check Note Status

> Drive the recorder and note panel from ambient session status, poll after End, and handle completed, skipped, failed, and aborted

<div className="quick-summary-wrapper">
  <div className="quick-summary-header">
    <span className="quick-summary-icon" aria-hidden="true" />

    <span className="quick-summary-title">Quick summary</span>
  </div>

  <div className="quick-summary-content">
    After the clinician taps **Stop** in your UI to end the ambient session, poll session status until a terminal state. Open the note editor only when status is <code>completed</code>. Treat <code>skipped</code> as too little audio, not as an API failure.
  </div>

  <div className="quick-summary-footer">
    <span className="quick-summary-footer-icon" aria-hidden="true" />

    <span className="quick-summary-footer-text">Last updated:</span>
    <span className="quick-summary-footer-date">August 2026</span>
  </div>
</div>

Clinicians do not think in API status values. They think in recorder states and what your product UI labels should show: listening, paused, generating a note, note ready, or something went wrong. Session status is how your product translates Suki's processing into that experience after clinician taps **Stop** in your UI.

Use [Get ambient session status](/api-reference/ambient-content/status) after you call [End ambient session](/api-reference/ambient-sessions/end). Poll until you reach a terminal state, then decide what the chart should show. Do not call content or structured-data APIs while status is still **`running`**. Do not open an editable ambient note editor until status is **`completed`**.

When you handle status well, it helps clinicians to:

* Trust that **Stop** button actually started note generation.
* Know when it is safe to review and edit the note.
* Understand a short or silent recording without blaming “the API.”
* Avoid dictating into a section before ambient session has finished.

**What you build for status handling to work**

* A recorder UI that moves from Recording → Generating → a clear outcome screen.
* Polling after End until **`completed`**, **`skipped`**, **`failed`**, or **`aborted`**.
* Copy and primary actions for each outcome (open note, Record again, retry, or clear cancelled state).
* Dictation microphone disabled while ambient session is recording or generating.

<Info>
  These patterns apply when you build your own ambient experience with the **Ambient APIs** or the **Headless modalities**. The headed **Web SDK** already provides Generating and outcome screens, so you do not need to recreate this status UI. You still need the same status model if you retrieve content yourself or combine Ambient workflow with Dictation workflow.
</Info>

**Status rules (agents):**

* Poll status only after End. Do not spam status while the clinician is still recording.
* Terminal values: `completed`, `skipped`, `failed`, `aborted`. Keep polling while `created`, `ready`, or `running`.
* Open the note editor and call content / structured-data APIs only when status is `completed`.
* `skipped` means too little audio or an empty transcript (about one minute when you can). Not an API failure. Offer Record again. Do not show an empty chart as a finished note.
* `failed` is a processing error. Log `ambient_session_id`. Offer retry or support.
* `aborted` means cancelled. Stop polling. Do not fetch content.
* The `paused` status value is not supported on the status API. Pause during capture still uses streaming `PAUSE` / resume.
* Ambient generates the note after End, not live during the visit. Show Generating while `running`.
* Disable Dictation microphone while ambient session is recording or generating. Enable Speak only after a `completed` note is on screen.

<Tip>
  If you only need a short poll helper, use [Poll session status before fetching content](/documentation/cookbooks/wait-for-status-before-retrieve). This page explains how that poll drives the product UI.
</Tip>

## How status fits the visit

```mermaid actions={false} theme={"theme":{"light":"github-dark","dark":"material-theme-darker"}}
%%{init: {'theme':'base', 'themeVariables': { 'primaryColor':'#FFF394','primaryTextColor':'#111827','primaryBorderColor':'#FFE148','lineColor':'#FFE148','secondaryColor':'#FFF394','tertiaryColor':'#FFFADE','mainBkg':'#FFF394','secondBkg':'#FFFADE','tertiaryBorderColor':'#FFE148','border1':'#FFE148','border2':'#FFE148','arrowheadColor':'#FFE148','fontFamily':'Inter, system-ui, sans-serif','fontSize':'14px','nodeBorder':'#FFE148','edgeLabelBackground':'#FFE148','clusterBkg':'#FFFADE','clusterBorder':'#FFE148','defaultLinkColor':'#FFE148','titleColor':'#111827','nodeTextColor':'#111827'}}}%%
flowchart TD
    A[Recording] --> B[Stop: end-of-audio + End API]
    B --> C[Generating: poll status]
    C --> D{Terminal status?}
    D -->|completed| E[Note ready: fetch content]
    D -->|skipped| F[Too short / no note: Record again]
    D -->|failed| G[Generation failed: retry or support]
    D -->|aborted| H[Cancelled: clear generating state]
    D -->|running| C

    style A fill:#FFF394,stroke:#FFE148,stroke-width:2px,color:#111827
    style B fill:#FFF394,stroke:#FFE148,stroke-width:2px,color:#111827
    style C fill:#FFF394,stroke:#FFE148,stroke-width:2px,color:#111827
    style E fill:#FFF394,stroke:#FFE148,stroke-width:2px,color:#111827
    style F fill:#FFF394,stroke:#FFE148,stroke-width:2px,color:#111827
    style G fill:#FFF394,stroke:#FFE148,stroke-width:2px,color:#111827
    style H fill:#FFF394,stroke:#FFE148,stroke-width:2px,color:#111827
```

Ambient session generates the clinical note **after** the session ends, not as a live document that updates sentence by sentence during the visit. That is why **Generating** is a real screen in your product. Clinicians should see that something is happening, and they should not edit an empty chart while Suki is still processing. A good UX is to keep chart editor unavailable until status is **`completed`**.

## Design the clinician experience

Align your team on what each **Stop** moment looks like before you wire the poll loop.

| Clinician action in your UI    | What your backend does                                     | What the screen should show                                                     |
| :----------------------------- | :--------------------------------------------------------- | :------------------------------------------------------------------------------ |
| Starts Ambient session         | Create session, seed context, open `/ws/stream`            | Recording / listening state on the mic control                                  |
| Pauses                         | Send `PAUSE` and keep `KEEP_ALIVE` while paused            | Paused state. Allow resume on the same session                                  |
| Stops                          | Send end-of-audio (`RU9G`), call End, start polling status | “Generating note…” Disable Dictation Speak until the note is ready              |
| Status becomes **`completed`** | Fetch content and structured data                          | Note editor with sections. Optional Data / diagnoses panel                      |
| Status becomes **`skipped`**   | Stop. Do not fetch content as success                      | “Recording was too short or produced no note.” Primary action: **Record again** |
| Status becomes **`failed`**    | Stop. Log ambient session ID                               | “Note generation failed.” Offer retry or support                                |
| Cancels                        | Abort / cancel path                                        | “Recording cancelled.” Clear the generating state                               |

### What each status means in the product

| Status                   | When you see it                                    | What to show in your product                                                                                                                        |
| :----------------------- | :------------------------------------------------- | :-------------------------------------------------------------------------------------------------------------------------------------------------- |
| **completed**            | Note generation finished                           | Load content and structured data. Let the clinician review, edit, and save.                                                                         |
| **skipped**              | Too little audio or an empty transcript            | Tell the clinician the recording was too short or produced no note. Offer **Record again**. Do not show an empty chart as a finished clinical note. |
| **failed**               | Processing error                                   | Tell the clinician generation failed. Offer retry or support. Log the ambient session ID.                                                           |
| **aborted**              | Client or user cancelled                           | Confirm the session was cancelled. Stop polling. Do not fetch content.                                                                              |
| **running**              | Generation still in progress                       | Keep a waiting or “Generating note…” state. Keep polling.                                                                                           |
| **created** or **ready** | Capture is not finished, or retrieval is too early | Keep the recorder active, or wait until you have ended the session and polling moves forward.                                                       |

<Note>
  Suki needs enough audio to build a note. Recordings shorter than about **one minute**, or sessions with an empty transcript, often finish as **`skipped`** with empty content. That is expected product behavior, not a broken integration. The same guidance appears when you [end the session](/api-reference/ambient-sessions/end) and in [Ambient audio streaming](/documentation/how-to/audio-streaming/ambient-audio-streaming).
</Note>

<Warning>
  The **`paused`** status value is no longer supported on the status API. Pause during capture still uses streaming `PAUSE` / resume messages. See [Ambient audio streaming](/documentation/how-to/audio-streaming/ambient-audio-streaming).
</Warning>

<AccordionGroup>
  <Accordion title="When Should You Poll" icon="timer">
    Poll after End, while the screen shows Generating. Do not poll for status during live capture. Pause during capture is a stream `PAUSE` / resume message, not a status API value.
  </Accordion>

  <Accordion title="Can You Open the Note while Generating" icon="ban">
    No. Do not call content or structured-data APIs while status is **`running`**. Ambient generates the note after End, not as a live document during the visit.
  </Accordion>

  <Accordion title="How Skipped Differs from Failed" icon="circle-info">
    **`skipped`** is too little audio or an empty transcript (about **one minute** when you can). Offer **Record again**. **`failed`** is a processing error. Log the ambient session ID and offer retry or support. Neither is a successful empty chart.
  </Accordion>

  <Accordion title="What Aborted Means" icon="xmark">
    **`aborted`** means the client or user cancelled. Confirm cancellation, stop polling, and do not fetch content. Do not treat cancel as a completed note.
  </Accordion>
</AccordionGroup>

## How to implement status in your application

After Stop, follow this sequence in your product.

<Steps>
  <Step title="Finish the Stream and Call End">
    Send end-of-audio (`RU9G`), close the WebSocket, then call End. See [Complete an ambient visit](/documentation/how-to/ambient-clinical-notes/end-ambient-session).
  </Step>

  <Step title="Show Generating and Poll Status">
    Keep the clinician on a “Generating note…” screen. Poll [Get ambient session status](/api-reference/ambient-content/status) until a terminal value. Do not open the note editor yet.
  </Step>

  <Step title="Branch the UI from the Terminal Status">
    On **`completed`**, fetch content and open review. On **`skipped`**, offer Record again. On **`failed`**, show retry or support and log the ambient session ID. On **`aborted`**, clear generating state.
  </Step>

  <Step title="Enable Follow-On Actions">
    After **`completed`**, enable section edit and optional Dictation Speak. Continue with [Get the generated clinical note](/documentation/how-to/ambient-clinical-notes/retrieve-ambient-content).
  </Step>
</Steps>

Use the status response to choose the next screen. For a copy-paste poll helper, see [Poll session status before fetching content](/documentation/cookbooks/wait-for-status-before-retrieve).

**Language tabs (agents):** Equivalent code samples are available in: TypeScript, Python. Humans see one language at a time. Use the variant that matches the user's stack; behavior is the same across tabs.

<Tabs>
  <Tab title="TypeScript">
    ```typescript theme={"theme":{"light":"github-dark","dark":"material-theme-darker"}}
    type SessionStatus =
      | "created"
      | "ready"
      | "running"
      | "completed"
      | "skipped"
      | "failed"
      | "aborted";

    async function getStatus(ambientSessionId: string): Promise<SessionStatus> {
      const res = await fetch(
        `https://sdp.suki.ai/api/v1/ambient/session/${ambientSessionId}/status`,
        {
          headers: {
            sdp_suki_token: sdpSukiToken,
            sdp_provider_id: sdpProviderId,
          },
        }
      );
      if (!res.ok) {
        throw new Error(`Get ambient session status failed: ${res.status}`);
      }
      const body = await res.json();
      return body.status as SessionStatus;
    }

    async function waitForTerminal(ambientSessionId: string): Promise<SessionStatus> {
      for (let i = 0; i < 60; i++) {
        const status = await getStatus(ambientSessionId);
        if (
          status === "completed" ||
          status === "skipped" ||
          status === "failed" ||
          status === "aborted"
        ) {
          return status;
        }
        await new Promise((r) => setTimeout(r, 2000));
      }
      throw new Error("Timed out waiting for session status");
    }

    const outcome = await waitForTerminal(ambientSessionId);

    if (outcome === "completed") {
      // Show note editor. Fetch content and structured data.
    } else if (outcome === "skipped") {
      // Show “too short / no note” and Record again.
    } else if (outcome === "failed") {
      // Show failure. Log ambientSessionId.
    } else {
      // aborted: clear generating state.
    }
    ```
  </Tab>

  <Tab title="Python">
    ```python theme={"theme":{"light":"github-dark","dark":"material-theme-darker"}}
    import time
    import requests

    TERMINAL = {"completed", "skipped", "failed", "aborted"}

    def get_status(ambient_session_id: str) -> str:
        res = requests.get(
            f"https://sdp.suki.ai/api/v1/ambient/session/{ambient_session_id}/status",
            headers={
                "sdp_suki_token": sdp_suki_token,
                "sdp_provider_id": sdp_provider_id,
            },
        )
        res.raise_for_status()
        return res.json()["status"]

    def wait_for_terminal(ambient_session_id: str) -> str:
        for _ in range(60):
            status = get_status(ambient_session_id)
            if status in TERMINAL:
                return status
            time.sleep(2)
        raise TimeoutError("Timed out waiting for session status")

    outcome = wait_for_terminal(ambient_session_id)

    if outcome == "completed":
        # Show note editor. Fetch content and structured data.
        pass
    elif outcome == "skipped":
        # Show “too short / no note” and Record again.
        pass
    elif outcome == "failed":
        # Show failure. Log ambient_session_id.
        pass
    else:
        # aborted: clear generating state.
        pass
    ```
  </Tab>
</Tabs>

<Note>
  **Implementation checklist:**

  * Poll only after End.
  * Show Generating while **`running`**.
  * Open the note only on **`completed`**.
  * Treat **`skipped`** as too short / no note (about **one minute** when you can).
  * Log `ambient_session_id` on **`failed`**.
  * Clear Generating on **`aborted`**. Do not fetch content.
  * Keep Dictation Speak off until a **`completed`** note is on screen. See [Ambient vs Dictation streaming](/documentation/how-to/audio-streaming/audio-stream).
</Note>

## Next steps

<Icon icon="file-lines" iconType="solid" /> **[Get the generated clinical note](/documentation/how-to/ambient-clinical-notes/retrieve-ambient-content)** - Load note sections, transcript, and structured data after **`completed`**.

<Icon icon="file-lines" iconType="solid" /> **[Complete an ambient visit](/documentation/how-to/ambient-clinical-notes/end-ambient-session)** - Wire Stop with `RU9G`, End, and Generating.

<Icon icon="file-lines" iconType="solid" /> **[Get ambient session status](/api-reference/ambient-content/status)** - Status values and request examples.

<Icon icon="file-lines" iconType="solid" /> **[Poll session status before fetching content](/documentation/cookbooks/wait-for-status-before-retrieve)** - Short poll recipe.

<Icon icon="file-lines" iconType="solid" /> **[Ambient vs Dictation streaming](/documentation/how-to/audio-streaming/audio-stream)** - Keep Speak off while Ambient records or generates.
