> ## Documentation Index
> Fetch the complete documentation index at: https://docs.d-edge.com/llms.txt
> Use this file to discover all available pages before exploring further.

> ## Agent Instructions
> This site documents the D-EDGE APIs for technology partners (web agencies, OTAs, PMS and RMS vendors, booking and CRM tools). It is written for developers integrating with hotels that use the D-EDGE platform.
> Seven APIs, grouped by domain. Connectivity: Channel Manager API (distribute a hotel's inventory to your channel and send bookings back). Pricing & Availability: Best Price API (best offers to highlight), Quotation API (all bookable offers for a stay), Daily Rates API (daily availability between two dates). Booking: Booking Engine API (a hotel's full direct booking funnel), Gift Shop API (gift vouchers from catalogue to payment). Guest Management: CRM API (guest profiles).
> Pick the API by the need: to display prices, use the Best Price API or the Daily Rates API; to quote a specific stay, use the Quotation API; to book, use the Booking Engine API; to sell gift vouchers, use the Gift Shop API; to manage guest profiles, use the CRM API; to receive hotel inventory and send bookings back as a distribution channel, use the Channel Manager API.
> Base URLs, hotel identifiers, and credentials are delivered by the D-EDGE partnership team during onboarding. Do not invent base URLs, endpoints, parameters, or example credentials that do not appear on these pages.
> Authentication differs per API: OAuth 1.0 for Best Price, Quotation, Daily Rates, and Booking Engine; an X-API-KEY header for Gift Shop; OAuth 2.0 client credentials for CRM; partner-defined credentials carried in the XML message for the Channel Manager API. Read each API's Authentication page before writing code.
> A mock environment returns realistic but fictitious data without credentials. The Postman and Insomnia collections on the API collections page target it by default. Use it for exploration and tests, never for production traffic.
> Use the official names exactly: D-EDGE, D-EDGE platform, Channel Manager API, partnership team. Do not use Back Office or Extranet.
> Each API has a Changelog page. Check it for the current behaviour before relying on an older answer. For questions these pages do not answer, direct the reader to the Contact us page.

# Alternative availability

> Offer a room split, a longer or shorter stay, or a nearby hotel

A guest asks for a specific stay, and the hotel has nothing to sell for it. Rather than show a dead end, offer the nearest bookable option: spread the party across rooms, extend or reduce the stay, or, when the hotel belongs to a group, search the other hotels nearby. Each option keeps the guest in the funnel and improves conversion.

> [!NOTE]
>
> The examples reuse the OAuth 1.0 signing from the [Quick start](/booking-engine-api/get-started/quick-start.md). Replace `{sessionId}` with your session.

## Move the guests across rooms

When the party does not fit in a single room, the room search can split it across rooms (for example 4 adults as 2 + 2). Add `AlternativeGuests` to `X-AVP-Properties` on `GET /v2/{sessionId}/search/rooms`:

```bash cURL theme={null}
curl --request GET \
  --url 'https://{apiBaseUrl}/v2/{sessionId}/search/rooms' \
  --header 'Authorization: OAuth ...' \
  --header 'X-AVP-Properties: AlternativeGuests'
```

```javascript Node.js theme={null}
const url = "https://{apiBaseUrl}/v2/{sessionId}/search/rooms";

const response = await fetch(url, {
  method: "GET",
  headers: {
    ...oauth.toHeader(oauth.authorize({ url, method: "GET" }, token)),
    "X-AVP-Properties": "AlternativeGuests",
  },
});

const results = await response.json();
```

```python Python theme={null}
response = session.get(
    "https://{apiBaseUrl}/v2/{sessionId}/search/rooms",
    headers={"X-AVP-Properties": "AlternativeGuests"},
)

results = response.json()
```

```php PHP theme={null}
$response = $client->get('v2/{sessionId}/search/rooms', [
    'headers' => ['X-AVP-Properties' => 'AlternativeGuests'],
]);

$results = json_decode($response->getBody(), true);
```

```csharp C# theme={null}
var request = new RestRequest("/v2/{sessionId}/search/rooms", Method.Get);
request.AddHeader("X-AVP-Properties", "AlternativeGuests");

var response = await client.ExecuteAsync(request);
var results = JsonDocument.Parse(response.Content!).RootElement;
```

```java Java theme={null}
HttpGet request = new HttpGet("https://{apiBaseUrl}/v2/{sessionId}/search/rooms");
request.setHeader("X-AVP-Properties", "AlternativeGuests");
consumer.sign(request);

JsonNode results;
try (CloseableHttpResponse response = client.execute(request)) {
    results = mapper.readTree(EntityUtils.toString(response.getEntity()));
}
```

The result is flagged `AvailabilityWithAlternativeGuests`, with one allocation entry per room. Only one split is returned:

```json theme={null}
{
  "unavailabilityType": "AvailabilityWithAlternativeGuests",
  "alternativeGuestsAllocation": [
    { "adults": 2, "children": 0, "infants": 0, "position": 1, "memberLevel": 0 },
    { "adults": 2, "children": 0, "infants": 0, "position": 2, "memberLevel": 0 }
  ]
}
```

## Extend or reduce the stay

When a rate is blocked by a minimum or maximum stay, the room search can return it at a length that works. Add `FetchExtendedStay` (minimum-stay) or `FetchReducedStay` (maximum-stay) to `X-AVP-Properties`:

```bash cURL theme={null}
curl --request GET \
  --url 'https://{apiBaseUrl}/v2/{sessionId}/search/rooms' \
  --header 'Authorization: OAuth ...' \
  --header 'X-AVP-Properties: FetchExtendedStay|FetchReducedStay'
```

```javascript Node.js theme={null}
const url = "https://{apiBaseUrl}/v2/{sessionId}/search/rooms";

const response = await fetch(url, {
  method: "GET",
  headers: {
    ...oauth.toHeader(oauth.authorize({ url, method: "GET" }, token)),
    "X-AVP-Properties": "FetchExtendedStay|FetchReducedStay",
  },
});

const results = await response.json();
```

```python Python theme={null}
response = session.get(
    "https://{apiBaseUrl}/v2/{sessionId}/search/rooms",
    headers={"X-AVP-Properties": "FetchExtendedStay|FetchReducedStay"},
)

results = response.json()
```

```php PHP theme={null}
$response = $client->get('v2/{sessionId}/search/rooms', [
    'headers' => ['X-AVP-Properties' => 'FetchExtendedStay|FetchReducedStay'],
]);

$results = json_decode($response->getBody(), true);
```

```csharp C# theme={null}
var request = new RestRequest("/v2/{sessionId}/search/rooms", Method.Get);
request.AddHeader("X-AVP-Properties", "FetchExtendedStay|FetchReducedStay");

var response = await client.ExecuteAsync(request);
var results = JsonDocument.Parse(response.Content!).RootElement;
```

```java Java theme={null}
HttpGet request = new HttpGet("https://{apiBaseUrl}/v2/{sessionId}/search/rooms");
request.setHeader("X-AVP-Properties", "FetchExtendedStay|FetchReducedStay");
consumer.sign(request);

JsonNode results;
try (CloseableHttpResponse response = client.execute(request)) {
    results = mapper.readTree(EntityUtils.toString(response.getEntity()));
}
```

The candidate comes back with the adjusted `availabilityType` on the room, and an `availabilityInfo` on the rate giving the required nights:

```json theme={null}
{
  "rooms": [
    {
      "availabilityType": "ExtendedStay",
      "rates": [
        { "availabilityInfo": { "reason": "MinStay", "minStay": 3, "maxStay": 0 } }
      ]
    }
  ]
}
```

`FetchReducedStay` mirrors this with `availabilityType: "ReducedStay"` and `reason: "MaxStay"`. On a rate blocked by a minimum stay, `FetchExtendedStay` takes precedence over `AlternativeGuests`.

## Search the group's other hotels

This path applies when the hotel belongs to a group (a multi-hotel booking engine). It picks up where the chosen hotel ran out, in two steps.

1. **The chosen hotel is full.** The room search at the selected hotel returns no availability.
2. **Open the search to the group.** Set `selectedHotelId` to `null` in the session context, centre a `Localisation` filter on the hotel's area, then search the hotels nearby.

Set the filter with `PATCH /v2/{sessionId}/session/filters/hotels`, passing the latitude, longitude, and a radius in metres:

```json theme={null}
{
  "filters": [
    { "type": "Localisation", "values": ["48.8713379", "2.3441099", "5000"] }
  ]
}
```

Then search the group for the available hotels nearby:

```bash cURL theme={null}
curl --request GET \
  --url 'https://{apiBaseUrl}/v2/{sessionId}/search/hotels' \
  --header 'Authorization: OAuth ...' \
  --header 'X-AVP-Properties: Description'
```

```javascript Node.js theme={null}
const url = "https://{apiBaseUrl}/v2/{sessionId}/search/hotels";

const response = await fetch(url, {
  method: "GET",
  headers: {
    ...oauth.toHeader(oauth.authorize({ url, method: "GET" }, token)),
    "X-AVP-Properties": "Description",
  },
});

const hotels = await response.json();
```

```python Python theme={null}
response = session.get(
    "https://{apiBaseUrl}/v2/{sessionId}/search/hotels",
    headers={"X-AVP-Properties": "Description"},
)

hotels = response.json()
```

```php PHP theme={null}
$response = $client->get('v2/{sessionId}/search/hotels', [
    'headers' => ['X-AVP-Properties' => 'Description'],
]);

$hotels = json_decode($response->getBody(), true);
```

```csharp C# theme={null}
var request = new RestRequest("/v2/{sessionId}/search/hotels", Method.Get);
request.AddHeader("X-AVP-Properties", "Description");

var response = await client.ExecuteAsync(request);
var hotels = JsonDocument.Parse(response.Content!).RootElement;
```

```java Java theme={null}
HttpGet request = new HttpGet("https://{apiBaseUrl}/v2/{sessionId}/search/hotels");
request.setHeader("X-AVP-Properties", "Description");
consumer.sign(request);

JsonNode hotels;
try (CloseableHttpResponse response = client.execute(request)) {
    hotels = mapper.readTree(EntityUtils.toString(response.getEntity()));
}
```

Each hotel comes back with a `location.distance`: order the results by that value in your interface to lead with the closest one.

## Tips

* **Ask for alternatives explicitly**. The room search returns them only when you set the values on `X-AVP-Properties`, and you can combine several in one call.
* **Know why it failed**. Add `DetailedUnavailabilityType` to see whether the block is on the room, the rate, both, or the guests, then pick the matching alternative.
* **Start at the same hotel**. A room split or a shifted stay is a smaller change than a new hotel, so it converts better. Keep the nearby hotel as a fallback.

## Related

> **[Search rooms](/booking-engine-api/build/reference/search/get-search-rooms.md)**
>
> Room search, alternative occupancies, and availability hints.

> **[Filter hotels](/booking-engine-api/build/reference/session/patch-session-filters-hotels.md)**
>
> Set the Localisation, Budget, Rating, and Amenities filters.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.