Travel To Discover

Loading documentation…

2. Guides

Export .md

Test More Scenarios

Status: not yet available

The Test header is accepted but no scenario is honoured yet. Every Trade API route parses the header and carries it on the request context, and nothing downstream reads it. A call sent with Test: scenario=soldOut is served as an ordinary live search against your enabled suppliers — the same response you would get with no Test header at all.

Do not treat a scenario run as evidence that your unhappy-path handling works. A soldOut or serviceUnavailable request that comes back with a normal populated result set has not exercised your error path; it has told you nothing. Until this page loses its status notice, cover those paths with your own fixtures or a stubbed transport, not with this header.

This page documents the vocabulary the header will use, so an integration written against it does not have to change when the switches land.

Test Header Format

Values are supplied as URL query-string key/value pairs:

http
Test: key1=value1&key2=value2&key3=value3

Basic Syntax

http
Test: scenario=priceChanged&hotel=HC1

Multiple Parameters

http
Test: scenario=soldOut&hotel=HC1&supplier=dida&rawcache=off

Sending an unrecognised key or value is safe: the server ignores what it does not understand and the call proceeds exactly as if no Test header had been sent. Today that describes every key on this page.

Reserved Scenarios

Value Intended effect What it will let you prove
scenario=available The ordinary availability path Your client reads and renders a successful search correctly
scenario=soldOut A hotel or room comes back with no inventory Your app degrades cleanly when nothing is bookable
scenario=priceChanged The price moves between the search response and the booking call Your app surfaces a price difference rather than booking blindly
scenario=serviceUnavailable A supplier is offline for the duration of the call Your app returns an error a human can act on
scenario=unknownInternalError An unanticipated system failure Your catch-all error handling holds

Cache Control Parameters

rawcache governs how supplier responses are cached for the request:

  • rawcache=on (default): caching enabled
  • rawcache=off: caching disabled — always retrieve fresh data
  • rawcache=bypass: skip the cache for this request only
  • rawcache=only: serve from cache only; do not call the supplier

rawttl sets how long the cached entry lives:

http
Test: scenario=available&rawttl=300s
Test: scenario=available&rawttl=1h
Test: scenario=available&rawttl=2d

Scoping Parameters

hotel points a scenario at one property, supplier at one supplier connection:

http
Test: scenario=soldOut&hotel=HC1
Test: scenario=serviceUnavailable&supplier=dida
Test: scenario=priceChanged&supplier=derbysoft

Request Bodies

The bodies below are ordinary, valid requests — they are what the endpoints accept today, with or without the header. Search takes roomOccupancies, one entry per room, each carrying adultCount and optional childrenAges. There is no occupancy field; sending one fails validation with 400 {"code":100000400}.

Example 1: HotelRates

http
POST /api/search/hotelRates
Authorization: Bearer your-jwt-token
Session-Id: 374337a797454a344ad999c7730da01c
Test: scenario=priceChanged&hotel=HC1
Content-Type: application/json

{
  "hotelId": "HC1",
  "checkIn": "2026-02-15",
  "checkOut": "2026-02-17",
  "roomOccupancies": [{ "adultCount": 2, "childrenAges": [] }]
}

Example 2: HotelList

http
POST /api/search/hotelList
Authorization: Bearer your-jwt-token
Session-Id: 374337a797454a344ad999c7730da01c
Test: scenario=soldOut&supplier=dida&rawcache=off
Content-Type: application/json

{
  "destinationId": "804028047",
  "checkIn": "2026-02-15",
  "checkOut": "2026-02-17",
  "roomOccupancies": [{ "adultCount": 2, "childrenAges": [] }]
}

Example 3: HotelRates against an unavailable supplier

http
POST /api/search/hotelRates
Authorization: Bearer your-jwt-token
Session-Id: 374337a797454a344ad999c7730da01c
Test: scenario=serviceUnavailable&supplier=derbysoft&rawttl=0s
Content-Type: application/json

{
  "hotelId": "HC1",
  "checkIn": "2026-02-15",
  "checkOut": "2026-02-17",
  "roomOccupancies": [{ "adultCount": 2, "childrenAges": [] }]
}

JavaScript/Node.js Example

javascript
async function testScenario(params = {}) {
  const testHeader = Object.entries(params)
    .map(([key, value]) => `${key}=${value}`)
    .join("&");

  const response = await fetch("/api/search/hotelList", {
    method: "POST",
    headers: {
      Authorization: `Bearer ${token}`,
      "Session-Id": sessionId,
      Test: testHeader,
      "Content-Type": "application/json",
    },
    body: JSON.stringify({
      destinationId: "804028047",
      checkIn: "2026-02-15",
      checkOut: "2026-02-17",
      roomOccupancies: [{ adultCount: 2, childrenAges: [] }],
    }),
  });

  return response.json();
}

// Until the switches land, every one of these returns an ordinary live search.
await testScenario({ scenario: "priceChanged", hotel: "HC1" });
await testScenario({ scenario: "soldOut", supplier: "dida" });
await testScenario({ scenario: "serviceUnavailable", rawcache: "off" });

Python Example

python
import requests

def test_scenario(params=None):
    if params is None:
        params = {}

    test_header = "&".join([f"{k}={v}" for k, v in params.items()])

    headers = {
        'Authorization': f'Bearer {token}',
        'Session-Id': session_id,
        'Test': test_header,
        'Content-Type': 'application/json'
    }

    payload = {
        "destinationId": "804028047",
        "checkIn": "2026-02-15",
        "checkOut": "2026-02-17",
        "roomOccupancies": [{"adultCount": 2, "childrenAges": []}]
    }

    response = requests.post(
        'https://api-test.ttdbooking.com/api/search/hotelList',
        headers=headers,
        json=payload
    )

    return response.json()

test_scenario({'scenario': 'priceChanged', 'hotel': 'HC1'})
test_scenario({'scenario': 'soldOut', 'supplier': 'dida'})

cURL Example

bash
curl -X POST "https://api-test.ttdbooking.com/api/search/hotelList" \
  -H "Authorization: Bearer your-jwt-token" \
  -H "Session-Id: 374337a797454a344ad999c7730da01c" \
  -H "Test: scenario=soldOut&supplier=dida" \
  -H "Content-Type: application/json" \
  -d '{
    "destinationId": "804028047",
    "checkIn": "2026-02-15",
    "checkOut": "2026-02-17",
    "roomOccupancies": [{ "adultCount": 2, "childrenAges": [] }]
  }'

Troubleshooting

The scenario never fires

Expected, for now — see the status notice at the top of this page. No scenario is implemented, so the header changes nothing. It is not a typo in your header and it is not the environment.

The request is rejected with 400 {"code":100000400}

The body failed validation; the Test header is never the cause. The usual culprit on search is occupancy in place of roomOccupancies, or roomOccupancies omitted altogether — it is required and must carry at least one entry. Session-Id is a required header on HotelRates, CheckAvail, Book and Cancel. See Error handling for the full business-code table.

Security Considerations

  • The Test header will be honoured only in the sandbox and test environments
  • Production ignores test parameters it does not recognise
  • Sandbox scenarios run against test data, separate from production systems

Support and Resources


This guide changes as the API does. Check the API documentation for the current reference.