Skip to main content
This guide walks you through booking a real flight from start to finish. The same flow works regardless of interface, so each step shows three variants: SDK, CLI, and MCP. The one-line version of the flow:

Prerequisites

  • A Jinko account and an API key (jnk_...). Get one.
  • For the SDK path: Node.js 20 or later, then npm install @gojinko/api-client.
  • For the CLI path: npm install -g @gojinko/cli && jinko auth login --key jnk_....
  • For the MCP path: any MCP client connected to https://mcp.builders.gojinko.com/mcp.

1) Discover flights

Start with discovery. It is cached, fast, and broad.

2) Live pricing

Discovery returns cached prices. Before booking, confirm them with flight_search. flight_search is a flat request: origin, destination, and departure_date are required (return_date for round-trips). To re-price a specific candidate from discovery, also pass its offer_token, but the route and dates are still required alongside it. The response is an offers[] list, and each offer carries a fares[] array. A fare’s trip_item_token is ready to drop straight into a trip, no assembly required.
If the response status is flight_unavailable, the flight sold out between discovery and now, and the alternatives[] field has replacements. Loop back to discovery or present them to the user.

3) Build the trip

Now you have a live trip_item_token. Add it to a trip AND set travelers in one call:

4) Quote and select ancillaries (optional)

If you want to preselect bags, seats, or meals before checkout, list what’s available with getAncillaries (it surfaces the ancillaries without generating a checkout URL), then pre-select. (Make sure travelers are set first; ancillaries are priced per passenger.)
You don’t have to pre-select. Your user can pick on the Stripe checkout page. Skip this step if you want the simplest flow.

5) Checkout

Create the Stripe checkout session:
The checkout_url points at app.gojinko.com/checkout, a Stripe-hosted page Jinko owns.
On REST / CLI / SDK, checkout is synchronous: it schedules the quote, polls until it’s ready, and returns the full checkout envelope in one call: { session_id, checkout_url, agent_spt_params, status: "ready", total_amount, items }. (On MCP, the booking widget drives this interactively instead of returning the envelope.) Either way, fulfillment still happens asynchronously after the user pays. See steps 7 to 8.
Paying agentically (no browser)? checkout also returns agent_spt_params. Mint a Shared Payment Token scoped to those params, then authorize the booking server-side with submit_agent_payment (jinko agent-pay submit --trip-id "$TRIP_ID" --token "$SPT" / client.submitAgentPayment(tripId, spt)). If the card issuer requires 3DS, the response falls back to a checkout_url.

6) User pays

Send the user to checkout_url. They:
  1. Confirm the itinerary.
  2. Pick ancillaries (if not pre-selected).
  3. Enter payment.
  4. Stripe holds the authorization.

7) Fulfillment is automatic

Once the user pays, Stripe webhooks trigger fulfillment on the API. No client-side confirm step is needed. Fulfillment states (get_trip → fulfillment.status):

8) Watch the booking land

Poll get_trip until fulfillment.status is terminal:

What’s next?

  • Add a hotel to the trip: see the Flight + Hotel guide for one trip with two items.
  • Hotel-only booking: see the Hotel booking guide.
  • Refund a booking: Refund flow, refund-check then refund-commit then refund-status.
  • Exchange dates: Exchange flow, a four-step variant of the booking flow.
  • Troubleshooting: Errors has the full status-code reference.