Read your hotels' bookings, rooms, prices and reports from your own tools.
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
Write to dev@bookeva.com from the email of your Bookeva account and say what you want to read.
We turn the API on for your account.
The account owner opens Settings › Bookeva API, creates a key, chooses what it can read and, if needed, which hotels.
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:
Scope
Name in Settings
What it can read
stays:read
Bookings
Every booking with its dates, rooms, channel, status and money. No guest names or contacts.
guests:read
Guest names and contacts
Adds 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:read
Rooms and rate plans
Room types, rooms and rate plans.
calendar:read
Prices and availability
Free rooms, prices and stay rules per night, as Bookeva sends them to travel sites.
reports:read
Reports
The 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.
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
Parameter
Type
What it does
property_id (in the path) (required)
uuid
The hotel's id, from GET /properties.
arrival_from
date (YYYY-MM-DD)
Only bookings that arrive on or after this date.
arrival_to
date
Only bookings that arrive on or before this date.
departure_from
date
Only bookings that leave on or after this date.
departure_to
date
Only bookings that leave on or before this date.
modified_since
date-time with a time zone, e.g. 2026-10-01T00:00:00Z
Only 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”.
status
list
One or more of confirmed, cancelled, no_show, separated by commas.
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.
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.
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.
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.
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.
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.
To keep your own copy of the bookings up to date without reading everything again:
First read (a full copy): all bookings, page by page, withoutmodified_since, until next_cursor is null. Save each booking by its id (replace what you had).
Only when you have read the last page, save its next_modified_since.
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"
}
}
Status
Code
Meaning
400
invalid_parameter
A query parameter is wrong. The message names it.
401
missing_key
No key in the Authorization header.
401
invalid_key
The key is not valid.
401
key_revoked
The 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.
403
access_not_enabled
The account is closed, so its keys no longer work.
403
insufficient_scope
The key does not have the scope this endpoint needs.
403
module_required
Intelligence figures need the Intelligence add-on.
404
not_found
No such endpoint, or the hotel is not one the key can read.
405
method_not_allowed
The API is read-only: use GET.
429
rate_limited
Too many requests. Wait for Retry-After.
429
key_paused
The key kept going after it was limited and is paused for 15 minutes.
429
too_many_failed_attempts
Too many requests with a wrong key from your address.
500
internal_error
Something went wrong on our side. Retry later.
503
temporarily_unavailable
The API cannot answer right now. Retry shortly.
Build on the code, not the message: messages may be reworded.
Rate limits
Limit
Applies to
10 requests per second
Per key (bursts)
60 requests per minute
Per key
10,000 requests per day
Per key
1,200 requests per minute
Per address, all keys together (wrong keys have their own limit below)
20 per 15 minutes, then locked out
Requests with a wrong key, per address
Paused for 15 minutes
A 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.