@gojinko/api-client
v2.14.0
Published
Typed API client for the Jinko BFF. Methods mirror the MCP tools and CLI commands 1:1.
Readme
@gojinko/api-client
Typed API client for the Jinko BFF. Methods mirror the MCP tools and CLI commands 1:1.
Install
npm install @gojinko/api-clientQuick Start
import { createJinkoClient } from '@gojinko/api-client';
// Uses credentials from ~/.jinko/config.yaml or JINKO_API_KEY env
const client = await createJinkoClient();
// Or pass an API key directly
const client = await createJinkoClient({ apiKey: 'jnk_...' });Authentication
The client resolves credentials automatically in this order:
apiKeyoption passed tocreateJinkoClient()JINKO_API_KEYenvironment variable~/.jinko/config.yaml— API key or OAuth tokens (managed byjinko auth login)
OAuth tokens auto-refresh when they expire.
Methods
The client targets the jinko-api public surface (https://api.gojinko.com,
canonical /v1/* routes). Authenticate with a jnk_ API key (X-API-Key).
Discovery (cached)
| Method | Endpoint |
|---|---|
| client.findFlight() | POST /v1/flight_calendar |
| client.flightCalendar() | POST /v1/flight_calendar |
| client.findDestination() | POST /v1/find_destination |
Live search & trip building
| Method | Endpoint |
|---|---|
| client.flightSearch() | POST /v1/flight_search |
| client.hotelSearch() | POST /v1/hotel_search |
| client.hotelDetails() | GET /v1/hotel_details/{hotel_id} |
| client.trip() | POST /v1/trip |
| client.getTrip(tripId) | GET /v1/trip/{trip_id} |
Checkout
| Method | Endpoint |
|---|---|
| client.book(tripId) | POST /v1/book |
| client.selectAncillaries() | POST /v1/select_ancillaries |
Post-booking
| Method | Endpoint |
|---|---|
| client.getBooking() | POST /v1/get_booking |
| client.refundCheck() | POST /v1/refund_check |
| client.refundCommit() | POST /v1/refund_commit |
| client.refundStatus() | POST /v1/refund_status |
| client.exchangeShop() | POST /v1/exchange_shop |
| client.exchangePrice() | POST /v1/exchange_price |
| client.exchangeCommit() | POST /v1/exchange_commit |
| client.exchangeStatus() | POST /v1/exchange_status |
| client.hotelCancelBooking() | POST /v1/hotel_cancel |
get_bookingreturns the whole booking (flight + hotel). There is no separate hotel-retrieve method on the public surface.
Usage
flight_search — Live search / price-check
Preferred flight entry point. Returns a bookable trip_item_token in one step.
// Search mode — canonical flat body (adults at top level)
const results = await client.flightSearch({
origin: 'PAR',
destination: 'NYC',
departure_date: '2026-06-15',
trip_type: 'oneway',
adults: 1,
});
// Price-check mode (returns trip_item_token)
const fares = await client.flightSearch({
offer_token: 'tok_abc123',
adults: 1,
});hotel_search — Live hotel search
Returns hotels with rooms + rates. Each rate's offer_id (an htl_* token) plugs into trip(add_item) exactly like a flight trip_item_token — flights and hotels share one cart.
const results = await client.hotelSearch({
city_name: 'Paris',
country_code: 'fr',
checkin: '2026-07-15',
checkout: '2026-07-18',
adults: 2,
});
// → { hotels: [ { hotel_id, name, star_rating, rooms: [ { rates: [ { offer_id: 'htl_...', total_amount, ... } ] } ] } ] }
// Pick a rate's offer_id and add to a trip — same call shape as flights:
await client.trip({ add_item: { trip_item_token: 'htl_xxx:rate_yyy' } });trip — Create trip, add flight or hotel, set travelers
const trip = await client.trip({
add_item: { trip_item_token: 'tok_xyz' },
upsert_travelers: {
travelers: [{
first_name: 'Jane',
last_name: 'Doe',
date_of_birth: '1990-01-15',
gender: 'FEMALE',
passenger_type: 'ADULT',
// Optional per-traveler loyalty program. airline = IATA code of the
// program issuer (e.g. 'LH'), not necessarily the operating carrier.
frequent_flyer: { airline: 'LH', number: '992100100' },
}],
contact: { email: '[email protected]', phone: '+33612345678' },
},
});
// → { trip_id, ... }book — Schedule checkout
const checkout = await client.book('42');
// {
// session_id, checkout_url, expires_at, status,
// total_amount: { amount, currency },
// items: [ ... ],
// }
// Send the user to checkout.checkout_url to complete payment.selectAncillaries — Add baggage, seats, meals
await client.selectAncillaries({
trip_id: '42',
item_id: 'item_1',
selections: [
{ offer_id: 'offer_bag_checked_1', quantity: 1 },
{ offer_id: 'offer_seat_12A', pax_ref_id: 'pax_1', quantity: 1 },
],
});getTrip — Full lifecycle state
const status = await client.getTrip('42');
// {
// trip_id, status,
// travelers, contact, items, total_amount,
// quote: { quoted_cart_id, status, expires_at },
// fulfillment: { fulfillment_cart_id, status, phase, scheduled_at },
// bookings: [ { item_id, booking_reference, pnr, provider_status } ],
// created_at, updated_at,
// }Poll getTrip() until status === 'fulfilled' (or 'partially_fulfilled') to read the PNRs.
refundCheck / refundCommit
Two auth modes: guest (booking_ref + last_name) or authenticated (order_id).
const eligibility = await client.refundCheck({ booking_ref: 'JNK-ABC123', last_name: 'Doe' });
const refund = await client.refundCommit({ booking_ref: 'JNK-ABC123', last_name: 'Doe' });Token Flow
findFlight / findDestination / flightCalendar → offer_token (cached, flights)
flightSearch (offer_token) → trip_item_token (live, flights)
hotelSearch → htl_* offer_id (live, hotels)
trip (trip_item_token OR htl_* + travelers) → trip_id (multi-domain)
book (trip_id) → checkout_url + items + ancillaries
[user pays on checkout_url]
getTrip (trip_id) → bookings / PNRsQuote is automatic — it's handled internally by book(). You don't call it.
Error Handling
import { createJinkoClient, ApiError, AuthError } from '@gojinko/api-client';
try {
const client = await createJinkoClient();
} catch (error) {
if (error instanceof AuthError) {
// No credentials configured — run `jinko auth login`
}
if (error instanceof ApiError) {
console.error(error.code, error.message, error.statusCode);
}
}Types
All request/response types are derived from the canonical public-api.yaml
contract (regenerated into src/types/generated.ts):
import type {
FlightDiscoveryRequest,
FindDestinationRequest,
FlightSearchRequest,
HotelSearchRequest,
HotelDetailsRequest,
TripRequest,
BookRequest,
BookResponse,
GetTripResponse,
AncillaryRequest,
BookingGetRequest,
BookingGetResponse,
RefundCheckRequest,
RefundCommitRequest,
Traveler,
Money,
} from '@gojinko/api-client';The generated paths and components from the OpenAPI spec are also exported
for advanced use.
Raw Client
The underlying openapi-fetch client is still accessible and is typed against the
jinko-api /v1/* surface:
const response = await client.raw.POST('/v1/flight_search', {
body: { origin: 'JFK', destination: 'LAX', departure_date: '2026-09-01' },
});