Endpoint
GEThttps://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) |
skip | integer | No | Offset. Default: 0 |
limit | integer | No | Page size. Default: 100 |
Example Request
# 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
[
{
"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
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
Export as CSV
Download all contact outcomes
Force Retry a Contact
Immediately re-call a specific contact