Create a booking

POST
/bookings

Creates a new booking, optionally with line items and customer details. The booking is always returned in pending state — it remains pending until it is paid for or cancelled.

If line_items are provided, stock is reserved for each item. If omitted, an empty booking is created that can be populated later via POST /bookings/:id/line-items.

subtotal is the price of the line items. It already contains any tax included in those prices. total and balance add any tax charged on top of the price.

If customer details are provided, they are attached to the booking immediately. Customer identity is set at creation only: PATCH /bookings/:id rejects a customer attribute with 422, and payment requires a customer, so send one here for any booking you intend to take payment for.

Whether a booking holds stock is controlled by hold_stock. When omitted, the booking follows the creator's reserved-cart setting. Set hold_stock to true to hold: pass expiration_minutes for a timed hold, or omit it to hold until the booking is paid for or cancelled. Set hold_stock to false to never hold, even when the creator has reserved carts enabled or an expiration_minutes is given.

A timed hold expires after expiration_minutes, or the company's configured reserved cart duration (default 10 minutes) when omitted. An explicit expiration_minutes is honoured as requested and is no longer capped to the company's configured maximum. Clients should proactively cancel bookings (DELETE /bookings/:id) for abandoned sessions rather than relying on server-side expiry.

Line item semantics depend on the underlying variant's pricing_strategy and headcounted flags (see the variant resource). Total guests on a line item are always quantity × adult_count. For accommodation rooms and per_person experience variants (requires_adult_count), adult_count is required and bounded by the variant's max_occupancy; the server returns 422 if absent or out of range. For other experience variants adult_count is informational. The server does not enforce a particular quantity ↔ adult_count ratio for headcounted or per_person variants — modelling them as one unit per guest is a UX convention, not a server constraint.

Header Parameters

Idempotency-Key?string

Client-generated key for idempotent writes; the server deduplicates retries within a 24-hour window.

Request Body

application/json

TypeScript Definitions

Use the request body type in TypeScript.

line_items?array<>

Optional. Line items to add to the booking. If omitted, an empty booking is created.

currency?string

Optional ISO 4217 currency code. Defaults to the company currency.

customer?object

Optional. Lead booker details. Can also be provided later via PATCH /bookings/:id.

first_name*string
last_name*string
email*string
Formatemail
billing_address?object

Optional. Billing address. Can also be provided later via PATCH /bookings/:id.

line_one*string

Address line 1

line_two?string | null

Address line 2

city*string
post_code*string
country_code*string

ISO 3166-1 alpha-2 country code (e.g. GB, US)

subdivision_code?string | null

ISO 3166-2 subdivision code (e.g. US-NY).

expiration_minutes?integer

Requested reservation hold time in minutes. If omitted, the company's configured reserved cart duration is used. An explicit value is honoured as requested and is no longer capped to the company's configured maximum.

Range1 <= value
hold_stock?boolean

Optional. Controls whether the booking holds stock. Omit to follow the creator's reserved-cart setting. Set true to hold: with expiration_minutes for a timed hold, or omit expiration_minutes to hold until the booking is paid for or cancelled. Set false to never hold stock, even when the creator has reserved carts enabled or an expiration_minutes is given.

sales_channel?string

Optional free-text sales distribution channel (e.g. "Kiosk"). Defaults to "API" when omitted. Not validated.

Response Body

application/json

application/json

application/json

application/json

curl -X POST "https://example.com/bookings" \  -H "Easol-API-Version: 2026-11-01" \  -H "Content-Type: application/json" \  -d '{}'
{
  "object": "booking",
  "id": "string",
  "reference": "string",
  "state": "pending",
  "sales_channel": "string",
  "total": {
    "amount": 0,
    "currency": "string"
  },
  "subtotal": {
    "amount": 0,
    "currency": "string"
  },
  "balance": {
    "amount": 0,
    "currency": "string"
  },
  "customer": {
    "object": "customer",
    "id": "string",
    "first_name": "string",
    "last_name": "string",
    "email": "user@example.com",
    "phone": "+447762000000",
    "email_marketing_consent": {
      "consented": true,
      "consented_at": "2026-09-04T10:00:00Z"
    },
    "sms_marketing_consent": {
      "consented": true,
      "consented_at": "2026-09-04T10:00:00Z"
    }
  },
  "billing_address": {
    "line_one": "string",
    "line_two": "string",
    "city": "string",
    "post_code": "string",
    "country_code": "string",
    "subdivision_code": "string"
  },
  "purchase_order_number": "string",
  "vat_number": "string",
  "expires_at": "string",
  "cancelled_at": "string",
  "created_at": "string",
  "custom_fields": [
    {
      "custom_field_id": "fld_aBcDeFgHiJ",
      "key": "flight_number",
      "type": "text",
      "value": "BA2612",
      "option": {
        "id": "string",
        "value": "string"
      }
    }
  ],
  "first_visit": {
    "object": "customer_visit",
    "id": "visit_7hK2mQ9x",
    "occurred_at": "2026-09-04T10:00:00Z",
    "landing_page": "https://shop.example.com/",
    "referrer_url": "https://partner.example.com/",
    "referral_code": "ExternalPartner"
  },
  "last_visit": {
    "object": "customer_visit",
    "id": "visit_7hK2mQ9x",
    "occurred_at": "2026-09-04T10:00:00Z",
    "landing_page": "https://shop.example.com/",
    "referrer_url": "https://partner.example.com/",
    "referral_code": "ExternalPartner"
  },
  "line_items": {
    "object": "list",
    "url": "string",
    "has_more": false,
    "next_cursor": "string",
    "data": [
      {
        "object": "line_item",
        "id": "string",
        "variant_id": "string",
        "product_id": "string",
        "quantity": 1,
        "state": "pending",
        "variant_name": "string",
        "product_name": "string",
        "start_date": "2019-08-24",
        "end_date": "2027-04-19",
        "start_time": "string",
        "experience_slot_id": "string",
        "total": {
          "amount": 0,
          "currency": "string"
        },
        "guest_count": 2,
        "allocated_resources": {
          "object": "list",
          "url": "string",
          "has_more": false,
          "next_cursor": "string",
          "data": [
            {
              "object": "resource",
              "id": "string",
              "name": "string",
              "resource_group_name": "string"
            }
          ]
        }
      }
    ]
  },
  "guests": {
    "object": "list",
    "url": "string",
    "has_more": false,
    "next_cursor": "string",
    "data": [
      {
        "object": "guest",
        "id": "string",
        "first_name": "string",
        "last_name": "string",
        "email": "string",
        "phone": "+447762000000",
        "line_item_id": "string",
        "check_in_status": "pending",
        "is_lead": true,
        "custom_fields": [
          {
            "custom_field_id": "fld_aBcDeFgHiJ",
            "key": "flight_number",
            "type": "text",
            "value": "BA2612",
            "option": {
              "id": "string",
              "value": "string"
            }
          }
        ]
      }
    ]
  }
}
{
  "error": {
    "code": "string",
    "message": "string"
  }
}
{
  "error": {
    "code": "string",
    "message": "string"
  }
}
{
  "error": {
    "code": "string",
    "message": "string"
  }
}