Welcome
We are here to help!
Asmus Jacobsen
Partner Success ManagerBefore you reach out for support, please make sure to answer a short list of questions.
Welcome to the SOAP API Documentation of our SECRA Destination system. This is the API for our integrated booking engine to make reservations or just retrieve data about the various properties.
Before you start, you need to request an account from our support at partner@secra.de. Please remember to describe your use-case, who you are and why you want access to our API.
Getting started
SOAP
As for testing, we suggest using SoapUI.
This is a SOAP 1.1 based API. You can use any capable SOAP client, which supports WS-Security header authentification. All of this is strictly following the standard, so you will be fine if you find a standards compliant framework.
API endpoints
The technical codename "USSOP" is a shorthand for Universal SOAP Service of the Optimale-Präsentation.
The SOAP API is split into three parts:
Core/Booking API
This is the main API for retrieving object details, prices and occupancy information. This is also used for real-time queries and bookings. For channelmanagers this is the API to set/update availability and prices.
Landlord-Management API
Here you can create and update landlord/host data. This API is mainly useful to you if you've got a large or highly changing landlord/object pool by yourself.
Object-Management API
This API provides access to creating and updating data of objects under an existing landlord.
You can use the same login for all three APIs, but your user account must be enabled to do so.
Which API should I use?
Which API to use depends on your role: If you are a classical sales channel you will need access to Core API, if you are a full content provider, you will need Landlord and Object APIs too.
Note: If you are only updating prices and occupancy and do not manage objects at an inventory level (e.g. you are a channelmanager), you will be fine with just Core API.
Before starting to implement you should read the corresponding technical API documentation (WSDL+XSD) to get an idea of what we provide.
Don't worry, we've got a human readable version of the WSDL+XSD for you too!
Versioning
All API endpoints are under Versioning. If new versions are deployed, the default version will move to the latest version. Our supplied WSDL files therefore always use Version-Pinning and so should you!
You can easily switch or pin the versions by supplying the required GET parameter v with the endpoint URL.
Example:
https://www.optimale-praesentation.de/comm/universal?v=1.42
Access Level
Depending on your use-case you will be granted several access rights, either globally or per customer. If you perform an action you are not allowed to, you will receive an error, claiming that you have insufficient access rights.
If you receive an error and think this is an error / misconfiguration you can contact our support with the method you were trying to use, the property or entity which you were trying to modify and the name of your user account.
The following scopes are currently available:
Reading Access
- reading occupancy (pure free/occupied data)
- reading reservations (reservation data with customer informations)
- read property data
- read restricted/internal property data
Hint: Binding requests is a reservation operation mode where the host must accept/confirm a reservation request, otherwise it will be rejected. It is pretty much like true online booking but with a delayed acceptance.
Writing/Editing Access
- cancel reservation until arrival day
- make new reservations / binding requests
- write prices/seasons
- write price addons and addon seasons (e.g. extra services for reservations)
- write catering and catering seasons
- write non-binding reservation requests (legacy, non-online-bookable path)
- accept binding reservation requests
- create/edit hosts
- create/edit properties
Authentication
We do provide different authentication methods. You are free to choose the one you prefer or which one you are able to implement on your platform. Whatever method you choose, all connections must be encrypted. The interface will force any connection to use SSL/TLS.
Supported authentication methods (following the official WS-Security standard):
- WS-Security header: UsernameTokenProfile - PasswordDigest mode
- WS-Security header: UsernameTokenProfile - plaintext password mode (deprecated)
Rate Limits
This API is using Rate Limiting for Load Control. Currently there are 2 independent Rate Limiting levels. All Rate Limits emit Rate Limit Headers (see "RateLimit Header Fields for HTTP"). While the global limit uses the default Headers, the lower Write Limits use additional Custom-Prefixed Headers. All Rate Limits follow a fixed-window approach. You can easily get the current Limits by reading the respective Headers in any response to which they apply.
In general there are two response Headers that are especially useful to you: X-RateLimit-Remaining and X-RateLimit-Reset.
You should at least parse these two Headers. For advanced Load Balancing and forward planning it is suggested to parse the X-RateLimit-Limit Header.
Example
| Header Name | Value (Example) |
|---|---|
| X-RateLimit-Limit | 6000, 6000;w=600;burst=24000;comment="fixed-window", 36000;w=3600;comment="fixed-window" |
| X-RateLimit-Remaining | 6000 |
| X-RateLimit-Reset | 378 |
| XX-RateLimit-w600-Remaining | 5999 |
| XX-RateLimit-w600-Usage | 1 |
| XX-RateLimit-w600-Limit | 6000 |
| XX-RateLimit-w600-Burst | 24000 |
| XX-RateLimit-w600-Reset | 378 |
| XX-RateLimit-w3600-Remaining | 35991 |
| XX-RateLimit-w3600-Usage | 9 |
| XX-RateLimit-w3600-Limit | 36000 |
| XX-RateLimit-w3600-Reset | 3378 |
X-RateLimit-* Headers
This is only a brief description of used Headers. Please read the documentation of standard Headers linked above if you have any more questions.
X-RateLimit-Limit: This outputs the closest Limit you are about to reach, followed by the fixed-window specifications, separated by commas (not the ; !)X-RateLimit-Reset: Seconds until the current window of the closest Limit resets. Keep in mind there will be an offset in time caused by processing/network.X-RateLimit-Remaining: The remaining Quota in the currently closest Limit to reach.
The remaining count will stay static while you use the burst Quota until the burst is used up. This means e.g. if burst is 24k and normal Limit is 6k, the remaining count will start to go down with the last 6k of the total 24k. The main reason for Rate Limiting is: Load Control. It is not intended for API Users to use burst all the time.
For your convenience we also supply some non-standard Headers:
XX-RateLimit-w*-Remaining: The w* part references the matching fixed-window and the value of this Header is telling you the remaining value of this specific window. This is useful for debugging or to get a better understanding of the Limits. However, we strongly recommend not to use them in production as window design might change in the future.XX-RateLimit-w*-Usage: The current serverside usage count for the given window.XX-RateLimit-w*-Limit: The specific limit for the given window as from theX-RateLimit-Limitheader set, just easier to extract.XX-RateLimit-w*-Burst: The specific burst limit for the given window as from theX-RateLimit-Limitheader set (if existing), just easier to extract.XX-RateLimit-w*-Reset: The specific upcoming end of the window in seconds left until reset occurs.
For Write Limits there are identical Headers just prefixed with X-Write-RateLimit-*. They follow the same fixed-window approach and standard as the general Headers.
Global API Rate Limit
The global API Rate Limit applies to ALL requests and all APIs under this documentation. There are some scenarios, especially when doing fullsync operations
of all data and entities, where you might reach the Limits if not optimized for Load Balancing and Quota Usage Monitoring. So reading the Rate Limit
Headers in response is always a good idea, especially the X-RateLimit-Remaining Header should never hit zero.
The global rate limits are now dynamic and tailored per channel based on the number of connected properties. This allows for more efficient quota allocation: smaller channels receive appropriate limits without excess, while larger channels can scale accordingly. The limits are calculated as follows:
Base hourly limit: 18,000 requests (approximately 50% of the previous static limit). Scaling: 2 requests per connected property per hour. Effective hourly limit: The maximum of the base limit or the scaled amount (i.e., max(18,000, 2 × number_of_properties)). Manual overrides: A configurable factor (from 1.0 to 3.0 in 0.1 increments) can be applied to multiply the effective hourly limit, allowing for custom adjustments up to 3x the calculated value.
The number of connected properties is retrieved from a cached value in Memcache (permanent cache, with rare resets possible—in such cases, the base limit applies as a fallback). This calculation is not recomputed on every request for efficiency.
At the point of writing, there are 2 global limits with the following windows (the 600-second window remains static to prevent massive peaks, while the 3600-second window is dynamic):
- 600 seconds, fixed-window, 6000 requests, burst up to 24000
- 3600 seconds, fixed-window, dynamic requests (as calculated above), NO burst
What this means is: You can use the 24k requests in a 10 minute window, but not in every 10 minute window, as you would exceed the hourly Limit. The dynamic limits are reflected in the emitted Rate Limit Headers (e.g., X-RateLimit-Limit will show the current effective values).
Unique Write Rate Limits
The current Rate Limit for some Write requests (setPrices, setCategoryOccupancy) are:
- 60 seconds, fixed-window, 300 requests, NO burst
This Rate Limit will emit its own custom-prefixed Header (X-Write-RateLimit-*).
Exceeding the Rate Limit
If you have exceeded the Rate Limit your requests will be dropped and we will return a response with HTTP status of 429 ("Too Many Requests"). If you hit this Limit there is nothing our Support-Team can do for you, you must wait until the next Window. Please keep in mind that dropped requests still count for your usage.
Other Limits / Non Rate Limit limits
Please keep in mind that for some methods there are additional usage Quotas, e.g. the number of Entities you can create or request.
Error Handling
In general, these APIs emit errors when there is something wrong. The only exception are bulk requests where failing parts are silently dropped to not drop all data for hundreds of properties. Keep in mind that we can also only detect formal not logical errors in your requests.
The APIs differentiate between hard syntax / usage errors and "soft" errors which mostly are caused by the content / values which have been submitted (e.g. an email address wasn't able to pass DNS validation checks but was formally correct).
It is often overlooked that responses with status code 500 do have a payload, because most frameworks just skip reading the body of the response in such cases. Doing so with SOAP Exceptions will keep you from reading valuable error codes and messages!
- SOAP Exception are thrown by the API when there is a hard error. Note that SOAP Exceptions are sent with a HTTP status of 500 by SOAP specification, but that does not mean there is no error message in the payload!
- Error Nodes are used for soft errors and they are embedded in the normal response and part of the XSD.
You can find a full list of all error codes here.
Receive Data Updates
The desired way of receiving notifications for data changes of any kind are Webhook Callbacks, called "Push Events", as we push the event to your Callback URL.
You can (and most likely should) register for Webhooks for Updates regarding the following topics:
- Property data changes (including prices)
- Occupancy changes
- Reservation changes (new/edited/cancelled/etc.)
Registration is done by providing our support with the 3 public(!) URLs you want to use as Webhook receivers. You can either use one for all or three separate URLs. Webhooks will be called using GET requests only.
Good to know: Your receiver URL may contain any number of own GET parameters, we will extend those with the ones to be submitted to you.
We only submit ...
- what has changed
- where (IDs) it has changed
- if needed: access keys for single reservations which must be used with your login
Webhooks never transfer confidential data directly. They are intended as triggers for you to fetch specific updates, so you can stay up-to-date in close to realtime. They are intended as a way to keep your data in sync between weekly fallback full syncs of all data.
Our send mechanism can cover short outages at your end and will try to resubmit after a short delay. We usually plan for covering around 1 hour outages (although we do in fact cover larger ranges, we do not guarantee to do so).
Depending on how many properties are in your scope the number of webhook events might be relevant for your design decisions, as we do transmit nearly all events in close to realtime with only microseconds of delay. Be aware that we highly suggest enqueuing and deduplicating those events when received as our senders only have a small timeout (15s) and then assume the delivery attempt to be failed. As we submit in realtime there is no real chance at our end to deduplicate these.
For most events we run a number of concurrent workers, so expect some connections to be done in parallel.
As this is only a short teaser of our Push Events, please see the separate topic for more details.
More on Webhooks / Push Events
Implementation Guides
Now that you've read all those Basics, the next question is: Where do I start? Which methods and APIs do I choose? The answer is: That depends on your Use-Case. We provide some short Introductions to the most common Use-Cases.
Specification / WSDL
Core/Booking API Specification
| Version | Link |
|---|---|
| Function Reference | Link |
| ZIP | Download |
| WSDL | Link |
Landlord-Management API Specification
| Version | Link |
|---|---|
| Function Reference | Link |
| ZIP | Download |
| WSDL | Link |
Object-Management API Specification
| Version | Link |
|---|---|
| Function Reference | Link |
| ZIP | Download |
| WSDL | Link |
Guides
General Informations
For all variations of implementations you will need to:
- Use a pinned version of the WSDL
- Authenticate with the API with WSSE Headers
- Make sure to stay within the Rate Limits
- Handle errors
- Register for Push Events / Webhooks as needed
You will find most of this information in the "Getting started" section or at least some introduction and links to more details.
How do I progress from here?
If you've read all the "Getting started" topics the next question is, what to do next? Generally speaking you need API credentials and you need to request access to test/demo data from our support. In most cases you will receive a backend login too, so you can compare what the UI shows to what you've read or wrote to or from our API.
You can try and find out which calls to use on your own from the human-readable function reference directly, but we highly suggest you save yourself a lot of time. Over the years the API gathered a quite huge call collection and in most Use-Cases you are only going to use very few of them.
So let us first cover some basics:
Your first call will be getState. getState is giving you a list of all properties you have access to, your "pool".
This "pool" will change over time: You will get access to new properties in it and you will lose access to some. If you lose access
it is required that you remove the properties at your end, this means at least that they aren't accessible in any public way.
This includes images and deeplinks! Make sure to do this in a reasonable amount of time (e.g. 24 hours).
There is no Push Event for losing access, so the only way is to diff the result of getState in some way and see what is
new, what is missing and what has changed.
So with getState you now know a lot of IDs. The main identifiers you always want to save here are category_type and
category_no. Make sure to store both. category_no alone is not unique as the numbers for the different types
originate from different primary keys.
You will also notice organisation_no which is marking the customer account at our end and the object_no which identifies
a single property. Each property can contain multiple category items and each category can contain multiple units (e.g. rooms).
If you come from a sole apartment view this might at first look confusing, but keep in mind that we also cover hotels under
the same scheme. So from the APIs perspective a single apartment is just one object, with one category and one unit in it.
For hotels you can have multiple categories (e.g. different room types) and of course there is more than one unit within the
categories.
To summarize:
| ID | Explanation |
|---|---|
| organisation_no | The customer account at our end from whom the data originates |
| landlord_no | The specific host under the organisations account |
| object_no | The ID of the property |
| category_no | The ID of one category inside the property |
| category_type | The type of the category_no (e.g. the index it is derived from and in which the ID is unique) |
| unit_no | ID of a single room inside the category |
Sales Channel Guide
What is a Sales Channel in terms of API usage?
You are a Sales Channel to us if you read property, price and availability data and the only thing (if at all) you write back are reservation (requests). If you write prices or any other data that is more in a property management role, you are a Channelmanager to us (there is a guide for you too!).
Walkthrough: Steps for fetching Data and Reservation Workflow
So you've got a list of IDs from getState and want to read the required data for a typical property details page or a
search result listing.
You will find two main methods to call for this: getObjectDetails and getCategoryDetails. Both support bulk requests.
We usually suggest batches of 100 items at once. Batching requests is very important if you want to stay within the Rate Limits.
If you fail to do so you will have a hard time on huge property pools. In general, if you use bulk requests wherever possible
(and it is supported widely across the API) you will have no worries with the Rate Limits.
With bulk or batch calls you need to keep in mind that response time will rise, so make sure your timeout is sufficiently high for the size of the batch that you are requesting. Low timeouts are a common support issue when "receiving no response!". In fact there was a response, but the timeout was too low. Also keep in mind that the response times of the API may vary based on overall system load due to other consumers.
From getObjectDetails and getCategoryDetails you will receive a lot of details, including images, prices and so on.
Even a direct booking URL, if you choose to not implement your own reservation flow, you can use that link and just redirect
the potential guest to it. However, most partners choose to do their own implementation or integration with their existing
web interface.
Using the previous two methods you can also calculate a price range. It is expected to filter as much as possible at your end. While there are also batch calls for price calculation, these calls will have a hard time to keep up with the full traffic of your website / portal / etc..
The next thing, and maybe the first thing you want to use for filtering, is availability. You can fetch this data from
getOccupancy. You will receive "free" (available slots) for each category you've requested. Make sure to store this and
use it locally at your end, this also applies to the property data from the previous calls. Never do live requests for these upon
page visits. Instead, register for Push Events / Webhooks to get informed about changes and then only request the changed dataset.
You will notice that each property (object) has a map of features (properties) for things like e.g. Wi-Fi or Cooking Tools.
These features are completely free to configure and name at our end on a per-organisation level. To give you a chance to auto-detect
updates, we provide getProperties, which does nothing more than returning a per-organisation list of all available choices.
Using this call is completely optional as it does not contain any new data besides the full feature flag matrix, but it is useful
for automated checks.
At this point you have everything for object presentation. Use caching / your database where possible and keep data in sync
with Push Events. Also adding a weekly full sync beside the updates is always a good idea to have some failsafe option if
you missed some event for whatever reason. A nightly job to diff getState and process changes is also a reasonable idea
most of the time.
When you are done with importing the properties you can use setCategoryParam to push back a deeplink to the public
presentation page. This call also supports adding various status details. The minimum to implement would be to fill in
values for "details_url", but "cause_of_rejection" is also welcome (human-readable short error message) as are all the other
options too. The details_url value is displayed to the customer and host and makes life for both our support teams much
easier!
So in short...
| Method | Description |
|---|---|
getObjectDetails |
fetch base property / object data, images, etc. |
getCategoryDetails |
fetch category data and prices/seasons |
getProperties |
optional: fetch feature matrix |
setCategoryParam |
add URL and status details back to us |
After implementing the presentational part of the connection, the next step is proceeding to the reservation workflow.
When a page visitor is requesting more details or an offer for one specific property you use checkAvailability with the
desired travel date ranges for arrival and departure, the number of persons and so on. The result is a positive or negative
response and a base price calculation (not the final price as this would need more details).
IF the result is positive and the visitor wants to take the offer and proceeds in your reservation flow, the next call
is getBookingParameters. Here you can supply more details and also get a list of available bookable extras. Supporting
these (means: offering those to the customer) is highly suggested. While there are extras that must be booked, there
are also optional or included ones. The price of these options might scale per stay, person or night - or a combination.
As an extra you can use getVisitorstax to calculate the visitorstax if there is a visitorstax_zone node in getObjectDetails
which is not null. In that case we can calculate the tax for you. Note that the tax will be added to the reservation
regardless of what you do, if the system is configured to include it. You can see if the tax was included in the reservations
calls response with the calculation details. If you want to read the tax rules you
can use getVisitorstaxRuleset to fetch them. It is not suggested to recreate the calculation at your end, but for guest information
reasons the rules might be useful.
If the visitor and potential guest has made his decision, the next step is to actually do the reservation. There are two
calls for this: makeBooking and makeRequestBooking. You will find that beside the name both are using the identical
input and also deliver the same output. So why two different calls? The main reason is to make absolutely clear, that
a request booking needs confirmation and therefore needs to display a lot of different information to the guest upfront.
A requested booking can be rejected by the host (there is also an auto-reject mechanic if the host simply does not respond
within a few days, but average response times are much lower). Opposed to that makeBooking is true online booking and when you
receive a positive response the reservation has been made. You can filter out the different reservation modes by using
the feature flags in getState response, so you skip importing these properties all together or you can group them as
needed by you.
During the reservation flow there are a few things to keep in mind:
Now, after the reservation has been placed, you might want to track it. With the reservation response you received the booking_no, which is the reservations ID. You will want to store this number. You will also get some pricing details back, especially the brokerage_base_price is of use to you as this is the price which is used to calculate the brokerage amount you get.
If you add your own reservation numbers (and maybe communicate these to the guests as well), it is suggested to use
attachExternalBookingNo to your newly created reservation. This allows for easier support as we will display the number
or code to the backend users. It also simplifies communication for the support teams for everyday tasks.
Using Push Events for Bookings you can stay informed and use getBookingExtendedInfo to fetch the new Details, e.g. if
the reservation is cancelled, extended or modified in any way. This is of course reflected to the brokerage_base_price.
| Method | Description |
|---|---|
checkAvailability |
check free/occupied state and a first price |
getBookingParameters |
fetch full offer options |
calculateVisitorstax |
calc tax based on input |
getVisitorstaxRuleset |
reads the base rules for tax calculation |
makeBooking |
perform the reservation |
makeRequestBooking |
perform a binding request for a reservation |
attachExternalBookingNo |
add your own reservation Id |
getBookingExtendedInfo |
fetch reservation data for updates on events |
Channelmanager Guide
What is a Channelmanager in terms of API usage?
You are a Channelmanager if you write data on behalf of your customer, who is registered as host in our system. Typical Use-Cases include updating prices and/or availability. In most cases this includes reading new reservations using the API for further processing at your end. You do not write new reservations to the system, besides updating the availability.
Walkthrough: Steps for Data Updates
In a first step you should get the list of accessible properties from getState as mentioned in the "general" section of this
guides chapter. Only properties which are on this list are enabled for your account.
In general, when a host wants to connect his existing properties in your and our system you have to ask him for some information:
- his host id (Integer, "landlord_no" in the API) in our system
- the generated "authcode" (String, matching
[A-Z0-9]{8,}) provided by our system, once the access is enabled - the IDs (Integer) of the properties the host wants to map to your entities
You can make this process easier for the host when you just ask for the landlord_no and then use
getStateto fetch the properties, maybe even enriched by a followinggetObjectDetailscall to fetch the names of the properties for a more user-friendly display to chose from for the host.
Additionally, you need your API credentials.
With the numbers available you must then choose between two options:
- write availability per unit or...
- per category of units
If you chose to write per unit, you will need the getUnits call to fetch the units for the connected categories and add
them to your mapping database. You can then use setOccupancy to write availability per unit.
If you chose to write per category, you can simply use setCategoryOccupancy. In this case availability is automatically
split to units, e.g. they are filled up one after another. This is usually the better option unless you need more detailed
control over the process.
Note that you can not overwrite internal occupancy plan states (e.g. reservations). These are write protected. Depending on your access level, reservations are auto-blocked after cancellation to allow you to only free the timeslots if you wish to do so and if there is still availability.
If you are not allowed to write availability, the timeslot is freed after cancellation.
The next step is then to write season data and prices. This starts of with a call to setPrices to write the base occupancy,
age range limits, prices, seasons, extra costs per person and other things needed to calculate a price.
You will also want to use setCatering for catering options and seasons (independent of the ones in setPrices).
As a last step, use setAddons to write additional services to the system (e.g. extra linen or other optional services,
even mandatory services if you want them to be presented seperated from the base price or if they need to be paid per
person or night). Keep in mind that all the calls above support writing more than one set at a time.
Using Push Events for Bookings you can stay informed and use getBookingExtendedInfo to fetch the new Details for further
processing.
| Method | Description |
|---|---|
getUnits |
fetch the units for a category |
setOccupancy |
write occupancy per unit |
setCategoryOccupancy |
write occupancy per category |
setPrices |
write base pricing details and season data |
setCatering |
write catering options |
setAddons |
write addon options |
Content Provider Guide
What is a Content Provider in terms of API usage?
If you do not only update data on behalf of a host, but you are also creating the host and/or property in our system, then you are a Content Provider. From the API view you are just a Channelmanager with extended access, but since this role uses different APIs we decided to provide you with a more detailed guide. However, for the data update part the Channelmanager guide is fully identical for your role.
Walkthrough: How to add hosts and objects
For the creation of new hosts you need to use the Landlord-Management API.
First you can use getRegions to fetch a list of available regions. If you only create hosts in an organisation without
regions enabled, you will not find any matching results here. You can then skip the region code node when creating a host.
With getLandlordLanguages you can fetch a list of supported spoken language options for your host-creation or update call.
You use createLandlord to create a new host. For some fields you will need to have the IDs ready from our support (e.g.
marketing and organisation_no). If you want to create objects for this new host also, remember to enable that option
in the "services" section, otherwise you will not be able to do so using the API.
In the following response you must store the landlord_no, organisation_no and the authcode. Send the password to the host and do not store it yourself. If you do not want the host to have access to our Web UI, you can drop the password. You do not need it for API access.
If you want to update the host data you must use updateLandlord.
Using getLandlords you can fetch a list of "your" hosts if you need to.
At this point you have created a new host. The next step is to then create objects for this host, if you need to.
Before you create an object you must understand that there are three different states for objects.
- online - the object is fully deployed and is channeled to other portals as specified
- offline - the object is not available to the public, it is disabled
- review - the object has been created and needs to be reviewed before it is switched to online state (e.g. while you write prices and availability for it or add any other missing data)
Use makeObject to create a new object for an existing host. If you created the host, this is where the authcode comes in.
If you did not create the host, you need to request the authcode from the host. You will find other required data in getDistances and
getHolidayThemes for local distance options (e.g. distance to next store or beach) and configured topics you want to join
the new object to (e.g. beach holidays or city trips). Both options are customized per organisation. If you want to read all
features which are supported by the API you can use getProperties (note: this does not mean objects in this context) call from Core API.
Your newly created object will be unpublished in review state. Add/modify more data as needed and when done use moveOnline call
to switch the state to online.
To forget the
moveOnlinecall is a common error. So if you miss your objects in the different channels, check if it is still in review state. Note that you can always callmoveOnlineif you are unsure. It will simply do nothing if the object is already online.
To change any data for an object use updateObject call. Unlike the host update, you should only write data which has changed
as this is expected to happen more often.
Finally, if you want to remove the object from channeling, use moveOffline call. Note that object removal is only available to our
support and is only suggested if there are no open invoices, reservations and so on. Most likely you want to wait for some months
after moving the object offline and only remove it then.
After this point you will only want to update prices and occupancy from time to time. See the Channelmanager guide on how to do so. The only difference is that you don't need the host to supply the required IDs if you created the host yourself.
Online Payment Workflow
Normally, all properties are working with invoices and bank transfer, but besides that we support paying with PayPal directly to the host or destination. Currently, PayPal is the only supported provider, but this approach is also applicable to future implementations.
Money is never transferred to our accounts, we only generate payment links with the host or destination as direct target, therefore any payment problems related to the used provider (e.g. PayPal) must be resolved with the receiving party (host etc.) directly. We especially have no option to refund or check any payment related stuff.
You can detect support for online payments in the response of getCategoryDetails in the fields onlinePaymentSupported.
This field is also present in the responses from makeBooking and makeRequestBooking.
If a property is supporting this payment method and the guest is choosing to use it, you can call generatePaymentProviderLink to get
a proxy URL for the payment. You will need to supply the booking_no, which step of the payment you want to process (with fresh reservations this should
be "initial") and a redirect URI where the customer will be sent back after the payment.
With the response you receive a paymentUri to which you can redirect the user directly or you can use this URI to integrate the dialog directly
in your website. There is also a flag present which tells you which provider will be used (can not be chosen).
If the guest fails to make the payment by mistake or any other reason, you can always request a new payment link. However,
after the reservation has been done we provide a little login protected area https://www.optimale-praesentation.de/ibe/status where
the guest can generate the payment links in self-service. Hosts with Online Payment Support do mention this section in the confirmation email,
so you do not need to do this, unless confirmation mails have been suppressed.
Length of Stay (LoS) API
What is LOS API
Length-of-Stay or LOS API format displays the price and availability of a property, for each person, starting from the specified date (startDate) and goes the given number of days in the future (daysInAdvance). For each day and each person the property defined, it shows the cost and availability for the specified number of nights (nights).
Example API response
{
"2024-07-09": {
"1": "120,240,360,0,0",
"2": "130,260,390,0,0"
},
"2024-07-10": {
"1": "120,240,360,0,0",
"2": "130,260,390,0,0"
}
}
Request parameters
| Parameter | Explanation |
|---|---|
| catNo | category id (PriUntNr) of the property |
| startDate | from which date to start calculating the prices, in format Y-m-d. Min value is today. |
| nights | number of nights for every day. Min value is 1, max 50. |
| daysInAdvance | number of days in advance from starting date. Max value is 600. |
| channelID | provided API key |
There are also optional parameters:
- useMaxOccupancy - true or false (default), specify whether to use max occupancy or max adults for the number of persons to calculate the price for
- baseRate - true or false (default), if true then don't add cleaning fee, booking fee and required addons to price calculation
- features - punchmaps that will be used in calculating if stay is allowed for a given date. If nothing is sent all punchmaps will be used. Allowed values are:
- add - arrival and departure days
- dba - days before arrival
- mrd - minimum residence
- occ - occupancy
- occ-extra - occupancy + days between bookings + min gap size
Examples
To get the LOS prices for a single property send a GET request to /list.php with parameters:
api_path/list.php?catNo=12345&startDate=2021-04-09&nights=40&daysInAdvance=300&channelID=provided-api-key
Rate limits
LOS API has fixed window policy, with allowed 295 requests per minute.
How the final price is calculated for one night
The final price for a single night and person has the following parts:
- base price - basic price per night
- required addons - e.g. bed linen, towels...
- booking fee - defined in OP as a portal provision
- discount days (days off) - similar to long stay discount, the guest gets a free night if he stays for the defined amount of nights
- cleaning fee - final cleaning that is done after the guest leaves
- long stay discount - price discounts for longer stays
- short stay fee - fee added to the price for shorter stays
Example stay:
- start date: 2024-07-10
- nights: 3
- base price: 60
- required addons: 20
- booking fee: 15
- short stay fee: 30
- cleaning fee: 40
which would be a total of 285 Euros.
Useful things to know
- LOS API is used both for price and availability calculation.
- The price can't be calculated for children, only for adults.
- Last minute discounts also can't be calculated
Webhooks / Push Events
Introduction
The system provides Push Notifications of several types for events in real-time. You can register your Listener to these events. In case of an event the system will call your Listener and send you some details (object no., event type and so on). You will be able to do whatever action you find suitable for the event. In most cases, this will be an update operation, reading the new data using the interface and updating your own database accordingly. All events are sent via a HTTP call to any URL you provide (which must be reachable via the internet, obviously). The called URL will be extended with additional GET key-value pairs. If your URL already contains GET data our data will be appended.
This process was intended to replace the otherwise needed polling of our system by connected services, since there are huge drawbacks in choosing polling over push events. The main argument is the timing. While there are only a few microseconds (plus network latency) between an event and the notification, polling requires you to use a wider timeframe for the single polling events. This can lead to several minutes or even hours delay. Especially in case of occupancy management this is not acceptable and produces a high risk of bookings with no available room. This is why push events for bookings are mandatory for channelmanagers.
Events
Bookings
This event gets fired in case of any new booking, any change to a booking, or any cancellation. It also fires for options and other kinds of reservations. At which point you receive notifications depends on your role. If you are a channelmanager, you will receive all events for your connected objects/units. It is very likely that you will use the provided informations to fetch booking details and update the other connected systems accordingly. If you are a sales channel, you will only get events for bookings you've made yourself via our interface. You can then update your own database and keep track of your bookings.
Occupancy
This event will get fired each time the occupancy gets updated per unit. It is very common to receive a whole bunch of events of this type at (nearly) the same time, for each unit affected by the change. If you are a channelmanager you are not required to listen to this event and it is not very likely that you receive any relevant notifications. This event is mainly designed for sales channels to update their own occupancy table, since they do not receive booking events of sources other than themselves.
Data
This event is in fact a combination of events. It gets fired if any landlord or object data gets changed or updated. This event breaks down to image changes, season/prices changes and simple data changes. This event is solely for sales channels to update their data in real-time, without the need to run a full resync for all objects. You do not need to listen to this event, if you don't want to use real-time updates.
Cancellation Policy (Change)
Cancellation policy events will be fired if your channel is configured for different cancellation policies. This can happen on channel, organisation or landlord level and will result in an event carrying the corresponding keys.
Webhook Example
Your Listener URL
https://myservice.com/listener/doSomething.php?somePara=1
URL we will send a GET request to in case of an event
https://myservice.com/listener/doSomething.php?somePara=1&extraPara=1&extraPara2=1&[...]
Booking Event
This is triggered whenever there is a new or changed reservation, covering the whole lifecycle of a reservation, including cancellation.
Cancellations are just reservations in a different state. They are not handled in a separate way.
Attached GET Parameter
| GET Key | Value | Type |
|---|---|---|
| booking_no | ID of the booking | Integer |
| keycode | access key | String |
| eventtype | booking |
String |
Expected Actions
Use the provided data to call getBookingExtendedInfo in Core API. You will notice that the two
required values for the function call are what is provided with the event call.
You can then read the full booking details using this method.
The access key is generated only once per reservation, so it is a good idea to save it and then use it to fetch updates when needed. However, if you need a huge amount of reservations you are better off with a method capable of bulk requests.
Example
GET https://somewhere.here/some/path/?booking_no=1234567&keycode=d93558b1901031862a75ab6b2a36f04b&object=1234&eventtype=booking&
Occupancy Event
This is triggered per year and per unit for any change in the occupancy.
Attached GET Parameter
| GET Key | Value | Type |
|---|---|---|
| catgeory_type | privat or gewerblich |
String |
| category_no | Id | Integer |
| unit_no | Id | Integer |
| eventtype | bplan |
String |
Expected Actions
Use the interface function getOccupancy to update your data for the submitted category/unit.
Example
GET https://somewhere.here/events/ussop?category_no=1234&category_type=privat&unit_no=1234&object=1234&eventtype=bplan&
Data Event
This is triggered for changes in property data (name, classification, rooms, etc.), property prices/seasons and images. It is pretty much a generic event that any base data has changed.
Attached GET Parameter
| GET Key | Value | Type |
|---|---|---|
| catgeory_type | privat or gewerblich |
String |
| category_no | Id | Integer |
| object_no | Id | Integer |
| eventtype | data or pricesor images |
String |
Expected Actions
Use the event type to determine what has been changed and use the required functions to
fetch the changed data (e.g. from getObjectDetails / getCategoryDetails ).
Example
GET https://somewhere.here/events/ussop?category_type=privat&category_no=1234&object_no=1234&object=1234&eventtype=prices&
Cancellation Policy Event
This is triggered for changes in cancellation policies on channel, organisation or landlord level. Notice: This is NOT a reservation cancellation event. This is a data/configuration change. You will only receive this, if you are configured to use different policies.
Attached GET Parameter
| GET Key | Value | Type |
|---|---|---|
| override_policy_name | the new policy code | String |
| landlord_no | Id (optional!) | Integer |
| organisation_no | Id (optional!) | Integer |
| eventtype | cancellationpolicy |
String |
Expected Actions
Update policy at given level accordingly. Do other updates as needed.
Example
GET https://somewhere.here/events/ussop?override_policy_name=booking_491&landlord_no=1234&organisation_no=1234&eventtype=cancellationpolicy&
Clients
PHP Client
Note that the PHP clients might need additional PHP extensions to be loaded for SOAP and XML support.
| PHP Version | Downloadlink | Status |
|---|---|---|
| 7.x | Download | basic connection only |
| 5.6 | Download | basic connection only |
Code Snippets
Here you can find code snippets for some common problems.
Core API getState with WSSE and PasswordDigest
Important: Replace
VERSIONwith the current API version you are using!POST https://www.optimale-praesentation.de/comm/universal/?v=VERSION HTTP/1.1
Accept-Encoding: gzip,deflate
Content-Type: text/xml;charset=UTF-8
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:urn="urn:USSOP">
<soapenv:Header>
<wsse:Security soapenv:mustUnderstand="0"
xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"
xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
<wsse:UsernameToken wsu:Id="UsernameToken-6A83B9CE21426F733316534947724901">
<wsse:Username>SOAP_USER_NAME</wsse:Username>
<wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordDigest">
PUT_PASSWORD_DIGEST_HERE
</wsse:Password>
<wsse:Nonce EncodingType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary">
USED_NONCE
</wsse:Nonce>
<wsu:Created>2022-05-25T16:06:12.488Z</wsu:Created>
</wsse:UsernameToken>
</wsse:Security>
</soapenv:Header>
<soapenv:Body>
<urn:getState>
<param_getState>
<category_type/>
</param_getState>
</urn:getState>
</soapenv:Body>
</soapenv:Envelope>
This is an example call of getState with WSSE headers for authentication using PasswordDigest mode.
Core API getObjectDetails call with multiple objects
Important: Replace VERSION with the current API version you are using!
POST https://www.optimale-praesentation.de/comm/universal/?v=VERSION HTTP/1.1
Accept-Encoding: gzip,deflate
Content-Type: text/xml;charset=UTF-8
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:urn="urn:USSOP">
<soapenv:Header>
<wsse:Security soapenv:mustUnderstand="0"
xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"
xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
<wsse:UsernameToken wsu:Id="UsernameToken-6A83B9CE21426F733316534947724901">
<wsse:Username>SOAP_USER_NAME</wsse:Username>
<wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordDigest">
PUT_PASSWORD_DIGEST_HERE
</wsse:Password>
<wsse:Nonce EncodingType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary">
USED_NONCE
</wsse:Nonce>
<wsu:Created>2022-05-25T16:06:12.488Z</wsu:Created>
</wsse:UsernameToken>
</wsse:Security>
</soapenv:Header>
<soapenv:Body>
<urn:getObjectDetails>
<param_getObjectDetails>
<!--1 or more repetitions:-->
<object_no>123</object_no>
<object_no>456</object_no>
</param_getObjectDetails>
</urn:getObjectDetails>
</soapenv:Body>
</soapenv:Envelope>
SOAP Body with native parameters (non-XML content)
Example of Core API cancelBooking (Request Body only)
<soapenv:Body>
<urn:cancelBooking>
<booking_no_cancelBooking>123456</booking_no_cancelBooking>
</urn:cancelBooking>
</soapenv:Body>
Some calls only use native SOAP parameter types, especially when the parameter structure is very simple and XML input would be over-the-top. In such cases the values are submitted directly.
PayPal Integration
Notice: This snippet is deprecated by Paypal. The solution is to just open the Paypal Payment URL in the same or another window that will get redirected back to you, just like with the below snippet, but without the previous payment method selection in you website.
<!-- put this in HEAD -->
<script type="application/javascript" src="https://www.paypalobjects.com/webstatic/ppplus/ppplus.min.js"></script>
<!-- place somewhere in BODY (or call after load) -->
<script> var ppp = PAYPAL.apps.PPP({
'approvalUrl': '___API_GENERATED_URI_GOES_HERE___',
'placeholder': 'ppplus',
'mode': 'live',
'country': 'DE', // modify as needed: user county, will directly influence available payment options!
'language': 'de_DE', // modify as needed: user language
'buttonLocation': 'inside',
'showPuiOnSandbox': true,
'showLoadingIndicator': false,
'useraction': 'commit',
'thirdPartyPaymentMethods': [],
}); </script>
<div id="ppplus" style="width: 100%;"></div>
We support PayPal Payment Link Generation over the API for reservation workflows, if PayPal Support is enabled for the property and host. However, if you want to build a customer facing UI, you might find this code snippet useful for HTML/JS UI.
This code will generate a javascript based payment method selection list, for embedding in your website. After selection has been made the user will be redirected to PayPal. Read the official PayPal Documentation for further explanation. We do not provide support for this snippet.
Changelogs
Core API Changelogs
Version 1.74
- Changes to
getCategoryDetails()- Added new optional string element
general_cleaning_external_id.This element specifies general cleaning external id.
- Added new optional string element
- Changes to
getBookingExtendedInfo()- Added new optional string element
general_cleaning_external_id.This element specifies general cleaning external id.
- Added new optional string element
- Changes to
getAllReservationObjects()- Added new optional string element
general_cleaning_external_id.This element specifies general cleaning external id.
- Added new optional string element
Version 1.73
- Changes to
makeBooking()- Added new optional element
booking_comtoexternal_price_detailswhich contains Booking.com-specific metadata: genius_rate(boolean, optional): Indicates if this is a Genius ratepromotion_id(string, optional): Booking.com promotion identifier. Must contain only lowercase letters (a-z), numbers (0-9), and hyphens (-)rate_id(string, optional): Booking.com rate identifier. Must contain only lowercase letters (a-z), numbers (0-9), and hyphens (-)rewritten_from_name(string, optional): Original name before rewritingtotal_price_hotel(float, optional): Total price for hoteltotal_price_guest(float, optional): Total price for guestextra_components(optional): Container for additional price components, each containing:type(string, required): Either "guest" or "hotel"name(string, required): Component nameamount(float, required): Component amountcurrency(string, required): Currency codeincluded(boolean, required): Whether included in base priceper_night(boolean, required): Whether charged per nightper_person(boolean, required): Whether charged per personpercentage(boolean, required): Whether amount is a percentage
- Added new optional element
Version 1.72
- Changes to
getBookingExtendedInfo()- Added new optional element
cancellation_policywhich contains:override_policy_name. Override policy name (e.g., "booking_168", "airbnb_firm_14").rule_summary. Summary of the cancellation rule in German (e.g., "direkt 50% nach Buchung", "flexible 7 days"). This is a short, human-readable label describing the rule in brief.rule_descriptions_deandrule_descriptions_en. Container for descriptions of the cancellation rule which contains:description. Description line
- Added new optional element
Version 1.71
- Changes to
setAddons()- Added new optional element
commissionable. Can be set to eithertrueorfalse.
- Added new optional element
Version 1.70
- Changes to
getBookings()- Added new parameter
broker. Hash of the source channel identifier. - Added new parameter
booking_type. To display the booking type whether it's Guest or Host booking.
- Added new parameter
Version 1.69
- Added
getCancellationFee() - Changes to
cancelBooking()- Added new parameter
expected_cancellation_fee
- Added new parameter
Version 1.68
- Changes to
setPrices()- Added new optional element
general_cleaning_fee_external_id. This element specificed external id for general cleaning fee.
- Added new optional element
Version 1.67
- Changes to
getCategoryDetails()- Added new element
gap_optimization_min_stayatperiod. This element specified the required minimum stay to close a gap in case the gap optimization is active. - Added new optional string element
external_idto eachaddonelement, placed after the name element.This element specifies external id for addon service.
- Added new element
- Changes to
setPrices()- Added new optional element
gap_optimization_min_stayatrange. This element specified the required minimum stay to close a gap in case the gap optimization is active.
- Added new optional element
- Changes to
setAddons()- Added new optional element
external_idatsetAddonsInputType. This element specifies external id for addon service. - Added additional error messages and error code for invalid external_id (error code 69)
- Added new optional element
- Changes to
getBookingExtendedInfo()- Added new optional string element
external_idto eachaddonelement, placed after the id attribute.This element specifies external id for addon service.
- Added new optional string element
- Changes to
getAllReservationObjects()- Added new optional string element
external_idto eachaddonelement, placed after the id attribute.This element specifies external id for addon service.
- Added new optional string element
- Changes to
getBookings()
- Added new optional string element
external_idto eachaddonelement, placed after the id attribute.This element specifies external id for addon service.
- Added new optional string element
Version 1.66
- Changes to
getCategoryDetails()- Added new optional element
discount_pricebasisatdiscounlist. This element specifies price basis for discount.
- Added new optional element
Version 1.65
- Changes to
getCategoryDetails()- Added new optional element
discountlist. This element contains a list of discounts that can be applied to an object.
- Added new optional element
- Changes to
makeBooking()- Added new optional element
discount. This element contains the discount information of the to be applied discount to the booking
- Added new optional element
- Added additional error messages.
Version 1.64
- Changes to
getLastminute()- Added new optional element
early_bird_daysto response. These are the minimum days before the arrival date when this offer should be listed. - Added new optional element
lastminute_daysto response. These are the maximum days before the arrival date when this offer should be listed. - Added new optional element
maxDaysApplicableto response. These are the maximum number of days the discount can be applied. If the booking period exceeds this duration, the discount will only apply to the specified maximum days. - Made element
offer_traveldates_fromoptional. - Made element
offer_traveldates_untiloptional. - Made element
removeOfferBeforeoptional.
- Added new optional element
Version 1.63
Changes to
getBookingExtendedInfo()- Added new parameter
totalsunder addons section to display addon total values, categorized by place of payment. - Added new parameter
markupto display markup fee based on type shortstay. - Added new parameter
rebateto display discount values applied on booking based on types longstay and discount. - Added new parameter
original_bookingdateto display the date on which the booking is created. This differs frombookingdate, which is the date of the last update to the booking. - Added new parameter
booking_typeto display the booking type whether it's Guest or Host booking. - Added new parameters
cancellation_feeandcancellation_reason(Only available for selected users)
- Added new parameter
Changes to
getBookings()- Added new parameter
original_bookingdateto display the date on which the booking is created. This differs frombookingdate, which is the date of the last update to the booking. - The following parameters are only available for selected users:
- parameter
agency_priceto display the agency price of the booking. - parameter
agency_price_advanceto display the part of the agency price that's paid in advance (as opposed to on-site). - parameter
rentto display the rent of the booking. - parameter
visitors_taxto display the visitors tax of the booking. - parameter
travelersto display traveler details relevant for the visitors tax. - parameter
tagsto display the tags of the booking and guest. - parameter
marginto display the margin of the booking. - parameters
notes,check_in_noteandcheck_out_noteto display notes related to the booking. - parameter
guestappto display if the user logged in at least once.
- Added new parameter
Version 1.62
- Changes to
getCategoryDetailsInternal()- Added new parameter
addBookingFeeTypeto controls the display of booking fee types as calculation mode under booking fee section.
- Added new parameter
Version 1.61
- Added
getObjectRatings()- This method now returns the censored name of the guest,
name, that has done the rating. Only available for selected users
- This method now returns the censored name of the guest,
Version 1.60
- Added
getObjectGroupDetails()- This new method returns object groups with the
object_noof the objects assigned to the object group by the organisation (TO) andobject_group_no(optional).
- This new method returns object groups with the
Version 1.59
- Added
getPaymentOptions()- This new method returns payment options selected by the organisation (TO) and host.
Version 1.58
- Changes to
getCategoryDetailsInternal()- Added new parameter
$addImportIdto controls the display of external_object_no as import_id
- Added new parameter
Version 1.57
- Changes to generatePaymentProviderLink()
- added new parameter
paymentProviderwill be use it to identify the payment provider e.g. PayPal, Stripe.
- added new parameter
- Changes to makeBooking()
- added new element
paymentProviderListto makeBookingResponse() response which contains a list of available payment providers for the booking.
- added new element
- Changes to getCategoryDetails()
- added new element
paymentProviderListto getCategoryDetailsResponse() response which contains a list of available payment providers for the category.
- added new element
Version 1.56
- Changes to
getCategoryDetailsInternal()- Added new parameter
showRoomWithoutBedto controls the display of rooms without assigned beds.
- Added new parameter
Version 1.55
- Changes to
getBookingParameter()- Added
paymentScheduleelement to getBookingParameter() response. This element contains concrete date and amount information for the necessary payments.
- Added
Version 1.54
- Changes to
getObjectDetails()- added new optional element
national_registration_noto response
- added new optional element
Version 1.53
- Added
getObjectRatings()
This new method returns object rating to view ratings for products or services, including recommendations and feedback. It supports multiple rating aspects (e.g., features, location) and allows responses to reviews.
Version 1.52
- Changes to checkAvailability()
- added new optional element
is_gap_optimizedto checkAvailability() response
- added new optional element
- Changes to checkMultiAvailability()
- added new optional element
is_gap_optimizedto checkMultiAvailability() response
- added new optional element
- Changes to getBookingParameter()
- added new optional element
is_gap_optimizedto getBookingParameter() response
- added new optional element
Version 1.51
- Changes to getCategoryDetails()
- added new element
gap_optimizationto elementperiod
- added new element
- Changes to setPrices()
- added new optional element
gap_optimizationto elementrange
- added new optional element
Version 1.50
- Changes to getObjectDetails()
countryis now compatible with country type used in other methods
- Country type enum was added in documentation for:
- getAllReservationObjects()
- getBookingExtendedInfo()
- getBookings()
- getInvoiceListing()
- getMyBookings()
- getMyListedBookings()
Version 1.49
- Added getObjectCategoryTree()
This new method returns a tree data structure that can be configured in the back end of the SECRA Destination system.
Version 1.48
- Changes to getState()
- add new optional element
internal_object_id
- add new optional element
Version 1.47
- Add new place of payment element to the following API methods
- getAllReservationObjects()
- getBookingExtendedInfo()
- getBookingParameter()
- getBookings()
- getCategoryDetails()
- getInvoiceListing()
- getMyBookings()
- getMyListedBookings()
- setAddons()
- setPrices()
Version 1.46
- Changes to setPrices()
- added new optional elements
general_cleaning_feeandgeneral_depositwhich will be used ifcleaningordepositis not set in the range element
- added new optional elements
Version 1.45
- Changes to getBookingParameter()
- added new optional element
cleaning_feeto elementcalculation_details
- added new optional element
Version 1.44
- Changes to getCategoryDetails()
- added new optional element
marginPercentageto response
- added new optional element
- Changes to setPrices()
- added new optional element
marginPercentageto elementrange
- added new optional element
Version 1.43
- Changes to makeBooking()
- added new optional element
price_difference_informationto elementexternal_price_details
- added new optional element
Version 1.42
- Changes to getBookingExtendedInfo()
- added new optional element
external_booking_noto response - added new optional element
booking_feeto response - added new optional element
cleaningto response - added new optional element
visitorstaxto response - added new optional element
external_object_noto response - added new optional element
free_text_hostto response - added new optional element
additional_feeto response - added new optional element
channel_nameto response - added new optional element
calculation_detailsto response - added new optional element
visitorstax_includedto elementcalculation_details - added new optional element
cleaning_fee_includedto elementcalculation_details - added new optional element
catering_pricesto response - added new element
price_overallto elementcatering_prices - added new element
cateringsto elementcatering_prices - added new optional element
catering_detailsto elementcaterings - added new element
idto elementcatering_details - added new element
fromto elementcatering_details - added new element
untilto elementcatering_details - added new element
price_adult_per_dayto elementcatering_details - added new optional element
price_children_per_dayto elementcatering_details - added attribute
price_per_unitto elementaddon - added attribute
price_overallto elementaddon
- added new optional element
Version 1.41
- Changes to getUnits() and getState()
- added new optional element
external_id_listto response
- added new optional element
Version 1.40
- Changes to getCategoryDetails() and getBookingParameter()
- added attribute "general_class" to element "name" of "addon"
- if attribute "general_class" is set then the addon is assigned to this class of addons
Version 1.39
- setCategoryOccupancy() now supports multiple category elements at once, allowing for less call usage
- added a maximum year for which data will be accepted (else: skipped silently), which is the current year plus 3
- breaking change: the "days" element has been moved inside the category node!
- Requests not matching the new syntax will trigger an error
- the maximum number of categories per call is 100
Version 1.38
- added setLandlordBookingSetting() which allows you to edit the cancellation policies of a Landlord.This is a method for channelmanagers only.
Version 1.37
- getCancellationPolicy() now returns named policies where applicable. If there is a named policy set, it will be added to the policy node. It is intended to override the other given policies which then only serve as a fallback. If there is no policy present, either none has been chosen or there are no named policies for your user (which is most likely).
Version 1.36
setExternalContentDeeplink() has been removed
- use setCategoryParam() with type "details_url" instead
- previously / with old method written data will be erased / transferred in a later step, currently both sources are merged for display
added setCategoryParam() method for adding multiple information to an object
- you can now add multiple URL types, the object id on your platform, online / import status and cause for rejection (if any) using the API, see API docs for full list.
- Not all information is currently displayed to the (end-)user, but we might do so later.
- Using this is fully optional but reduces support requests as more data is available directly to the user
added option to getState() to filter response to one specific category_no when using category_type filtering
added RateLimit headers X-RateLimit-* (global) and X-Write-RateLimit-* (only selected calls), note that the global limit uses a sliding-window method with burst option, but the remaining count is calculated using the permanent maximum without burst. Bursts will however lower the remaining count, so if you go for bursts the remaining count will not reflect the true ratelimit anymore (as this wouldn‘t fit the spec anyway).
Version 1.35
- setExternalContentDeeplink() has been removed
- use setCategoryParam() with type "details_url" instead
- previously / with old method written data will be erased / transferred in a later step, currently both sources are merged for display
- added setCategoryParam() method for adding multiple information to an object
- you can now add multiple URL types, the object id on your platform, online / import status and cause for rejection (if any) using the API, see API docs for full list.
- Not all information is currently displayed to the (end-)user, but we might do so later.
- Using this is fully optional but reduces support requests as more data is available directly to the user
Version 1.34
- Changes to getCategoryDetails()
- Updated roomType and bedType field. Added field restriction on both fields
- possible roomTypes: “single_room”, “double_room”, “shared_room”, “family_room”, “junior_suite”, “apartment”, “studio”, “suite”, “log_cabin”, “a_frame_building”, “tepee_tent”, “hay_bed”, “triple_room”, “bed_rooms”, “living_and_bedrooms”
- possible bedTypes: “single_bed”, “french_double_bed”, “double_bed”, “large_double_bed”, “bunk_bed”, “sofa_bed”, “futon”
- standardize field names
- roomType -> room_type
- maxPersons -> max_persons
- bedType -> bed_type
- bed descriptions are in english only now
- added “single_time” option to “check_in_time” and “check_out_time” as an alternative to the “time_window” option. In combination with the “single_time” option a check-in can only have a “from”, and a check-out only a “to” time.
Version 1.33
- Added check-in/out times to getCategoryDetails() as “check_in_out_times” which
contains “check_in_time” and/or “check_out_time” with
- “option” - ex. “time_window” or “around_the_clock”
- “from” - string with the format ”HH:mm:ss”
- “to” - string with the format ”HH:mm:ss”
Version 1.32
- Changes to getCategoryDetails()
- Added room information which contains:
- “roomType” as string ex. “Schlafzimmer” or “Wohn-/Schlafzimmer”
- “size” as float
- “persons” as positive integer
- “beds” which contains the bed information
- Moved bed information into the room information
Version 1.31
- added optional fields "external_object_id" and "external_landlord_id" to getState response
Version 1.30
- added new field for bed information to getCategoryDetails()
- contains bed_type as string ex. “Einzelbett” or “Doppelbett”
- contains quantity as positive integer
- contains description as string
Version 1.29
- added new method for reading the cancellation policy of any object in a machine-readable
format (previously there was only a textual form in getTerms() )
- cancellation policy is defined as a set of rules (selected by the days before arrival setting) and a base setting which applies, when no other rule matches
- it is possible to not have any explicit cancellation policy set and only define rules in getTerms(), though this is not suggested. However, this means that the absence of a policy does not mean that there is none.
- cancellation policies are defined by the host and / or the organisation she/he belongs to, the rules are set per object-type and each host, so do not assume a policy because it was valid for another host!
- added new value "is_inclusive" on catering_prices of method "getBookingParameter", which shows explicitly that an addon is inclusive while booking.
Version 1.28
- added cancelBookingCustom() call which allows setting a different cancellation fee
- not available to all users
Version 1.27
- added new optional field "external_landlord_id" to getObjectDetails() response
Version 1.26
- added support for online payments
- added method "generatePaymentProviderLink()" which should be used after the
booking has been successful (requires the booking_no)
- the response will state which provider is used (currently only PayPal is supported, but this might be extended)
- you can redirect the user to the payment link directly or use a more customized approach (e.g. using a PayPal JS integration)
- after the payment, the user will be redirected to any page/url including GET params you specify, so you can display a success or error message
- payments will be tracked in the system's payment history on success
- you can generate links for the initial payment or the final payment, usually you will only use the initial payment
- online payments require specific configurations by the user and is enabled on a per-object basis, so it will not be widely available at launch
- added flag to makeBooking() response to indicate whether this object supports an online payment method or not (onlinePaymentSupported)
- added flag to getCategoryDetails() response to indicate whether this object supports an online payment method or not (onlinePaymentSupported)
- there is a PayPal integration example in the docs (common > PayPal Integration Example)
- added method "generatePaymentProviderLink()" which should be used after the
booking has been successful (requires the booking_no)
- removed the documentURL node from makeBooking() response as it is not supported anymore
- added videos to getObjectDetails() and getCategoryDetails() responses using Vimeo and/or YouTube
Version 1.25
- added new optional field "external_id" to getUnits() response
Version 1.24
- added new getVisitorstaxRuleset()
- contains visitorstax rules for new extended mode
- adds calculation rules to organisation which do not have simple mode rules
- calculation rules are split into
- region
- season
- zone
- guest category
- price rule
- calculation has to evaluate the rules to compute a tax value for every day/night of the stay
- before you think of implementing this by yourself (and we wouldn‘t suggest to do that) look at calculateVisitorstax() method mentioned later!
- added new field "visitorstax_zone" in getObjectDetails() for matching with the above rules
- added calculateVisitorstax() method for extended mode calculation to help you with
the implementation of the complex ruleset – be aware that this is currently only
computing the new mode, not old tax settings
- you can identify old v.s new mode by the visitorstax_zone key being present in get ObjectDetails()
- calculation of the visitorstax is using minimum data, so real world tax might change due to more complex scenarios which can not be calculated upfront, e.g. if there are tariffs with additional requirements like student id or other things that are unknown at a pre-reservation stage. Be sure to communicate this to the guest (e.g. "taxes are estimates based on your current settings, final results may vary").
- This method does no saving in any way, it simply takes your input and computes a number.
- In case you tried to retrieve the tax amount for a legacy mode object you will
get
<error>true</error>in the response. This also applies when there is not enough data to compute the tax, either because you missed out on some data or because the tax settings by our user are incomplete or missing. Be aware that the calculation depends on the user providing data, if you do not get a response this might indicate we have no setup yet. You can easily verify this by looking at the complete ruleset response. In such cases the system will not apply taxes in the reservation process too. - anyway: getBookingParameters() will return the tax amount – old and new calculation model - so if you do not precalculate taxes for your search you will not need to change anything.
Version 1.23
- added flags element to getState response, flag values are non-public at this time
Version 1.22
- added internal id numbers for accounts with sufficient access to the object (typically PMS)
Version 1.21
- added booking fee calculation details under getCategoryDetails()
- Note: Booking fee will be calculated on booking, but you can use this details to calculate the fee upfront.
- Added lastminute discount details to checkAvailability requests:
- if the result is using a lastminute offer (at least partial)
- value of discount (discount is already included in price)
- the ad text the host has added to the lastminute offer, e.g. including specials (if any)
- this text is not parseable, it is added in german by the host itself, decide on your own if you want to display the text
- removed setObjectDetails() from Core API, this functionality is now superseded by the Objectdata API
Version 1.20
- added new fields "unifiedName" in getObjectDetails() and getCategoryDetails() for use-cases where the regular user-chosen name of the object is not sufficient
Version 1.19
- added base64 encoded pdf version of booking terms and cancellation policy in getBookingTerms()
Version 1.18
- added child_rebate rules in getCategoryDetails(), if any set
- added broker id to response of getBookingExtendedInfo()
- fixed an error in XSD in getCategoryDetails() visitortax segment where "years" and "year" elements had been required, but should have been optional
Version 1.17
- getObjectDetails()
- now contains a new node "holidaytopics" with all attached topics this object belongs to
- added paymentSchedule to objectdetails which contains payment steps (if known to the system)
- added local registration number which is required for e.g. Spain
Version 1.16
- makeBooking / makeRequestBooking
- the calculated initial payment for the guest was added to the responses of these methods
Version 1.15
This version adds landlord languages, cleaning_fee_included tags and a field for external prices.
- getObjectDetails
- added languages list to contact attribute which contains a list of languages spoken by the customer
- getBookingParameter
- added "cleaning_fee_included" flag which indicates if the price includes the cleaning fee or not
- makeBooking
- added new request field "external_price" which allows you to send us a custom price, which should obviously be higher than the calculated price
Version 1.14
This version adds visitortaxes, md5 hashes for images, and addon counts.
- getCategoryDetails
- added vistortaxes, which, if the field "add_to_price" has been set to true, has to be added to the booking, otherwise it's just an informational value which you can display to your customer. The tax is calculated per day and in EUR.
- Added md5 attribute to image tag, which is calculated on the file content, so you can check if the image has to be re-downloaded
- getObjectDetails
- Added md5 attribute to image tag, which is calculated on the file content, so you can check if the image has to be re-downloaded
- getBookingExtendedInfo, getBookings, getAllReservationObjects,
getMyBookings, getMyListedBookings
- Added count and basis attribute to addon tag which represents how often a certain addon has been booked and per which basis the price is calculated and therefore the number of addons (e.g. one per night or on per stay). Possible values of the "basis" field are: per day, per person, per visit or per person per day
Version 1.13
This version introduces some booking optimizations besides multiple new channelmanager options.
- gap optimized booking
- important: while this feature is included in this API version it is not yet fully functional for channelmanagers, we will enable this feature a few days after the release of this API version, however as a pure sales channel you can already implement this.
- booking can now be declined if the landlord specifies a minimum gap after each booking that is either fulfilled or exceeded or there is no gap at all (this is to prevent random bookings from producing free-day fragmentation with such small fragments that the remaining fragments are very unlikely to be sold)
- the landlord is free in his choice of the exact value of the minimum gap
- you receive the selected value (if any) in the price table in getCategoryDetails (field "minimum_gap_size")
- if you try a booking on an object with this restriction in place and you don't meet the requirements the booking will be declined (e.g. the request to checkAvailability will result in a negative response)
- channelmanagers will be able to write this new value via setPrices() (field "gapsize")
- the unit for gapsize are days (for getCategoryDetails and setPrices too)
- setAddons and setCatering
- this is a channelmanager only change, we are now giving you the full features we introduced in v1.12 for the normal channels, addon and catering changes were mapped using setPrices until now, but since we introduced many more new features to this two topics we are now releasing two new methods for writing addons and catering. This means using setPrices() for writing addons and catering is now unsupported.
- new features:
- addons and catering now have their own date ranges and are independent of pricing seasons
- addons can now be mandatory for booking
- addons can be booked multiple times (and you can specify a maximum)
- addons and catering have a base state which is valid if there is no rule defined
- you can remove a rule by setting it's state to "base"
- you can remove an addon and a catering option completely by setting it to unavailable and remove all future rules which might have exceptions from that state (it is sufficient to define a single rule with state = "base" and a very long time range to remove multiple previous exception rules)
- it is highly recommended to have a look in our backend to compare the UI and the API for understanding
- setObjectDetails
- this is channelmanager only: you can update the object title and its description using the API (previously you had to ask our support to do so)
- this method will be extended in the next versions with more options
- different minor changes and bugfixes, some additional error messages
Version 1.12
- getCategoryDetails()
- Addons and catering options have been removed from the pricetable element.
- Addons and catering now have standalone nodes (addons, catering). Both are now able to have individual date ranges which they are valid for. These do not need to relate to the seasons in the pricetable section!
- Now addons and catering both have base level settings which apply if no date range matches.
- Example: You could define a base setting as follows: no breakfast available, but in September 2017 there is this one month were you would like to serve breakfast.
- Addons can now be "required" which means they are mandatory.
- It is very likely that you want to include them in your calculated minimum price to fulfill legal requirements, if calculated by your own. Methods checkAvailability, checkMultiAvailability, getBookingParameter, makeBooking and makeRequestBooking will enforce booking of mandatory addons and include them in the baseprice from now on and in all cases.
- The difference to just "included" addons is that you are able to list the price in detail, included addons are just included without any price.
- There is now a maximum bookable amount of an addon. Previously the amount was always assumed as one unit of whatever addon, this has changed. Landlords are now able to define a maximum amount of times this addon is bookable within the same booking. A good example would be any service, let's say a single special dinner. Previously you could only order this addon one time. Now you are able to order as many times as the landlord provides. This gets even more clear if you think about the supply of some goodies or specials. See makeBooking/makeRequestBooking section for how to add an addon multiple times (though: it is just as easy as it sounds!).
- Important: There is a change in the way we handle addons that are inclusive or mandatory on a per person base. Before this update you could just add the addon one time to order for all persons. This has now changed, you will have to add these type of addons for each traveller once. You can determine which option to use by the return value of getBookingParameter(): addons > addon > valid_per -> "persaufenthalt" and "persuebernachtung". These are calculated per person.
- getBookingParameter(), checkAvailability(), checkMultiAvailability()
- Addon and catering sections have been updated to reflect the change in getCategoryDetails (see above!!). Addons and catering does not need to be available throughout the whole trip. It is important to notify the guest about this, if this scenario happens.
- For now we will only send you results with full-travel coverage. This might change in the future.
- Mandatory addons are included in the baseprice with a quantity of one unit, if addon is calculated per person it is added once for each person. You can always choose to add more, up to the maximum.
- makeBooking() / makeRequestBooking()
- You are now able to order an addon multiple times (up to the defined maximum).
- To order an addon for example twice, just add its ID a second time to the addons list.
- Mandatory addons will always be added with a quantity of one or the number of travellers in the background, unless you specify them on your own (doing so is highly suggested, since it makes things easier for you). You can not order less than the minimum of an addon.
- setPrices()
- Using this method to set addons and catering will still work, but will change in the next release to allow setting individual date ranges for addons and catering using new methods, if needed.
- For now, we will map your addons and catering options to a "not-available" base state and just add specific rules for your seasons.
- This change will apply the next time you write any price, and it is pretty much completely backwards compatible.
- If you are a channelmanager you are not required to do anything this time.
- older interface versions
- Addon and catering information is removed from older versions of the interface in getCategoryDetails() since they wouldn't fit in the old format anymore
- You will still be able to get a list using getBookingParameter, but it will be empty.
Version 1.11
You are now able to receive selected request-only objects (this was only supported on a global level before). These objects are included in getState(), but are not online bookable nor available for request booking. You can use sendRequest() to send a request of your guest to the landlord. This request is non-binding. You need to be enabled for this feature to work.
- sendRequest()
- sends a request to a landlord
- only available for landlords which are not online bookable nor request-bookable (pretty much obvious: if they are online bookable you could make a booking directly...)
- there are two modes for a request: information (general) and bookings (e.g. "is your apartment available from ... until... we are 5 persons and have a huge monster dog..."), depending on the mode you are able to provide travel details (arrival, departure, adults, children, age of children, pet description).
- you are always able to provide a request text (please make sure to follow the encoding rules, CDATA, UTF-8)
- a valid guest email address is mandatory (this is not only a regex validation, domain must exist and is compared to a blacklist)
- full guest name is mandatory
- provide as many details as possible
- provided details will be validated for plausibility, this is yet to come and will be extended, so do not provide placeholders or things like this, if a field is empty, provide it as empty - otherwise we might filter your request as non-human request.
- all your requests are tracked
- please note that a request will trigger a direct notification to the landlord, even using his cellphone. So take care not to send too many requests to a single landlord (spamming).
- getState()
- we've added a new field in the response of getState(): inquiry_enabled
- this boolean value tells you whether sendRequest() is usable for the given object category
Version 1.10
- added new method "getOpenRequestBookings()"
- requires channelmanager level access rights
- enables you to fetch a full list of all pending request bookings which haven't been confirmed or declined yet
- you will only get booking base data like object, category, arrival, departure, number of persons, date and time of request
- added new method "answerOpenRequestBooking()"
- if you have sufficient rights you are able to accept or decline a request booking
- you are only able to reject a request booking if the landlord is allowed to do so by the destination's settings, otherwise you will get an error telling you that you have insufficient rights to do so
- you will receive a simple boolean feedback in case of error the interface will throw an exception with an explanation for the error, you shouldn't encounter exceptions very often (if any at all) if you implemented everything correctly ;)
- added new method "getStandardGuestQueries()"
- requires channelmanager level access rights
- enables you to fetch all new/read/unread landlord queries
- only lists queries which have been placed within the last month
- this is a one-way-only method, you are not able to send a response using this interface (nevertheless you will receive all required contact data, if provided by the guest)
Version 1.9
- added new method "getInvoiceListing()"
- provides you with a one year history of bookings/cancellations/and so on
- includes your brokerage and the current state of the booking
- entries will become available after departure date of the booking
- booking data is extended with some additional information for generating listings
- this method takes no parameters, but you must be authenticated
- you might find this useful for getting all your data without any restriction (this is only limited in time (1 year back))
- depending on the number of bookings you've made, this will fetch you a huge amount of data, so the answer is cached and will only be updated every few hours (but at least once a day)
- "getCategoryDetails()" now includes ageranges (in years), if specified by landlord
- new element
<ageranges>per category - upper age limit is optional
- please note that the upper age limit is excluded (maxExclusive)
- these ranges are already validated during calls of "makeBooking()" or "makeRequestBooking()" (see error code 35)
- age ranges are set by landlord and do not need to cover all ages
- excluding or limiting the number of young children due to a limited amount of required supplies (beds/chairs for example) should be the most common cause
- if no agerange is used this will fallback to "max_adults" / "max_children", these fields are otherwise removed and replaced by ageranges
- new element
- added new method "getLastminute()"
- fetches all currently active lastminute offers for all of your objects
- lastminute offers are (and were in the past too) automatically applied during online booking with "makeBooking()" or "makeRequestBooking()" (and the required previous steps), no need to specify them explicitly
- please note the "removeOfferBefore" date field, offer gets invalid with reaching this date
Version 1.8
- new function setExternalContentDeeplink()
- allows a channel to set a reference link to its objectdetails page
- link won't be public, only for review by the organisation containing the object
- fully optional feature, link can be changed or overwritten at any time
- Country information in getObjectDetails() has been extended with a 3 Byte ISO code
(ISO 3166-1 alpha-3) as an attribute to the full country name
- internal changes to the authentification system
- added support for subclient logins within a main channel
- isolation of booking data and calculation/brokerage between the subclients
- subclients will be tracked only internally, end-users will just notice the main channel
- subclients can use the same workflow/functions as before, simply changing their login credentials
- subclient information will be tracked through our own booking mask as well (the api generated links now include the required parts: no need to change anything, just use fresh links)
- subclients receive individual push notifications
- setExternalContentDeeplink() is not available for subclients yet
- session timeout has been extended for cases where there was too much data to proceed within the given session timeout
- added new exceptions in setOccupancy(), setCategoryOccupancy() and setPrices(), debugging errors in this functions should be more easy now for the most common causes
- added the expiration date of object classifications to getObjectDetails() and getCategoryDetails()
- fixed different smaller bugs
- removed some countries from the supported country list (all versions)
Landlord-Management API Changelogs
Version 1.2
- added
landlordbilling_languageto createLandlord() and updateLandlord() call
Version 1.1
- added getLandlords() call
Version 1.0
- initial release
Object-Management API Changelogs
Version 1.6
- Changes to setObjectDetails()
- added new type
Dreibettzimmer
- added new type
- Changes to makeObject()
- added new type
Dreibettzimmer
- added new type
Version 1.5
- Changes to setObjectDetails()
- added new optional element
visitor_tax_place_of_payment
- added new optional element
Version 1.4
- Changes to setObjectDetails()
- added new optional element
local_registration_no - added new optional element
check_in_out_times - added new optional element
rooms
- added new optional element
Version 1.3
- added new required element "landlord_no" to "setObjectDetails" method
Version 1.2
- added new method "moveReview()"
- requires authcode for given landlord
- allows you to set an object ready for review
Version 1.1
- added new method "moveOffline()"
- requires authcode for given landlord
- allows you to set an object offline systemwide
Version 1.0
- initial release
Errors
See Error Handling for more details.
Error Code List
| Code | Message |
|---|---|
| 0 | success |
| 1 | login failed - missing or empty parameter |
| 2 | login failed - wrong credentials or not authorized |
| 3 | login required |
| 4 | parameter missing or invalid |
| 5 | unspecified query error |
| 6 | no matching record found |
| 7 | object found, but missing configuration |
| 8 | arrival date invalid |
| 9 | departure date invalid |
| 10 | arrival and departure date invalid |
| 11 | too less days before arrival |
| 12 | travel dates not accepted |
| 14 | no direct booking enabled, requires (human) request |
| 15 | partly or complete missing date ranges configuration |
| 16 | too many adults |
| 17 | too many children |
| 18 | too many people |
| 19 | not available / in use |
| 20 | maximum price exceeded |
| 21 | departure before arrival |
| 22 | arrival in the past |
| 23 | action failed |
| 24 | missing value: anrede |
| 25 | missing value: land |
| 26 | missing value: email |
| 27 | from-value is in the past |
| 28 | there are undefined periods within given ranges |
| 29 | overlaping date ranges |
| 30 | incorrect authcode |
| 31 | too many requests, flooding detected - you should not encounter this error if you are using this service in the right way. contact technical support if required. |
| 32 | you logged in too many times without performing any action, please check your implementation and avoid pointless traffic (this is a temporary error) |
| 33 | the requested object does not support this type of action |
| 34 | invalid addon specified, code was not listed in current addons (try calling getBookingParameter again or check your code) |
| 35 | age ranges do not match (and there are age restrictions in effect for this object) |
| 36 | range too long, exceeded maximum duration |
| 37 | invalid value for field: catering |
| 38 | access denied: insufficient rights |
| 39 | url invalid |
| 40 | from and until date are identical, please specify at least one night |
| 41 | tried to book more units of an addon than available |
| 42 | the answer to life, the universe and everything |
| 43 | you can not make a booking for literally nobody, please submit a valid person count |
| 44 | external price is not the same as the calculated booking price, please submit a value higher or even |
| 45 | unable to calculate price, check parameters for logical errors |
| 46 | input format invalid, validate your code against the xsd |
| 47 | catering option invalid |
| 48 | no record found for given booking_no or reservation not done by you |
| 49 | payment option is not supported for this object |
| 50 | missing or invalid redirect URIs |
| 51 | no payment required |
| 52 | payment flow step is unrecognized |
| 53 | payment link could not be retrieved from provider, possible config error |
| 54 | rrv data is already added |
| 55 | value for field email failed validation (invalid domain or not cappable of mail transfer due to missing A and MX DNS records), either this mail is fake or a typo |
| 56 | missing parameter booking_no |
| 57 | operation not permitted on this reservation |
| 58 | specified cancellation fee is not valid/accepted |
| 59 | cancellation fee amount is not valid |
| 60 | maximum available addon amount can not be lower than 1, set addon to unavailable instead, rule partially ignored |
| 61 | extra traveller data has errors |
| 62 | season start is identical to end date |
| 63 | there is a gap in an addonbeds price definition (make sure to leave no price definition gaps or fill gaps with explicit definitions even if step price is zero) |
| 64 | there is a syntax error in your submitted request, check your request against the embedded XSD in the WSDL spec |
| 65 | addon bed definitions must not overlap with base occupancy |
| 66 | margin has to be a positiv integer or float value |
| 67 | invalid value for field: cleaning_fee_place_of_payment |
| 68 | invalid value for field: deposit_place_of_payment |
| 69 | invalid value for field: external_id |
| 70 | payment provider is not supported |
| 71 | payment provider is not available for host |
| 80 | Discount id is not valid. |
| 81 | Discount for this id not found. |
| 82 | Invalid value for discounted amount. |
| 83 | Discount not applicable. |
| 101 | property id not found in the objects organisation |
| 102 | holiday_theme id not found in the objects organisation |
| 103 | distance id not found in the objects organisation |
| 104 | to age lower then from age |
| 105 | the number of adults is higher than the number of overall persons |
| 106 | required parameter not found in persons element |
| 107 | more age ranges than persons |
| 110 | object is missing the minimum required data, see docs for details |
| 111 | the landlord_no provided, is invalid |
| 112 | the country given is invalid |
| 113 | the type given is invalid |
| 114 | the location given is invalid |
| 115 | the geolocation given is invalid |
| 116 | the visitor tax place of payment given is invalid |
| 120 | object_no not found |
| 130 | from date is invalid |
| 131 | until date is invalid |
| 132 | from value is too far in the past |
| 133 | until value is too far in the past |
| 134 | room type is invalid |
| 200 | landlord creation is not enabled for this account and/or on this organisation |
| 201 | landlord is not accessible or non existent |
| 202 | you can only modify landlords you have created (using this api) |
| 203 | your current account status is not valid for this type of action |
| 204 | formal error, content validation failed on some fields: iban |
| 205 | landlord is missing the minimum required data, see docs for details |
| 206 | provided landlord_no and landlord of the provided object_no do not match |
| 207 | provided landlordbilling_language is not supported |
| 1000 | quota reached: max landlords |
| 1001 | quota reached: max objects |
| 1002 | quota reached: max images per object |
| 1003 | quota reached: max objects per landlord |
FAQ
This is a collection of commonly asked questions and their answers.
I receive a "parameter missing or invalid" error without further details. What does that mean?
In general there are two possible reasons:
- your request violeted the XSD specification
- some expected (and not optional) values are missing (what also violates the XSD)
The provided WSDL file contains an embedded XSD specification. We highly suggest validating your request against it as it will point to the most common errors. If you are using some kind of testing software (e.g. SoapUI) there is a good chance there is already a feature for this.
I have received a success response, but my data isn't showing up. Why?
The success response only indicates that the server has processed your response without an error, it does not mean that your request was without logical/content errors. Especially errors related to the content you submit are not detectable to the server.
Other reasons are that if you violate the XSD for example, invalid/misplaced parts of your request might have been cut, so the success response only says there was no error in the valid part (if any).
If you look for an error, the first step is as always to validate your request against the embedded XSD in the WSDL file. This will cover like 90% of typical errors.
I receive responses with HTTP status 429, what does that mean?
You are blocked by the Rate Limiting. More details here.
Can you raise the Rate Limit for me?
No. Rate Limits are specified globally and can not be adjusted per user.
The API stopped working after a new version was deployed. What can I do?
We are running a versioned API, that means you can use older versions with unchanged interfaces. It also means that you
must pin your usage to a specific version (as mentioned in the docs), otherwise you will always use the latest version with the possibility of breaking
changes. If you encounter this error because you are running on "latest", pin the version in the WSDL or endpoint URL (depending on what
you are using). This is as simple as just adding the missing GET parameter v to the URL and set a version explicitly. Just pin to the last kown working version
and you have this fixed within under 10 keystrokes. See Versioning section.
Where do I get XML sample requests?
You can use the WSDL file with the embedded XSD to generate your own XML samples with many SOAP tools like for example SoapUI.
For SoapUI just open a new project and load our WSDL file, then mark the checkbox to generate samples (link).

Since our API is versioned and updated frequently this is a lot more useful than any static (and maybe outdated) samples in the documentation could ever be, since the WSDL file is using the exact same version as you.
Help
We are here to help! Contact us!

Asmus Jacobsen
Partner Success Manager
Before you write or call us
Please answer these questions before reaching out to us. It makes our support process a lot faster, as we will otherwise most likely need to ask you these questions anyway at a later stage.
- Which API Request did you send?
- Which Endpoint/Version did you submit your Request to?
- What was the Result you expected from our API?
- What was the actual Result you've got from our API?
- When exactly did you send the Requests - ideally down to the Second? (add timezone if needed)
- Under which Username did you send the Requests?
- Do you use Version-Pinning?
- Have you checked if you exceeded our Rate-Limit?
- Have you received any HTTP Error Codes 429 from our API?
- Have you implemented the evaluation of our Rate-Limit-Headers?