Push API v1 (Accommodations) User Guide

The Push API can be used to make OpenGDS push availability, rates and inventory to your own servers.
For example, the preferred way to show calendars to guests is to use the Core API and build calendars real-time on the client side.
But in case you want to use your own database, you can use the Push API to synchronize the status data.

Status push (POST)

You have for example endpoint "https://mydomain.com/api/push/status.php" for Status push URL. The basic PHP for status.php, to convert the JSON encoded string you receive, into a PHP variable $data, can look like this:

<?php

$data = json_decode(file_get_contents('php://input'), true);

Info: OpenGDS always sends a UTF-8 JSON array. (Content-Type: application/json; charset=UTF-8)

Note: The Status push URL must be secured with HTTP Basic authentication over TLS.

Below an example of the JSON array sent to your endpoint:

[
    {
        "init": true,
        "rate_id": 9048,
        "rate_interface_id": [
            "847345",
            "LG5653"
        ],
        "property_id": 16405,
        "currency_code": "USD",
        "rate_enabled": true,
        "valid_from": "2026-01-30",
        "valid_till": "2026-10-04",
        "arrival_days": [
            "Mon",
            "Tue",
        ],
        "restriction_type": "till",
        "restriction_days": 5,
        "default_minlos": 1,
        "default_maxlos": 3,
        "rate_type": "pppn",
        "single_rate_type": 0,
        "daily_supplement": {
            "Fri": "4.5"
        },
        "child_rate": {
            "1": {
                "rate": "5",
                "type": 1
            }
        },
        "res_fee": "10",
        "accommodations": [
            {
                "_sequence": 1,
                "accom_id": 19732,
                "accom_enabled": true,
                "default_available": 3,
                "default_rate": "119",
                "default_single_rate": "105",
                "default_single_rate_type": 0,
                "extra_night_rate": "",
                "status": [
                    {
                        "date": "2026-08-26",
                        "available": 5,
                        "daily_rate": "120",
                        "daily_single_rate": "91",
                        "minlos": 2,
                        "maxlos": 4,
                        "close_out": true,
                        "cta": true,
                        "ctd": false
                    }
                ]
            }
        ]
    }
]

Info: The JSON array sent contains one or multiple rates from one or multiple properties.

Note: Not all possible JSON elements are visible in the example above. They are present in the table below.

JSON element Presence Description
init When the rate is (re-)initialized. Whether the rate is (re-)initialized.
Format: true
rate_id Always The ID of the rate.
Format: integer
rate_interface_id When the rate has an Interface ID. The Interface IDs of the rate.
Format: Array containing one or multiple interface IDs as string.
property_id Always The ID of the property owning the rate.
Format: integer
property_interface_id When the property has an Interface ID. The Interface ID of the property.
Format: string
currency_code Always The currency code of the property and thus of the rate.
Format: Three-letter uppercase currency code according to ISO-4217.
rate_enabled When changed or initializing. Whether the rate is enabled.
Format: true or false (boolean)
valid_permanent When changed or initializing and only when true. Whether the rate is permanently valid.
Format: true
valid_from When changed or initializing and only when not permanently valid. From this date, the rate is valid.
Format: YYYY-MM-DD (with leading zeros)
valid_till When changed or initializing and only when not permanently valid. Until this date, the rate is valid.
The rate is valid up to and including the valid_till date.
Format: YYYY-MM-DD (with leading zeros)
arrival_days When changed or initializing. The days of the week on which the guest can arrive for this rate.
Arrival days not set here, can never be overwritten to become arrival days. So always keep these arrival days leading when determining your availability.
Format: Array with a textual representation of the day, three letters
restriction_type When changed or initializing. The arrival restriction set for this rate, possible values are:
0 => Disabled
"till" => Restriction till
"from" => Restriction from
restriction_days When changed or initializing and restriction_type not equals 0. The number of days set for the arrival restriction.
Format: integer
default_minlos When changed or initializing. The default Minimum Length of Stay setting, more about this later.
Format: integer
default_maxlos When changed or initializing. The default Maximum Length of Stay setting, more about this later.
Format: integer
rate_type When changed or initializing. How the rate is calculated, possible values are:
"pppn" => Per person per night
"papn" => Per accommodation per night
"pp" => Per person
"ps" => Per stay
"pppd" => Per person per day
"papd" => Per accommodation per day
single_rate_type When changed or initializing. How the single rates are handled, possible values are:
0 => Single supplement (fixed supplement / percentage via default_single_rate)
1 => Single rate (dynamic rate, can be set for each day via default_single_rate/daily_single_rate)
daily_supplement When changed or initializing. The supplements valid for certain days of the week.
Default rates and daily rates are always sent through the API without this supplement.
Format: Days as a textual three letter representation, followed by the daily supplement as string.
child_rate When changed or initializing. The child rate per child category.
Format: Each set category is sent as an object with the elements rate and type.
An empty array is returned when no child rate values are set.
The possible values for the type element:
0 => Fixed rate
1 => Percentage
res_fee When changed or initializing. The reservation fee.
An empty string is returned when no value is set.
Format: number as string
accommodations Always Array containing one or multiple accommodations connected to the rate. All accommodations connected to the rate are always present in this array, so if an accommodation was present in the previous request and is missing in the current request, the accommodation is no longer connected to the rate.
_sequence Always The sequence index for this accommodation, according to the order set in the backend.
Format: integer
accom_id Always The ID of the accommodation.
Format: integer
accom_interface_id When the accommodation has an Interface ID. The Interface ID of the accommodation.
Format: string
accom_enabled When changed or initializing. Whether the accommodation is enabled.
Format: true or false (boolean)
default_available When changed or initializing. The default availability of the accommodation, more about this later.
Format: integer
default_rate When changed or initializing. The default rate of the accommodation, more about this later.
Format: number as string
default_single_rate When changed or initializing and applicable for the accommodation. The default single rate of the accommodation, more about this later.
An empty string is returned when no value is set.
Format: number as string
When single_rate_type equals 0, this value can be a positive or a negative number and must be added to or subtracted from the default_rate/daily_rate.
default_single_rate_type When changed or initializing and applicable for the accommodation. The default single rate type of the accommodation, possible values are:
0 => Fixed rate
1 => Percentage
When single_rate_type equals 1, this value will always be 0.
extra_bed_rate When changed or initializing and applicable for the accommodation. The extra bed rate for the accommodation.
An empty string is returned when no value is set.
Format: number as string
extra_bed_rate_type When changed or initializing and applicable for the accommodation. The extra bed rate type of the accommodation, possible values are:
0 => Fixed rate
1 => Percentage
extra_night_rate When changed or initializing and applicable for the rate. The extra night rate for the accommodation.
An empty string is returned when no value is set.
Format: number as string
status When changes to the status are made. Array containing zero, one or multiple status updates for the accommodation.
This can be an empty array if rate updates are sent, but no status updates are performed.
date Always The date for which the update is applicable.
Format: YYYY-MM-DD (with leading zeros)
available When changed or when close_out changed to false. The new availability.
Format: integer
daily_rate When changed. The new daily rate.
Format: number as string
daily_single_rate When changed, possible for the accommodation and single_rate_type equals 1. The new daily single rate.
Format: number as string
minlos When changed and possible for the rate_type. The new Minimum Length of Stay.
Format: integer
maxlos When changed and possible for the rate_type. The new Maximum Length of Stay.
Format: integer
close_out When changed or when available changed. The new Close out status.
Format: true or false (boolean)
cta When changed. The new Closed to Arrival status.
Format: true or false (boolean)
ctd When changed. The new Closed to Departure status.
Format: true or false (boolean)

Tip: if your system does not support close_out, you can set your availability to 0 when close_out is true and to available when close_out is false.

Within the period the rate is valid, each accommodation/date has attributes (sent in the status array) you can use, depending on what you need for your service.

When an attribute for a date is untouched (nonexistent, never overwritten in the status array), you must use the default value.
The following table shows each possible attribute and its default value:

Attribute Default value
available default_available (see JSON element)
daily_rate default_rate (see JSON element)
daily_single_rate default_single_rate (see JSON element)
minlos default_minlos (see JSON element)
maxlos default_maxlos (see JSON element)
close_out false
cta false
ctd false

daily_single_rate can only be used if single_rate_type equals 1 and default_single_rate is present for the accommodation.


Important: There are four cases in which you explicitly need to set the attributes back to untouched.

  1. When init is true, the complete rate is (re-)initialized and every attribute must be untouched.
    The same call can also contain new status updates which must be set after the (re-)initialization has been completed.
  2. When the rate is not permanently valid, every attribute for dates smaller than valid_from and greater than valid_till must be untouched.
  3. When single_rate_type is set to 0, every daily_single_rate attribute associated with the rate must be untouched.
  4. When an accommodation is disconnected from the rate (is not present in the accommodations array), all attributes for the accommodation must be untouched.

If a rate is updated, the changes will be sent through the API. If this concerns one of the above cases, you must set the attributes to untouched instantly.

Reset

When you enable the Push API, reset buttons appear in OpenGDS. These buttons can be used to reinitiate the Push API globally or per rate.
init is true will be used for this purpose.

Response

When your server returns HTTP status code 200, OpenGDS will register the call as successful. Every other HTTP status code will be seen as error, in this case OpenGDS will try again later. The response body is also visible in the API log and can be used for debug purposes.

Tip: The data pushed to your server can grow very large very quickly.
It is recommended to verify the received data globally and then to queue it raw, to keep the connection open for as short a time as possible.
You can then process the queue in a background service, independent of the connection.
It is important that OpenGDS receives the HTTP status code 200 within 60 seconds, otherwise the request will time out and be marked as erroneous.
In this case, OpenGDS will try again and meanwhile the data will continue to grow.

Note: If there are 100 consecutive errors, the API is automatically disabled. During initialization, the API is disabled after 1 error.

Tip: If an update cannot be processed internally, for example because a rate_interface_id has not yet been created, it is best to return an HTTP status code 200. This will prevent 100 consecutive errors from occurring, causing the API to be disabled. Once a processing error occurs, it is best to notify employees via email with a clear error message so they can resolve the error. The Reset button can then be used for the rate in OpenGDS to reinitiate the rate via the Push API.