← Developers

Escapra Developer Docs

A governance-first, PMS-agnostic distribution API. One canonical booking lifecycle. Scoped authorization. Live revalidation. Signed webhooks. Explicit error taxonomy. Queryable lineage.

API contract subject to integration review

Status of this document: conceptual reference for integration evaluation and design. Endpoint paths and payload shapes are subject to integration review and confirmed under a sandbox engagement.

§01

Overview

Escapra is a governance-first distribution API. It connects hotel inventory to authorized B2B demand through a governed layer between hotel supply and approved partners.

Escapra is

A governance, authorization, revalidation, settlement, and audit layer between hotel supply and authorized B2B demand.

Escapra is not

A property management system. An online travel agency. A channel manager. A bed bank.

The API exposes a single canonical booking lifecycle, scoped authorization tokens, an explicit error taxonomy, contracted idempotency on write endpoints, a signed webhook catalog, and queryable lineage per booking. Developers build against one contract — there are no per-partner special cases.

§02

Escapra Concept Model

The platform is described in nouns. Each noun is defined once and referenced everywhere. Implementation details that are not part of the contract are intentionally omitted.

  • Hotel

    The legal and commercial entity that owns the property and authorizes distribution.

  • Property

    The canonical identity of a physical hotel property. One property has many room types and rate plans.

  • Room Type

    A sellable room category under a property (e.g. Deluxe King). Inventory and rates are organized per room type.

  • Rate Plan

    A sellable rate definition under a property (currency, restrictions, cancellation policy). Rate plans carry governance metadata.

  • Availability Slot

    A time-bounded count of sellable units under a room type, with a sourceUpdatedAt freshness marker.

  • Authorized Partner

    A B2B demand partner that a hotel has explicitly authorized to sell, scoped by rate plan, segment, geography, and date range.

  • Booking

    A confirmed (or held) intent against a rate plan and dates. Carries lineage to governance, commission, distribution chain, and settlement.

  • Governance Decision

    The captured decision that authorized (or denied) a booking. Append-only; one per booking lifecycle event.

  • Settlement Lineage

    The chain from booking → governance → property → commission rule → distribution chain → settlement record.

  • Webhook Event

    A signed, replay-safe notification of a lifecycle or scope change on your authorized surface.

§03

Core Platform Objects (Relationships)

How the objects relate:

Hotel
 └── Property
       ├── Room Type
       │     └── Availability Slot   (sourceUpdatedAt + freshness state)
       └── Rate Plan
             └── Authorized Partner   (scope: rate plans · segment · geography · date range)
                   └── Booking
                         ├── Governance Decision     (append-only)
                         ├── Inventory Decision      (FRESH | STALE_WARNING | STALE_BLOCKED)
                         └── Settlement Lineage      (commission rule · distribution chain · settlement record)

The relationships above describe the contract, not a database schema. Implementation is per-service isolated; cross-service relationships are resolved by ids, never by shared writeable surfaces.

§04

Booking Lifecycle

The single canonical flow Escapra implements for every booking, regardless of partner or upstream system. This is the centerpiece of the API. Build against this; everything else is reference.

Hotel
  ↓ (system of record)
PMS
  ↓ (read what is authoritatively exposed)
Escapra Governance Layer
  ↓ (scoped authorization check)
Authorized Partner
  ↓ (quote → hold → confirm)
Booking Request
  ↓ (inventory + rate revalidation against source of truth)
Confirmation     — or —     409 PRICE_CHANGED → re-accept
  ↓
Settlement (atomic, idempotent, lineage end-to-end)
  ↓
Audit (append-only)

Step-by-step

  1. 01

    Partner · Quote

    Request availability under your authorized rate plans for given dates and occupancy.

  2. 02

    Escapra · Resolve scope

    Verify your authorization scope, classify inventory freshness, and return only what you may sell.

  3. 03

    Partner · Hold

    Create a hold with an Idempotency-Key. A governance decision is captured against the booking-in-progress.

  4. 04

    Escapra · Capture

    Record the governance decision and the inventory decision (FRESH / STALE_WARNING / STALE_BLOCKED) for this attempt.

  5. 05

    Partner · Confirm

    Submit confirmation with guest detail and the original Idempotency-Key.

  6. 06

    Escapra · Revalidate

    Live revalidation against the hotel's source of truth. If the rate matches, write the booking with lineage; if not, return 409 PRICE_CHANGED.

  7. 07

    Partner · Re-accept

    On 409 PRICE_CHANGED, you receive the new rate and must explicitly re-accept (or decline).

  8. 08

    Escapra · Settle

    Once confirmed, the booking flows into settlement under its commission rule and distribution chain.

  9. 09

    Escapra · Audit

    Every decision is captured to an append-only audit. History is never updated; lineage is queryable per booking.

API contract subject to integration review

Endpoint paths for quote / hold / confirm are subject to integration review. The lifecycle shape above is stable; wire-level shapes are aligned per integration in sandbox before production activation.

§05

Authorization Model

Authorization is the contract between a hotel and a partner — not between Escapra and a partner. Escapra is the mechanism that captures, scopes, and enforces what the hotel decided.

Hotel-controlled access

Hotels — not Escapra — decide which partners may sell, at what rate plans, on what terms.

Partner approval workflow

Partners request access; hotels review and scope; revocation is immediate and audit-logged.

Distribution rules

Rules express which partner may sell which rate plans, under which restrictions (segment, geography, date range).

Scoped authorization

Your token is bound to your scope. It cannot exceed what the hotel authorized — the platform enforces governance-first, before any booking decision.

Revocation

Revocations take effect immediately. Held bookings honor their existing terms; new quotes are denied.

Audit trail

Every authorization, scope change, and revocation is captured to the append-only audit. Queryable per partner and per booking.

The authorization is captured as a Governance Decision on every booking attempt. Audit is read-only and queryable per booking, per partner, and per property.

§06

Inventory & Availability

Availability slots carry a sourceUpdatedAt marker and a freshness classification. The classification is observable on every quote and recorded on every booking attempt.

FRESH

Availability is current and bookable. Quote and hold flow normally.

STALE_WARNING

Availability is older than the soft threshold. Bookable, but a freshness signal is attached to the booking record.

STALE_BLOCKED

Availability exceeds the hard freshness threshold. Quotes and bookings are blocked, not silently confirmed.

Out-of-order ingest protection

Ingest is guarded against out-of-order updates: a later sourceUpdatedAt never silently overwrites a freshness classification with an older one. The platform records skipped-stale events for observability.

Live validation where available

When a hotel’s source of truth exposes a live capability surface, Escapra revalidates against it at the moment of booking confirmation. When the capability surface is degraded, the platform fails closed rather than book unsafely.

§07

Revalidation Contract

Every booking is revalidated against the hotel’s source of truth before confirmation. This is the contract. There is no path that confirms a booking without revalidation.

  1. 01

    You submit confirm with the original Idempotency-Key and the rate you quoted.

  2. 02

    Escapra revalidates against the hotel's source of truth at the moment of confirmation.

  3. 03

    If the rate is unchanged, the booking is written with full lineage and you receive a confirmation.

  4. 04

    If the rate has changed, Escapra returns 409 PRICE_CHANGED with the new rate, the prior quote, and the reason.

  5. 05

    You explicitly re-accept (which confirms at the new rate) or decline (which releases the hold).

  6. 06

    If inventory is stale or capability has degraded, Escapra fails closed — the booking does not confirm.

# Conceptual: confirmation response on rate drift
HTTP/1.1 409 Conflict
Content-Type: application/json

{
  "error": "PRICE_CHANGED",
  "quoted":      { "currency": "EUR", "total": 1240.00 },
  "revalidated": { "currency": "EUR", "total": 1280.00 },
  "reason":      "rate_plan_updated_between_quote_and_confirm",
  "next":        "re_accept_with_new_total_or_decline"
}

API contract subject to integration review

Exact payload field names are subject to integration review; the contract shape above is stable.

§08

Webhooks & Events

Subscribe to lifecycle and scope-change events on your authorized surface. Delivery is at-least-once, payloads are HMAC-signed, and event ids let you dedupe and replay safely.

EventFires when
booking.createdA booking has been created in hold state, awaiting confirmation.
booking.confirmedA booking has been confirmed and lineage written.
booking.cancelledA booking has been cancelled under governed terms.
availability.changedAvailability on a rate plan within your scope has changed.
rate.changedA rate plan within your scope has been updated by the hotel.
authorization.updatedYour authorization scope has been changed (granted, restricted, or revoked).
settlement.generatedA statement of account or settlement record has been generated for your scope.
incident.createdAn operational incident affecting your scope has been raised.

Delivery contract

  • At-least-once delivery. Dedupe by event_id.
  • Signed payload. Verify the HMAC signature against your subscription secret on every event.
  • Retry with backoff. Non-2xx responses are retried with exponential backoff; dead-letter behavior is documented on the subscription.
  • Replay safety. Same event_id delivered twice describes the same fact — never two distinct facts.

API contract subject to integration review

Exact webhook payload shapes and subscription endpoints are subject to integration review and confirmed in sandbox.

§09

Error Model

Errors are a stable taxonomy at the category level. Messages may evolve; categories do not. The categories below describe behavior — not internal causes — so client code paths stay stable.

CodeHTTPMeaningRetry
AUTHORIZATION_REQUIRED401No valid token, or token is missing scope claims.no
AUTHORIZATION_DENIED403Token is valid but the requested action exceeds the authorization scope hotels granted you.no
PRICE_CHANGED409The rate revalidated to a different value at confirmation. Re-accept explicitly or decline.after re-accept
AVAILABILITY_CHANGED409Inventory available at quote is no longer available at confirmation. Re-quote and retry.after re-quote
STALE_INVENTORY_BLOCKED409Availability has exceeded the freshness threshold. Wait for ingest, then re-quote.after re-quote
PMS_UNAVAILABLE503The hotel's upstream system of record is unavailable or degraded. Escapra fails closed by design.safe
BOOKING_REVALIDATION_FAILED409Revalidation against the source of truth failed for a reason not covered above (e.g. capability degradation).conditional
IDEMPOTENCY_CONFLICT409Same Idempotency-Key + different payload. Generate a fresh key for the new payload.no
RATE_LIMITED429Too many requests on this route class. Honor the Retry-After header.safe
INTERNAL_ERROR5xxEscapra-side error. Retries with the same Idempotency-Key are safe.safe

Idempotency & retries

  • — Every write endpoint accepts an Idempotency-Key header.
  • — Same key + same payload → same result. Same key + different payload → IDEMPOTENCY_CONFLICT.
  • — Retries on INTERNAL_ERROR / PMS_UNAVAILABLE with the same key are safe.
  • — Backoff with jitter. Honor Retry-After on RATE_LIMITED.
§10

Getting Started

The integration path is sandbox-first. Production activation is a joint readiness review with Escapra and an authorizing hotel — never a public self-serve switch.

  1. 01

    Request sandbox access

    Tell us your segment and integration profile. Sandbox keys are issued against a synthetic property, partner, and scope set.

  2. 02

    Confirm authentication model

    Bind your client to an authentication model (OAuth 2.0 for partner platforms, API key for server-to-server). Tokens are scoped to your authorization.

  3. 03

    Map properties

    Validate that your local property model maps to Escapra Property identities. Mapping is unidirectional — Escapra reads what the hotel authoritatively exposes.

  4. 04

    Sync rooms / rates / availability

    Read room types, rate plans, and availability slots within your authorized scope. Respect freshness state on every slot.

  5. 05

    Test booking lifecycle

    Exercise the full lifecycle in sandbox: quote → hold → revalidate → confirm. Force PRICE_CHANGED, AVAILABILITY_CHANGED, and STALE_INVENTORY_BLOCKED paths.

  6. 06

    Configure webhooks

    Subscribe to the events your integration depends on. Verify HMAC signatures, dedupe by event id, and tolerate at-least-once delivery.

  7. 07

    Run pilot validation

    Pilot scoping is a joint conversation with Escapra and an authorizing hotel. The pilot exercises every lifecycle in a controlled scope.

  8. 08

    Production readiness review

    Joint review covers scope, idempotency hygiene, webhook delivery, error handling, and incident response — before production activation.