Booking Tickets

This guide covers the complete booking process, from creating a booking to receiving confirmed tickets.

Understanding the Booking Lifecycle

The booking process includes these stages:

  1. Booking: A temporary reservation that holds your selected offers. Bookings expire if not converted to orders within a set time (check the expiresAt field).

  2. Order: The confirmed purchase. Creating an order pre-books the tickets with the train operator. At this point, tickets are reserved but not yet issued.

  3. Finalized Order: Completes the purchase and triggers ticket issuance. After finalization, tickets are automatically generated.

  4. Tickets Issued: Digital tickets become available for download. This usually happens within 15 minutes of finalization.

Creating a Booking

Start by creating a booking from one or more offer IDs. This verifies avaialbility but doesn't reserve them yet.

You can optionally provide passengers when creating the booking to set up passenger details upfront. The passenger types and ages/birth dates must match those used when fetching the original offer. For YOUTH and SENIOR passengers, you must provide either birthDate or age to validate fare eligibility.

Example: Create a booking
graphql
mutation CreateBooking {
  createBooking(
    offerIds: ["offer_m7v416q0d0v524h2p434x3t614"]
    passengers: [
      { type: ADULT, firstName: "Jane", lastName: "Doe" }
      { type: YOUTH, age: 22, firstName: "John", lastName: "Doe" }
    ]
  ) {
    id
    passengers {
      id
      age
      type
    }
    requirements {
      passportNumber
      dateOfBirth
      nationality
      email
      tel
    }
    selections {
      ... on JourneyOfferSelection {
        offers {
          ...OfferFragment
        }
        journey {
          ... on JourneySelection {
            itinerary {
              ... on Stopover {
                location {
                  name
                }
              }
              ... on SegmentCollection {
                status
                segments {
                  departureAt
                  arrivalAt
                  origin {
                    name
                  }
                  destination {
                    name
                  }
                }
                offers {
                  ...OfferFragment
                }
              }
            }
          }
        }
      }
    }
  }
}

fragment OfferFragment on Offer {
  id
  price {
    amount
    currency
  }
  parts {
    ... on AdmissionPart {
      conditions {
        description
        type
      }
      flexibility
      serviceClass
      comfortClass
    }
    ... on ReservationPart {
      conditions {
        description
        type
      }
      flexibility
      comfortClass
      accommodation {
        type
      }
    }
  }
}
mutation CreateBooking {
  createBooking(
    offerIds: ["offer_t3c7m2p3y401x074b3v232a331"]
    passengers: [
      { type: ADULT, firstName: "Jane", lastName: "Doe" }
      { type: YOUTH, age: 22, firstName: "John", lastName: "Doe" }
    ]
  ) {
    id
    passengers {
      id
      age
      type
    }
    requirements {
      passportNumber
      dateOfBirth
      nationality
      email
      tel
    }
    selections {
      ... on JourneyOfferSelection {
        offers {
          ...OfferFragment
        }
        journey {
          ... on JourneySelection {
            itinerary {
              ... on Stopover {
                location {
                  name
                }
              }
              ... on SegmentCollection {
                status
                segments {
                  departureAt
                  arrivalAt
                  origin {
                    name
                  }
                  destination {
                    name
                  }
                }
                offers {
                  ...OfferFragment
                }
              }
            }
          }
        }
      }
    }
  }
}

fragment OfferFragment on Offer {
  id
  price {
    amount
    currency
  }
  parts {
    ... on AdmissionPart {
      conditions {
        description
        type
      }
      flexibility
      serviceClass
      comfortClass
    }
    ... on ReservationPart {
      conditions {
        description
        type
      }
      flexibility
      comfortClass
      accommodation {
        type
      }
    }
  }
}

The booking includes requirements that tell you what passenger information is needed. Different train operators require different details. Some need passport numbers, others just names and dates of birth.

Booking expiration

Bookings expire if not converted to orders. Check the expiresAt field to see how long you have.

Updating Passengers Details

Before you can create an order, ensure that all required passenger information is provided. The booking's requirements field shows exactly what's needed.

Contact person

At least one passenger needs to be marked as the contact person. The contact person's details will be forwarded to the train operator and is the person who will be contacted in case of any issues. The contact person must provide both email and phone number.

Example: Updating passengers details
graphql
mutation UpdatePassengers {
  updateBooking(
    id: "booking_m1y707p1v5d6y3r0c3j6w1r0b6"
    passengers: [
      {
        id: "e96511b5-50a5-4d75-b772-c5d3d0d21f8d"
        email: "jane.doe@example.com"
        isContactPerson: true
        birthDate: "1980-02-15"
        nationality: "NL"
        firstName: "Jane"
        lastName: "Doe"
      }
    ]
  ) {
    id
    passengers {
      ... on FullPassenger {
        id
        isContactPerson
        email
        birthDate
        nationality
        firstName
        lastName
        title
      }
    }
  }
}
mutation UpdatePassengers {
  updateBooking(
    id: "booking_m1y707p1v5d6y3r0c3j6w1r0b6"
    passengers: [
      {
        id: "e96511b5-50a5-4d75-b772-c5d3d0d21f8d"
        email: "jane.doe@example.com"
        isContactPerson: true
        birthDate: "1980-02-15"
        nationality: "NL"
        firstName: "Jane"
        lastName: "Doe"
      }
    ]
  ) {
    id
    passengers {
      ... on FullPassenger {
        id
        isContactPerson
        email
        birthDate
        nationality
        firstName
        lastName
        title
      }
    }
  }
}

Selecting Offers

The offers you pass to createBooking via offerIds are used as the initial selection. Each journey segment may have additional offers available with different fare types or service levels. You can change these selections by updating the booking (updateBooking):

Example: Select specific offers
graphql
mutation SelectOffer {
  updateBooking(
    id: "booking_m1y707p1v5d6y3r0c3j6w1r0b6"
    selections: [{ offer: { id: "offer_p7s6a5w2p6f4q534p4b0k5e595" } }]
  ) {
    selections {
      ... on JourneyOfferSelection {
        offers {
          id
          price {
            amount
            currency
          }
          parts {
            ... on AdmissionPart {
              flexibility
              serviceClass
              comfortClass
            }
            ... on ReservationPart {
              flexibility
              comfortClass
              accommodation {
                type
              }
            }
          }
        }
      }
    }
  }
}
mutation SelectOffer {
  updateBooking(
    id: "booking_m1y707p1v5d6y3r0c3j6w1r0b6"
    selections: [{ offer: { id: "offer_h306a203z1w7r1p3c7d2s06093" } }]
  ) {
    selections {
      ... on JourneyOfferSelection {
        offers {
          id
          price {
            amount
            currency
          }
          parts {
            ... on AdmissionPart {
              flexibility
              serviceClass
              comfortClass
            }
            ... on ReservationPart {
              flexibility
              comfortClass
              accommodation {
                type
              }
            }
          }
        }
      }
    }
  }
}

Selecting Seat Preferences

Some offers include place properties: options for seat preferences, sleeping accommodations, or special requirements. These might include:

  • Window or aisle seat preference
  • Upper or lower berth (for night trains)
  • Special meal requirements
  • Accessibility needs

Some place properties are required (you must select an option), while others are optional. Check the required field to see which ones you need to set. Use updatePart to set place properties.

Example: Select seat preferences
graphql
query GetBooking {
  node(id: "booking_m1y707p1v5d6y3r0c3j6w1r0b6") {
    ... on Booking {
      selections {
        ... on JourneyOfferSelection {
          offers {
            parts {
              ... on ReservationPart {
                id
                placeProperties {
                  id
                  type
                  required
                  availableOptions {
                    id
                    value
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}
query GetBooking {
  node(id: "booking_m1y707p1v5d6y3r0c3j6w1r0b6") {
    ... on Booking {
      selections {
        ... on JourneyOfferSelection {
          offers {
            parts {
              ... on ReservationPart {
                id
                placeProperties {
                  id
                  type
                  required
                  availableOptions {
                    id
                    value
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}
graphql
mutation UpdatePart {
  updatePart(
    id: "7f4391c4-f3ad-4bb1-8246-61e42023a3c5"
    booking: "booking_m1y707p1v5d6y3r0c3j6w1r0b6"
    placeProperties: [{
      propertyId: "00872abf-e589-4572-9db4-96de24bd26d9",
      optionId: "20b4462c-8971-43ab-8ef2-f8fe1b5689ff"
    }]
  ) {
    selections {
      ... on JourneyOfferSelection {
        offers {
          parts {
            ... on ReservationPart {
              id
              placeProperties {
                selectedOption {
                  id
                  value
                }
              }
            }
          }
        }
      }
    }
  }
}
mutation UpdatePart {
  updatePart(
    id: "dc4d6cf6-082f-40f8-a81b-f29b90ea0cb9"
    booking: "booking_m1y707p1v5d6y3r0c3j6w1r0b6"
    placeProperties: [{
      propertyId: "69e6fcc3-92e1-4df8-a9f7-4c426012da38",
      optionId: "de0ef564-3987-4c5f-ba76-d0181247dfa9"
    }]
  ) {
    selections {
      ... on JourneyOfferSelection {
        offers {
          parts {
            ... on ReservationPart {
              id
              placeProperties {
                selectedOption {
                  id
                  value
                }
              }
            }
          }
        }
      }
    }
  }
}

Using the Offer Selection Embed

For a ready-made user interface, consider using the Offer Selection Embed. The embed provides an intuitive interface for selecting an offer, place properties and ancillaries, useful to quickly set up a booking flow on your website without writing any custom UI code.

html
<aa-offer-selection
  publicApiKey="my-api-key"
  booking="booking_m1y707p1v5d6y3r0c3j6w1r0b6"
  offer="offer_h1r6p437430741v4n0k4g2j2f4"></aa-offer-selection>
<aa-offer-selection
  publicApiKey="my-api-key"
  booking="booking_m1y707p1v5d6y3r0c3j6w1r0b6"
  offer="offer_s6p3q6f7w5f18046e5r115w737"></aa-offer-selection>

Creating and Finalizing Orders

Once your booking has all passenger details and selected offers, you're ready to create an order. How you do this depends on your payment method:

Payment Methods

Most API users don't use the payment gateway. Instead, they use one of these methods:

  1. Wallet (Pre-paid Credits): Most common for API integrations. You maintain a balance of credits that are used for orders. Credits are deducted when you finalize an order.

  2. Payment Gateway: For end-customer payments. Redirects customers to All Aboard's payment page to pay, then automatically creates and finalizes the order. See Payments for details.

  3. Invoice: Available for vetted commercial clients only. Orders are invoiced monthly.

Using Wallet or Invoice

If you're using wallet credits or invoice billing, create the order manually:

  1. Create the order: Call createOrder. This pre-books the tickets with the train operator
  2. Finalize the order: Call finalizeOrder. This completes the purchase and triggers ticket issuance

Both steps happen immediately. There's no payment redirect.

Example: Create and finalize order (wallet/invoice)
graphql
mutation CreateOrder {
  createOrder(booking: "booking_m1y707p1v5d6y3r0c3j6w1r0b6") {
    id
    status
    reference
  }
}

mutation FinalizeOrder {
  finalizeOrder(order: "order_31r441m642c625p09103j457e7") {
    id
    status
    reference
  }
}
mutation CreateOrder {
  createOrder(booking: "booking_m1y707p1v5d6y3r0c3j6w1r0b6") {
    id
    status
    reference
  }
}

mutation FinalizeOrder {
  finalizeOrder(order: "order_p167y4t5t1g655z4w5k0h1w782") {
    id
    status
    reference
  }
}

Creating an order can take up to 30 seconds because it pre-books tickets with train operators. Use WebSocket connections to avoid timeouts and see progress updates.

Using Payment Gateway

If you're collecting payment from end customers, use the payment gateway flow (createPayment). This automatically creates and finalizes the order after payment:

Example: Create payment (gateway)
graphql
mutation CreatePayment {
  createPayment(
    booking: "booking_m1y707p1v5d6y3r0c3j6w1r0b6"
    successUrl: "https://example.com/success/{order}"
    cancelUrl: "https://example.com/cancel"
  ) {
    url
  }
}
mutation CreatePayment {
  createPayment(
    booking: "booking_m1y707p1v5d6y3r0c3j6w1r0b6"
    successUrl: "https://example.com/success/{order}"
    cancelUrl: "https://example.com/cancel"
  ) {
    url
  }
}

Redirect the customer to the returned URL. After payment, they're redirected back to your successUrl with the order ID, and the order is automatically finalized.

See Payments for complete details on the payment gateway flow.

Retrieving Tickets

Once an order is finalized, tickets are automatically issued. Fetch them using the node query. This usually takes 15 minutes or more. Train operators need time to generate and deliver the tickets.

Tickets come in different formats depending on the operator:

PDF Tickets

Most tickets are PDF files that passengers can download and show on their phone or print. These are the most common format.

Some operators require passengers to check in online before departure. The API provides a check-in URL where passengers complete the process and receive their tickets.

Ticket Collection References

Some UK operators issue "Ticket on Departure" references. Passengers use these at station ticket machines to collect physical tickets.

Example: Get tickets from finalized order
graphql
query GetTickets {
  node(id: "order_46k3h3g3p434v5h6x11112d6a4") {
    ... on Order {
      items {
        ... on JourneyOrderItem {
          resources {
            ... on PdfTicket {
              url
            }
            ... on CheckInResource {
              url
            }
            ... on TicketOnDeparture {
              reference
              description
            }
          }
        }
      }
    }
  }
}
query GetTickets {
  node(id: "order_t2s5y1q0p0j34163974402h6a7") {
    ... on Order {
      items {
        ... on JourneyOrderItem {
          resources {
            ... on PdfTicket {
              url
            }
            ... on CheckInResource {
              url
            }
            ... on TicketOnDeparture {
              reference
              description
            }
          }
        }
      }
    }
  }
}

Ticket availability

Tickets may not be available immediately after finalization. Poll the order every few minutes until resources appear. Most tickets are available within 15 minutes, but some can take longer.

Complete Flow Summary

The complete booking flow from start to finish:

  1. Search for journeys between locations
  2. Get offers for the journey you want
  3. Create booking from one or more offer IDs (createBooking), optionally with passengers
  4. Add passenger details (if not already provided during booking creation)
  5. Select offers (if you want different options than defaults)
  6. Select seat preferences (if applicable)
  7. Create order (createOrder to pre-book tickets)
  8. Finalize order (finalizeOrder to complete purchase and trigger ticket issuance)
  9. Retrieve tickets (download PDFs or get collection references)

For detailed information on each step, see the relevant sections in this documentation.