---
agentTools:
  projectIndex: https://api-doc.hostex.io/llms.txt
---

# Event Types

# Webhook Event Types

Reference for the payload shape of every event Hostex emits. Read the\
[Usage Guide](https://api-doc.hostex.io/reference/webhook-useage-guide) first for headers, delivery semantics,\
and security.

Every payload is a single **flat JSON object**: `event`, the\
event-specific fields listed below, and a `timestamp` (ISO 8601 UTC,\
e.g. `2026-05-22T02:51:12Z`) stamped when the event was queued:

```json
{
  "event": "<event_name>",
  "...event-specific fields...": "...",
  "timestamp": "2026-05-22T02:51:12Z"
}
```

> Webhook payloads are deliberately thin: they identify **what** changed\
> and carry no further detail. Fetch the current state from the\
> corresponding `GET` endpoint — the webhook is a "something changed,\
> go look" signal, not a change feed.

***

## `reservation_created`

Fired when a new reservation lands in Hostex — from any channel\
(Airbnb, Booking.com, custom-channel via `POST /reservations`, etc.).

```json
{
  "event": "reservation_created",
  "reservation_code": "ABC123",
  "stay_code": "ABC123",
  "property_id": 12345,
  "timestamp": "2026-05-22T02:51:12Z"
}
```

A multi-room booking fires one event per stay: same\
`reservation_code`, a distinct `stay_code` for each room.

Use it to: index a new booking, trigger an onboarding email, create a\
cleaning task — after fetching the details via\
`GET /reservations?reservation_code=<...>`.

***

## `reservation_updated`

Fired when an existing reservation changes in any of these ways:

* Status transition (e.g. `accepted` → `cancelled`).
* Date / guest-count change, or room reassignment (allocate).
* Arrival / departure time set (`sub_event: arrival_and_departure_time_updated`).
* Nightly rates changed (`sub_event: rates_updated`).
* Door-lock code set or removed (`sub_event: lock_code_updated` / `lock_code_deleted`).
* Check-in details updated (`sub_event: check_in_details_updated`).
* `note` (host-side reservation remarks) edited (`sub_event: remarks_updated`).
* Custom fields saved via the OpenAPI custom-fields endpoint (no `sub_event`).

The optional `sub_event` field, when present, tells you which of the\
above happened; when absent, treat it as a generic change.

```json
{
  "event": "reservation_updated",
  "sub_event": "rates_updated",
  "reservation_code": "ABC123",
  "stay_code": "ABC123",
  "property_id": 12345,
  "timestamp": "2026-05-22T02:51:12Z"
}
```

Tip: the payload only confirms *that* the reservation changed; if you need\
the post-change snapshot, call `GET /reservations?id=<...>` and read the\
fresh state. Avoid trying to diff payloads — the same reservation can\
emit several `reservation_updated` events in quick succession.

***

## `property_availability_updated`

Fired whenever a property's nightly availability changes in Hostex,\
**whatever the cause**: your `POST /availabilities` calls, portal\
edits, reservations being accepted or cancelled (dates auto-close /\
re-open), iCal imports, listing deactivation, and so on.

```json
{
  "event": "property_availability_updated",
  "property_id": 12345,
  "availabilities": [
    { "date": "2026-06-01", "available": false },
    { "date": "2026-06-02", "available": false }
  ],
  "timestamp": "2026-05-22T02:51:12Z"
}
```

The payload lists each affected date individually — it is not a\
date-range summary.

***

## `listing_calendar_updated`

Fired after Hostex successfully pushes calendar changes (prices,\
inventory) to a channel-side listing — whether the change originated\
from your `POST /listings/prices` / `POST /listings/inventories` calls\
or from Hostex's own sync. Not fired for edits made directly on the\
channel (OTA) itself.

Not fired in these cases:

* `POST /listings/restrictions`, `POST /listings/airbnb/price_and_rules` and `POST /listings/vrbo/price_and_rules` write to the channel directly and never send this event.
* The push fails, or finishes with a warning instead of a clean success.

```json
{
  "event": "listing_calendar_updated",
  "channel_type": "airbnb",
  "listing_id": "12345678",
  "start_date": "2026-06-01",
  "end_date": "2026-06-30",
  "timestamp": "2026-05-22T02:51:12Z"
}
```

`listing_id` is the channel-side listing identifier (always a string).

What the event does and does not tell you:

* It normally means the channel accepted the push. Hostex does not read the calendar back from the channel to verify it.
* It carries no identifier linking it to the API request that caused it; match it on `channel_type` + `listing_id` + dates. `timestamp` is when the event was queued, not when the channel applied the change.
* For the same channel, listing and date range, only the first event in a 5-second window is sent. Identical events raised during the rest of that window are dropped — they are not folded into the delivery you received, and no later event reports them. If you need the final values, wait a few seconds before reading, and rely on periodic reconciliation.

Use it to: keep your own price intelligence / channel-manager bridge\
in sync with less polling of the listing calendar endpoints. Because\
failed deliveries are not sent again (see the [Usage Guide](https://api-doc.hostex.io/reference/webhook-useage-guide)),\
still reconcile periodically with `POST /listings/calendar`.

***

## `message_created`

Fired when a new message lands in a conversation thread — inbound from\
the guest, outbound sent by you (`POST /conversations/{id}`), by the\
host from the Host Portal or the channel's own app, or by automation.\
For OTA channels the event can arrive with a delay of some seconds\
(channel sync round-trip).

```json
{
  "event": "message_created",
  "conversation_id": "0-2588930000",
  "message_id": "0-31777061577-667553000",
  "timestamp": "2026-05-22T02:51:12Z"
}
```

Both ids are opaque strings whose format varies by channel — store and\
compare them as-is.

> ⚠️ The payload does **not** tell you who sent the message. Call\
> `GET /conversations/{id}` and check the message's `sender_role`\
> before acting — an auto-replier that treats every `message_created`\
> as a guest message will answer its own outbound messages and loop.

***

## `review_created`

Fired the first time Hostex sees a review record for a reservation on\
the channel. On some channels this record is created around checkout\
**before any content is written**, so `review_created` does not\
guarantee that review content exists yet.

```json
{
  "event": "review_created",
  "reservation_code": "ABC123",
  "stay_code": "ABC123",
  "property_id": 12345,
  "timestamp": "2026-05-22T02:51:12Z"
}
```

***

## `review_updated`

Fired on any subsequent change to that review record — the guest\
submits their review, the host replies, scores or content change.

```json
{
  "event": "review_updated",
  "reservation_code": "ABC123",
  "stay_code": "ABC123",
  "property_id": 12345,
  "timestamp": "2026-05-22T02:51:12Z"
}
```

Recommended: handle `review_created` and `review_updated` identically —\
fetch the fresh state via `GET /reviews` and act on what is actually\
there.

***

## `transaction_created`

Fired when an income/expense entry is created — via `POST /v3/transactions`,\
the Hostex portal, or system-generated charges (e.g. refunds).

```json
{
  "event": "transaction_created",
  "transaction_id": 123456,
  "timestamp": "2026-05-22T02:51:12Z"
}
```

***

## `transaction_updated`

Fired when an existing entry is edited — amount, item, payment method,\
`action_at`, or note. Note that editing does **not** change the entry's\
`action_at`, so polling `GET /v3/transactions` by date window alone will\
miss edits to older entries; this event is the reliable signal.

```json
{
  "event": "transaction_updated",
  "transaction_id": 123456,
  "timestamp": "2026-05-22T02:51:12Z"
}
```

***

## `transaction_deleted`

Fired when an entry is deleted. Deletion is permanent — the entry will\
no longer appear in `GET /v3/transactions` responses.

```json
{
  "event": "transaction_deleted",
  "transaction_id": 123456,
  "timestamp": "2026-05-22T02:51:12Z"
}
```

Recommended: on `transaction_created` / `transaction_updated`, fetch the\
current state via `GET /v3/transactions?id=<transaction_id>`; on\
`transaction_deleted`, remove the entry from your mirror. Together these\
three events let you keep an up-to-date transaction mirror without\
scanning a wide action-date window.

***

## Forward compatibility

Hostex may add new events or new fields to existing events at any time\
without bumping the v3 API version. Your handler must:

1. **Ignore unknown event types** (drop or log; do not crash).
2. **Ignore unknown fields** within known events.
3. **Re-derive state from the API** when the payload is not enough —\
   the webhook is a "something changed, go look" signal, not a full\
   change feed.