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 a journey offer. This reserves the journey but doesn't confirm it yet. You'll add passenger details and select specific offers next.
Example: Create a booking
graphql
mutation CreateBooking {
createBooking(journeyOffer: "7a341862-5c91-4cbc-82f1-010c8bd7e7e8") {
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(journeyOffer: "cb860c0d-cac4-48c2-91c9-dce0fc54a868") {
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.
Adding Passenger Details
Before you can create an order, you must provide all required passenger information. The booking's requirements field tells you exactly what's needed.
One passenger must be marked as the contact person (isContactPerson: true). This person receives booking confirmations and is contacted if there are issues. The contact person must provide both email and phone number.
Example: Update passenger details
graphql
mutation UpdatePassengers {
updateBooking(
id: "503776b6-3d98-4903-adab-1b5ba9f64e80"
passengers: [
{
id: "b9ddd550-1970-45c7-8cab-52d0c89a89ac"
email: "jane.doe@example.com"
isContactPerson: true
birthDate: "1980-02-15"
nationality: "NL"
firstName: "Jane"
lastName: "Doe"
title: MS
}
]
) {
id
passengers {
... on FullPassenger {
id
isContactPerson
email
birthDate
nationality
firstName
lastName
title
}
}
}
}mutation UpdatePassengers {
updateBooking(
id: "503776b6-3d98-4903-adab-1b5ba9f64e80"
passengers: [
{
id: "b9ddd550-1970-45c7-8cab-52d0c89a89ac"
email: "jane.doe@example.com"
isContactPerson: true
birthDate: "1980-02-15"
nationality: "NL"
firstName: "Jane"
lastName: "Doe"
title: MS
}
]
) {
id
passengers {
... on FullPassenger {
id
isContactPerson
email
birthDate
nationality
firstName
lastName
title
}
}
}
}Selecting Offers
When you create a booking, the API automatically selects default offers (usually the most affordable options). You can change these selections if you want different fare types or service levels.
Each journey segment has multiple offers available. Update the booking (updateBooking) to select the offers you want:
Example: Select specific offers
graphql
mutation SelectOffer {
updateBooking(
id: "503776b6-3d98-4903-adab-1b5ba9f64e80"
selections: [{ offer: { id: "7057ab29-2656-48b1-91c4-77e75ebd2849" } }]
) {
selections {
... on JourneyOfferSelection {
offers {
id
price {
amount
currency
}
parts {
... on AdmissionPart {
flexibility
serviceClass
comfortClass
}
... on ReservationPart {
flexibility
comfortClass
accommodation {
type
}
}
}
}
}
}
}
}mutation SelectOffer {
updateBooking(
id: "503776b6-3d98-4903-adab-1b5ba9f64e80"
selections: [{ offer: { id: "b61af44a-1a04-4956-b84a-ec6c9116ade7" } }]
) {
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: "503776b6-3d98-4903-adab-1b5ba9f64e80") {
... on Booking {
selections {
... on JourneyOfferSelection {
offers {
parts {
... on ReservationPart {
id
placeProperties {
id
type
required
availableOptions {
id
value
}
}
}
}
}
}
}
}
}
}query GetBooking {
node(id: "503776b6-3d98-4903-adab-1b5ba9f64e80") {
... on Booking {
selections {
... on JourneyOfferSelection {
offers {
parts {
... on ReservationPart {
id
placeProperties {
id
type
required
availableOptions {
id
value
}
}
}
}
}
}
}
}
}
}graphql
mutation UpdatePart {
updatePart(
id: "e62d06a7-30d7-4806-83b2-a41183b9a923"
booking: "503776b6-3d98-4903-adab-1b5ba9f64e80"
placeProperties: [{
propertyId: "cc3f7817-a919-484d-a6d3-4df3a519be11",
optionId: "6b7c4e88-d72a-4fd7-be2d-d26513bdc5e8"
}]
) {
selections {
... on JourneyOfferSelection {
offers {
parts {
... on ReservationPart {
id
placeProperties {
selectedOption {
id
value
}
}
}
}
}
}
}
}
}mutation UpdatePart {
updatePart(
id: "f2588b13-0ea1-42cc-993c-6491f33181e6"
booking: "503776b6-3d98-4903-adab-1b5ba9f64e80"
placeProperties: [{
propertyId: "380a14b9-1a2d-4f31-abd4-6bd6c5399b56",
optionId: "79a97e8f-0f06-4d6c-80ad-ef95e96ceb53"
}]
) {
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-id"
offer="offer-id"></aa-offer-selection><aa-offer-selection
publicApiKey="my-api-key"
booking="booking-id"
offer="offer-id"></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: "503776b6-3d98-4903-adab-1b5ba9f64e80") {
id
status
reference
}
}
mutation FinalizeOrder {
finalizeOrder(order: "b81b4895-28c3-422a-beb7-d16a418d1d6c") {
id
status
reference
}
}mutation CreateOrder {
createOrder(booking: "503776b6-3d98-4903-adab-1b5ba9f64e80") {
id
status
reference
}
}
mutation FinalizeOrder {
finalizeOrder(order: "15c34be0-add3-4f5d-be30-1374e6d446cf") {
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: "503776b6-3d98-4903-adab-1b5ba9f64e80"
successUrl: "https://example.com/success/{order}"
cancelUrl: "https://example.com/cancel"
) {
url
}
}mutation CreatePayment {
createPayment(
booking: "503776b6-3d98-4903-adab-1b5ba9f64e80"
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: "2dfaea11-cfba-4fc7-bea1-f5f742d5c14e") {
... on Order {
items {
... on JourneyOrderItem {
resources {
... on PdfTicket {
url
}
... on CheckInResource {
url
}
... on TicketOnDeparture {
reference
description
}
}
}
}
}
}
}query GetTickets {
node(id: "b3a4b4e7-6e37-46e7-98a6-0d4ebfe01f29") {
... 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 the offer (
createBooking) - Add passenger details (required information)
- 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.