# Webhooks API Reference — Callback URLs & Secrets

> Register or update the completion callback URL for a batch, and retrieve its signing secret — the ImageToTable.ai v1 API's Webhooks reference.

Register a URL to be called when a batch finishes processing, instead of polling [Get batch status](/developers/reference/batches#get-batch-status). This page covers the one registration endpoint; for payload shape, the three signature headers, and the retry schedule, see the [Webhooks guide](/developers/guides/webhooks) — including how **reprocessing a batch** (uploading and processing more documents into a `batch_name` that already notified you once) gets its own, separate notification automatically, with no action needed on this endpoint.

**There is no separate registration for [bbox](/developers/guides/bbox) completion.** The same `callback_url` you register here also receives a `document.bbox_completed` event whenever a bbox annotation job finishes on any document in this batch — triggering bbox does not require (or support) its own webhook endpoint. See the [Webhooks guide](/developers/guides/webhooks) for the event payload shape and the delivery caveat specific to bbox.

## Register a batch webhook

Creates or updates the completion callback for one batch. You can also set `webhook_url` directly on [Start processing a batch](/developers/reference/batches#start-processing-a-batch) to register it in the same call — this endpoint exists for registering (or changing) it separately, e.g. before you're ready to call `process`, or to fix a typo'd URL afterward.

`PUT /api/v1/batches/{batch_name}/webhook`

### Parameters

| Name | Location | Type | Description |
| --- | --- | --- | --- |
| batch_name | path | string | The batch to attach this callback to. Doesn't need to already have documents uploaded — you can register a webhook ahead of uploading. |
| callback_url | body (JSON) | string | Required. Must be http:// or https:// . Called once, when every document in the batch reaches a terminal status. |

**`webhook_secret` is returned in every successful response** — on first registration and on every subsequent update — not masked after the first call. There is no separate `GET` for this resource, so re-`PUT`-ing the same `callback_url` is the supported way to retrieve your secret again if you lose it. Updating an existing registration only ever touches `callback_url`: `webhook_secret` is never rotated by this call, and `fired_at` (whether this batch's most recent wave of processing has already notified you) is never reset by this call. Re-arming `fired_at` for a new wave happens on [Start processing a batch](/developers/reference/batches#start-processing-a-batch) instead, automatically, the moment it finds new eligible documents in a batch whose previous wave already fired — see the [Webhooks guide](/developers/guides/webhooks)'s "Reprocessing a batch" section. Re-`PUT`-ing this endpoint does not by itself get you notified again.

### Delivered event payloads

Once registered, `callback_url` receives a `POST` for either of two event types, distinguished by the top-level `"type"` field — this endpoint itself never returns either shape; these are what *your* server receives.

`batch.completed` — fires once, when every document in the batch reaches a terminal status:

```json
{
  "type": "batch.completed",
  "created_at": "2026-07-16T09:14:31Z",
  "data": {
    "batch_name": "260716-4K9P",
    "status": "succeeded",
    "document_count": 3
  }
}
```

`document.bbox_completed` — fires when a [bbox annotation job](/developers/guides/bbox) triggered on any document in this batch finishes:

```json
{
  "type": "document.bbox_completed",
  "created_at": "2026-07-16T09:20:07Z",
  "data": {
    "document_id": "3f9c9e2a-1b7d-4e2b-9a3e-2f5b6c7d8e9f",
    "group_batch_id": "bx_8a3c2e1f",
    "status": "succeeded"
  }
}
```

Neither payload carries the extracted results themselves — call `GET /batches/{batch_name}/results` or `GET /documents/{document_id}/bbox` after receiving the corresponding event to fetch the actual data. Both events are delivered at most once per completion, even when several documents (or several bbox row-groups) reach a terminal status within moments of each other — see the [Webhooks guide](/developers/guides/webhooks) for the signature headers and retry schedule.

### Possible errors

- `missing_api_key` / `invalid_api_key` / `plan_required` — see [Error Handling](/developers/guides/errors).
- `missing_parameter` (`param: "callback_url"`)
- `invalid_parameter` (`param: "callback_url"`) — not an `http://`/`https://` URL.
- `invalid_parameter` (`param: "batch_name"`)

## Code Examples

### Register a batch webhook

PUT /api/v1/batches/{batch_name}/webhook

**cURL**

```bash
curl -X PUT https://imagetotable.ai/api/v1/batches/july-invoices/webhook \
  -H "Authorization: Bearer $API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"callback_url": "https://example.com/webhooks/imagetotable"}'
```

**Python**

```python
import os
import requests

response = requests.put(
    "https://imagetotable.ai/api/v1/batches/july-invoices/webhook",
    headers={"Authorization": f"Bearer {os.environ['API_KEY']}"},
    json={"callback_url": "https://example.com/webhooks/imagetotable"},
)
print(response.json())
```

**Javascript**

```javascript
const response = await fetch("https://imagetotable.ai/api/v1/batches/july-invoices/webhook", {
  method: "PUT",
  headers: {
    "Authorization": `Bearer ${process.env.API_KEY}`,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({ callback_url: "https://example.com/webhooks/imagetotable" }),
});
console.log(await response.json());
```

### Response

```json
{
  "batch_name": "july-invoices",
  "callback_url": "https://example.com/webhooks/imagetotable",
  "webhook_secret": "9f2c1e6a4b8d0f37c5a2e9d1b6f4038a7c1e5d29b4f81c62",
  "created_at": "2026-07-16T09:00:00+00:00",
  "fired_at": null
}
```

`webhook_secret` stays the same across repeat calls to this endpoint for the same `batch_name` — it's only ever generated once, on first registration. `fired_at` flips from `null` to a timestamp the first (and only) time this batch's completion notification is delivered.

---

Source: https://imagetotable.ai/developers/reference/webhooks
