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:
Booking: A temporary reservation that holds your selected offers. Bookings expire if not converted to orders within a set time (check the
expiresAtfield).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.
Finalized Order: Completes the purchase and triggers ticket issuance. After finalization, tickets are automatically generated.
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:
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.
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.
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:
- Create the order: Call
createOrder. This pre-books the tickets with the train operator - 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.
Check-in Links
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:
- Search for journeys between locations
- Get offers for the journey you want
- Create booking from one or more offer IDs (
createBooking), optionally with passengers - Add passenger details (if not already provided during booking creation)
- Select offers (if you want different options than defaults)
- Select seat preferences (if applicable)
- Create order (
createOrderto pre-book tickets) - Finalize order (
finalizeOrderto complete purchase and trigger ticket issuance) - Retrieve tickets (download PDFs or get collection references)
For detailed information on each step, see the relevant sections in this documentation.