Sb Sabee
Docs

Sabee REST API reference.

The Sabee API is a versioned, JSON-over-HTTPS REST API that gives you programmatic access to the same reservations, rates, guests, channels and invoices your Sabee dashboard shows. This page documents authentication, every endpoint, pagination and versioning, with runnable examples for each.

Overview & base URL

Sabee is a hospitality operations platform for independent hotels, hostels and aparthotel groups, covering property management, channel management, direct booking, revenue analytics, accounting and housekeeping in one product. The API surfaces the same underlying data model your team already uses inside the dashboard, so anything you can see on a reservation or invoice screen has a corresponding API representation.

All API requests use HTTPS and a versioned base path. There is no unversioned endpoint — every request must include the version segment.

https://api.sabee.esesun.com/v1

Requests and responses are JSON (Content-Type: application/json) except for file uploads. Timestamps are ISO 8601 in UTC. Monetary amounts are represented as integers in the smallest currency unit (cents for EUR) alongside a three-letter currency code, to avoid floating-point rounding errors on financial data.

Authentication

The API authenticates with an API key sent as a bearer token in the Authorization header. API keys are generated from Settings → Developer inside the Sabee dashboard on Growth-tier accounts and above, and are scoped to a single property or, for multi-property groups, to the whole portfolio depending on which key you generate.

curl -H "Authorization: Bearer $SABEE_API_KEY" \
  https://api.sabee.esesun.com/v1/reservations

Keys are secrets — treat them like a password. Never embed a live key in client-side JavaScript, a mobile app binary, or a public repository. Use a server-side proxy if you need to call the API from a browser context. Each key can be revoked independently from Settings → Developer without affecting other keys on the account, and Sabee logs the last-used timestamp and originating IP range for every key so you can audit usage.

Enterprise accounts can request scoped, read-only keys for reporting integrations, and separate write-enabled keys for systems that create or modify reservations — a useful separation if you're piping data into a BI tool that should never be able to mutate a booking.

Endpoint catalogue

ResourceMethod & pathDescription
ReservationsGET /v1/reservationsList reservations with filters for date range, status and channel.
ReservationsPOST /v1/reservationsCreate a new reservation.
ReservationsGET /v1/reservations/{id}Retrieve a single reservation.
ReservationsPATCH /v1/reservations/{id}Update dates, room assignment or status.
ReservationsPOST /v1/reservations/{id}/cancelCancel a reservation according to its rate plan policy.
Rate plansGET /v1/rate-plansList rate plans across all connected room types.
Rate plansPOST /v1/rate-plansCreate a rate plan.
Rate plansPATCH /v1/rate-plans/{id}Update pricing rules or cancellation policy.
Room typesGET /v1/room-typesList room types and their inventory counts.
Room typesPOST /v1/room-typesCreate a room type.
GuestsGET /v1/guestsList and search guest profiles.
GuestsGET /v1/guests/{id}Retrieve a guest profile including stay history.
GuestsPATCH /v1/guests/{id}Update guest details or preference notes.
ChannelsGET /v1/channelsList connected OTA channels and their sync status.
ChannelsPOST /v1/channels/{id}/resyncForce a manual resync of rates and availability.
InvoicesGET /v1/invoicesList invoices with filters for status and date range.
InvoicesGET /v1/invoices/{id}Retrieve a single invoice including line items.
InvoicesPOST /v1/invoices/{id}/sendEmail the invoice PDF to the guest on file.
WebhooksGET /v1/webhooksList configured webhook endpoints.
WebhooksPOST /v1/webhooksRegister a new webhook endpoint.
WebhooksPOST /v1/webhooks/testSend a test event to a registered endpoint.

Reservations

The reservations endpoint is the most heavily used part of the API. A reservation carries the guest reference, room type, rate plan, stay dates, status, source channel and any deposit or balance information.

curl -X POST https://api.sabee.esesun.com/v1/reservations \
  -H "Authorization: Bearer $SABEE_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "room_type_id": "rt_204",
    "rate_plan_id": "rp_flex_bb",
    "check_in": "2026-09-14",
    "check_out": "2026-09-17",
    "guest": {
      "first_name": "Elena",
      "last_name": "Kovac",
      "email": "elena.kovac@example.com",
      "phone": "+385911234567"
    },
    "channel": "direct",
    "adults": 2
  }'

A successful call returns 201 Created with the full reservation object, including a system-generated id, computed total, and the initial status of confirmed or pending_payment depending on the rate plan's deposit rule.

{
  "id": "res_8a41f0",
  "status": "confirmed",
  "room_type_id": "rt_204",
  "rate_plan_id": "rp_flex_bb",
  "check_in": "2026-09-14",
  "check_out": "2026-09-17",
  "nights": 3,
  "total": { "amount": 45000, "currency": "EUR" },
  "channel": "direct",
  "guest_id": "gst_5521c9",
  "created_at": "2026-07-26T09:14:02Z"
}

Listing reservations supports filtering by check_in_from, check_in_to, status and channel as query parameters, e.g. GET /v1/reservations?status=confirmed&channel=booking_com. Cancelling a reservation through POST /v1/reservations/{id}/cancel applies the cancellation policy attached to its rate plan and returns the resulting refund or fee, if any.

Rate plans

Rate plans define pricing, cancellation policy and any restrictions (minimum stay, closed-to-arrival) attached to a room type. Each rate plan can be mapped independently to one or more channels through the Channel Manager module.

curl https://api.sabee.esesun.com/v1/rate-plans?room_type_id=rt_204 \
  -H "Authorization: Bearer $SABEE_API_KEY"

Updating a rate plan's price for specific dates is done through the same PATCH endpoint with a price_overrides array, which is how most revenue-management integrations push dynamic pricing calculated externally.

Room types

Room types define inventory count, occupancy limits and the base attributes (bed configuration, size, amenities) shown on the booking engine and pushed to connected channels. Creating a room type through the API is typically a one-time setup step rather than a recurring integration call.

curl https://api.sabee.esesun.com/v1/room-types \
  -H "Authorization: Bearer $SABEE_API_KEY"

Guests

The guests endpoint mirrors the Guest CRM module — a unified profile per guest with stay history, preference notes and lifetime value. Searching by email or phone is supported via query parameters, useful for checking whether an incoming reservation belongs to a returning guest before creating a duplicate profile.

curl "https://api.sabee.esesun.com/v1/guests?email=elena.kovac@example.com" \
  -H "Authorization: Bearer $SABEE_API_KEY"

Channels

The channels endpoint reports the connection and sync status of every connected OTA — the same green/amber/red status shown on the operations dashboard. An amber status typically means a channel is temporarily throttling requests (see error codes for the SB-1002 code); a red status means credentials need re-authenticating inside the dashboard, which cannot currently be done through the API for security reasons.

curl https://api.sabee.esesun.com/v1/channels \
  -H "Authorization: Bearer $SABEE_API_KEY"

Invoices

Invoices mirror the Accounting & Billing module, including VAT breakdown, line items and payment status. This endpoint is commonly used to sync invoice data into an external accounting system beyond Sabee's native Xero, QuickBooks Online and Sage exports.

curl https://api.sabee.esesun.com/v1/invoices/inv_30291 \
  -H "Authorization: Bearer $SABEE_API_KEY"

Webhooks endpoint

Webhook endpoints are registered through the API or the dashboard. See the dedicated webhooks page for the full event catalogue, payload examples and signature verification.

curl -X POST https://api.sabee.esesun.com/v1/webhooks \
  -H "Authorization: Bearer $SABEE_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "url": "https://yourapp.example.com/hooks/sabee", "events": ["reservation.created", "invoice.paid"] }'

Pagination

List endpoints use cursor-based pagination rather than page numbers, which keeps results stable even as new reservations are created between page requests. Each response includes a next_cursor value; pass it back as the cursor query parameter to fetch the next page.

{
  "data": [ { "id": "res_8a41f0", "..." : "..." } ],
  "next_cursor": "eyJpZCI6InJlc184YTQxZjAifQ",
  "has_more": true
}
curl "https://api.sabee.esesun.com/v1/reservations?cursor=eyJpZCI6InJlc184YTQxZjAifQ&limit=50" \
  -H "Authorization: Bearer $SABEE_API_KEY"

The default page size is 25 and the maximum is 100 via the limit parameter. When has_more is false, or next_cursor is absent, you've reached the end of the result set. Do not construct or guess cursor values — treat them as opaque tokens, since the internal encoding may change between API versions.

Versioning

The current stable version is v1, included in every request path. Sabee does not make breaking changes within a version — new fields may be added to responses, but existing fields are never removed or repurposed, and required request fields are never added, within v1. When a breaking change is genuinely necessary, it ships as v2 alongside a deprecation timeline for v1 of at least twelve months, announced in advance on the changelog and by email to every account with an active API key.

Because non-breaking additions can still surprise a strict client, we recommend deserializing responses in a forward-compatible way — ignore unknown fields rather than rejecting the response outright.

Errors

Errors return a standard HTTP status code plus a JSON body with a machine-readable code and a human-readable message.

{
  "error": {
    "code": "SB-1001",
    "message": "Requested room type has no availability for the given dates.",
    "status": 409
  }
}

The full catalogue of standard and Sabee-specific error codes, with an example body for each, is documented on the error codes page. For request-volume errors specifically, see rate limits.

Idempotency for write requests

Network failures happen, and a client that retries a POST /v1/reservations call after a timeout risks creating the same reservation twice. To make retries safe, every write endpoint accepts an Idempotency-Key header — any unique string you generate per logical operation, typically a UUID.

curl -X POST https://api.sabee.esesun.com/v1/reservations \
  -H "Authorization: Bearer $SABEE_API_KEY" \
  -H "Idempotency-Key: 6f2a9e10-6b2e-4b7a-9c9d-2a6b6e2a9e10" \
  -H "Content-Type: application/json" \
  -d '{ "room_type_id": "rt_204", "..." : "..." }'

If a request with the same key arrives again within 24 hours, Sabee returns the original response instead of creating a second reservation, regardless of whether the first attempt actually succeeded on the server before the client's connection dropped. We strongly recommend generating the idempotency key once per user action — for example, once when a guest clicks "confirm booking" in your own checkout flow — and reusing it for every retry of that same action, rather than generating a fresh key per HTTP attempt.

Sandbox environment

Every account with API access also has a sandbox environment at https://api.sandbox.sabee.esesun.com/v1, mirroring the same endpoints and authentication model against a separate, non-production dataset. Use the sandbox to build and test an integration — including exercising webhook deliveries via the /v1/webhooks/test endpoint — before pointing your code at production data. Sandbox API keys are prefixed sk_sandbox_ rather than sk_live_, which makes it easy to catch a misconfigured environment variable before it causes a real reservation to be created against a live property by mistake.

Client libraries

Sabee does not currently maintain first-party SDKs in every language, since the API surface is intentionally small and plain REST-over-HTTPS covers most integration needs without a wrapper library. Community-maintained clients exist for Node.js and Python; both are linked from the developer settings page inside the dashboard. If you're integrating from a typed language, the OpenAPI schema backing this documentation is available on request through contact and can be fed into most code-generation tools to produce typed request and response models automatically.

Ready to generate an API key?

API access ships with Growth-tier accounts and above. Get access to provision your first key from the dashboard, or talk to us about an Enterprise integration.