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

# Debug Batch

> Inspect batch state to diagnose stuck or slow dispatching

## Endpoint

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

Returns diagnostic information about a batch's internal state. Use this when a batch is `in_progress` but calls don't seem to be going out.

## Path Parameters

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

## Headers

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

## Example Request

```bash theme={null}
curl "https://api.graine.ai/api/v1/batches/btc_xyz001/debug" \
  -H "Authorization: Bearer gat_your_token"
```

## Response

### 200 OK — Healthy batch

```json theme={null}
{
  "batch_id": "btc_xyz001",
  "status": "in_progress",
  "status_breakdown": {
    "pending": {
      "count": 22,
      "oldest_updated_at": "2026-05-10T09:05:00Z"
    },
    "dispatched": {
      "count": 3,
      "oldest_updated_at": "2026-05-10T10:28:00Z"
    },
    "completed": {
      "count": 58,
      "oldest_updated_at": "2026-05-10T10:25:00Z"
    }
  },
  "pending_sample": [
    "con_111",
    "con_112",
    "con_113"
  ],
  "diagnostics": {
    "stuck_pending": false,
    "tip": "Batch is healthy — contacts are being dispatched normally."
  }
}
```

### 200 OK — Stuck batch

```json theme={null}
{
  "batch_id": "btc_xyz001",
  "status": "in_progress",
  "status_breakdown": {
    "pending": {
      "count": 78,
      "oldest_updated_at": "2026-05-10T08:00:00Z"
    },
    "dispatched": { "count": 0 },
    "completed": { "count": 22 }
  },
  "pending_sample": [
    "con_201",
    "con_202",
    "con_203"
  ],
  "diagnostics": {
    "stuck_pending": true,
    "tip": "78 contacts have been pending for over 30 minutes with no dispatching activity. The worker is likely down or disconnected from Kafka. Restart the worker, then POST to /batches/btc_xyz001/dispatch to re-trigger."
  }
}
```

## Response Fields

| Field                       | Description                                                                       |
| --------------------------- | --------------------------------------------------------------------------------- |
| `status_breakdown`          | Per-status contact count and `oldest_updated_at` timestamp                        |
| `pending_sample`            | Up to 3 oldest `contact_id`s in `PENDING` state — useful for grepping worker logs |
| `diagnostics.stuck_pending` | `true` if pending contacts have stale timestamps (>30 min with no progress)       |
| `diagnostics.tip`           | Human-readable next step to fix the issue                                         |

## How to Interpret Results

<AccordionGroup>
  <Accordion title="stuck_pending: true — worker down">
    **Cause:** The Apollo worker container is not running or not connected to Kafka, so `PENDING` contacts are never being consumed and dispatched.

    **Fix:**

    1. Restart the worker container
    2. Wait \~30 seconds for it to reconnect
    3. POST to `/batches/{id}/dispatch` to re-publish pending contacts
  </Accordion>

  <Accordion title="All contacts stuck in dispatched (never complete)">
    **Cause:** The telephony provider (RotaryRouter / Jambonz) is accepting calls but not sending status webhooks back to Apollo.

    **Fix:**

    1. Check RotaryRouter logs for webhook delivery failures
    2. Verify the `APOLLO_WEBHOOK_URL` env var in RotaryRouter points to Apollo's `/webhooks/call-status`
    3. Check network connectivity between RotaryRouter and Apollo
  </Accordion>

  <Accordion title="High no_answer count">
    **Cause:** Contacts aren't answering. Could be time-of-day, invalid numbers, or carrier blocking.

    **Fix:**

    * Review working\_hours configuration — are you calling at the right time?
    * Check if specific area codes or number ranges are failing
    * Consider reducing concurrency to avoid appearing as spam
  </Accordion>

  <Accordion title="Batch completed but count looks wrong">
    **Cause:** Counters might show stale data from the batch document.

    **Fix:** Counters in `GET /batches/{id}` are always computed live. If they look wrong, compare with `GET /batches/{id}/contacts` status breakdown to see the ground-truth per-contact status.
  </Accordion>
</AccordionGroup>

## Next Steps

<CardGroup cols={2}>
  <Card title="Force Dispatch" icon="bolt" href="/api-reference/batches/dispatch">
    Re-publish pending contacts to Kafka
  </Card>

  <Card title="Get Batch" icon="eye" href="/api-reference/batches/get">
    Check current batch status and counters
  </Card>
</CardGroup>
