> ## 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.

# Session Status & Retrieve Content

> Learn how to check the processing status and retrieve the generated content of a session in the mobile SDK

<Callout type="updates" color="orange" icon="bell">
  **Updated:**

  Starting with Mobile SDK `v2.7.0`, you can list and read shared clinical notes across Suki products.

  Learn more in the [Shared notes across products](/mobile-sdk/ambient-guides/session-status-and-content-retrieval#shared-notes-across-products) section.
</Callout>

<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 an ambient session ends, use the Mobile SDK to check processing status and retrieve the generated content. Use `status(for:)` to check processing status, `content(for:)` to retrieve the clinical note, `transcript(for:)` to retrieve the transcript, and `getStructuredData(for:)` to retrieve structured output. These session-level APIs require a valid `sessionId`.

    <br />

    <br />

    To access clinical notes shared across Suki products, use `listEncounterNotes`, `getNoteContext(noteId:)`, `getNoteContent(noteId:)`, `getNoteStructuredData(noteId:)`, and `encounterContent(encounterId:)`. Pass the `compositionId` as the `noteId` for note-level APIs. For `encounterContent(encounterId:)`, pass the Session Group ID as `encounterId`, not the EMR encounter id. All of these APIs are asynchronous.
  </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">July 2026</span>
  </div>
</div>

The Suki Mobile SDK provides methods to check the processing status and retrieve the generated content of a session. Use these methods to track the progress of your session and retrieve the generated content after it has been completed.

**What will you learn?**

In this guide, you will learn how to:

* Check the processing status of a session using the `status(for:)` method.
* Retrieve generated content by calling the `content(for:)` method to get clinical note suggestions.
* Retrieve the full transcript of the conversation using the `transcript(for:)` method.
* Get structured data, such as generated diagnoses and entities, using the `getStructuredData(for:)` method.
* List and read shared notes across products with `listEncounterNotes(emrEncounterId:)`, `getNoteContext(noteId:)`, `getNoteContent(noteId:)`, `getNoteStructuredData(noteId:)`, and `encounterContent(encounterId:)`.
* Submit user feedback on AI-generated content using the `submitFeedback(_:for:onCompletion:)` method, including both quantitative and qualitative data.
* Handle asynchronous results using a completion handler for all retrieval methods.
* Understand and adhere to constraints for submitting feedback, including providing feedback only once per entity type per session.

<Note>
  Before calling session-scoped methods, ensure the Mobile SDK is initialized and that you use a valid `sessionId` from an active or completed session. Note-level methods use the same token provider and take an EMR encounter id or composition id instead.
</Note>

## Check status and retrieve content

After you end a session, asynchronously check its processing status and retrieve the generated content. You must provide a valid `sessionId` for the session you want to query.

***

The diagram below illustrates the process of retrieving the generated content of a session.

```mermaid actions={false} theme={"theme":{"light":"github-dark","dark":"material-theme-darker"}}
%%{init: {'theme':'base', 'themeVariables': { 'primaryColor':'#FFF394','primaryTextColor':'#1a1a1a','primaryBorderColor':'#FFE148','lineColor':'#FFE148','secondaryColor':'#FFE148','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':'#1a1a1a','nodeTextColor':'#1a1a1a'}}}%%
graph TD
    A[Start: You have a valid sessionId] --> B{Call a retrieval method, passing the ID}
    B --> C[SDK performs an asynchronous operation...]
    C --> D{Completion Handler is called with a Result}
    D -->|Success| E[Process the returned content<br/>e.g., display suggestions, transcript]
    D -->|Failure| F[Handle the returned error]
    E --> G[End]
    F --> G[End]

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

***

All retrieval methods are **asynchronous**. The result is returned in a <Tooltip tip="A closure that runs when a task, such as a network request, is complete. Use it to process the final result or handle an error">
Completion handler
</Tooltip>, which provides either the requested content or an error.

### Check the processing status

Call `status(for:)` after a session ends to check whether Suki has finished processing the audio. The clinical note, transcript, and structured data are only available once processing is complete, so use this method to decide when to call the retrieval methods and to drive a "processing" or "note ready" state in your UI.

Suki needs at least **one minute of audio** to generate content. If a session was too short or is not yet complete, the status reflects that, and the retrieval methods return no content.

<CodeGroup>
  ```swift Swift theme={"theme":{"light":"github-dark","dark":"material-theme-darker"}}
  SukiAmbientCoreManager.shared.status(for: sessionId) { result in
      // The completion handler returns a result type.
      switch result {
      case .success(let status):
          // On success, the status object contains the current state.
          print("Session status: \(status)")
      case .failure(let error):
          // On failure, an error object is returned.
          print("Error fetching status: \(error)")
      }
  }
  ```
</CodeGroup>

### Get generated suggestions

Call `content(for:)` to retrieve the AI-generated clinical note: the suggestions your provider reviews, edits, and signs before handoff to the EHR. This is the primary output most integrations display after a visit.

Call it only after `status(for:)` reports that processing is complete. Calling it earlier returns no content.

<CodeGroup>
  ```swift Swift theme={"theme":{"light":"github-dark","dark":"material-theme-darker"}}
  SukiAmbientCoreManager.shared.content(for: sessionId) { result in
      switch result {
      case .success(let suggestions):
          // The suggestions object contains the generated note content.
          print("Generated Suggestions: \(suggestions)")
      case .failure(let error):
          print("Error fetching content: \(error)")
      }
  }
  ```
</CodeGroup>

### Get the audio transcript

Call `transcript(for:)` to retrieve the word-for-word text of the conversation, which is separate from the generated clinical note. Use it when you need exactly what was said rather than the summarized note, for example to let a provider verify the note against the transcript, support QA or compliance review, or display the transcript alongside the note.

The response contains transcript segments. The example below joins them into a single string.

<CodeGroup>
  ```swift Swift theme={"theme":{"light":"github-dark","dark":"material-theme-darker"}}
  SukiAmbientCoreManager.shared.transcript(for: sessionId) { result in
      switch result {
      case .success(let response):
          // The response object contains transcript segments.
          // This example joins them into a single string.
          let transcriptText = (response.finalTranscript ?? []).compactMap { $0.transcript }.joined(separator: " ")
          print(transcriptText)
      case .failure(let error):
          print("Error fetching transcript: \(error)")
      }
  }
  ```
</CodeGroup>

### Get structured data

Call `getStructuredData(for:)` when you need discrete, machine-readable output instead of free-text notes, for example to populate diagnosis fields, drive orders, support medical coding, or feed analytics in your application. It returns diagnoses and other entities generated from the session.

<Note>
  Starting with Mobile SDK `v2.6.0`, the response may include Medication orders when that capability is enabled for your integration. Medication orders are **optional**, so check for them before you use them, as shown below.
</Note>

<CodeGroup>
  ```swift Swift theme={"theme":{"light":"github-dark","dark":"material-theme-darker"}}
  SukiAmbientCoreManager.shared.getStructuredData(for: sessionId) { result in // [!code ++:19]
      switch result {
      case .success(let response):
          let data = response.structuredData
          // Diagnoses
          for d in data.diagnoses.diagnoses {
              print(d.note)
          }
          // Medication orders (optional) [!code ++:6] if Medication orders are enabled
          if let orders = data.orders?.medicationOrders {
              let all = orders.values + orders.partialValues
              for order in all {
                  print(order.drugName, order.instructions)
              }
          }
      case .failure(let error):
          print(error)
      }
  }
  ```
</CodeGroup>

## Shared notes across products

`status(for:)`, `content(for:)`, `transcript(for:)`, and `getStructuredData(for:)` retrieve the processing status or generated content for a single ambient recording session. Each method requires a `sessionId`.

To list or retrieve clinical notes shared across Suki products, use the note read APIs described below. Depending on the API, pass one of the following:

* An EMR encounter id
* A `compositionId` as the `noteId`
* A Session Group ID as `encounterId` for `encounterContent`

All of these APIs are asynchronous, and their completion handlers are invoked on the main queue. Errors are returned as generic or gRPC errors, not `SukiStatus`. These APIs use the same token provider configured for the ambient session APIs.

For more information, see [Ambient interoperability](/mobile-sdk/ambient-guides/ambient-interoperability).

<ResponseField name="listEncounterNotes(emrEncounterId:)" type="method">
  Lists compositions for an EMR encounter so you can discover shared notes across products.

  <Expandable title="Parameter and success type">
    <ResponseField name="emrEncounterId" type="String" required={true}>
      Your EMR or EHR encounter id for the patient visit. This is the same value you pass as `SukiAmbientConstant.kEmrEncounterId` on create.
    </ResponseField>

    <ResponseField name="Success" type="[EncounterCompositionSummary]">
      Each summary includes **`compositionId`** only. Pass that value as **`noteId`** to the note-level APIs below.
    </ResponseField>
  </Expandable>
</ResponseField>

<ResponseField name="getNoteContext(noteId:)" type="method">
  Reads note-level context for a shared clinical note.

  <Expandable title="Parameter and success type">
    <ResponseField name="noteId" type="String" required={true}>
      Pass the **`compositionId`** from `listEncounterNotes` or from an online `createSession` response.
    </ResponseField>

    <ResponseField name="Success" type="NoteLevelContext">
      Returns **`NoteLevelContext`**.
    </ResponseField>
  </Expandable>
</ResponseField>

<ResponseField name="getNoteContent(noteId:)" type="method">
  Reads note content (suggestions) for a shared clinical note.

  <Expandable title="Parameter and success type">
    <ResponseField name="noteId" type="String" required={true}>
      Pass the **`compositionId`** from `listEncounterNotes` or from an online `createSession` response.
    </ResponseField>

    <ResponseField name="Success" type="[Suggestion]">
      Returns **`[Suggestion]`** through `ContentCallback` (`Result<[Suggestion], Error>`).
    </ResponseField>
  </Expandable>
</ResponseField>

<ResponseField name="getNoteStructuredData(noteId:)" type="method">
  Reads structured note data for a shared clinical note.

  <Expandable title="Parameter and success type">
    <ResponseField name="noteId" type="String" required={true}>
      Pass the **`compositionId`** from `listEncounterNotes` or from an online `createSession` response.
    </ResponseField>

    <ResponseField name="Success" type="StructuredDataResponseModel">
      Returns **`StructuredDataResponseModel`** through `StructuredDataCallback` (`Result<StructuredDataResponseModel, Error>`).
    </ResponseField>
  </Expandable>
</ResponseField>

<ResponseField name="encounterContent(encounterId:)" type="method">
  Reads encounter-level content for a Session Group. This is not an EMR encounter lookup.

  <Expandable title="Parameter and success type">
    <ResponseField name="encounterId" type="String" required={true}>
      Pass the Session Group ID (Ambient API **`encounter_id`**). This is the same value you pass as **`SukiAmbientConstant.kSessionId`** on create or re-ambient. Do not pass the EMR encounter id.
    </ResponseField>

    <ResponseField name="Success" type="[Suggestion]">
      Returns **`[Suggestion]`**, same shape as `getNoteContent`, through `ContentCallback`.
    </ResponseField>
  </Expandable>
</ResponseField>

#### Note read method signatures

The following are the method signatures for the note read APIs in the Mobile SDK.

```swift Swift theme={"theme":{"light":"github-dark","dark":"material-theme-darker"}}
public func listEncounterNotes(
    emrEncounterId: String,
    onCompletion completionHandler: @escaping (Result<[EncounterCompositionSummary], Error>) -> Void
)

public func getNoteContext(
    noteId: String,
    onCompletion completionHandler: @escaping (Result<NoteLevelContext, Error>) -> Void
)

public func getNoteContent(
    noteId: String,
    onCompletion completionHandler: @escaping ContentCallback
)
// ContentCallback = (Result<[Suggestion], Error>) -> Void

public func getNoteStructuredData(
    noteId: String,
    onCompletion completionHandler: @escaping StructuredDataCallback
)
// StructuredDataCallback = (Result<StructuredDataResponseModel, Error>) -> Void

public func encounterContent(
    encounterId: String,
    onCompletion completionHandler: @escaping ContentCallback
)
// Same ContentCallback as getNoteContent. Pass the Session Group ID as encounterId
// (Ambient API encounter_id). Do not pass the EMR encounter id.
```

#### List encounter notes and get note content

```swift Swift theme={"theme":{"light":"github-dark","dark":"material-theme-darker"}}
SukiAmbientCoreManager.shared.listEncounterNotes(emrEncounterId: emrEncounterId) { result in
    switch result {
    case .success(let summaries):
        for summary in summaries {
            let noteId = summary.compositionId
            SukiAmbientCoreManager.shared.getNoteContent(noteId: noteId) { contentResult in
                switch contentResult {
                case .success(let suggestions):
                    print(suggestions)
                case .failure(let error):
                    print(error)
                }
            }
        }
    case .failure(let error):
        print(error)
    }
}
```

### Submit user feedback

<Note>
  `New` Submit user feedback for the AI-generated content.
</Note>

Call `submitFeedback(_:for:onCompletion:)` to capture how well a generated note matched the encounter, so Suki can improve future note quality. Use it after a provider reviews the content, for example behind a star rating or thumbs control with an optional comment box.

You capture both quantitative feedback (a rating) and qualitative feedback (comments) in a single submission.

#### Function signature

The method takes a `FeedbackSubmission`, the `sessionId` for the session you are rating, and a completion handler. On success, the handler returns a unique `feedbackId`; on failure, it returns an error.

<CodeGroup>
  ```swift Swift theme={"theme":{"light":"github-dark","dark":"material-theme-darker"}}
  public func submitFeedback(
      _ submission: FeedbackSubmission,
      for sessionId: SessionId,
      onCompletion completionHandler: @escaping ((Result<String, Error>) -> Void)
  )
  public typealias SessionId = String
  ```
</CodeGroup>

#### Required data structures

To submit feedback, construct a `FeedbackSubmission`. It combines a `FeedbackEntity` (what the feedback is about), a `QuantitativeFeedback` (the rating and its scale), and an optional `comments` string for free-text feedback.

<CodeGroup>
  ```swift Swift theme={"theme":{"light":"github-dark","dark":"material-theme-darker"}}
  public struct FeedbackSubmission {
      public let entity: FeedbackEntity
      public let quantitative: QuantitativeFeedback
      public let comments: String?

      public init(entity: FeedbackEntity,
                  quantitative: QuantitativeFeedback,
                  comments: String? = nil)
  }

  public enum FeedbackEntity: String {
      case content = "content"
  }

  public struct QuantitativeFeedback {
      public let minRating: Int
      public let maxRating: Int
      public let rating: Int

      public init(minRating: Int, maxRating: Int, rating: Int)
  }
  ```
</CodeGroup>

#### Implementation example

To submit feedback, you first create the `FeedbackSubmission` object and then pass it to the `submitFeedback` method along with the `sessionId`.

The method is **asynchronous**. The completion handler returns a `Result` containing either a success message with the unique feedbackId or an error if the submission failed.

<CodeGroup>
  ```swift Swift theme={"theme":{"light":"github-dark","dark":"material-theme-darker"}}
  // 1. Create the quantitative feedback object.
  let quantitativeFeedback = QuantitativeFeedback(minRating: 1, maxRating: 5, rating: 4)

  // 2. Create the full feedback submission object.
  let submission = FeedbackSubmission(
      entity: .content,
      quantitative: quantitativeFeedback,
      comments: "The patient's history was captured accurately."
  )

  // 3. Call the submit method with the submission object and session ID.
  SukiAmbientCoreManager.shared.submitFeedback(submission, for: sessionId) { result in
      switch result {
      case .success(let feedbackId):
          print("Feedback submitted successfully with ID: \(feedbackId)")
      case .failure(let error):
          print("Error submitting feedback: \(error)")
      }
  }
  ```
</CodeGroup>

<Warning>
  * Provide feedback for each entity type **once per session** only.

  * At present feedback submissions are only supported for the `.content` entity. This may be expanded in the future.

  * Submitting feedback for the same entity type a second time in the same session will be considered invalid.
</Warning>

#### Rating system

* The `maxRating` must be greater than the `minRating`.

* The rating must be within the inclusive range of `minRating` and `maxRating`.

* The `comments` string is optional and has a maximum length of **2000** characters.

<Note>
  - Configure any integer rating scale. For example, create a 1 to 5 scale by setting `minRating` to 1 and `maxRating` to 5, or a binary scale by setting the values to 0 and 1.

  - Suki recommends using a scale of 1 to 5 for ratings.
</Note>

## FAQs

<AccordionGroup>
  <Accordion title="Why Is the Content Not Being Generated?">
    The content is not being generated because the session is not in a completed state or the session was too short. We require a **minimum of 1 minute of audio** to generate content. You must ensure that the session is in a completed state before retrieving the content.
  </Accordion>

  <Accordion title="Why Is the Content Not Being Retrieved?">
    The content is not being retrieved because the `sessionId` is not valid. You must ensure that you are using a valid `sessionId` from an active or completed session.
  </Accordion>

  <Accordion title="How Do I Know If the Content Has Been Generated?">
    Check the status of the session to determine if the content has been generated.
  </Accordion>

  <Accordion title="How Do I Know If the Content Has Been Retrieved?">
    Check the status of the session to determine if the content has been retrieved.
  </Accordion>

  <Accordion title="What Happens If the Internet Connection Is Lost?">
    If the internet connection is lost, the content will be retrieved when the connection is restored. Please refer to the [Offline mode](/mobile-sdk/ambient-guides/offline-mode) guide for more information.
  </Accordion>

  <Accordion title="What Happens If the Session Is Not Completed?">
    The content will not be retrieved if the session is not completed. You must ensure that the session is in a completed state before retrieving the content.
  </Accordion>
</AccordionGroup>

## Verify your integration

After you complete your first ambient session, verify that you can:

* Check the session status with `status(for:)` and confirm processing is complete.
* Retrieve the clinical note with `content(for:)` and the transcript with `transcript(for:)`.
* Access structured data, such as diagnoses and entities, with `getStructuredData(for:)`.

## Next steps

<Icon icon="file-lines" iconType="solid" /> After you have retrieved the content, you can proceed to the [Clear session](/mobile-sdk/ambient-guides/clearing-sessions) guide to create a new session.
