Adrasis™

Trip bundling

Group any mix of confirmed hotel, transfer, tour, and flight bookings into one trip itinerary without combining their finances.

A trip groups any mix of confirmed hotel, transfer, tour, and flight bookings into one itinerary. The grouping is non-destructive and money-free: each member keeps its own total, its own cancellation policy, and its own lifecycle. The trip is a view over them, not a new priced product.

Book each leg first through its own vertical, then link the resulting public_ids into a trip. All trip endpoints require the distribution:booking scope.

Every trip carries a link_type that records the regulatory relationship between the grouped bookings:

link_type Meaning
1 Package
2 Linked travel arrangement
3 Operational grouping (itinerary convenience only)

link_type: 1 records a regulatory relationship over independent bookings. It does not produce an atomic package: there is no single inclusive price and no all-or-nothing finalize. To sell several services as one contract, use Package booking instead.

Create a trip

POST /api/v1/trip

Groups the listed bookings. member_booking_public_ids is optional at creation, so you can create an empty trip and add members later. A booking already linked to an active trip returns 409 BOOKING_ALREADY_LINKED; a referenced booking that does not exist returns 404 BOOKING_NOT_FOUND.

curl -s -X POST \
  https://ari.console.adrasis.com/api/v1/trip \
  -H 'Authorization: Bearer eyJ...' \
  -H 'Content-Type: application/json' \
  -d '{
    "link_type": 1,
    "title": "Antalya in July",
    "member_booking_public_ids": ["bk_8H2nQ4pZ", "bk_Tf81nQ4p", "bk_Fl63kZ0m"]
  }'
{
  "trip": {
    "public_id": "tp_Jul9Xy2",
    "link_type": 1,
    "title": "Antalya in July",
    "status": 0,
    "members": [
      { "booking_public_id": "bk_8H2nQ4pZ", "booking_number": 100482, "product_type": 1, "status": "CONFIRMED", "currency_code": "EUR", "total_amount": "300.00", "sequence": 1 },
      { "booking_public_id": "bk_Tf81nQ4p", "booking_number": 100731, "product_type": 2, "status": "CONFIRMED", "currency_code": "EUR", "total_amount": "54.00", "sequence": 2 },
      { "booking_public_id": "bk_Fl63kZ0m", "booking_number": 100755, "product_type": 4, "status": "CONFIRMED", "currency_code": "EUR", "total_amount": "540.00", "sequence": 3 }
    ],
    "combined_totals": [
      { "currency_code": "EUR", "total_amount": "894.00", "count": 3 }
    ]
  },
  "trace_id": "0f2c9d6e-7b1a-4c3e-9a2f-1d6e7b1a4c3e"
}

combined_totals is reported per currency and is never netted across currencies. A trip mixing EUR and TRY members returns one entry for each. product_type is 1 hotel, 2 transfer, 3 tour, 4 flight.

Read a trip

GET /api/v1/trip/{public_id}

Returns every member envelope plus the per-currency combined totals. A missing trip returns 404 TRIP_NOT_FOUND.

curl -s \
  https://ari.console.adrasis.com/api/v1/trip/tp_Jul9Xy2 \
  -H 'Authorization: Bearer eyJ...'

Add and remove members

POST   /api/v1/trip/{public_id}/members
DELETE /api/v1/trip/{public_id}/members/{booking_public_id}

Adding links one more booking; a booking already in an active trip returns 409 BOOKING_ALREADY_LINKED. Removing unlinks the membership only. The booking itself is never touched and stays independently cancellable. Removing an absent membership is a no-op. Both return the updated trip projection.

curl -s -X POST \
  https://ari.console.adrasis.com/api/v1/trip/tp_Jul9Xy2/members \
  -H 'Authorization: Bearer eyJ...' \
  -H 'Content-Type: application/json' \
  -d '{ "booking_public_id": "bk_To52pZ9k" }'

Cancel a whole trip

POST /api/v1/trip/{public_id}/cancel

A convenience cancel-all: it drives the canonical per-booking cancel for every member. Members are independent. A non-cancellable or already-cancelled member is reported in its own outcome and is never rolled back against the others. Each cancellation applies that booking's own penalty. The body is optional.

curl -s -X POST \
  https://ari.console.adrasis.com/api/v1/trip/tp_Jul9Xy2/cancel \
  -H 'Authorization: Bearer eyJ...' \
  -H 'Content-Type: application/json' \
  -d '{ "reason": "traveller cancelled the trip" }'
{
  "trip_public_id": "tp_Jul9Xy2",
  "outcomes": [
    { "booking_public_id": "bk_8H2nQ4pZ", "status": "CANCELLED", "penalty": "0.00" },
    { "booking_public_id": "bk_Tf81nQ4p", "status": "CANCELLED", "penalty": "54.00" },
    { "booking_public_id": "bk_Fl63kZ0m", "status": "CANCELLED", "penalty": "540.00" }
  ],
  "trace_id": "0f2c9d6e-7b1a-4c3e-9a2f-1d6e7b1a4c3e"
}

To cancel a single member instead, use the canonical two-phase cancel on that booking's /bookings/{public_id}. See The booking flow.