# Webhooks

A webhook calls an address in your system as soon as a certain event happens to a document, e.g. when it is finished. Your system then doesn't have to poll the [Document API](/en/docs/api-documentation/document-api.md) regularly.

Webhooks are available for orders, order confirmations, requests for quotation, invoices and delivery notes.

## Prerequisites {#voraussetzungen}

- A Workbench account with the IT or Admin role (see [Users and roles](/en/docs/administration/users-and-roles.md)).
- An address in your system that is reachable from the internet and accepts `POST` requests with JSON. Use HTTPS.

## Set up a webhook {#einrichten}

1. Click **Settings** in the left navigation bar and choose **Integrations**.
2. In the sub-navigation under **Workflow Tools**, choose **Webhooks**.
3. Click **Add Webhook**.
4. Fill in the fields (see table) and click **Create Webhook**.

<!-- generated by .claude/tasks/docs-audit/scripts/webhook_reference.py -->

| Field | Meaning |
|---|---|
| **Name** | Name to tell webhooks apart in the list. |
| **Enabled** | Only enabled webhooks are called. |
| **URL** | Address of your receiver. Workist sends `POST` requests with JSON. |
| **Auth Type** | Prefix of the header value, e.g. `Bearer`. Optional. |
| **Auth Credentials** | Secret value for the header, e.g. a token. |
| **Auth Header** | Header name. Default: `Authorization`. |
| **Username** | User name for HTTP Basic auth. When set, Basic auth replaces the header above. |
| **Password** | Password for HTTP Basic auth. |
| **Events** | Events that trigger the webhook. At least one. |
| **Show Unfinished Data** | `data` contains the document data before the document is finished. |
| **Channels** | Channels per document type. No selection: all channels of all types. |

The list shows all webhooks with their status, URL and number of events. Use the pencil icon to edit a webhook and the trash icon to delete it. **Auth Credentials** and **Password** stay hidden after saving; if you leave the fields empty while editing, the stored value is kept.

### Authentication {#authentifizierung}

Workist sends exactly one authentication header with every call:

- **Basic auth:** If **Username** is filled in, Workist sends `Authorization: Basic <Base64 of username:password>`.
- **Custom header:** Otherwise Workist sends the header from **Auth Header** (default `Authorization`) with the value `<Auth Type> <Auth Credentials>`, e.g. `Authorization: Bearer abc123`. Without **Auth Type**, the header only contains the value from **Auth Credentials**.

Workist does not sign the requests. Check the header in your system and only accept requests over HTTPS.

### Channels {#kanaele}

- Without a selection, the webhook applies to all channels of all document types.
- If you select channels, the webhook only applies to those channels. Document types where you selected no channel then don't trigger it.

## Events {#ereignisse}

An event name combines the document type and the event, e.g. `order.finished` or `invoice.assistance_needed`.

| Event | Name | Meaning | Sent for |
|---|---|---|---|
| **Assistance Needed** | `assistance_needed` | The document is waiting for assistance in the Workbench. | all document types |
| **Assisted** | `assisted` | A user finished assisting the document or discarded it. | all document types |
| **Before Generate Output** | `before_generate_output` | Workist starts generating the output file. | all document types |
| **Output Generated** | `output_generated` | The output file has been generated. | all document types |
| **Before Send Output** | `before_send_output` | Workist starts the transfer. | Orders, Requests for quotation |
| **Output Sent** | `output_sent` | The transfer is complete. | currently never |
| **Finished** | `finished` | Processing has ended: finished, discarded or routed to another channel. | all document types |

| Document type | Prefix |
|---|---|
| Orders | `order.` |
| Order confirmations | `order_confirmation.` |
| Requests for quotation | `rfq.` |
| Invoices | `invoice.` |
| Delivery notes | `delivery_note.` |

Notes:

- **Output Sent** is currently not triggered. Use **Finished** and check `data.status`: `DELIVERED` means Workist transferred the result via SFTP, AS2 or ERP integration.
- **Finished** is also sent for discarded documents (`data.status` is then `DISCARDED`). If the transfer fails, Workist doesn't send **Finished**.
- For most integrations **Finished** is enough. **Assistance Needed** is useful to alert staff to open documents.

## Request content {#inhalt}

Workist sends a `POST` request with `Content-Type: application/json`:

| Field | Content |
|---|---|
| `timestamp` | Time of the event as a Unix timestamp in seconds. |
| `event` | Event name, `<document type>.<event>`, e.g. `order.finished`. |
| `user` | Currently always an empty object. |
| `data` | The document in the same format as in the [Document API](/en/docs/api-documentation/document-api.md). For invoices only `{"id": ...}`. |
| `payload` | Always an empty object for the selectable events. |

Example (shortened):

```json
{
  "timestamp": 1760000000,
  "event": "order.finished",
  "user": {},
  "data": {
    "id": "3f2a9c1e-7d1b-4c55-9a43-0e6f1b2c8d90",
    "channel": "8b1d2f40-5c3e-4a7a-9e21-6d4c3b2a1f00",
    "status": "FINISHED",
    "subject": "Purchase order 4500012345",
    "finished_at": "2026-10-09T08:15:42Z",
    "workbench_url": "https://wb.workist.com/...",
    "data": {
      "order_number": "4500012345",
      "line_items": []
    }
  },
  "payload": {}
}
```

- `data.data` is empty (`{}`) as long as the document has been neither assisted nor finished. Enable **Show Unfinished Data** if you need the intermediate state for early events.
- For **invoices**, `data` only contains the ID. Retrieve the invoice with `GET /invoices/{id}` through the [Document API](/en/docs/api-documentation/document-api.md).
- File links in `data` are valid for at most 30 minutes.

## Delivery and errors {#zustellung}

- Workist sends webhooks in the background, shortly after the event. The order of several events is not guaranteed. Match events by `timestamp` and `data.id`.
- **Not reachable:** If no connection can be made, Workist retries up to ten times, with growing intervals of 1, 2, 4 up to 512 seconds (about 17 minutes in total). After that Workist drops the event.
- **Error response:** If your system answers with an error status (`4xx` or `5xx`), Workist does not repeat the call.
- The Workbench doesn't show a log of the calls. If your system missed an event, fetch the documents through the [Document API](/en/docs/api-documentation/document-api.md#ablauf), e.g. with `finished=true&imported=false`.
- Answer quickly with a `2xx` status and process the data afterwards. Handle events so that a duplicate call does no harm.
