Skip to content
Last updated

Create orders

If you are implementing the Search, look and book integration, use this guide to take a traveller from a selected travel service to a confirmed order.


Order creation flow

This is the overall order creation flow:

  1. Retrieve current accommodation or car data from the relevant search or availability endpoint.
  2. Let the traveller select the accommodation rooms or car offer they want to book.
  3. Call /orders/preview with the selected details.
  4. Display the preview response and resolve any warnings.
  5. Collect the information required by /orders/create.
  6. Ask the traveller to confirm the order.
  7. Call /orders/create with the order_token returned by preview.
  8. Display a creation confirmation after /orders/create succeeds - For car orders, retrieve the latest status from /orders/details/cars/live before presenting the order as confirmed.

Before you start

Make sure your integration has:

✓ Access to the relevant Demand API v3.2 OpenAPI schema - Accommodation order creation is available in v3.2 Stable; car order creation is currently available in Beta.

✓ The required authentication and Affiliate-Id header;

✓ Current accommodation or car data from the relevant search or availability response;

✓ The traveller's actual booking context such as country and platform.

✓ Permission to create orders and process payments.

✓ A user interface that can display prices, payment timings, cancellation policies, and warnings.

Prices, availability, and booking conditions can change. Do not use a previously stored price or offer as the final order state. Refresh the relevant search or availability data before calling /orders/preview.

Endpoints involved in order creation

To create an order, use the following endpoints in sequence:

Endpoint
Use it to...
/orders/previewValidate the selected order, calculate the current price, return payment and cancellation information, and generate the order_token.
/orders/createCreate the order using the order_tokenand the fields required by the create request.

/orders/preview is consultative. It does not create an order or confirm a reservation.


Step 1 - Keep the traveller's selection

Accommodation

When the traveller selects accommodation products, retain:

  • The accommodation ID;
  • Check-in and check-out dates;
  • Selected product IDs;
  • The guest allocation for each selected product.

Car rentals

When the traveller selects a car rental, retain:

  • The offer ID
  • The search_token from the same current car search or availability flow.
  • Any selected optional product IDs and amounts.
  • The insurance quote reference, if the traveller selected third-party insurance.

Do not silently change product IDs, dates, guest ages, or room allocations while moving to preview. If the selection changes, treat it as a new preview attempt.

Step 2 - Build the preview request

Send exactly one travel service object.

The shared currency property is optional. Include a supported three-letter currency code when you want to request a preferred traveller-facing currency.

Accommodation preview request

The accommodation object must contain

FieldDescription
accommodation.idThe accommodation identifier returned by the preceding search or availability response.
accommodation.bookerThe traveller's booking context. country and platform are required.
accommodation.checkin and accommodation.checkoutThe selected stay dates.
accommodation.productsThe selected room products and their guest allocations.

The booker object must be nested inside accommodation:

Example:

{
    "currency": "EUR",
    "accommodation": {
      "id": 6745031,
      "booker": {
        "country": "nl",
        "platform": "mobile",
        "travel_purpose": "leisure",
        "user_groups": [
          "authenticated"
        ]
      },
      "checkin": "2026-12-12",
      "checkout": "2026-12-20",
      "products": [
        {
          "id": "674503106_275710478_0_2_0",
          "allocation": {
            "number_of_adults": 1,
            "children": [
              8
            ]
          }
        },
        {
          "id": "674503113_275710486_0_1_0",
          "allocation": {
            "number_of_adults": 1,
            "children": []
          }
        }
      ]
    }
  }

Use the traveller's actual context:

  • country is a two-letter lowercase country code, such as nl.
  • platform is one of android, desktop, ios, mobile, or tablet.
  • travel_purpose is optional and can be business or leisure.
  • user_groups is optional. Include it only when applicable, for example when the traveller is authenticated.

Guest allocation

For each room product:

  • Copy the allocation supplied by the preceding search or availability response when one is provided.

Otherwise, assign guests manually after checking the room product's occupancy limits.

Example:

{
  "products": [
    {
      "id": "room-product-1",
      "allocation": {
        "number_of_adults": 1,
        "children": [2]
      }
    },
    {
      "id": "room-product-2",
      "allocation": {
        "number_of_adults": 1,
        "children": [5]
      }
    }
  ]
}
  • number_of_adults must be at least 1.
  • Child ages must be integers from 0 through 17.

See the Occupancy and allocation guide for details.

Car preview request

The car object must contain offer and search_token:

{
  "currency": "EUR",
  "car": {
    "offer": 123456789,
    "search_token": "search-token-from-the-current-car-flow"
  }
}

Add optional products only when they were selected by the traveller and returned by the current car availability response:

{
  "currency": "EUR",
  "car": {
    "offer": 123456789,
    "search_token": "search-token-from-the-current-car-flow",
    "products": [
      {
        "id": "001234567890",
        "amount": 1
      }
    ],
    "insurance": {
      "quote_reference": "quote-reference-from-car-availability"
    },
    "language": "it"
  }
}
  • Use car.language when the traveller needs insurance documents in a particular language.
  • If insurance is not selected, omit the insurance object; do not send a placeholder quote reference.

Step 3 - Validate the request before sending it

Before calling /orders/preview:

✓ Confirm that exactly travel service is present.

✓ Confirm that the selected IDs belong to the latest search or availability result.

✓ Confirm that accommodation dates are valid and checkout is after check-in.

✓ Confirm that every room has the intended guests and child ages.

✓ Confirm that the car offer and search token came from the same current flow.

✓ Confirm that an insurance quote reference is present only when insurance was selected.

✓ Confirm that secrets and payment data are not being logged.

Application validation improves feedback, but it does not replace the API preview. Booking conditions and prices must still be obtained from /orders/preview.

Step 4 - Call orders/preview

Send a POST request with the required authentication headers and the JSON request body:

POST /orders/preview
Affiliate-Id: YOUR_AFFILIATE_ID
Content-Type: application/json

On a successful response:

  1. Save the complete data object for the preview page.
  2. Save data.order_token for the create request.
  3. Save request_id for support and diagnostics.

Do not alter the selected room products, car offer, dates, allocation, optional products, or insurance before create without running preview again.

Step 5 - Display the order preview page

Build the preview page from the latest /orders/preview response, not from the earlier search or availability response.

Accommodation preview

For accommodation, show:

  • The accommodation and selected room products;
  • Stay dates and guest allocation;
  • The returned total price and currency;
  • Relevant charges and the amount payable online, when returned;
  • Cancellation policies for each room product;
  • Meal-plan information;
  • Available payment timings and methods; and
  • Any occupancy_mismatch warning.

Example:

order-preview

In case of occupancy mismatch, inform your travellers so they can change guest allocation. (See the Occupancy and allocation guide for details)

Handle occupancy mismatch

Inspect occupancy_mismatch for every accommodation room product:

  • null means that the requested allocation fits according to the preview response.
  • An object identifies the guests that can be allocated and those that cannot.

If guests are unallocated, explain the issue and let the traveller change the allocation, select another room product, or add another room where supported. Do not silently drop or reassign guests.

Car rentals

For cars, show:

  • The selected offer;
  • The total and its currency;
  • Optional products and their prices;
  • Cancellation terms;
  • Deposit, damage excess, theft excess, fuel policy, and mileage information when returned;
  • Payment timing; and
  • Insurance details and documents when returned.

Display prices and charges

Use the total returned by the API. Do not recalculate it by adding individual charges.

Clearly distinguish between:

  • The total price;
  • The amount payable online now;
  • Later instalments;
  • Amounts payable at the property or pickup desk.

Always label the currency. Handle null monetary fields as unavailable; do not display them as zero.

Display payment options

For accommodation

  • Read payment information from: data.accommodation.general_policies.payment
  • Use only the timings and methods returned for this order. Depending on the selected room products, the response can include pay_online_now, pay_online_later, or pay_at_the_property, with different dates, amounts, and supported methods.

Do not preselect an unsupported method, promise that a method will be accepted, or assume all products have the same payment terms. For a multi-product order, present the payment options applicable to the complete returned order.

See the available accommodation payment models for details.

For car rentals

Read car payment information from:

data.car.policies.payment

Use the payment timing, payable amounts, and payment requirements returned for the selected car offer. Depending on the offer, the preview can support:

  • pay_at_pickup, where the traveller pays at the car rental pick-up location;
  • pay_online_now, where the traveller pays online at the time of order creation; or
  • pay_partial_online_now, where part of the amount is paid online and the remainder is paid at pick-up.

When payment is required for a car order, the create schema currently supports card as the payment method.

  • Display the card-payment requirement only when it is returned for the selected offer.
  • Do not assume that every car order requires a card.

For eligible cardless pay-at-pick-up offers:

  • The traveller does not need to provide payment details.
  • This applies only when the selected offer returns credit_card_required: false and the accepted price has no online payable amount.

In that case, explain that payment is due at the pick-up location and omit the payment object from /orders/create.

Do not determine the payment flow from payment.timing alone.

Step 6 - Collect information for /orders/create

After the traveller reviews the preview, collect the fields required by /orders/create. The required fields depend on the travel service and payment flow.

For an accommodation order, collect:

  • Booker details;
  • The guest details for each room product;
  • Arrival information or special requests, when applicable; and
  • Payment information.

For a car order, collect:

  • The booker details;
  • The driver's details; and
  • Payment information when the selected car offer requires it.

The order_token represents the validated order context, but it does not remove the need to provide fields required by the create request. Use the /orders/create schema as the authority for required and optional fields.

Before submitting create, verify:

✓ The traveller confirmed the displayed total and booking conditions;

✓ If payment is required, confirm that the selected timing and method are supported by the preview response.

✓ The product selection has not changed;

✓ The preview token is still valid; and

✓ The create request contains no stale or unrelated product IDs.


Step 7 - Create the order

Call /orders/create with:

  • The order_token returned in data.order_token; and
  • All fields required by the /orders/create schema for the selected travel service and payment flow.

The order token expires 15 minutes after it is issued. If it expires, call /orders/preview again with current data and use the new token.

Run preview again if the traveller changes the room product, dates, guest allocation, car offer, optional car products, insurance, or any other detail that affects the order.

Accommodation create request

An accommodation create request requires:

  • accommodation.products[].id must exactly match a room product ID used in the /orders/preview request.
  • accommodation.products[].guests[].email and name are required for guests.
  • booker.address, booker.email, booker.name, and booker.telephone are required by the create schema.
  • booker.name.first_name and last_name are required.
  • payment object - Use the payment method returned by /orders/preview.
    • Depending on the selected order, the method can be airplus, card, or wallet.
    • Include the corresponding payment object when required.
    • payment.timingis also required and must be one of the timings returned by orders/preview.

The following example is for a card payment and also includes optional bed configuration, remarks, and receipt generation:

{
  "accommodation": {
    "products": [
      {
        "id": "room-product-id-from-preview",
        "bed_configuration": "123456",
        "guests": [
          {
            "email": "traveller@example.com",
            "name": "Test Name"
          }
        ]
      }
    ],
    "remarks": {
      "estimated_arrival_time": {
        "hour": 12
      },
      "special_requests": "We will need an extra cot."
    }
  },
  "booker": {
    "address": {
      "address_line": "Road-1, house-2",
      "city": "Amsterdam",
      "country": "nl",
      "post_code": "11111"
    },
    "company": "Booking B.V",
    "email": "traveller@example.com",
    "language": "en-gb",
    "name": {
      "first_name": "Test",
      "last_name": "Name"
    },
    "telephone": "12345678"
  },
  "order_token": "order-token-from-preview",
  "payment": {
    "card": {
      "cardholder": "Test Name",
      "cvc": "111",
      "expiry_date": "2030-10",
      "number": "23333333333333"
    },
    "include_receipt": true,
    "method": "card",
    "timing": "pay_online_now"
  }
}

See the Payment methods for more details.

Car create request with payment

When creating a car rental order:

  • Do not send offer, search_token, optional car products, or insurance.quote_reference again in the /orders/create body. These details are represented by the order_token.
  • Include the car driver, booker, and payment fields (when required).
  • If a card is required or any amount is payable online, include the payment object with:
    • payment.method: "card"
    • payment.card details.

The following example is for a car order with card payment:

{
  "car": {
    "driver": {
      "email": "john.doe@example.com",
      "first_name": "John",
      "last_name": "Doe",
      "telephone": "12345678",
      "title": "Mr"
    }
  },
  "booker": {
    "address": {
      "address_line": "Road-1, house-2",
      "city": "Amsterdam",
      "country": "nl",
      "post_code": "11111"
    },
    "email": "john.doe@example.com",
    "language": "en-gb",
    "name": {
      "first_name": "John",
      "last_name": "Doe"
    },
    "telephone": "12345678"
  },
  "order_token": "order-token-from-preview",
  "payment": {
    "card": {
      "cardholder": "John Doe",
      "cvc": "111",
      "expiry_date": "2030-10",
      "number": "23333333333333"
    },
    "include_receipt": false,
    "method": "card",
    "timing": "pay_at_pickup"
  }
}

Car create request without payment

For car rental orders, omit the payment object from /orders/create only when all of the following conditions apply:

  • The selected offer is payable locally at the pick-up desk (pay_at_pickup);
  • credit_card_required is false; and
  • The accepted price has no online payable amount.

The cardless car request still requires car, booker, driver details and order_token.

  • The car booker's address may be omitted in this branch.

Insurance does not automatically mean that a card is required. Check the returned payment requirements and payable amounts for the selected car and insurance combination.

For an eligible cardless pay-at-pick-up order, omit both payment and booker.address:

{
  "car": {
    "driver": {
      "email": "john.doe@example.com",
      "first_name": "John",
      "last_name": "Doe",
      "telephone": "12345678",
      "title": "Mr"
    }
  },
  "booker": {
    "company": "Booking B.V",
    "email": "john.doe@example.com",
    "language": "en-gb",
    "name": {
      "first_name": "John",
      "last_name": "Doe"
    },
    "telephone": "12345678"
  },
  "order_token": "order-token-from-preview"
}

Do not use this request shape merely because the timing is pay_at_pickup. Confirm that the selected offer returns credit_card_required: false and that the accepted price has no online payable component.

Step 8 - Confirm the order

Travel serviceConfirmation phaseWhat to do next
AccommodationTreat the order as created only after /orders/create returns a successful response.Display the order confirmation and the returned order details.

Cars

A successful response means that the order request has been accepted for asynchronous processing.

The response returns the car reservation ID and a Processing status.

Retrieve the latest state using /orders/details/cars/live before telling the traveller that the car order is confirmed.

Use the creation response to display:

  • An order confirmation page;
  • The returned order and reservation identifiers, when available;
  • The receipt URL when one was requested;
  • Any authorisation form URL when returned;

Store the information required for post-booking management, cancellation, support, and reconciliation.

Do not show a confirmed state while /orders/create is still pending, while a car order has Processing status, or after a failed request.

Create response fields

The successful response contains request_id and data. The shape of data depends on the travel service:

For accommodation orders, use:

  • data.order for the order ID, when returned;
  • data.accommodation.pincode for the accommodation PIN, when returned;
  • data.accommodation.reservation for the accommodation reservation ID, when returned;
  • data.accommodation.third_party_inventory.checkin_number and confirmation_number for third-party inventory orders, when returned; and
  • data.payment.receipt_url or authorisation_form_url, when returned.

For car orders, use:

  • data.order for the order ID, when returned;
  • data.car.reservation_id to retrieve the latest car order details; and
  • data.car.status, which is Processing in the current create response.

The car create response does not itself provide the final car order status. Retrieve the latest details from /orders/details/cars/live.

Receipt generation

If the request includes payment.include_receipt: true, use data.payment.receipt_url when it is returned.

For pay_online_later, the payment receipt or credit slip may need to be retrieved later when payment becomes due. Follow the payment and order-details documentation for the relevant flow.

If the request includes payment.business_information.authorisation_form, use data.payment.authorisation_form_url when it is returned. The authorisation form URL is valid for a limited time; follow the payment documentation for its validity period.

Error handling and recovery

Use the error identifier and message to provide a specific next action.

SituationRecommended action
Invalid or expired accommodation room productRefresh accommodation data and ask the traveller to review the updated selection.
Invalid or expired car offer or search tokenStart a fresh car search or availability flow.
Invalid insurance quote referenceRe-fetch the insurance quote or remove the insurance selection after informing the traveller.
Occupancy mismatchShow the affected guests and let the traveller revise the allocation.
Unsupported payment optionRe-run preview and display the payment options returned for the latest order.
Expired order tokenRun preview again before calling create.
Order unavailable (409)Do not retry blindly. Refresh the relevant travel service data and ask the traveller to review the updated order.
Duplicate request (409)Do not retry. Use the returned reservation ID to retrieve the existing car order through /orders/details/cars/live and check its status.
Transient server failureRetry cautiously using a duplicate-safe strategy. Do not create duplicate orders.

Log request_id, endpoint, HTTP status, and a redacted request summary. Never log full search tokens, order tokens, card numbers, CVCs, or other payment secrets.

UX and accessibility guidance

  • Put the total price and currency near the confirmation action.
  • Explain taxes, fees, conditional charges, and payment timing in plain language.
  • Show cancellation deadlines with an unambiguous date, time, and timezone where available.
  • Keep payment timing and payment method as separate controls.
  • Preserve entered data after validation or network errors.
  • Place errors next to the affected field and provide an error summary for screen readers.
  • Do not rely on colour alone for warnings or status.
  • Support keyboard navigation, visible focus, logical headings, and sufficient contrast.
  • Use a clear action such as “Confirm and book” when the action creates an order.
  • Do not use “Continue” alone for an action that creates an order.

Implementation checklist

Check
RequirementDescription
✓Refresh search or availability dataRefresh the current search or availability data before starting the preview and booking flow.
✓Preserve traveller selectionsPreserve the traveller's selected room product IDs, car offer, dates, allocations, and optional selections.
✓Send one travel serviceSend exactly one of accommodation or car in the request.
✓Nest accommodation booker dataNest the accommodation booker object in the correct location.
✓Validate and previewValidate the request locally before calling /orders/preview.
✓Build the preview pageBuild the preview page using the latest preview response.
✓Display preview detailsDisplay the returned total, currency, charges, payment options, and cancellation terms.
✓Handle nullable fieldsHandle nullable fields and the occupancy_mismatch response for accommodations.
✓Handle cardless car ordersHandle eligible cardless pay-at-pick-up car orders correctly.
✓Confirm traveller intentObtain explicit confirmation from the traveller before creating the order.
✓Use the order tokenUse data.order_token within 15 minutes of receiving it.
✓Re-run the preview when neededRe-run /orders/preview after any material change or when the order token expires.
✓Create the orderCall /orders/create with all fields required by its schema.
✓Handle car processingHandle asynchronous car order processing through /orders/details/cars/live.
✓Confirm the final stateConfirm the order only after the relevant travel-service response shows the appropriate final status.

Curious to know more?