NurCore API
SDKs & Examples

TypeScript Client

Минимальный TypeScript wrapper для NurCore API.

Готового npm-пакета пока нет. Ниже — компактный standalone wrapper, который можно скопировать в свой проект и адаптировать.

Базовый client

type ApiOptions = {
  baseUrl: string;
  apiKey: string;  // тип клиента и client_id определяются по самому ключу на сервере
};

class NurCoreClient {
  constructor(private opts: ApiOptions) {}

  private async request<T>(path: string, init: RequestInit = {}): Promise<T> {
    const headers: Record<string, string> = {
      "Content-Type": "application/json",
      "X-API-Key": this.opts.apiKey,
      ...((init.headers as Record<string, string>) || {}),
    };

    const res = await fetch(`${this.opts.baseUrl}${path}`, { ...init, headers });
    if (!res.ok) {
      const detail = await res.json().catch(() => ({}));
      throw Object.assign(new Error(detail.detail || res.statusText), {
        status: res.status,
        detail: detail.detail,
        headers: Object.fromEntries(res.headers.entries()),
      });
    }
    if (res.status === 204) return undefined as T;
    return res.json();
  }

  get<T>(path: string, qs?: Record<string, any>) {
    const url = qs ? `${path}?${new URLSearchParams(qs as any)}` : path;
    return this.request<T>(url);
  }

  post<T>(path: string, body?: any) {
    return this.request<T>(path, {
      method: "POST",
      body: JSON.stringify(body || {}),
    });
  }

  patch<T>(path: string, body?: any) {
    return this.request<T>(path, {
      method: "PATCH",
      body: JSON.stringify(body || {}),
    });
  }

  delete<T>(path: string) {
    return this.request<T>(path, { method: "DELETE" });
  }
}

export const api = new NurCoreClient({
  baseUrl: "https://api.nurcore.kg/api/v1",
  apiKey: process.env.NURCORE_API_KEY!,
});

Примеры

Поиск рейсов

interface Flight {
  id: string;
  flight_number: string;
  scheduled_departure: string;
  scheduled_arrival: string;
  status: string;
  total_seats: number;
  booked_seats: number;
}

const result = await api.get<{ data: Flight[]; total: number }>(
  "/schedules/flights/",
  { route_code: "BSZ-OSS", flight_date: "2026-05-10" }
);

console.log(`Found ${result.total} flights`);

Создание брони

interface Booking {
  id: string;
  booking_reference: string;
  status: string;
  total_amount: number;
  currency: string;
  expiry_date: string | null;
}

const booking = await api.post<Booking>("/bookings/", {
  flight_id: "...",
  fare_price_id: "...",
  passengers: [
    {
      first_name: "JOHN",
      last_name: "DOE",
      passenger_type: "adult",
      date_of_birth: "1990-01-15",
      gender: "male",
      nationality: "KGZ",
      document_type: "passport",
      document_number: "AN1234567",
    },
  ],
  contact_email: "user@example.com",
  contact_phone: "+996555000000",
});

console.log(`Created PNR: ${booking.booking_reference}`);
async function loadPublicBooking(bookingId: string, accessToken: string) {
  const res = await fetch(
    `https://api.nurcore.kg/api/v1/bookings/${bookingId}/public?access_token=${accessToken}`
  );
  if (!res.ok) throw new Error("Failed");
  return res.json();
}

async function consumerCheckin(
  bookingId: string,
  passengerId: string,
  flightId: string,
  seatNumber: string,
  accessToken: string
) {
  const res = await fetch(
    `https://api.nurcore.kg/api/v1/checkin/consumer?access_token=${accessToken}`,
    {
      method: "POST",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify({
        booking_id: bookingId,
        passenger_id: passengerId,
        flight_id: flightId,
        seat_number: seatNumber,
      }),
    }
  );
  if (!res.ok) throw new Error("Checkin failed");
  return res.json();
}

React + TanStack Query

import { useQuery, useMutation } from "@tanstack/react-query";

export function useBooking(id: string) {
  return useQuery({
    queryKey: ["booking", id],
    queryFn: () => api.get(`/bookings/${id}`),
    enabled: !!id,
  });
}

export function useConfirmBooking() {
  return useMutation({
    mutationFn: (id: string) => api.post(`/bookings/${id}/confirm`, {}),
  });
}

Best practices

  • Не размещайте API Key в frontend-bundle. Используйте серверный proxy (BFF — Backend for Frontend), который добавляет заголовки и пробрасывает запросы.
  • Для magic-link flow X-API-Key не нужен — token уже встроен в URL.
  • Кешируйте справочники (airports, fare-families) на стороне клиента.

On this page