> ## Documentation Index
> Fetch the complete documentation index at: https://docs.dev.gojinko.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Trip

> Create and manage a trip: add or remove items, set travelers, select ancillaries

Assemble and edit a trip before sending it to checkout. Use it to add a flight or hotel offer, set traveler details, swap one item for another, or attach ancillaries like bags and seats. Flights and hotels can sit side by side in the same trip and settle through a single checkout.

<Accordion title="Tool description (what the LLM sees)" defaultOpen={false}>
  ```text theme={null}
  Create and manage a trip: add flight or hotel items, remove items, set traveler details, and select ancillaries.

  Operations:
  - add_item: Add a flight or hotel to the trip. Pass trip_item_token from flight_search (offer__* tokens) or offer_id from hotel_search (htl_* tokens). Omit trip_id to create a new trip.
  - remove_item: Remove an existing item from the trip by item_id (from trip response items[].item_id). Requires an existing trip_id. Can be combined with add_item in a single call to swap an item: remove runs first, then add.
  - upsert_travelers: Set traveler details and contact info on an existing trip_id.
  - select_ancillaries: Select bags, seats, meals for a quoted trip item. Requires trip_id and item_id.

  Returns trip_id for use with the checkout tool. Flights and hotels can coexist in the same trip (single Stripe checkout).

  IMPORTANT, TRAVELER DATA:
  NEVER invent or fabricate traveler data. Before calling upsert_travelers, you MUST ask the user for the required fields:
  - Always: first_name, last_name, passenger_type
  - Flights only: date_of_birth (YYYY-MM-DD), gender (male/female), required when the trip contains a flight, optional for hotel-only trips
  - Contact: email, phone (with country code)
  If a required field is missing, ASK the user. Do not use placeholder or default values.

  ANCILLARY FLOW:
  After adding an item and setting travelers, check trip response for available_ancillaries on trip items.
  If ancillaries are available, offer them to the user before proceeding to checkout.
  Use select_ancillaries with the offer_ids from available_ancillaries. Full replacement semantics: send all desired selections.

  Flows:
  - Flights: flight_calendar → flight_search → trip(add_item) → trip(upsert_travelers) → [trip(select_ancillaries)] → checkout
  - Hotels: hotel_search → trip(add_item) → trip(upsert_travelers) → checkout
  - Mixed: both in the same trip, one cart, one checkout
  ```
</Accordion>

## Parameters

| Name                                                  | Type            | Required | Description                                                                                                                                                                                                                       |
| ----------------------------------------------------- | --------------- | -------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `trip_id`                                             | `string`        | No       | Existing trip ID. Omit to create a new trip.                                                                                                                                                                                      |
| `add_item`                                            | `object`        | No       | Add a flight or hotel item to the trip.                                                                                                                                                                                           |
| `add_item.trip_item_token`                            | `string`        | Yes      | Token from flight\_search results (offer\_\_\* format) or offer\_id from hotel\_search results (htl\_\* format).                                                                                                                  |
| `remove_item`                                         | `object`        | No       | Remove an existing item from the trip. Requires an existing trip\_id; you cannot remove from a trip that has not been created yet. Can be combined with add\_item in a single call to swap an item (remove runs first, then add). |
| `remove_item.item_id`                                 | `string`        | Yes      | ID of the trip item to remove. Matches the value returned in the trip response items\[].item\_id field.                                                                                                                           |
| `upsert_travelers`                                    | `object`        | No       | Set or update travelers and contact info on the trip. Optional per call (you can add\_item while building the cart), but travelers and a contact must be present before booking.                                                  |
| `upsert_travelers.travelers`                          | `array<object>` | Yes      | List of travelers (replaces all). Required to complete a booking; the first traveler also supplies the booking contact name.                                                                                                      |
| `upsert_travelers.travelers[].first_name`             | `string`        | Yes      | First name as on the travel document.                                                                                                                                                                                             |
| `upsert_travelers.travelers[].last_name`              | `string`        | Yes      | Last name as on the travel document.                                                                                                                                                                                              |
| `upsert_travelers.travelers[].passenger_type`         | `string`        | Yes      | One of `ADULT` (12+), `CHILD` (2–11), `INFANT` (under 2).                                                                                                                                                                         |
| `upsert_travelers.travelers[].date_of_birth`          | `string`        | Flights  | `YYYY-MM-DD`. Required for flights; optional for hotel-only trips.                                                                                                                                                                |
| `upsert_travelers.travelers[].gender`                 | `string`        | Flights  | One of `MALE`, `FEMALE`. Required for flights; optional for hotel-only trips.                                                                                                                                                     |
| `upsert_travelers.travelers[].frequent_flyer`         | `object`        | No       | Optional per-passenger frequent-flyer membership, so miles are credited on the booking. Flights only (ignored for hotel-only trips). When present, both sub-fields are required.                                                  |
| `upsert_travelers.travelers[].frequent_flyer.airline` | `string`        | Cond.    | IATA code of the loyalty **program issuer** (e.g. `LH` for Lufthansa Miles & More), not necessarily the operating carrier — alliances credit miles on partner flights. Required when `frequent_flyer` is present.                 |
| `upsert_travelers.travelers[].frequent_flyer.number`  | `string`        | Cond.    | Membership / account number for that program. Required when `frequent_flyer` is present.                                                                                                                                          |
| `upsert_travelers.contact`                            | `object`        | Yes      | Booking contact (email + phone, both required). Required before the trip can be booked.                                                                                                                                           |
| `select_ancillaries`                                  | `object`        | No       | Select ancillaries (bags, seats, meals) for a quoted trip item. Uses full-replacement semantics: send all desired selections.                                                                                                     |
| `select_ancillaries.item_id`                          | `string`        | Yes      | ID of the trip item to select ancillaries for. Get from trip response trip\_items\[].id                                                                                                                                           |
| `select_ancillaries.selections`                       | `array<object>` | Yes      | Ancillary selections. Full replacement: send all desired selections each time. Get offer\_ids from trip\_item.available\_ancillaries\[].offer\_id                                                                                 |

## Examples

**Create a new trip (add flight + set travelers in one call):**

```json theme={null}
{
  "name": "trip",
  "arguments": {
    "add_item": {
      "trip_item_token": "offer_abc123:fare_xyz"
    },
    "upsert_travelers": {
      "travelers": [
        {
          "first_name": "Jane",
          "last_name": "Doe",
          "date_of_birth": "1990-01-15",
          "gender": "FEMALE",
          "passenger_type": "ADULT",
          "frequent_flyer": { "airline": "LH", "number": "992100100" }
        }
      ],
      "contact": {
        "email": "jane@example.com",
        "phone": "+33612345678"
      }
    }
  }
}
```

**Add a hotel to an existing trip:**

```json theme={null}
{
  "name": "trip",
  "arguments": {
    "trip_id": "42",
    "add_item": { "trip_item_token": "htl_abc..." }
  }
}
```

**Update travelers only (no new items):**

```json theme={null}
{
  "name": "trip",
  "arguments": {
    "trip_id": "42",
    "upsert_travelers": {
      "travelers": [
        { "first_name": "Jane", "last_name": "Doe", "date_of_birth": "1990-01-15", "gender": "FEMALE", "passenger_type": "ADULT", "frequent_flyer": { "airline": "LH", "number": "992100100" } },
        { "first_name": "John", "last_name": "Doe", "date_of_birth": "2015-05-20", "gender": "MALE", "passenger_type": "CHILD" }
      ],
      "contact": { "email": "jane@example.com", "phone": "+33612345678" }
    }
  }
}
```

**Add a frequent-flyer number:**

Each traveler can carry an optional `frequent_flyer` object so miles are credited on the booking. `airline` is the IATA code of the **program issuer** (e.g. `LH` for Lufthansa Miles & More), not necessarily the operating carrier, since alliances credit miles on partner flights. Both `airline` and `number` are required when the object is present.

```json theme={null}
{
  "name": "trip",
  "arguments": {
    "trip_id": "42",
    "upsert_travelers": {
      "travelers": [
        {
          "first_name": "Jane",
          "last_name": "Doe",
          "date_of_birth": "1990-01-15",
          "gender": "FEMALE",
          "passenger_type": "ADULT",
          "frequent_flyer": { "airline": "LH", "number": "992100100" }
        }
      ]
    }
  }
}
```

<Warning>
  Traveler details must match real travel documents, airlines enforce name / DOB matching and reject bookings where they don't. Never let an agent fabricate these.
</Warning>

The response includes `trip_id`, the current item list, and totals. Use `trip_id` with `checkout` when you're ready to check out.
