Skip to content

Getting Started

Quickstart

Five calls, from an API key to a confirmed sandbox booking and back out again.

Everything below runs against sandbox. Sandbox bookings are always test bookings: they never reach a live supplier endpoint and never cost anyone money. Swap in a gws_live_… key when you are ready, and read Sandbox and live first.

Set your key once
export GWS_KEY="gws_sandbox_YOUR_KEY"

1. Confirm the Key and Its Mode

The cheapest call in the API. It tells you who the key belongs to and which mode it runs in.

Request
curl https://api.gatewaystream.com/api/v1/me \
  -H "x-api-key: gws_sandbox_YOUR_KEY"

If mode is not what you expected, stop here — a sandbox key never reaches live data, but a live key most certainly reaches live suppliers.

2. Find a Property

There is nothing to sync first: hotels are available as soon as you ask. Take a propertyId from the response — that is the aggregator id search and booking use.

List properties
curl "https://api.gatewaystream.com/api/v1/properties?limit=5" \
  -H "x-api-key: $GWS_KEY"

3. Search for Rates

One search, every source that holds the property. Each rate comes back with a rateKey — the thing you will book with.

Request
curl -X POST https://api.gatewaystream.com/api/v1/search \
  -H "x-api-key: $GWS_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "checkIn": "2026-12-05",
    "nights": 2,
    "rooms": [{ "adults": 1, "childAges": [] }],
    "currency": "USD",
    "propertyIds": ["a9702286-9b22-498d-8bc9-97471f68d798"]
  }'

Keep the rateKey and the price.sell figure. You need both for the next step, and the key is good for about 30 minutes.

4. Book

Booking redeems the rate key. Idempotency-Key is required: it is what makes a retried request safe. expectedPrice is your guard against a price that moved between search and book — if the live total is higher, the call is rejected rather than quietly booked.

Request
curl -X POST https://api.gatewaystream.com/api/v1/bookings \
  -H "x-api-key: $GWS_KEY" \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "Content-Type: application/json" \
  -d '{
    "leadGuest": {
      "name": { "first": "Test", "last": "Guest" },
      "contact": { "email": "test@example.invalid", "phone": "+263700000000" }
    },
    "rooms": [{
      "rateKey": "rk_01JD8Q5T6H2V8ZCN4PQ1RMB7XE",
      "guests": [{ "name": { "first": "Test", "last": "Guest" }, "age": 30 }]
    }],
    "expectedPrice": { "amount": 164.00, "currency": "USD" },
    "isTest": true
  }'

5. Cancel

simulation has no default: every cancel must say whether it is a preview or the real thing. Send true first if you want the fee before committing.

Cancel for real
curl -X POST https://api.gatewaystream.com/api/v1/bookings/0b5e1a92-6c3f-4a7d-8e21-9b4f0d3c5a18/cancel \
  -H "x-api-key: $GWS_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "simulation": false, "reason": "quickstart cleanup" }'

A 200 carrying status: "CANCELLED" is the only answer that means the booking is gone. Anything else is covered on the Cancel page.

Next

Read Request conventions for pagination, idempotency and rate limits, then Search for everything the search body can do — destinations, geo radius, filters and sorting.