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

# List Batch Contacts

> Retrieve every contact in a batch with full call history

## Endpoint

**GET** `https://api.graine.ai/api/v1/batches/{batch_id}/contacts`

Returns every contact in a batch with its status, retry history, and (optionally) the full call record chain for each attempt.

## Path Parameters

| Parameter  | Type   | Required | Description      |
| ---------- | ------ | -------- | ---------------- |
| `batch_id` | string | Yes      | Batch to inspect |

## Headers

| Header          | Required | Description          |
| --------------- | -------- | -------------------- |
| `Authorization` | Yes      | `Bearer gat_<token>` |

## Query Parameters

| Parameter       | Type    | Required | Description                                                                                              |
| --------------- | ------- | -------- | -------------------------------------------------------------------------------------------------------- |
| `include_calls` | boolean | No       | Include full call\_records for each contact. Default: `false`                                            |
| `status`        | string  | No       | Filter by contact status (see [Contact Statuses](/api-reference/batches/overview#contact-status-values)) |
| `skip`          | integer | No       | Offset. Default: `0`                                                                                     |
| `limit`         | integer | No       | Page size. Default: `100`                                                                                |

## Example Request

```bash theme={null}
# All contacts with full call history
curl "https://api.graine.ai/api/v1/batches/btc_xyz001/contacts?include_calls=true&skip=0&limit=100" \
  -H "Authorization: Bearer gat_your_token"

# Only retrying contacts
curl "https://api.graine.ai/api/v1/batches/btc_xyz001/contacts?status=retrying&include_calls=true" \
  -H "Authorization: Bearer gat_your_token"
```

## Response

### 200 OK

```json theme={null}
[
  {
    "contact_id": "con_111",
    "batch_id": "btc_xyz001",
    "campaign_id": "cmp_abc123",
    "phone_number": "+919876543210",
    "call_variables": {
      "callee_name": "Rajesh Sharma",
      "current_plan": "Basic Health",
      "renewal_date": "2026-07-01",
      "premium": "12000"
    },
    "status": "completed",
    "retry_count": 1,
    "follow_up_count": 0,
    "last_attempted_at": "2026-05-10T10:15:00Z",
    "next_retry_at": null,
    "latest_retry_count": 1,
    "current_call": {
      "execution_id": "exec_aaa",
      "call_status": "completed",
      "duration_seconds": 142,
      "recording_url": "https://recordings.example.com/rec123.wav",
      "transcript": "Agent: Hello Rajesh! I'm calling about your Health Insurance renewal...",
      "summary": "Customer expressed interest in upgrading to Family Floater plan.",
      "sentiment": "positive",
      "hangup_by": "assistant",
      "hangup_reason": "goal_completed",
      "total_cost": 0.12,
      "retry_count": 1,
      "is_follow_up": false
    },
    "call_records": [
      {
        "execution_id": "exec_bbb",
        "call_status": "no-answer",
        "duration_seconds": 0,
        "recording_url": null,
        "retry_count": 0,
        "is_follow_up": false,
        "created_at": "2026-05-10T09:00:00Z"
      },
      {
        "execution_id": "exec_aaa",
        "call_status": "completed",
        "duration_seconds": 142,
        "recording_url": "https://recordings.example.com/rec123.wav",
        "transcript": "...",
        "summary": "Customer expressed interest in upgrading to Family Floater plan.",
        "sentiment": "positive",
        "hangup_by": "assistant",
        "hangup_reason": "goal_completed",
        "total_cost": 0.12,
        "retry_count": 1,
        "is_follow_up": false,
        "created_at": "2026-05-10T10:15:00Z"
      }
    ]
  }
]
```

### Contact Response Fields

| Field                | Description                                                         |
| -------------------- | ------------------------------------------------------------------- |
| `status`             | Current contact status                                              |
| `retry_count`        | Number of retry attempts so far                                     |
| `follow_up_count`    | Number of follow-up calls made                                      |
| `last_attempted_at`  | Timestamp of most recent call attempt                               |
| `next_retry_at`      | When the next retry is scheduled (`null` if none)                   |
| `latest_retry_count` | Highest `retry_count` seen across all call records for this contact |
| `current_call`       | The most recent call attempt (populated when `include_calls=true`)  |
| `call_records`       | Full retry chain in chronological order (when `include_calls=true`) |

### call\_record fields

| Field              | Description                                                             |
| ------------------ | ----------------------------------------------------------------------- |
| `execution_id`     | Unique ID for this call attempt                                         |
| `call_status`      | Outcome: `completed` · `no-answer` · `busy` · `failed` · `canceled` · … |
| `duration_seconds` | Call length in seconds                                                  |
| `recording_url`    | URL of the call recording (if available)                                |
| `transcript`       | Full conversation transcript                                            |
| `summary`          | AI-generated call summary                                               |
| `sentiment`        | Detected sentiment: `positive` · `neutral` · `negative`                 |
| `hangup_by`        | Who ended the call: `assistant` · `user`                                |
| `hangup_reason`    | Reason string (e.g. `goal_completed`, `user_requested`)                 |
| `total_cost`       | Cost of this call attempt in USD                                        |
| `retry_count`      | Which retry attempt this was (0 = original)                             |
| `is_follow_up`     | `true` if this was a scheduled follow-up call                           |

## Code Examples

```python theme={null}
import requests

url = "https://api.graine.ai/api/v1/batches/btc_xyz001/contacts"
headers = { "Authorization": "Bearer gat_your_token" }
params = {
    "include_calls": "true",
    "status": "retrying",
    "skip": 0,
    "limit": 100
}

response = requests.get(url, headers=headers, params=params)
contacts = response.json()
for c in contacts:
    print(c["contact_id"], c["status"], c["retry_count"])
```

## Next Steps

<CardGroup cols={2}>
  <Card title="Export as CSV" icon="file-csv" href="/api-reference/batches/export">
    Download all contact outcomes
  </Card>

  <Card title="Force Retry a Contact" icon="arrows-rotate" href="/api-reference/contacts/retry">
    Immediately re-call a specific contact
  </Card>
</CardGroup>
