> ## 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.

# Promotional campaigns

> Show a live offer and open landing pages on a promo code

Hotels run public promotions, including time-limited flash sales, and distribute private codes through email, social, or partner channels. The Booking Engine API exposes both: read the active promotion to display it, and seed a code into the session to unlock the rates it grants.

> [!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.

## Show the active promotion

`GET /v2/{sessionId}/promotion` returns the latest active public promotion for the session's hotel, or `204 No Content` when none is running. Use it to render a promotional banner, with a countdown when the promotion is a flash sale.

```bash cURL theme={null}
curl --request GET \
  --url 'https://{apiBaseUrl}/v2/{sessionId}/promotion' \
  --header 'Authorization: OAuth ...'
```

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

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

const promotion = response.status === 204 ? null : await response.json();
```

```python Python theme={null}
response = session.get("https://{apiBaseUrl}/v2/{sessionId}/promotion")
promotion = response.json() if response.status_code == 200 else None
```

```php PHP theme={null}
$response = $client->get('v2/{sessionId}/promotion');
$promotion = $response->getStatusCode() === 204
    ? null
    : json_decode($response->getBody(), true);
```

```csharp C# theme={null}
var request = new RestRequest("/v2/{sessionId}/promotion", Method.Get);

var response = await client.ExecuteAsync(request);
var promotion = response.StatusCode == HttpStatusCode.NoContent
    ? (JsonElement?)null
    : JsonDocument.Parse(response.Content!).RootElement;
```

```java Java theme={null}
HttpGet request = new HttpGet("https://{apiBaseUrl}/v2/{sessionId}/promotion");
consumer.sign(request);

JsonNode promotion = null;
try (CloseableHttpResponse response = client.execute(request)) {
    if (response.getStatusLine().getStatusCode() == 200) {
        promotion = mapper.readTree(EntityUtils.toString(response.getEntity()));
    }
}
```

A running promotion comes back with its discount and, for a flash sale, a deadline:

```json theme={null}
{
  "id": "0b1f2c3d-4e5f-6a7b-8c9d-0e1f2a3b4c5d",
  "description": "Spring flash sale",
  "isPublic": true,
  "isFlashSales": true,
  "displayCountdown": true,
  "endDate": "2026-12-10T00:00:00Z",
  "discount": { "calculationMode": "Percentage", "percent": 15 }
}
```

Show the countdown only when `displayCountdown` is `true`, and hide the banner on a `204`.

## Build a promo-code landing page

A promo code converts best when its landing page opens straight onto the offer it unlocks. Seed the code into `context.promoCode` when you create the session (see the [Quick start](/booking-engine-api/get-started/quick-start.md)), then search as usual: the results are scoped to the rates the code grants.

Confirm the code resolved by reading the session scope:

```bash cURL theme={null}
curl --request GET \
  --url 'https://{apiBaseUrl}/v2/{sessionId}/session/scope' \
  --header 'Authorization: OAuth ...'
```

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

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

const scope = await response.json();
const promoCode = scope.activePromoCode;
```

```python Python theme={null}
response = session.get("https://{apiBaseUrl}/v2/{sessionId}/session/scope")

scope = response.json()
promo_code = scope.get("activePromoCode")
```

```php PHP theme={null}
$response = $client->get('v2/{sessionId}/session/scope');

$scope = json_decode($response->getBody(), true);
$promoCode = $scope['activePromoCode'] ?? null;
```

```csharp C# theme={null}
var request = new RestRequest("/v2/{sessionId}/session/scope", Method.Get);

var response = await client.ExecuteAsync(request);
var scope = JsonDocument.Parse(response.Content!).RootElement;
var promoCode = scope.GetProperty("activePromoCode");
```

```java Java theme={null}
HttpGet request = new HttpGet("https://{apiBaseUrl}/v2/{sessionId}/session/scope");
consumer.sign(request);

JsonNode scope;
try (CloseableHttpResponse response = client.execute(request)) {
    scope = mapper.readTree(EntityUtils.toString(response.getEntity()));
}
JsonNode promoCode = scope.path("activePromoCode");
```

```json theme={null}
{
  "activePromoCode": {
    "type": "RateCode",
    "code": "AUTUMN2026",
    "rateIds": [32643]
  }
}
```

`type` tells you what the code is (`RateCode`, `OfferCode`, or `DiscountCode`), and `rateIds` lists the rates it unlocked. When the code does not apply, session creation can return `400` with `Code: InvalidPromoCode` (unknown code), `InvalidPromoCodeBookingPeriod` (booked outside the campaign window), or `InvalidPromoCodeStayPeriod` (stay dates outside the offer). Catch these codes and show a fallback explaining why the code is not valid for this stay, rather than a raw error.

## Tips

* **Pass the code through the URL**. A campaign link like `https://book.example.com/offer?code=AUTUMN2026` opens the page on the offer in one flow, with no form.
* **Treat a `204` as "no promotion", not an error**. Hide the banner when no promotion is active.
* **Log every code, even unresolved ones**. Marketing needs both how many guests arrived with a code and how many got a valid offer: the gap surfaces a misconfigured offer fast.

## Related

> **[Get a promotion](/booking-engine-api/build/reference/promotion/get-promotion.md)**
>
> Full schema for the promotion endpoint.

> **[Create a session](/booking-engine-api/build/reference/session/post-session.md)**
>
> Seed `context.promoCode` when you open the session.


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