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

# Create and start a batch

> Create a batch draft, start dialing, and track batch status.

Batch dialing is a two-step flow: create a draft, then explicitly start it. A batch accepts 1–1,000 unique canonical recipients.

## Prerequisites

* A server-side `bt_live_` key with `batches:write` and `batches:read`.
* An eligible `agent_id` and either unique `contact_ids` or unique inline recipients from the same organization.
* Separate nonsecret idempotency keys for creating and starting the batch.
* If scheduling, an RFC 3339 `start_at` and/or one contiguous daily `calling_window` supported by the contract.

Save JavaScript samples as `.mjs` or run them in an ESM project. Their top-level `await` requires ESM, and Node 18 or later provides the built-in `fetch` they use.

## Create the draft

The canonical example uses two existing contacts. Creation returns `status: draft` and does not begin dialing.

<Warning>
  Starting this batch can place real PSTN calls to every recipient. Verify the complete recipient set, agent, schedule, calling window, and timing before starting it.
</Warning>

<CodeGroup>
  ```curl theme={null}
  curl --request POST 'https://api.brightalk.ai/batches' \
    --header "Authorization: Bearer $BRIGHTALK_API_KEY" \
    --header "Brightalk-Version: 2026-07-16" \
    --header "Content-Type: application/json" \
    --header "Idempotency-Key: createBatch-example-001" \
    --data '{"name":"Renewal reminders","agent_id":"agt_demo_001","contact_ids":["con_demo_001","con_demo_002"]}'
  ```

  ```javascript theme={null}
  const response = await fetch("https://api.brightalk.ai/batches", {
    method: "POST",
    headers: {
      Authorization: `Bearer ${process.env.BRIGHTALK_API_KEY}`,
      "Brightalk-Version": "2026-07-16",
      "Content-Type": "application/json",
      "Idempotency-Key": "createBatch-example-001",
    },
    body: JSON.stringify({"name":"Renewal reminders","agent_id":"agt_demo_001","contact_ids":["con_demo_001","con_demo_002"]}),
  });
  console.log(response.status, await response.json());
  ```

  ```python theme={null}
  import os
  import requests

  response = requests.request(
      "POST",
      "https://api.brightalk.ai/batches",
      headers={
      "Authorization": f"Bearer {os.environ['BRIGHTALK_API_KEY']}",
      "Brightalk-Version": "2026-07-16",
      "Content-Type": "application/json",
      "Idempotency-Key": "createBatch-example-001",
      },
      json={"name":"Renewal reminders","agent_id":"agt_demo_001","contact_ids":["con_demo_001","con_demo_002"]},
  )
  print(response.status_code, response.json())
  ```
</CodeGroup>

## Expected draft

The API returns `201 Created` with aggregate counts. Save the batch `id`.

```json theme={null}
{
  "id": "bat_demo_001",
  "name": "Renewal reminders",
  "agent_id": "agt_demo_001",
  "total_recipients": 2,
  "pending_recipients": 2,
  "queued_recipients": 0,
  "in_progress_recipients": 0,
  "completed_recipients": 0,
  "failed_recipients": 0,
  "cancelled_recipients": 0,
  "answered_recipients": 0,
  "no_answer_recipients": 0,
  "busy_recipients": 0,
  "created_at": "2026-07-20T01:00:00Z",
  "updated_at": "2026-07-20T01:00:00Z",
  "status": "draft"
}
```

Review the returned identity and counts before continuing. Do not skip the explicit start transition.

## Start the batch

Replace `bat_demo_001` with the returned `id`. Starting immediately returns `status: queued`; configured scheduled eligibility can return `status: scheduled`.

<CodeGroup>
  ```curl theme={null}
  curl --request POST 'https://api.brightalk.ai/batches/bat_demo_001/start' \
    --header "Authorization: Bearer $BRIGHTALK_API_KEY" \
    --header "Brightalk-Version: 2026-07-16" \
    --header "Content-Type: application/json" \
    --header "Idempotency-Key: startBatch-example-001" \
    --data '{}'
  ```

  ```javascript theme={null}
  const response = await fetch("https://api.brightalk.ai/batches/bat_demo_001/start", {
    method: "POST",
    headers: {
      Authorization: `Bearer ${process.env.BRIGHTALK_API_KEY}`,
      "Brightalk-Version": "2026-07-16",
      "Content-Type": "application/json",
      "Idempotency-Key": "startBatch-example-001",
    },
    body: JSON.stringify({}),
  });
  console.log(response.status, await response.json());
  ```

  ```python theme={null}
  import os
  import requests

  response = requests.request(
      "POST",
      "https://api.brightalk.ai/batches/bat_demo_001/start",
      headers={
      "Authorization": f"Bearer {os.environ['BRIGHTALK_API_KEY']}",
      "Brightalk-Version": "2026-07-16",
      "Content-Type": "application/json",
      "Idempotency-Key": "startBatch-example-001",
      },
      json={},
  )
  print(response.status_code, response.json())
  ```
</CodeGroup>

The start operation returns `202 Accepted`. Capacity can keep eligible recipients queued; monitor aggregate counts instead of treating queueing as an error.

## Inspect and control

Use the same batch `id` and preserve the required scope pair.

| Action  | Endpoint                          | Next action                                                       |
| ------- | --------------------------------- | ----------------------------------------------------------------- |
| Inspect | `GET /batches/{batch_id}`         | Poll with backoff until `completed`, `failed`, or `cancelled`     |
| Pause   | `POST /batches/{batch_id}/pause`  | Stops subsequent dispatch; active calls may continue              |
| Resume  | `POST /batches/{batch_id}/resume` | Requeues eligible remaining recipients                            |
| Cancel  | `POST /batches/{batch_id}/cancel` | Stops remaining work and requests best-effort active cancellation |

Pause, resume, and cancel accept an optional `Idempotency-Key`. Use one when an action might be retried.

## Common errors

| Error                     | What to check                                                                                                                               |
| ------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------- |
| `validation_error`        | There are 1–1,000 unique canonical recipients, exactly one recipient form, and a valid schedule/window                                      |
| `insufficient_scope`      | The key has `batches:write` for controls and `batches:read` for inspection                                                                  |
| `resource_state_conflict` | Only a `draft` is started; only `scheduled`, `queued`, or `in_progress` work is paused; and the requested transition fits the current state |
| `unsupported_destination` | Every destination is enabled before dispatch                                                                                                |
| `idempotency_conflict`    | Create and start each have their own stable key and unchanged semantic body                                                                 |
| `rate_limit_exceeded`     | Wait for numeric `Retry-After`; keep the same key when retrying the same action                                                             |
