Webhooks
Webhooks (Booking Status Updates)
Section titled “Webhooks (Booking Status Updates)”A webhook is a message Project Expedition sends to your system the moment something happens to one of your bookings, such as a new booking or a date change. You don’t have to keep checking the booking_updates endpoint to find out.
- You provide a web address on your system that accepts HTTPS POST requests (e.g.,
https://yoursite.com/pe-webhook). - Project Expedition sets it up on your account — no API call required on your side.
- Whenever one of your bookings is placed, changes, is canceled or has its commission paid, PE sends a short JSON message to that address describing what happened.
To set up a webhook, email partners@projectexpedition.com with your endpoint URL.
Staging: Webhooks can be configured for the staging environment as well, allowing you to test your handler before going live.
Event Types
Section titled “Event Types”Every message has a type field that says what happened:
type |
What happened |
|---|---|
New Booking |
A booking was placed (confirmed or pending confirmation). Sent again when a pending booking is confirmed |
Booking Update |
Something changed on a confirmed booking after it was placed, such as the date or time, pickup, number of travelers, traveler names or contact details, price or payments, cancellation date, operator notes or voucher. Changes made close together arrive as one message, at most one per booking every 5 minutes |
Cancel Booking |
The booking was canceled |
Commission Paid |
Project Expedition has paid your commission for the booking |
Example Notification Body
Section titled “Example Notification Body”This is what a message looks like. The first three fields are always there. The data part is a copy of the booking, included if you ask for it when the webhook is set up.
{ "booking_reference": "PE2847391", "type": "Booking Update", "timestamp": "2026-09-23 14:05:00", "data": { "iata": "12345678", "business_unit": "Example Consortium", "agency_name": "Doe Travel Agency", "agent_name": "Jane Doe", "agent_email": "jane@doetravelagency.com", "booking_reference": "PE2847391", "voucher": "https://www.projectexpedition.com/account/voucher/PE2847391", "status": "Confirmed", "payment_status": "Fully Paid", "travel_date": "2026-10-15", "purchase_date": "2026-09-01", "latestcancellation_date": "2026-10-13", "percent_norefund": "0", "end_date": "2026-10-15", "product_type": "Private Single Day Tour", "product_id": "PRD129761", "town": "Agra", "country": "India", "product": "Private Taj Mahal Tour", "number_of_passengers": "2", "lead_passenger": "John Smith", "gross_amount": "450.00", "net_amount": 405.5, "commission": "44.50" }}data shows the booking as it was when the message was sent. You can always look up the latest version of the booking with GET /booking?id=PE2847391.
| Field | What it means |
|---|---|
booking_reference |
The booking’s reference number, the same one GET /booking?id= uses |
type |
What happened, from the table above |
timestamp |
When the message was sent, in US Eastern time (YYYY-MM-DD HH:MM:SS) |
data.status |
Booking status, e.g. Confirmed, Pending Confirmation, Canceled |
data.payment_status |
Payment status, e.g. Fully Paid, Deposit Paid, Partial Payment, Hold without Payment, Returned to Traveler |
data.travel_date, data.end_date |
First and last day of the tour or trip (YYYY-MM-DD) |
data.purchase_date |
Day the booking was placed (YYYY-MM-DD) |
data.latestcancellation_date, data.percent_norefund |
Last day to cancel under the cancellation policy, and the non-refundable percentage when the policy has one |
data.gross_amount, data.commission, data.net_amount |
Booking total, your commission, and the total minus your commission. gross_amount and commission are sent as strings (e.g. "450.00"); net_amount is sent as a number (e.g. 405.5) |
data.product_id |
PRD followed by the product number (the same number as the product’s PE id elsewhere in this API) |
data.voucher |
Link to the booking voucher |
Handling Notifications
Section titled “Handling Notifications”- Reply quickly. Send back a success status (any
2xx, such as200 OK) within 10 seconds. PE sends each message once and does not retry. If your system was down, usebooking_updatesto catch up on anything you missed. - Expect repeats. The same
typecan arrive more than once for a booking. For example,New Bookingarrives when a booking is placed and again when it is confirmed. Checkbooking_referenceanddata.statusso each change is handled only once. - Check the signature (optional). To confirm a message really came from Project Expedition, ask for a shared secret when the webhook is set up. PE then signs every message with
base64(HMAC-SHA256(raw request body, secret))and sends the result in a request header agreed during setup. Compute the same value over the message exactly as received, before parsing the JSON, and reject any message where the two don’t match.