npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@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-client

Quick 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:

  1. apiKey option passed to createJinkoClient()
  2. JINKO_API_KEY environment variable
  3. ~/.jinko/config.yaml — API key or OAuth tokens (managed by jinko 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_booking returns 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 / PNRs

Quote 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' },
});