Panion Docs

API

Quick book: tours

The tours an integration client can sell on a day, with start times and prices.

Restricted.

Needs a Panion-issued Quick book key. Not available with partner API keys. Contact hello@panion.travel for access.

GET /api/quickbook/v1/tours

List the tours this terminal can sell on a day.

Every bookable tour the terminal the key is bound to can sell with a departure that day that fits the party: the tours of every operator whose payments that terminal can take. Each has its start times with seats left, the lowest price per guest and whether the guest's phone is required.

Headers: Authorization: Bearer pqb_live_... and Quickbook-Terminal: <terminal id>. Rate limit: reads.

Query parameters:

  • date (string, YYYY-MM-DD): The departure day, YYYY-MM-DD (local). From yesterday to 18 months ahead (Europe/Oslo); other days answer invalid_request.
  • guests (integer): Party size. Only departures with this many seats left are listed.
  • q (string, optional): Filter by tour or operator name, case-insensitive.

Response fields (200):

  • date (string, YYYY-MM-DD): Local date, YYYY-MM-DD.
  • guests (integer)
  • tours (array)
    • each item:
      • activityId (string): Panion activity id (a UUID), from GET /tours.
      • tourName (string)
      • operatorName (string)
      • timeZone (string): IANA time zone, e.g. Europe/Oslo.
      • starts (array): Start times that day that fit the party, with seats left.
        • each item:
          • time (string): Local wall-clock start time, HH:MM (24 hour).
          • seatsLeft (integer): Seats left right now.
      • fromPriceMinor (integer): Lowest price per guest, in minor units.
      • currency (string): ISO 4217 currency code.
      • requiresPhone (boolean): The guest's phone number is required in book.

Example: Tours on 14 November for 3 guests

curl "https://www.panion.travel/api/quickbook/v1/tours?date=2026-11-14&guests=3" \
  -H "Authorization: Bearer $PANION_QUICKBOOK_KEY" \
  -H "Quickbook-Terminal: $TERMINAL_ID"
{
  "date": "2026-11-14",
  "guests": 3,
  "tours": [
    {
      "activityId": "6f1e2d3c-4b5a-4c6d-8e7f-9a0b1c2d3e4f",
      "tourName": "Fjord and Whale Safari",
      "operatorName": "Destination Tromsø",
      "timeZone": "Europe/Oslo",
      "starts": [
        {
          "time": "09:00",
          "seatsLeft": 4
        },
        {
          "time": "12:30",
          "seatsLeft": 11
        }
      ],
      "fromPriceMinor": 94500,
      "currency": "NOK",
      "requiresPhone": true
    }
  ]
}

Errors:

  • 400: terminal_not_registered: the Quickbook-Terminal header is missing or malformed. invalid_request: The body or query does not validate (a missing field, a bad date or number).
  • 401: unauthorized: The Quick book key is missing, not valid, expired or revoked, or was sent in the URL. Answers with WWW-Authenticate: Bearer realm="panion-quickbook".
  • 403: terminal_not_registered: The terminal in the Quickbook-Terminal header is not registered, not active or not bound to this key. A missing or malformed header answers 400 with this code.
  • 429: rate_limited: Too many requests from this terminal: 60 writes, 60 books and 300 reads per minute. Retry-After says when to try again.
  • 503: provider_unavailable: The tour operator's booking system did not answer. Try again in a moment.

Restricted.

Needs a Panion-issued Quick book key. Not available with partner API keys. Contact hello@panion.travel for access.

GET /api/quickbook/v1/tours/{activityId}/slots

Start times and guest prices for a tour on a day.

Per start time: seats left, fewSeats, and the guest types (adult, child and so on, from the operator's pricing categories) with their price per guest. Use the guest type keys in POST /quote.

Headers: Authorization: Bearer pqb_live_... and Quickbook-Terminal: <terminal id>. Rate limit: reads.

Path parameters:

  • activityId (string): Panion activity id (a UUID), from GET /tours.

Query parameters:

  • date (string, YYYY-MM-DD): The departure day, YYYY-MM-DD (local). From yesterday to 18 months ahead (Europe/Oslo); other days answer invalid_request.

Response fields (200):

  • activityId (string): Panion activity id (a UUID), from GET /tours.
  • date (string, YYYY-MM-DD): Local date, YYYY-MM-DD.
  • timeZone (string): IANA time zone, e.g. Europe/Oslo.
  • currency (string): ISO 4217 currency code.
  • slots (array)
    • each item:
      • time (string): Local wall-clock start time, HH:MM (24 hour).
      • seatsLeft (integer): Seats left right now.
      • fewSeats (boolean): Few seats left. A good moment to offer reserve so the seats cannot go elsewhere while the guest pays.
      • guestTypes (array)
        • each item:
          • type (string): Guest type key from GET /tours/{activityId}/slots (adult, child and so on, from the operator's pricing categories).
          • label (string): Display label, e.g. Adult.
          • unitMinor (integer): Price per guest of this type, in minor units.

Example: Slots on 14 November

curl "https://www.panion.travel/api/quickbook/v1/tours/6f1e2d3c-4b5a-4c6d-8e7f-9a0b1c2d3e4f/slots?date=2026-11-14" \
  -H "Authorization: Bearer $PANION_QUICKBOOK_KEY" \
  -H "Quickbook-Terminal: $TERMINAL_ID"
{
  "activityId": "6f1e2d3c-4b5a-4c6d-8e7f-9a0b1c2d3e4f",
  "date": "2026-11-14",
  "timeZone": "Europe/Oslo",
  "currency": "NOK",
  "slots": [
    {
      "time": "09:00",
      "seatsLeft": 4,
      "fewSeats": true,
      "guestTypes": [
        {
          "type": "adult",
          "label": "Adult",
          "unitMinor": 189000
        },
        {
          "type": "child",
          "label": "Child",
          "unitMinor": 94500
        }
      ]
    }
  ]
}

Errors:

  • 400: terminal_not_registered: the Quickbook-Terminal header is missing or malformed. invalid_request: The body or query does not validate (a missing field, a bad date or number).
  • 401: unauthorized: The Quick book key is missing, not valid, expired or revoked, or was sent in the URL. Answers with WWW-Authenticate: Bearer realm="panion-quickbook".
  • 403: terminal_not_registered: The terminal in the Quickbook-Terminal header is not registered, not active or not bound to this key. A missing or malformed header answers 400 with this code. tour_not_sellable_here: This terminal cannot charge for this tour's operator, so it cannot sell it.
  • 429: rate_limited: Too many requests from this terminal: 60 writes, 60 books and 300 reads per minute. Retry-After says when to try again.
  • 503: provider_unavailable: The tour operator's booking system did not answer. Try again in a moment.

On this page