> ## 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 Call Recordings — Shilo API GET /api/v1/calls

> Retrieve a paginated list of non-roleplay call recordings. Filter by user, contact, stage, source, or date range. Returns Call objects.

This endpoint returns a paginated list of call recordings associated with your Shilo organization. Only non-roleplay calls are returned. You can narrow results using filters for the owning agent, associated contact, sales stage, recording source, or creation date range. Results are returned in cursor-based pages to support efficient traversal of large datasets.

## Endpoint

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

## Query Parameters

<ParamField query="limit" type="number">
  Maximum number of call records to return in a single page. Defaults to `50`. Maximum allowed value is `100`.
</ParamField>

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

<ParamField query="sort" type="string">
  Sort order for results by creation date. Accepts `"asc"` (oldest first) or `"desc"` (newest first). Defaults to `"asc"`.
</ParamField>

<ParamField query="created_date_gte" type="string">
  Return only calls created on or after this timestamp. Must be a valid ISO-8601 datetime string (e.g. `2030-01-01T00:00:00Z`).
</ParamField>

<ParamField query="created_date_lte" type="string">
  Return only calls created on or before this timestamp. Must be a valid ISO-8601 datetime string. Use together with `created_date_gte` to define a date range.
</ParamField>

<ParamField query="source_id" type="string">
  Filter calls by their recording source ID. Corresponds to `source_id` on the Call object.
</ParamField>

<ParamField query="user_id" type="string">
  Filter calls by the agent who owns them. Supports three formats:

  * `{uuid}` — Shilo User UUID directly
  * `id:{uuid}` — explicit Shilo UUID prefix
  * `external_user_id:{value}` — your own system's agent identifier
</ParamField>

<ParamField query="contact_id" type="string">
  Filter calls by the associated contact. Supports three formats:

  * `{uuid}` — Shilo Contact UUID directly
  * `id:{uuid}` — explicit Shilo UUID prefix
  * `external_contact_id:{value}` — your own system's contact identifier
</ParamField>

<ParamField query="stage_id" type="string">
  Filter calls by the sales stage ID associated with the contact at the time of the call.
</ParamField>

## Response

A successful request returns HTTP `200` with a `CallsResponseDto` object containing a `data` array of Call objects and a `pagination` object.

<ResponseField name="data" type="array">
  Array of Call objects matching the query.

  <Expandable title="Call object fields">
    <ResponseField name="id" type="string">
      Shilo's unique UUID for this call recording.
    </ResponseField>

    <ResponseField name="type" type="string">
      Resource type identifier. Always `"call"` for this endpoint.
    </ResponseField>

    <ResponseField name="created_date" type="string">
      ISO-8601 timestamp of when the call was ingested by Shilo.
    </ResponseField>

    <ResponseField name="duration" type="number">
      Length of the call in seconds.
    </ResponseField>

    <ResponseField name="external_user_id" type="string">
      Your system's identifier for the agent on this call.
    </ResponseField>

    <ResponseField name="user_id" type="string">
      Shilo's UUID for the agent on this call.
    </ResponseField>

    <ResponseField name="external_contact_id" type="string">
      Your system's identifier for the contact on this call.
    </ResponseField>

    <ResponseField name="contact_id" type="string">
      Shilo's UUID for the contact on this call.
    </ResponseField>

    <ResponseField name="from_number" type="string">
      The phone number the call originated from, in display format.
    </ResponseField>

    <ResponseField name="to_number" type="string">
      The phone number the call was placed to, in display format.
    </ResponseField>

    <ResponseField name="incoming" type="boolean">
      `true` if the call was inbound (received by the agent); `false` if outbound.
    </ResponseField>

    <ResponseField name="source" type="string">
      Human-readable name of the recording source (e.g. `"Broker"`).
    </ResponseField>

    <ResponseField name="source_id" type="string">
      Identifier of the recording source.
    </ResponseField>

    <ResponseField name="stage" type="string">
      Human-readable sales stage associated with the contact at call time.
    </ResponseField>

    <ResponseField name="stage_id" type="string">
      Identifier of the associated sales stage.
    </ResponseField>

    <ResponseField name="external_recording_id" type="string">
      The `recording_id` your system supplied when this call was submitted via `POST /calls`.
    </ResponseField>
  </Expandable>
</ResponseField>

<ResponseField name="pagination" type="object">
  Pagination metadata for iterating through large result sets.

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

    <ResponseField name="next_cursor" type="string">
      Opaque cursor string to pass as the `cursor` query parameter to retrieve the next page. `null` when `has_more` is `false`.
    </ResponseField>
  </Expandable>
</ResponseField>

### Example Response

```json theme={null}
{
  "data": [
    {
      "id": "ee6f2136-b94a-4438-9335-3acf5b2a0d31",
      "type": "call",
      "created_date": "2030-09-24T12:34:56Z",
      "duration": 120,
      "external_user_id": "432",
      "user_id": "ee6f2136-b94a-4438-9335-3acf5b2a0d31",
      "external_contact_id": "4534",
      "contact_id": "ee6f2136-b94a-4438-9335-3acf5b2a0d31",
      "from_number": "(555) 555-1234",
      "to_number": "(555) 555-5678",
      "incoming": true,
      "source": "Broker",
      "source_id": "80",
      "stage": "Agents",
      "stage_id": "60",
      "external_recording_id": "ext-123"
    }
  ],
  "pagination": {
    "has_more": true,
    "next_cursor": "eyJjcmV..."
  }
}
```

## Example Request

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

## Error Responses

**401 Unauthorized** — Returned when the API key is missing or invalid.

Missing `x-api-key` (or `Authorization: Bearer`) header:

```json theme={null}
{
  "error": "unauthorized",
  "message": "Missing API key"
}
```

Unrecognized or revoked key:

```json theme={null}
{
  "error": "unauthorized",
  "message": "Invalid API key"
}
```
