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

# Retrieve Appointment Analysis — Shilo API

> Retrieve AI-generated analysis for an appointment recording: rating, coaching, summary, disposition, and objections. Poll the progress field until it reaches 100.

Use this endpoint to retrieve the AI-generated analysis for an appointment recording. Shilo processes each appointment asynchronously after ingestion, producing coaching feedback, a call rating, conversation summary, disposition outcomes, objection handling insights, and speaker identification. Because processing takes time, you should poll this endpoint and check the `progress` field — results are only fully available once `progress` reaches `100`.

## Endpoint

```
GET https://api.shilo.ai/api/v1/appointments/{identifier}/analysis
```

## Authentication

All requests require your API key in the `x-api-key` header.

## Path Parameters

<ParamField path="identifier" type="string" required>
  The unique identifier for the appointment recording. Two formats are accepted:

  * `{uuid}` — The Shilo recording UUID (e.g., `ee6f2136-b94a-4438-9335-3acf5b2a0d31`)
  * `external_recording_id:{string}` — The external recording ID your integration provided (e.g., `external_recording_id:ext-789`)
</ParamField>

## Response

A successful request returns HTTP `200` with a `RecordingAnalysis` object. The top-level fields `id`, `recording_id`, `created_at`, and `progress` are always present. All sub-resource fields (`coaching`, `rating`, `summary`, etc.) are optional and only fully populated once `progress` equals `100`.

<ResponseField name="id" type="string" required>
  The UUID of this analysis record.
</ResponseField>

<ResponseField name="recording_id" type="string" required>
  The Shilo recording UUID of the appointment this analysis belongs to.
</ResponseField>

<ResponseField name="created_at" type="string" required>
  The ISO-8601 timestamp indicating when this analysis was created.
</ResponseField>

<ResponseField name="progress" type="number" required>
  A value between `0` and `100` representing how far along the AI processing pipeline this recording is. Poll this endpoint until `progress` equals `100` before reading any result fields.
</ResponseField>

<ResponseField name="action_items" type="object">
  Recommended follow-up actions identified by the AI. Present only after processing completes.

  <Expandable title="action_items fields">
    <ResponseField name="id" type="string">
      The UUID of this action items record.
    </ResponseField>

    <ResponseField name="primary" type="string[]">
      The most important follow-up actions for the rep to take after this appointment.
    </ResponseField>

    <ResponseField name="secondary" type="string[]">
      Additional, lower-priority follow-up actions.
    </ResponseField>
  </Expandable>
</ResponseField>

<ResponseField name="coaching" type="object">
  AI-generated coaching feedback for the rep on this appointment. Present only after processing completes.

  <Expandable title="coaching fields">
    <ResponseField name="id" type="string">
      The UUID of this coaching record.
    </ResponseField>

    <ResponseField name="possible_improvements" type="string[]">
      Areas where the rep could have performed better, with specific suggestions.
    </ResponseField>

    <ResponseField name="top_moments" type="string[]">
      Highlights from the appointment where the rep performed particularly well.
    </ResponseField>
  </Expandable>
</ResponseField>

<ResponseField name="disposition" type="object">
  The AI-assessed outcome and reasoning for this appointment. Present only after processing completes.

  <Expandable title="disposition fields">
    <ResponseField name="id" type="string">
      The UUID of this disposition record.
    </ResponseField>

    <ResponseField name="outcomes" type="string[]">
      The determined outcome labels for the appointment (e.g., booked, not interested).
    </ResponseField>

    <ResponseField name="reasoning" type="string">
      A plain-language explanation of why the AI assigned these outcomes.
    </ResponseField>
  </Expandable>
</ResponseField>

<ResponseField name="objections" type="object">
  Objections raised by the contact during the appointment. Present only after processing completes.

  <Expandable title="objections fields">
    <ResponseField name="id" type="string">
      The UUID of this objections record.
    </ResponseField>

    <ResponseField name="outcomes" type="string[]">
      A list of objections identified in the conversation.
    </ResponseField>
  </Expandable>
</ResponseField>

<ResponseField name="rating" type="object">
  A numeric quality rating assigned to the rep's performance on this appointment. Present only after processing completes.

  <Expandable title="rating fields">
    <ResponseField name="id" type="string">
      The UUID of this rating record.
    </ResponseField>

    <ResponseField name="outcome" type="number">
      The numeric rating score assigned to the rep's performance.
    </ResponseField>

    <ResponseField name="reasoning" type="string">
      A plain-language explanation of what drove the assigned score.
    </ResponseField>
  </Expandable>
</ResponseField>

<ResponseField name="speakers" type="object">
  AI-resolved speaker identities for the appointment recording. Present only after processing completes.

  <Expandable title="speakers fields">
    <ResponseField name="id" type="string">
      The UUID of this speakers record.
    </ResponseField>

    <ResponseField name="user_name" type="string">
      The resolved name of the sales rep in this recording.
    </ResponseField>

    <ResponseField name="client_name" type="string">
      The resolved name of the client or contact in this recording.
    </ResponseField>
  </Expandable>
</ResponseField>

<ResponseField name="summary" type="object">
  A concise AI-generated summary of the appointment. Present only after processing completes.

  <Expandable title="summary fields">
    <ResponseField name="id" type="string">
      The UUID of this summary record.
    </ResponseField>

    <ResponseField name="outcome" type="object">
      An object containing the summary text.

      <Expandable title="outcome fields">
        <ResponseField name="summary" type="string">
          The full text of the AI-generated appointment summary.
        </ResponseField>
      </Expandable>
    </ResponseField>
  </Expandable>
</ResponseField>

<Note>
  Poll this endpoint until `progress` equals `100` before reading result fields such as `coaching`, `rating`, or `summary`. Sub-resource fields are absent or incomplete until processing finishes.
</Note>

### Error Responses

| Status            | Description                                                                 |
| ----------------- | --------------------------------------------------------------------------- |
| `400 Bad Request` | The `identifier` path parameter is malformed or uses an unsupported format. |
| `404 Not Found`   | No appointment recording was found matching the provided identifier.        |

## Example Request

```bash theme={null}
curl --request GET \
  --url "https://api.shilo.ai/api/v1/appointments/ee6f2136-b94a-4438-9335-3acf5b2a0d31/analysis" \
  --header "x-api-key: YOUR_API_KEY"
```

## Example Response

```json theme={null}
{
  "id": "a1b2c3d4-0000-4000-8000-111122223333",
  "recording_id": "ee6f2136-b94a-4438-9335-3acf5b2a0d31",
  "created_at": "2030-09-24T12:40:00Z",
  "progress": 100,
  "action_items": {
    "id": "a1b2c3d4-0000-4000-8000-aaaaaaaaaaaa",
    "primary": [
      "Send follow-up email with pricing sheet",
      "Schedule a product demo for next week"
    ],
    "secondary": [
      "Add contact to nurture sequence"
    ]
  },
  "coaching": {
    "id": "a1b2c3d4-0000-4000-8000-bbbbbbbbbbbb",
    "possible_improvements": [
      "Slow down when presenting pricing to allow time for questions",
      "Ask more open-ended discovery questions early in the call"
    ],
    "top_moments": [
      "Excellent handling of the budget objection at the 12-minute mark",
      "Strong rapport-building during the opening"
    ]
  },
  "disposition": {
    "id": "a1b2c3d4-0000-4000-8000-cccccccccccc",
    "outcomes": ["demo_scheduled"],
    "reasoning": "The contact agreed to a product demo and expressed strong interest in the enterprise plan."
  },
  "objections": {
    "id": "a1b2c3d4-0000-4000-8000-dddddddddddd",
    "outcomes": [
      "Price is too high",
      "Need to involve another decision-maker"
    ]
  },
  "rating": {
    "id": "a1b2c3d4-0000-4000-8000-eeeeeeeeeeee",
    "outcome": 82,
    "reasoning": "The rep demonstrated strong product knowledge and handled objections confidently, with room to improve discovery questioning."
  },
  "speakers": {
    "id": "a1b2c3d4-0000-4000-8000-ffffffffffff",
    "user_name": "Jordan Smith",
    "client_name": "Alex Rivera"
  },
  "summary": {
    "id": "a1b2c3d4-0000-4000-8000-000000000000",
    "outcome": {
      "summary": "Jordan connected with Alex to discuss upgrading from the starter plan. Alex raised concerns about pricing and the need to consult a second decision-maker. Jordan successfully navigated both objections and secured commitment for a follow-up demo next Thursday."
    }
  }
}
```
