Bookeva
    • All features
    • Channel manager
    • Front desk
    • Direct booking
    • Rates
    • Guest experience
    • Housekeeping
    • Demo Hotel
    • Guides
    • Blog
    • FAQ
    • Talk to us
  • Integrations
  • Pricing
Log inStart your free trial
Home/Bookeva API

Bookeva API

Read your hotels' bookings, rooms, prices and reports from your own tools.

  • Overview
  • Getting access
  • Authentication
  • Requests and responses
  • Endpoints
  • Pagination
  • Keeping a copy in sync
  • Errors
  • Rate limits
  • Versioning
  • Changelog
  • Data protection (GDPR)

Access to the Bookeva API is an additional paid service.

To get access, contact us at dev@bookeva.com. We turn it on for your account; then the account owner creates keys in Settings.

Overview

The Bookeva API lets your own software read the data Bookeva keeps for your hotels: hotels, room types and rooms, bookings, free rooms and prices per night, and the figures of Reports and Intelligence. A reporting tool, a spreadsheet or a data warehouse can stay up to date without anyone exporting files.

Version 1 is read only. It never changes a booking, a price or a setting, and reading it never sends anything to Booking.com, Airbnb, Expedia, Agoda or any other travel site.

Getting access

  1. Write to dev@bookeva.com from the email of your Bookeva account and say what you want to read.
  2. We turn the API on for your account.
  3. The account owner opens Settings › Bookeva API, creates a key, chooses what it can read and, if needed, which hotels.
  4. Copy the key right away. We store only a fingerprint of it, so it cannot be shown again. You can revoke a key at any time; it stops working on its next request.

An account can have up to 10 active keys. Each key has scopes:

ScopeName in SettingsWhat it can read
stays:readBookingsEvery booking with its dates, rooms, channel, status and money. No guest names or contacts.
guests:readGuest names and contactsAdds the guest's given name, family name, email and phone to each booking. Needs stays:read, and the owner must be signed in with two-step verification to give it. It is personal data: give it only to tools that need it.
rooms:readRooms and rate plansRoom types, rooms and rate plans.
calendar:readPrices and availabilityFree rooms, prices and stay rules per night, as Bookeva sends them to travel sites.
reports:readReportsThe figures of Reports and, with the Intelligence add-on, of Intelligence.

Authentication

Send the key in the Authorization header of every request:

Header
Authorization: Bearer bkv_q4m7tz2k_…

Keys start with bkv_ and eight characters you also see in Settings, so you can tell your keys apart. Keep keys on a server, never in a web page or a mobile app, and never in a URL. If a key may have leaked, revoke it and create a new one.

Requests and responses

Base URL: https://app.bookeva.com/api/v1. Use HTTPS and GET. Responses are JSON with your data under data.

  • Money is a whole number of minor units (cents) with its currency: 31200 in EUR is 312.00 euros.
  • Stay dates (arrival, departure, calendar nights) are the hotel's own dates, without a time. Times such as updated_at are in UTC.
  • Ids are UUIDs. They never change.
  • Every response has an X-Request-Id header. Quote it when you write to us.
  • Responses carry an ETag. Send it back in If-None-Match and you get 304 with no body when nothing changed.
  • Responses are Cache-Control: private, no-store: proxies and browsers must not keep them.
  • Unknown query parameters are refused with invalid_parameter, so a typo never silently reads everything.

Endpoints

All paths are relative to the base URL. Jump to: Your key · Hotels · Rooms and rate plans · Bookings · Prices and availability · Daily report · Pace and pick-up · On the books · Channels and lead time

Your key

GET/v1/me

Checks a key. Returns your organisation, the key's name, prefix and scopes, and the hotels it can read.

Scope: any valid key

Example request
curl -H "Authorization: Bearer $BOOKEVA_API_KEY" \
  https://app.bookeva.com/api/v1/me
Example response
{
  "data": {
    "organization": { "id": "0d2c…", "name": "Harbour Hotels" },
    "key": {
      "name": "Monthly reports",
      "prefix": "bkv_q4m7tz2k",
      "scopes": ["reports:read", "rooms:read", "stays:read"],
      "all_properties": true,
      "created_at": "2026-10-21T09:12:44.512000Z"
    },
    "property_ids": ["7c9e6679-7425-40de-944b-e07fc1f90ae7"]
  }
}

Hotels

GET/v1/properties

The hotels the key can read, with their time zone, currency and number of rooms. Archived hotels are not listed.

Scope: any valid key

Example request
curl -H "Authorization: Bearer $BOOKEVA_API_KEY" \
  https://app.bookeva.com/api/v1/properties
Example response
{
  "data": [
    {
      "id": "7c9e6679-7425-40de-944b-e07fc1f90ae7",
      "name": "Harbour House",
      "timezone": "Europe/Paris",
      "currency": "EUR",
      "country": "FR",
      "check_in_time": "15:00",
      "check_out_time": "11:00",
      "business_date": "2026-10-21",
      "room_count": 12
    }
  ]
}

Rooms and rate plans

GET/v1/properties/{property_id}/rooms

Room types with their rooms and rate plans. Use the ids to read the calendar and to match bookings to rooms.

Scope: rooms:read

ParameterTypeWhat it does
property_id (in the path) (required)uuidThe hotel's id, from GET /properties.
Example request
curl -H "Authorization: Bearer $BOOKEVA_API_KEY" \
  https://app.bookeva.com/api/v1/properties/7c9e6679-7425-40de-944b-e07fc1f90ae7/rooms
Example response
{
  "data": {
    "room_types": [
      {
        "id": "4f1a…",
        "name": "Double room",
        "kind": "hotel_room",
        "room_count": 2,
        "max_adults": 2,
        "max_children": 1,
        "rooms": [
          { "id": "9b0e…", "name": "101", "kind": "room", "parent_room_id": null }
        ],
        "rate_plans": [
          {
            "id": "c3d2…",
            "name": "Standard",
            "currency": "EUR",
            "occupancy": 2,
            "pricing": "per_room",
            "derived_from_rate_plan_id": null
          }
        ]
      }
    ]
  }
}

Bookings

GET/v1/properties/{property_id}/stays

Bookings of one hotel, cancelled ones included, 50 per page (at most 100). Money is in minor units (cents) of the booking's currency; dates are the hotel's own dates. Each room in rooms has amount_minor and currency: the travel site's figure for that room, for all its nights and every room it counts (quantity), and it may include taxes. It is null when there is none (bookings made in Bookeva, rooms changed during the stay, or a travel site that sent none). For room revenue use room_revenue_minor; for what the guest owes use total_minor.

Scope: stays:read

ParameterTypeWhat it does
property_id (in the path) (required)uuidThe hotel's id, from GET /properties.
arrival_fromdate (YYYY-MM-DD)Only bookings that arrive on or after this date.
arrival_todateOnly bookings that arrive on or before this date.
departure_fromdateOnly bookings that leave on or after this date.
departure_todateOnly bookings that leave on or before this date.
modified_sincedate-time with a time zone, e.g. 2026-10-01T00:00:00ZOnly bookings that changed at or after this time, at most 90 days ago. Turns on the sync order: oldest change first. See “Keeping a copy in sync”.
statuslistOne or more of confirmed, cancelled, no_show, separated by commas.
limitintegerBookings per page, 1 to 100. Default 50.
cursorstringThe next_cursor of the previous page.
Example request
curl -H "Authorization: Bearer $BOOKEVA_API_KEY" \
  "https://app.bookeva.com/api/v1/properties/7c9e6679-7425-40de-944b-e07fc1f90ae7/stays?modified_since=2026-10-01T00:00:00Z&limit=100"
Example response
{
  "data": [
    {
      "id": "1e7b…",
      "status": "confirmed",
      "check_in_state": "expected",
      "arrival": "2026-11-03",
      "departure": "2026-11-05",
      "nights": 2,
      "booking_code": null,
      "channel_reference": "4410012345",
      "channel": { "code": "booking_com", "name": "Booking.com" },
      "rooms": [
        {
          "room_type_id": "4f1a…",
          "room_type_name": "Double room",
          "room_id": "9b0e…",
          "room_name": "101",
          "quantity": 1,
          "arrival": "2026-11-03",
          "departure": "2026-11-05",
          "adults": 2,
          "children": 0,
          "amount_minor": 31200,
          "currency": "EUR"
        }
      ],
      "adults": 2,
      "children": 0,
      "infants": 0,
      "currency": "EUR",
      "total_minor": 31200,
      "room_revenue_minor": 28800,
      "channel_taxes_minor": 2400,
      "ota_commission_minor": 4320,
      "balance_due_minor": 0,
      "payment_collected_by": "travel_site",
      "created_at": "2026-10-14T08:02:11.070512Z",
      "cancelled_at": null,
      "updated_at": "2026-10-14T08:02:11.070512Z",
      "guest": null
    }
  ],
  "next_cursor": "eyJhIjoiMjAyNi0xMC0xNFQwODowMjoxMS4wNzA1MTJaIiwiaSI6IjFlN2Ii…",
  "next_modified_since": "2026-10-21T08:55:00.000000Z"
}

Prices and availability

GET/v1/properties/{property_id}/calendar

For each room type and night: rooms still free to sell and, per rate plan, the price and stay rules. At most 366 nights per call. A night without a value comes back as null.

Scope: calendar:read

ParameterTypeWhat it does
property_id (in the path) (required)uuidThe hotel's id, from GET /properties.
from (required)dateFirst night.
to (required)dateLast night (at most 365 days after from).
Example request
curl -H "Authorization: Bearer $BOOKEVA_API_KEY" \
  "https://app.bookeva.com/api/v1/properties/7c9e6679-7425-40de-944b-e07fc1f90ae7/calendar?from=2026-11-01&to=2026-11-30"
Example response
{
  "data": {
    "from": "2026-11-01",
    "to": "2026-11-30",
    "currency": "EUR",
    "room_types": [
      {
        "room_type_id": "4f1a…",
        "name": "Double room",
        "nights": [
          {
            "date": "2026-11-01",
            "available": 1,
            "rate_plans": [
              {
                "rate_plan_id": "c3d2…",
                "price_minor": 13500,
                "min_stay_arrival": 2,
                "min_stay_through": 1,
                "max_stay": null,
                "stop_sell": false,
                "closed_to_arrival": false,
                "closed_to_departure": false
              }
            ]
          }
        ]
      }
    ]
  }
}

Daily report

GET/v1/properties/{property_id}/reports/daily

The Reports figures per day: occupancy, ADR, RevPAR and room revenue, from closed days. A day the hotel has not closed yet comes back as closed: false with no figures. At most 367 days per call.

Scope: reports:read

ParameterTypeWhat it does
property_id (in the path) (required)uuidThe hotel's id, from GET /properties.
from (required)dateFirst day.
to (required)dateLast day.
Example request
curl -H "Authorization: Bearer $BOOKEVA_API_KEY" \
  "https://app.bookeva.com/api/v1/properties/7c9e6679-7425-40de-944b-e07fc1f90ae7/reports/daily?from=2026-10-01&to=2026-10-31"
Example response
{
  "data": {
    "from": "2026-10-01",
    "to": "2026-10-31",
    "business_date": "2026-10-21",
    "days": [
      {
        "date": "2026-10-01",
        "closed": true,
        "currency": "EUR",
        "rooms": 12,
        "blocked_rooms": 0,
        "available_rooms": 12,
        "sold_rooms": 9,
        "free_rooms_given": 0,
        "no_show_rooms": 0,
        "occupancy_basis_points": 7500,
        "room_revenue_minor": 121500,
        "room_revenue_ex_vat_minor": 110455,
        "no_show_revenue_minor": 0,
        "adr_minor": 13500,
        "revpar_minor": 10125,
        "foreign_currency_rooms": 0
      },
      { "date": "2026-10-21", "closed": false }
    ]
  }
}

Pace and pick-up

GET/v1/properties/{property_id}/reports/pace

Intelligence › Pace and pick-up: room nights and room revenue on the books for the next 12 months and 12 weeks against the same point last year, and net pick-up. Needs the Intelligence add-on.

Scope: reports:read

ParameterTypeWhat it does
property_id (in the path) (required)uuidThe hotel's id, from GET /properties.
Example request
curl -H "Authorization: Bearer $BOOKEVA_API_KEY" \
  https://app.bookeva.com/api/v1/properties/7c9e6679-7425-40de-944b-e07fc1f90ae7/reports/pace
Example response
{
  "data": {
    "asOf": "2026-10-21T09:00:00+00:00",
    "today": "2026-10-21",
    "currency": "EUR",
    "rooms": 12,
    "historyStart": "2025-03-01T10:12:00+00:00",
    "lastYearKnown": true,
    "lastYearWeeksKnown": true,
    "months": [
      {
        "month": "2026-11-01",
        "available": 360,
        "roomNights": 214,
        "revenue": 2889000,
        "lastYearRoomNights": 190,
        "lastYearRevenue": 2470000,
        "lastYearFinalRoomNights": 251,
        "lastYearFinalRevenue": 3263000,
        "lastYearUnknownRoomNights": 0
      }
    ],
    "weeks": [ { "weekStart": "2026-10-19", "available": 84, "roomNights": 61, "lastYearRoomNights": 55 } ],
    "pickup": [ { "days": 7, "bookings": 9, "roomNights": 23, "revenue": 310500, "cancellations": 1, "cancelledRoomNights": 2, "cancelledRevenue": 27000 } ]
  }
}

On the books

GET/v1/properties/{property_id}/reports/on-the-books

Intelligence › On the books: forward occupancy, ADR, RevPAR and room revenue for the next 30, 90 and 365 days and per day. Needs the Intelligence add-on.

Scope: reports:read

ParameterTypeWhat it does
property_id (in the path) (required)uuidThe hotel's id, from GET /properties.
Example request
curl -H "Authorization: Bearer $BOOKEVA_API_KEY" \
  https://app.bookeva.com/api/v1/properties/7c9e6679-7425-40de-944b-e07fc1f90ae7/reports/on-the-books
Example response
{
  "data": {
    "asOf": "2026-10-21T09:00:00+00:00",
    "today": "2026-10-21",
    "currency": "EUR",
    "historyStart": "2025-03-01T10:12:00+00:00",
    "lastYearKnown": true,
    "horizons": [
      {
        "days": 30,
        "available": 360,
        "roomNights": 214,
        "revenue": 2889000,
        "occupancyBasisPoints": 5944,
        "adr": 13500,
        "revpar": 8025,
        "unassignedRoomNights": 0,
        "lastYearAvailable": 360,
        "lastYearRoomNights": 190,
        "lastYearRevenue": 2470000,
        "lastYearOccupancyBasisPoints": 5278,
        "lastYearAdr": 13000,
        "lastYearRevpar": 6861
      }
    ],
    "days": [ { "date": "2026-10-21", "available": 12, "roomNights": 9, "revenue": 121500, … } ]
  }
}

Channels and lead time

GET/v1/properties/{property_id}/reports/channels

Intelligence › Channels and lead time: for bookings made in the last 30, 90 or 365 days, the channel mix, cancellations, lead time and length of stay. Needs the Intelligence add-on.

Scope: reports:read

ParameterTypeWhat it does
property_id (in the path) (required)uuidThe hotel's id, from GET /properties.
daysinteger30, 90 or 365. Default 90.
Example request
curl -H "Authorization: Bearer $BOOKEVA_API_KEY" \
  "https://app.bookeva.com/api/v1/properties/7c9e6679-7425-40de-944b-e07fc1f90ae7/reports/channels?days=30"
Example response
{
  "data": {
    "asOf": "2026-10-21T09:00:00+00:00",
    "days": 30,
    "from": "2026-09-21",
    "to": "2026-10-21",
    "currency": "EUR",
    "excludedImported": 0,
    "totals": { "bookings": 41, "cancelled": 3, "roomNights": 97, "revenue": 1309500 },
    "channels": [
      {
        "provider": "channel",
        "name": "BookingCom",
        "key": null,
        "channel": { "code": "booking_com", "name": "Booking.com" },
        "bookings": 25,
        "cancelled": 2,
        "roomNights": 61,
        "revenue": 823500
      }
    ],
    "leadTime": [ { "bucket": "0-7", "bookings": 12, "roomNights": 20, "revenue": 270000, "pricedRoomNights": 20 } ],
    "lengthOfStay": [ { "bucket": "1", "bookings": 15, "roomNights": 15 } ]
  }
}

Booking fields. status is confirmed, cancelled or no_show. check_in_state is expected, checked_in, checked_out or null. channel.code is booking_com, airbnb, expedia, agoda, direct or other (then channel.name says which). room_revenue_minor is the room part of the price, without what the travel site added for itself; channel_taxes_minor is what the travel site collected as taxes (for example city tax). In rooms, amount_minor is the travel site's figure for that room, for all its nights and every room it counts, and may include taxes; it is null when there is none. currency is the booking's. payment_collected_by is hotel, travel_site or unknown. guest is null unless the key has guests:read, and always null after a guest's data was erased.

Intelligence reports. Pace, On the books and Channels return exactly what the Intelligence screen draws, so their field names are in camelCase (roomNights, occupancyBasisPoints). Money there is in minor units too. Last-year fields are null while Bookeva has no history for that point. Each channel row also has the same channel code and name as a booking. In Channels, provider is bookeva (your own booking page and bookings you add) or channel (a travel site).

Pagination

Lists of bookings come in pages. When there are more, the response has a next_cursor; send it as cursor with the same other parameters to get the next page. When next_cursor is null you have everything. A cursor only continues the query that made it, and it is signed: send it exactly as you got it.

Next page
curl -H "Authorization: Bearer $BOOKEVA_API_KEY" \
  "https://app.bookeva.com/api/v1/properties/{property_id}/stays?limit=100&cursor=eyJhIjoiMjAy…"

Keeping a copy in sync

To keep your own copy of the bookings up to date without reading everything again:

  1. First read (a full copy): all bookings, page by page, without modified_since, until next_cursor is null. Save each booking by its id (replace what you had).
  2. Only when you have read the last page, save its next_modified_since.
  3. Next time, ask with modified_since set to the value you saved and page through the same way.

next_modified_since is five minutes before your read started, on purpose: a change saved while you were reading is never missed, and reading a booking twice does no harm. If a run stops halfway, do not save anything: continue with the last next_cursor, or start again from the value you saved before.

With modified_since, bookings come oldest change first. A booking counts as changed when its dates, rooms, status, price, guest details, check-in or payments change. Cancelled bookings are included, so you also learn about cancellations. Reading every 15 minutes is plenty for most tools. modified_since can be at most 90 days ago; if your copy is older than that, make a full copy again.

Errors

Every error has the same shape and a stable code:

Example
HTTP/1.1 403 Forbidden
{
  "error": {
    "code": "insufficient_scope",
    "message": "This key does not have the scope this endpoint needs.",
    "request_id": "5f0f6a8e-3c1d-4f7a-9c55-0d1b2a3c4d5e"
  }
}
StatusCodeMeaning
400invalid_parameterA query parameter is wrong. The message names it.
401missing_keyNo key in the Authorization header.
401invalid_keyThe key is not valid.
401key_revokedThe key was revoked, by the account owner or because API access ended. While access is on, the owner can create a new key in Settings.
403access_not_enabledThe account is closed, so its keys no longer work.
403insufficient_scopeThe key does not have the scope this endpoint needs.
403module_requiredIntelligence figures need the Intelligence add-on.
404not_foundNo such endpoint, or the hotel is not one the key can read.
405method_not_allowedThe API is read-only: use GET.
429rate_limitedToo many requests. Wait for Retry-After.
429key_pausedThe key kept going after it was limited and is paused for 15 minutes.
429too_many_failed_attemptsToo many requests with a wrong key from your address.
500internal_errorSomething went wrong on our side. Retry later.
503temporarily_unavailableThe API cannot answer right now. Retry shortly.

Build on the code, not the message: messages may be reworded.

Rate limits

LimitApplies to
10 requests per secondPer key (bursts)
60 requests per minutePer key
10,000 requests per dayPer key
1,200 requests per minutePer address, all keys together (wrong keys have their own limit below)
20 per 15 minutes, then locked outRequests with a wrong key, per address
Paused for 15 minutesA key refused more than 120 times in 10 minutes

Answers to a valid key carry X-RateLimit-Limit (requests per minute for the key) and X-RateLimit-Remaining. Over a limit you get 429 with a Retry-After header in seconds: wait that long before the next request. A client that keeps sending while limited gets its key paused for 15 minutes. The account owner sees each key's requests and refusals for the last 30 days in Settings.

Versioning

The version is in the path: /v1. Within v1 we only add: new endpoints, new optional parameters and new fields. Ignore fields you do not know. A change that could break a client gets a new version (/v2), and we tell key owners by email well before v1 changes or ends.

Changelog

  • 2026-10-28 — Bookings: each room in rooms now has amount_minor and currency. Nothing else changed: the keys are new; read keys by name, not by position.
  • 2026-10-21 — Version 1: me, properties, rooms, bookings with modified_since, prices and availability, daily report, and the three Intelligence reports. Read only.

Data protection (GDPR)

Your hotel is the controller of its guests' data; Bookeva processes it for you, as our Data Processing Agreement says. When you send data from the API to another tool, that tool becomes one of your processors or recipients: make sure you have a contract with it and that your privacy notice covers it.

  • Guest names and contacts come only with the guests:read scope. Leave it off when a tool only needs figures.
  • The API never returns card data, identity documents, door codes or notes.
  • When a guest's data is erased in Bookeva, the API stops returning it. Delete it from your copies too.
  • We log each request (time, key, endpoint, result) to protect your account. Log entries and the record of who turned access on or off and who created or revoked keys are deleted after 90 days, and everything goes when your account is closed and removed. The log never holds the data returned or the query values, and it holds addresses only as a fingerprint.

Questions: dev@bookeva.com.

Bookeva

The hotel PMS and channel manager for vacation units, independent hotels, hostels and aparthotels.

Solutions
  • Vacation apartments and homes
  • Boutique hotels
  • Hostels
  • Bed & breakfasts and guest houses
  • Aparthotels
  • Switch to Bookeva
Resources
  • Guides
  • Blog
  • FAQ
  • Pricing
  • Demo Hotel
  • Changelog
  • Bookeva API
Company
  • About us
  • Contact us
Legal
  • Terms of Service
  • Privacy Policy
  • Cookie Policy
  • Data Processing Agreement
  • Report a Legal Concern
  • Imprint
© 2026 Bookeva. All rights reserved.