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

# Webhooks

> Have Vizito call your endpoint the moment something happens.

Polling the visitor list every minute works, but a webhook is better: Vizito calls your endpoint as the event happens, and you do nothing in between.

<Note>
  Webhooks are part of the Enterprise plan. On Standard and Pro the configuration endpoints answer `404` and no events are delivered.
</Note>

## Configure the endpoint

One webhook per location, set either on the Integrations page in the Backoffice or through the API:

```bash cURL theme={null}
curl -X POST https://api.vizito.eu/api/companies/{company_id}/webhooks \
  -H "Authorization: Bearer $VIZITO_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://example.com/hooks/vizito",
    "http_method": "POST",
    "auth_username": "vizito",
    "auth_password": "a-shared-secret",
    "enabled": true
  }'
```

```json Response theme={null}
{ "message": "Webhook configured successfully", "webhook_id": "66c2b3c4d5e6f70011223344" }
```

`http_method` may be `POST`, `PUT`, `PATCH` or `GET`. With `POST`, `PUT` and `PATCH` the event is the JSON body; with `GET` it is the query string.

If you set `auth_username` and `auth_password`, Vizito sends them as HTTP Basic credentials on every call — the simplest way to prove the call came from Vizito.

## What you receive

```json theme={null}
{
  "eventName": "visitor_signed_in",
  "companyId": "5f2a1b9c4d3e2f0011223344",
  "visitorId": "66b0f1a2c3d4e5f600112233",
  "visitTypeId": "5f2a1b9c4d3e2f0011223399",
  "knownVisitorId": "66c1a2b3c4d5e6f700112233"
}
```

The payload is deliberately thin: it names what happened and to which object, not the object itself. Fetch what you need with the ids — [`GET /visitors/{visitorId}`](/api-reference/visitors/fetching-a-visitor) gives you the whole visit, photo and signature included.

### Events

| Event                              | Extra fields                                    | Fires when                                          |
| ---------------------------------- | ----------------------------------------------- | --------------------------------------------------- |
| `visitor_signed_in`                | `visitorId`, `visitTypeId`, `knownVisitorId`    | A visit starts, from any source                     |
| `visitor_signed_out`               | `visitorId`, `visitTypeId`, `knownVisitorId`    | A visit is closed                                   |
| `visitor_updated`                  | `visitorId`, `visitTypeId`, `knownVisitorId`    | A visit's details change                            |
| `visitor_screening_approved`       | `visitorId`, `knownVisitorId`, `approvalStatus` | A host approves a screened visitor                  |
| `visitor_screening_rejected`       | `visitorId`, `knownVisitorId`, `approvalStatus` | A host rejects a screened visitor                   |
| `registered_visitor_created`       | `knownVisitorId`, `visitTypeId`                 | A registered visitor is added                       |
| `registered_visitor_updated`       | `knownVisitorId`, `visitTypeId`                 | A registered visitor changes                        |
| `registered_visitor_deleted`       | `knownVisitorId`, `visitTypeId`                 | A registered visitor is removed                     |
| `registered_visitor_preregistered` | `knownVisitorId`                                | An invited visitor completes their pre-registration |
| `device_added`                     | `deviceUuid`                                    | A kiosk is activated                                |
| `device_online` / `device_offline` | `deviceUuid`                                    | A kiosk connects or drops off                       |
| `device_deleted`                   | `deviceUuid`                                    | A kiosk is removed                                  |
| `company_updated`                  | —                                               | The location's configuration changes                |

## Delivery rules

<AccordionGroup>
  <Accordion title="Failures are counted, and five in a row disables the webhook" icon="triangle-exclamation">
    Every delivery error — a timeout, a non-2xx answer, an unreachable host, an invalid URL — increments a counter. At five consecutive failures the webhook is switched off and the location's global admins are emailed the last error, so a dead endpoint does not silently swallow events forever. One successful delivery resets the counter to zero.

    Re-enable it on the Integrations page or by posting the configuration again — saving it clears the failure count.
  </Accordion>

  <Accordion title="There are no retries" icon="rotate-right">
    A failed delivery is not retried. Answer quickly with a 2xx and do your work asynchronously; if your endpoint is down, reconcile afterwards by reading the visitor list.
  </Accordion>

  <Accordion title="Answer fast" icon="stopwatch">
    Events are delivered as they happen and your response time is on the critical path of somebody standing at a kiosk. Acknowledge first, process later.
  </Accordion>
</AccordionGroup>

## Reading the current configuration

```bash theme={null}
curl https://api.vizito.eu/api/companies/{company_id}/webhooks \
  -H "Authorization: Bearer $VIZITO_API_KEY"
```

Returns the enabled webhook, or `{}` when there is none. An auto-disabled webhook reads as `{}` too — which is the quickest way to check whether yours is still alive.


## Related topics

- [Fetching the webhook](/api-reference/webhooks/fetching-the-webhook.md)
- [Configuring the webhook](/api-reference/webhooks/configuring-the-webhook.md)
- [Introduction](/index.md)
- [Signing in registered visitors](/api-reference/registered-visitors/signing-in-registered-visitors.md)
- [Listing devices](/api-reference/devices/listing-devices.md)
