# Bookings

> List your bookings and read one in detail.

Source: https://www.panion.travel/docs/api/reference/bookings

### GET /api/v1/bookings

List bookings.

Bookings made through Panion for the tours of every operator on the key (or the one in `partner_id`), newest first, 50 per page by default. Each carries its `partner`. Holds and abandoned checkouts never appear.

Scope: `bookings:read`.

Query parameters:

- `date_from` (string, YYYY-MM-DD, optional): Experience date on or after (YYYY-MM-DD).
- `date_to` (string, YYYY-MM-DD, optional): Experience date on or before (YYYY-MM-DD).
- `updated_since` (string, ISO 8601 date-time, optional): Only bookings created or changed at or after this instant.
- `status` (one of `CONFIRMED`, `CANCELLED`, `REFUNDED`, optional)
- `cursor` (string, optional): `next_cursor` of the last page.
- `limit` (integer, optional, default 50)
- `partner_id` (string, optional): Only this operator: one of the key's operators (see GET /api/v1/me). Any other id answers 404. Omit for every operator on the key.

Response fields (200):

- `data` (array)
  - each item:
    - `id` (string)
    - `confirmation_code` (string)
    - `status` (one of `CONFIRMED`, `CANCELLED`, `REFUNDED`)
    - `partner` (object): The operator a row belongs to: one of the key's operators (the tour's operator for a booking).
      - `id` (string)
      - `name` (string)
    - `tour` (object)
      - `id` (string, nullable)
      - `name` (string, nullable)
    - `experience_date` (string, YYYY-MM-DD, nullable)
    - `start_time` (string, nullable): Local wall-clock time (HH:MM) in `timezone`.
    - `timezone` (string): IANA timezone, e.g. Europe/Oslo.
    - `participants` (integer, nullable)
    - `amount_minor` (integer): Integer minor units (øre, cents).
    - `currency` (string): ISO 4217 code.
    - `channel` (string, nullable)
    - `guest` (object)
      - `name` (string, nullable)
      - `email` (string, nullable, optional): Only with the guests.contact:read scope.
      - `phone` (string, nullable, optional): Only with the guests.contact:read scope.
    - `booked_at` (string, ISO 8601 date-time, nullable)
    - `created_at` (string, ISO 8601 date-time)
    - `updated_at` (string, ISO 8601 date-time, nullable)
- `next_cursor` (string, nullable): Pass as `cursor` for the next page.

Example: Bookings for one week

```sh
curl "https://www.panion.travel/api/v1/bookings?date_from=2026-11-10&date_to=2026-11-16&limit=50" \
  -H "Authorization: Bearer $PANION_API_KEY"
```

```json
{
  "data": [
    {
      "id": "8f6d2c1e-4b7a-4e3f-9c2d-1a5b6c7d8e9f",
      "confirmation_code": "PNN-7K2Q9X",
      "status": "CONFIRMED",
      "partner": {
        "id": "2b7e1516-28ae-4d2a-9f15-88094f3c4f3c",
        "name": "Arctic Tours"
      },
      "tour": {
        "id": "3a1b2c3d-4e5f-4a6b-8c7d-9e0f1a2b3c4d",
        "name": "Northern Lights Chase"
      },
      "experience_date": "2026-11-14",
      "start_time": "19:00",
      "timezone": "Europe/Oslo",
      "participants": 2,
      "amount_minor": 359800,
      "currency": "NOK",
      "channel": "panion",
      "guest": {
        "name": "Ingrid Hansen"
      },
      "booked_at": "2026-10-01T12:30:00Z",
      "created_at": "2026-10-01T12:30:00Z",
      "updated_at": null
    }
  ],
  "next_cursor": null
}
```

Responses:

- 200: OK
- 400: Invalid request
- 401: Missing, invalid, expired or revoked key
- 403: The key lacks the scope
- 429: Rate limited (300 requests per minute per key)

### GET /api/v1/bookings/{id}

Get one booking.

One booking by its id. A booking whose tour belongs to none of the key's operators (or not to `partner_id`) answers 404.

Scope: `bookings:read`.

Path parameters:

- `id` (string): Booking id (UUID).

Query parameters:

- `partner_id` (string, optional): Only this operator: one of the key's operators (see GET /api/v1/me). Any other id answers 404. Omit for every operator on the key.

Response fields (200):

- `id` (string)
- `confirmation_code` (string)
- `status` (one of `CONFIRMED`, `CANCELLED`, `REFUNDED`)
- `partner` (object): The operator a row belongs to: one of the key's operators (the tour's operator for a booking).
  - `id` (string)
  - `name` (string)
- `tour` (object)
  - `id` (string, nullable)
  - `name` (string, nullable)
- `experience_date` (string, YYYY-MM-DD, nullable)
- `start_time` (string, nullable): Local wall-clock time (HH:MM) in `timezone`.
- `timezone` (string): IANA timezone, e.g. Europe/Oslo.
- `participants` (integer, nullable)
- `amount_minor` (integer): Integer minor units (øre, cents).
- `currency` (string): ISO 4217 code.
- `channel` (string, nullable)
- `guest` (object)
  - `name` (string, nullable)
  - `email` (string, nullable, optional): Only with the guests.contact:read scope.
  - `phone` (string, nullable, optional): Only with the guests.contact:read scope.
- `booked_at` (string, ISO 8601 date-time, nullable)
- `created_at` (string, ISO 8601 date-time)
- `updated_at` (string, ISO 8601 date-time, nullable)
- `provider_reference` (string, nullable): Your booking system's own reference (e.g. Bokun code).
- `payment` (object)
  - `strategy` (one of `pay_now`, `pay_later`)
  - `pay_later` (object, nullable)
    - `status` (string)
    - `amount_minor` (integer): Integer minor units (øre, cents).
    - `currency` (string, nullable): ISO 4217 code.
    - `charge_at` (string, ISO 8601 date-time, nullable)
    - `paid_at` (string, ISO 8601 date-time, nullable)
- `commission` (object, nullable)
  - `amount_minor` (integer): Integer minor units (øre, cents).
  - `rate_percent` (number, nullable)
  - `currency` (string, nullable): ISO 4217 code.
  - `status` (string, nullable)

Example: A paid booking

```sh
curl "https://www.panion.travel/api/v1/bookings/8f6d2c1e-4b7a-4e3f-9c2d-1a5b6c7d8e9f" \
  -H "Authorization: Bearer $PANION_API_KEY"
```

```json
{
  "id": "8f6d2c1e-4b7a-4e3f-9c2d-1a5b6c7d8e9f",
  "confirmation_code": "PNN-7K2Q9X",
  "status": "CONFIRMED",
  "partner": {
    "id": "2b7e1516-28ae-4d2a-9f15-88094f3c4f3c",
    "name": "Arctic Tours"
  },
  "tour": {
    "id": "3a1b2c3d-4e5f-4a6b-8c7d-9e0f1a2b3c4d",
    "name": "Northern Lights Chase"
  },
  "experience_date": "2026-11-14",
  "start_time": "19:00",
  "timezone": "Europe/Oslo",
  "participants": 2,
  "amount_minor": 359800,
  "currency": "NOK",
  "channel": "panion",
  "guest": {
    "name": "Ingrid Hansen"
  },
  "booked_at": "2026-10-01T12:30:00Z",
  "created_at": "2026-10-01T12:30:00Z",
  "updated_at": null,
  "provider_reference": "ARC-123456",
  "payment": {
    "strategy": "pay_now",
    "pay_later": null
  },
  "commission": {
    "amount_minor": 53970,
    "rate_percent": 15,
    "currency": "NOK",
    "status": "pending"
  }
}
```

Responses:

- 200: OK
- 400: Invalid request
- 401: Missing, invalid, expired or revoked key
- 403: The key lacks the scope
- 404: Not found, or not yours
- 429: Rate limited (300 requests per minute per key)

### GET /api/v1/bookings/{id}/reschedule-options

Departures a booking can move to on one day.

Read only. Whether the booking can move to `date` and the departures it can take there, from the booking's own booking system (one availability read for that day). A day with room only at a different price shows `price_differs` and no options: a move never changes the price. Needs the bookings.reschedule:write scope.

Scope: `bookings.reschedule:write`.

Path parameters:

- `id` (string): Booking id (UUID) from GET /api/v1/bookings.

Query parameters:

- `date` (string, YYYY-MM-DD): The day to check (YYYY-MM-DD).

Response fields (200):

- `id` (string): The booking id.
- `date` (string)
- `current_date` (string, nullable): The booking's departure day now.
- `reschedulable` (boolean): False when the booking cannot be moved at all; `detail` says why.
- `available` (boolean): True when the booking can move to `date`.
- `price_differs` (boolean): True when `date` has room only at a different price. A move never changes the price, so it is refused.
- `detail` (string, nullable)
- `options` (array)
  - each item:
    - `start_time_id` (string)
    - `rate_id` (string, nullable)
    - `start_time` (string, nullable)
    - `label` (string, nullable)
    - `remaining` (integer)

Example: Departures on the new day

```sh
curl "https://www.panion.travel/api/v1/bookings/8f6d2c1e-4b7a-4e3f-9c2d-1a5b6c7d8e9f/reschedule-options?date=2026-12-14" \
  -H "Authorization: Bearer $PANION_API_KEY"
```

```json
{
  "id": "8f6d2c1e-4b7a-4e3f-9c2d-1a5b6c7d8e9f",
  "date": "2026-12-14",
  "current_date": "2026-12-12",
  "reschedulable": true,
  "available": true,
  "price_differs": false,
  "detail": null,
  "options": [
    {
      "start_time_id": "4821",
      "rate_id": "1093",
      "start_time": "18:00",
      "label": null,
      "remaining": 12
    }
  ]
}
```

Responses:

- 200: OK
- 400: Invalid request
- 401: Missing, invalid, expired or revoked key
- 403: The key lacks the scope
- 404: Not found, or not yours
- 429: Rate limited (300 requests per minute per key)
