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

# POST /capture-events

> Send up to 500 events in one request and inspect acceptance or rejection for each event.

Send a batch of events with one request. Each event uses the same fields as [POST /capture-event](/api-reference/capture-event). Tensile reports each row's outcome so you can retry rejected events without resending accepted ones.

```http theme={null}
POST https://ingest-production-9936.up.railway.app/api/v1/capture-events
```

## Headers

| Header         | Value                  | Required |
| -------------- | ---------------------- | -------- |
| `x-api-key`    | Your ingestion API key | Yes      |
| `Content-Type` | `application/json`     | Yes      |

## Body

The body contains an `events` array. Each event must include `event_id` and `session_id`; other event fields are described in the [single-event reference](/api-reference/capture-event).

```json theme={null}
{
  "events": [
    {
      "event_id": "b1d7a2f4-8c60-4e21-9f3a-1c2d3e4f5a6b",
      "session_id": "6f9c1b8e-3d2a-4a1f-9c7b-2e5d0a4b1c33",
      "primitive_name": "support-bot",
      "primitive_type": "prompt",
      "args": "How do I reset my password?",
      "result": "Open Settings, then choose Reset password."
    },
    {
      "event_id": "d9e0c1a2-7b34-4f56-8a9b-0c1d2e3f4a5b",
      "session_id": "6f9c1b8e-3d2a-4a1f-9c7b-2e5d0a4b1c33",
      "primitive_name": "knowledge_search",
      "primitive_type": "tool",
      "parent_id": "b1d7a2f4-8c60-4e21-9f3a-1c2d3e4f5a6b",
      "args": "{\"query\": \"password reset\"}",
      "result": "{\"hits\": 3}"
    }
  ]
}
```

## Response

A valid batch request returns HTTP `202 Accepted`. The response includes totals and a result for every input row. `index` is zero-based and refers to the row in `events`.

```json theme={null}
{
  "accepted": 2,
  "rejected": 0,
  "results": [
    {
      "index": 0,
      "event_id": "b1d7a2f4-8c60-4e21-9f3a-1c2d3e4f5a6b",
      "status": "accepted",
      "reason": ""
    },
    {
      "index": 1,
      "event_id": "d9e0c1a2-7b34-4f56-8a9b-0c1d2e3f4a5b",
      "status": "accepted",
      "reason": ""
    }
  ]
}
```

For a rejected row, `status` is `rejected` and `reason` explains the failure (for example, `session_id is required`). Retry only rejected rows after addressing their reason. A temporary enqueue failure includes a `Retry-After` header; accepted rows should not be sent again.

## Errors

* More than 500 events returns HTTP `400` for the whole request.
* Missing or invalid API key returns HTTP `401`.
* Invalid JSON or a request body that is too large is rejected before processing rows.

<Note>
  Batch ingestion confirms that events reached the ingestion endpoint. Captured events may appear in operational views, but ingestion does not by itself create a pack, approve an evaluator, or activate evaluator-pack scoring. See [Evaluator packs](/evaluator-packs) for the review and validation workflow.
</Note>
