Overview

Ananas GDS can push event notifications to any HTTPS endpoint you register. When a matching event occurs — a stop sale changes, an invoice is sent, a property updates — Ananas GDS immediately dispatches a signed POST request to all subscribed endpoints. This eliminates the need for polling and allows your systems to react in real time.

Registering a Webhook

1
Go to Developer Tools → Webhooks in the dashboard.
2
Click Add Endpoint. Enter a name, the HTTPS URL, and select the events to subscribe to.
3
Ananas GDS generates a signing secret. Copy it — it is shown once.
4
Send a test ping to verify your endpoint is reachable and your signature verification code is correct.

HTTPS required

Webhook endpoints must use HTTPS. HTTP endpoints are rejected at registration time. Your server must present a valid TLS certificate.

Payload Structure

Every webhook delivery is a JSON POST body with a consistent envelope:

Webhook Payload Envelope
{
  "event": "stopsale.created",
  "timestamp": "2026-05-11T14:32:00Z",
  "delivery_id": "del_a1b2c3d4e5f6",
  "data": {
    // Event-specific data object
  }
}

Event Data Objects

EventData Object
property.updatedFull property object with changed fields highlighted.
stopsale.createdStop sale event: property_id, date, status, allotment, room_type, source.
stopsale.updatedSame as created, with previous values included.
stopsale.cancelledStop sale event ID and property_id.
invoice.sentInvoice summary: id, invoice_number, from, to, amount, currency, due_date.
invoice.paidInvoice summary plus paid_at timestamp and payment reference.
invoice.disputedInvoice summary plus dispute note text.
invoice.cancelledInvoice ID, invoice_number, cancellation timestamp.
availability.updatedProperty ID, affected date range, allotment values.

Signature Verification

Every delivery includes an X-Ananas-Signature header. This is an HMAC-SHA256 digest of the raw request body, keyed with the endpoint's signing secret. Always verify this signature before processing the payload.

Signature Header
X-Ananas-Signature: sha256=a1b2c3d4e5f6...
Python Verification Example
import hmac
import hashlib

def verify_signature(payload_body: bytes, signature_header: str, secret: str) -> bool:
    expected = hmac.new(
        secret.encode(),
        payload_body,
        hashlib.sha256
    ).hexdigest()
    received = signature_header.replace("sha256=", "")
    return hmac.compare_digest(expected, received)

Use constant-time comparison

Always use hmac.compare_digest() (or your language's equivalent) rather than == for comparing signatures. This prevents timing-based attacks.

Retry Policy

A delivery is considered successful when your endpoint responds with any 2xx HTTP status code within 30 seconds. If delivery fails (non-2xx, timeout, or connection error), Ananas GDS retries with exponential backoff:

AttemptDelay
1st retry5 minutes
2nd retry30 minutes
3rd retry2 hours
4th retry8 hours
5th retry (final)24 hours

After 5 failed attempts the delivery is marked failed and no further retries are attempted. You can manually retry from the delivery log in the dashboard.

Delivery Log

Every delivery attempt is recorded in WebhookDelivery with the response code, response body, attempt count, and next retry timestamp. Access the log for any endpoint from Developer Tools → Webhooks → Deliveries, or via the API:

List Deliveries
GET /api/dev/integrations/webhooks/{id}/deliveries/
Authorization: Token <token>
Manually Retry a Delivery
POST /api/dev/integrations/webhooks/deliveries/{delivery_id}/retry/
Authorization: Token <token>

Test Ping

Send a synthetic test event to verify your endpoint without waiting for a real event to occur:

Test Ping
POST /api/dev/integrations/webhooks/{id}/test/
Authorization: Token <token>

The test payload uses the event type test.ping with a minimal data object. Inspect the delivery log to confirm receipt.

Idempotency

Each delivery has a unique delivery_id in the envelope. If your endpoint receives the same delivery_id twice (e.g. after a retry following a timeout where your server actually processed the request), treat the second as a duplicate and return 2xx without re-processing. Store processed delivery IDs for at least 24 hours.