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

# Abandoned booking recovery

> Bring a guest back to a pre-filled basket after they drop off

Most booking sessions are abandoned before payment. Because the Booking Engine API funnel is stateful, you can capture where a guest left off and bring them back to it, instead of starting from scratch.

## How it works

Recovery has three parts, all on your side, built on the session:

* **Capture**: when the guest reaches the basket or quote, store their contact details and the search context (dates, guests, hotel) along with their chosen room and extras.
* **Detect**: if the guest does not accept the quote within your window, send a reminder (email or SMS) with a deep link back to the funnel.
* **Recover**: on return, resume the session if it is still alive, or rebuild it from the captured context if it has expired.

## Resume or rebuild the session

A session has a limited lifetime, set with `X-AVP-SessionDuration` at creation. On return, read the stored session to see whether it is still valid.

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

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

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

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

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

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

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

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

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

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

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

* **Session still alive**: the basket comes back as the guest left it. Re-quote, then send them to the quote step.
* **Session expired**: the call returns `400` with `Code: InvalidSessionId`. Open a fresh session from the captured context, add the saved room and extras back to the basket, then quote.

```bash cURL theme={null}
# Session expired: open a new one with the stored context, then rebuild the basket
curl --request POST \
  --url 'https://{apiBaseUrl}/v2/session' \
  --header 'Authorization: OAuth ...' \
  --header 'Content-Type: application/json' \
  --data '{ "engineId": "YOUR_ENGINE_ID", "context": { ... } }'
```

```javascript Node.js theme={null}
// Session expired: open a new one with the stored context, then rebuild the basket
const url = "https://{apiBaseUrl}/v2/session";

const response = await fetch(url, {
  method: "POST",
  headers: {
    ...oauth.toHeader(oauth.authorize({ url, method: "POST" }, token)),
    "Content-Type": "application/json",
  },
  body: JSON.stringify({ engineId: "YOUR_ENGINE_ID", context: { /* ... */ } }),
});

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

```python Python theme={null}
# Session expired: open a new one with the stored context, then rebuild the basket
response = session.post(
    "https://{apiBaseUrl}/v2/session",
    json={"engineId": "YOUR_ENGINE_ID", "context": {...}},
)

new_session = response.json()
```

```php PHP theme={null}
// Session expired: open a new one with the stored context, then rebuild the basket
$response = $client->post('v2/session', [
    'json' => ['engineId' => 'YOUR_ENGINE_ID', 'context' => [ /* ... */ ]],
]);

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

```csharp C# theme={null}
// Session expired: open a new one with the stored context, then rebuild the basket
var request = new RestRequest("/v2/session", Method.Post);
request.AddJsonBody(new { engineId = "YOUR_ENGINE_ID", context = new { /* ... */ } });

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

```java Java theme={null}
// Session expired: open a new one with the stored context, then rebuild the basket
String body = mapper.writeValueAsString(Map.of(
    "engineId", "YOUR_ENGINE_ID",
    "context", Map.of( /* ... */ )
));

HttpPost request = new HttpPost("https://{apiBaseUrl}/v2/session");
request.setEntity(new StringEntity(body, "UTF-8"));
request.setHeader("Content-Type", "application/json");
consumer.sign(request);

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

## Tips

* **Set the session duration deliberately**. Use `X-AVP-SessionDuration` to balance how long a basket is held against releasing stale inventory. The session is short-lived, so do not count on it to span a long recovery window.
* **Always re-quote on return**. Prices and availability move while the guest is away, so confirm the current price before payment. See [Re-quote right before confirmation](/booking-engine-api/build/best-practices.md#re-quote-right-before-confirmation).
* **Design for rebuild, not resume alone**. Do not assume the original session survives: store enough context to recreate it.
* **Store only what you need**. A recovery flow holds guest contact details: handle and retain them in line with your privacy obligations.

## Related

> **[Create a session](/booking-engine-api/build/reference/session/post-session.md)**
>
> Open a new session from the captured context.

> **[Retrieve the basket](/booking-engine-api/build/reference/basket/get-basket.md)**
>
> Read the basket the guest left behind.


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