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

# List Appointment Recordings — Shilo API

> Retrieve a paginated list of appointment recordings filtered by user, contact, or date range. Appointments are created automatically via CRM integration, not via API.

Use this endpoint to retrieve a paginated list of appointment recordings from your Shilo account. Appointments are created automatically through your CRM integration — they cannot be created directly via the API. You can narrow results by user, contact, or creation date, and page through large result sets using the cursor returned in each response.

## Endpoint

```text theme={null}
GET https://api.shilo.ai/api/v1/appointments
```

## Authentication

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

## Query Parameters

<ParamField query="limit" default="50" type="number">
  The maximum number of appointment records to return per page. Accepted values are between `1` and `100`.
</ParamField>

<ParamField query="cursor" type="string">
  An opaque pagination cursor returned in the previous response's `pagination.next_cursor` field. Pass this value to retrieve the next page of results. Omit to start from the beginning.
</ParamField>

<ParamField query="sort" default="asc" type="string">
  The sort order for results, based on `created_date`. Accepted values are `asc` (oldest first) or `desc` (newest first).
</ParamField>

<ParamField query="created_date_gte" type="string">
  Return only appointments created on or after this date and time. Must be an ISO-8601 formatted string (e.g., `2030-01-01T00:00:00Z`).
</ParamField>

<ParamField query="created_date_lte" type="string">
  Return only appointments created on or before this date and time. Must be an ISO-8601 formatted string (e.g., `2030-12-31T23:59:59Z`).
</ParamField>

<ParamField query="user_id" type="string">
  Filter appointments by the associated user. Accepts a prefix-qualified identifier in one of three formats:

  * `id:{uuid}` — Shilo user UUID
  * `external_user_id:{value}` — your external user ID
  * `{uuid}` — bare Shilo user UUID (shorthand)
</ParamField>

<ParamField query="contact_id" type="string">
  Filter appointments by the associated contact. Accepts a prefix-qualified identifier in one of three formats:

  * `id:{uuid}` — Shilo contact UUID
  * `external_contact_id:{value}` — your external contact ID
  * `{uuid}` — bare Shilo contact UUID (shorthand)
</ParamField>

## Response

A successful request returns HTTP `200` with an `AppointmentsResponseDto` object.

<ResponseField name="data" type="Appointment[]">
  An array of Appointment objects matching the query filters.

  <Expandable title="Appointment fields">
    <ResponseField name="id" type="string" required>
      The Shilo recording UUID for this appointment.
    </ResponseField>

    <ResponseField name="type" type="string" required>
      Always `"appointment"` for records returned by this endpoint.
    </ResponseField>

    <ResponseField name="created_date" type="string" required>
      The ISO-8601 timestamp indicating when the appointment recording was created in Shilo.
    </ResponseField>

    <ResponseField name="user_id" type="string | null">
      The Shilo UUID of the user associated with this appointment. `null` if no user is matched.
    </ResponseField>

    <ResponseField name="external_user_id" type="string | null">
      The external user ID provided by your integration at the time the appointment was created. `null` if not provided.
    </ResponseField>

    <ResponseField name="external_contact_id" type="string | null">
      The external contact ID provided by your integration at the time the appointment was created. `null` if not provided.
    </ResponseField>

    <ResponseField name="external_recording_id" type="string | null">
      The external recording ID provided by your integration, if any. Use this value in other appointment endpoints with the `external_recording_id:{value}` prefix format. `null` if not provided.
    </ResponseField>
  </Expandable>
</ResponseField>

<ResponseField name="pagination" type="object" required>
  Metadata for paginating through additional results.

  <Expandable title="Pagination fields">
    <ResponseField name="has_more" type="boolean" required>
      `true` if there are additional pages of results beyond the current response; `false` if this is the last page.
    </ResponseField>

    <ResponseField name="next_cursor" type="string | null">
      An opaque cursor string to pass as the `cursor` query parameter in your next request. Returns `null` when there are no further pages.
    </ResponseField>
  </Expandable>
</ResponseField>

### Error Responses

| Status             | Description                            |
| ------------------ | -------------------------------------- |
| `401 Unauthorized` | Missing or invalid `x-api-key` header. |

## Example Request

```bash theme={null}
curl --request GET \
  --url "https://api.shilo.ai/api/v1/appointments?limit=50&sort=desc" \
  --header "x-api-key: YOUR_API_KEY"
```

## Example Response

```json theme={null}
{
  "data": [
    {
      "id": "ee6f2136-b94a-4438-9335-3acf5b2a0d31",
      "type": "appointment",
      "created_date": "2030-09-24T12:34:56Z",
      "user_id": "ee6f2136-b94a-4438-9335-3acf5b2a0d31",
      "external_user_id": "432",
      "external_contact_id": "4534",
      "external_recording_id": "ext-789"
    }
  ],
  "pagination": {
    "has_more": false,
    "next_cursor": null
  }
}
```
