Getting Your Baby on a Train Through the KAI API

So you want to book a train ticket for an infant through the KAI API system. This is one of those edge cases in the API workflow that trips people up because the documentation glosses over infant handling. Most developers just try to slot a baby into a regular passenger payload and get rejected. Here is how it actually works in practice. The core issue is that KAI's API treats passengers under 2 years old differently from everyone else. They do not get their own seat assignment in the standard sense. Instead, they are linked as an infant companion to an adult ticket. The API endpoint for creating a booking expects a passenger array, and within that array there is a specific field for passenger type or age category. You need to flag the child as an infant, provide the adult's booking reference as the parent record, and supply the child's birth date. Nothing complicated if you know the shape of the request.

Ultan Akal Syarat Naik Kereta API Untuk Bayi Panduan Lengkap Mudah

This is where most people go wrong. They think they can create two separate PNRs and then somehow link them. The system does not work that way. You must add the infant during the same booking transaction as the adult. I spent about three hours debugging a sandbox flow where I was trying to retroactively attach a baby to an existing adult reservation. The API simply returns a validation error because infant records must be part of the initial passenger list. After I realized this, I adjusted the payload to include both passengers upfront and it worked on the next attempt. Here is the practical flow. First, you authenticate and get your access token through the standard KAI OAuth2 flow. Then you search for available trains using the route and date parameters. Once you select a seat or class, you build the passenger object. For the adult, you fill in the normal fields. For the infant, you include the passport or birth certificate number, the full name, and set the age category to infant. The API will calculate the fare automatically, which is typically a reduced rate or sometimes free depending on the route and carrier policy. One thing the docs do not make clear is that the infant does not generate a separate seat map entry. You are essentially attaching a second passenger record that references the adult's seat. This means if you are booking business or executive class, the infant shares the same space. It sounds obvious but I saw several support tickets from people confused about why no seat number appeared for the child. There is no seat number. It is not assigned one.

Common Pitfalls and What to Watch For

The age limit is strict. If the child is 2 years or older on the date of travel, the system will reject an infant booking and require a regular child fare. Make sure your date calculation is based on the departure date, not the booking date. I once had a case where a child turned 2 between booking and travel, and the reservation was flagged at check-in. The agent had to issue a supplemental fare on the spot, which caused a delay and some friction. Documentation requirements vary by route. For domestic trips in Indonesia, a birth certificate or family card is sufficient. If the itinerary involves any cross-border segments, the infant will need a passport. The API itself does not validate document type. It only checks that a document number exists. So you need to handle that validation on your end before submitting the request. I usually run a simple check: if the route contains a border crossing, enforce passport format. Otherwise accept the Indonesian ID formats. Payment for infant bookings sometimes behaves oddly in the sandbox. The total amount shown may not include the infant fare initially. The final charge appears only after the booking is confirmed. This is a known behavior in their test environment and does not reflect a bug. In production, the invoice should reflect the correct total. Still, I recommend verifying the line item breakdown before confirming payment, especially when integrating with a third-party checkout flow.

Get the Full Details

Panduan Lengkap: Cara Mudah Naik Kereta Api untuk Pemula
Panduan Lengkap: Cara Mudah Naik Kereta Api untuk Pemula

When the API Approach Fails

There are scenarios where the API is not the best path. If you are building a high-volume booking system and expect a significant portion of reservations to include infants, the manual payload construction can become error-prone. The infant field requirements are not always consistent across different train classes. Some classes have additional restrictions or require manual verification after booking. In those cases, it is faster to handle the infant booking through the KAI call center or counter after securing the adult ticket online. This is slower and less elegant, but it avoids the back-and-forth that comes from API rejections. Another limitation is that the API does not always expose real-time seat availability for infant configurations. You might see an available seat, submit the booking with an infant, and receive an error saying the configuration is not supported for that particular train. This happens more often on peak travel days. The workaround is to retry with a different train or class if the first attempt fails. I built a retry loop with a fallback to alternate schedules, which cut my rejection rate from about 12 percent down to under 3 percent. The API response structure for infant passengers also lacks some detail compared to adult bookings. Field names can be inconsistent, and error messages are sometimes vague. A validation failure might return a generic code without explaining that the birth date was interpreted as the child being over 2 years old. I ended up writing a small validation layer that pre-checks the child's age against the travel date before sending anything to the API. It added maybe ten lines of code but saved a lot of retry traffic and user confusion.

Final Notes on Implementation

If you are integrating this into a larger system, store the infant booking reference alongside the adult's. They are separate records in the database even though they are linked in the API. When your users query their booking history, you will want to display them together. Building that association requires you to maintain the relationship explicitly, because the API does not return a nested infant list in the adult booking response. You have to match them yourself using the passenger identifiers or the parent reference field. The entire process from authentication to confirmed booking for an infant ticket usually takes under two minutes if the request is well-formed. With retries and validation logic, it can stretch to five or six minutes. That is acceptable for most use cases. The main bottleneck is not the API speed. It is the pre-checks and fallback handling that eat up time.