Docs / SDKs / TypeScript
TypeScript SDK
@teo-core/sdk for Node 18+ and modern browsers. Zero external dependencies.
Install
npm install @teo-core/sdk
Configure
import { TEO } from '@teo-core/sdk';
const teo = new TEO({
apiKey: process.env.TEO_API_KEY!,
// Optional: override base URL for local gateway.
// baseUrl: 'https://teofetch-api.onrender.com',
});Scored search
teo.search() runs a flight search and scores every result with TEOScore in a single call — use this when you want ranked results. See the Search API reference for the full schema.
const result = await teo.search({
origin: 'JFK',
destination: 'LHR',
departureDate: '2026-08-15',
returnDate: '2026-08-22',
passengers: { adults: 1 },
cabinClass: 'business',
searchMode: 'all', // 'all' | 'award' | 'cash'
});
// Flights come back in result.providerOptions, and the TEOScore for
// each is in result.teoscoreOptions (joined by optionId):
for (const option of result.providerOptions) {
const scored = result.teoscoreOptions.find((s) => s.optionId === option.id);
console.log(option.id, scored?.teoScore, scored?.rank);
}Category labels
Each scored option carries a categoryScores map keyed by the eight canonical TEO21 category labels, exported as TEO_SCORE_CATEGORY_LABELS.
import {
TEO_SCORE_CATEGORY_LABELS,
normalizeTeoScoreCategoryLabel,
} from '@teo-core/sdk';
// TEO_SCORE_CATEGORY_LABELS (spec order, Categories 1-8):
// 'Financial Value & Loyalty'
// 'Schedule & Time Efficiency'
// 'Routing & Logistics'
// 'Risk & Protection'
// 'Ground Experience & Ancillaries'
// 'Cabin Comfort & Hardware'
// 'Seating Logistics & Strategy'
// 'Ground Connectivity'
const score = scored.categoryScores?.['Financial Value & Loyalty'];Migration (v0.3.0): these labels were renamed to match the TEO21 spec (for example Economic Value → Financial Value & Loyalty). The SDK types are unchanged (categoryScores is a Record<string, number>), so this is not a compile break — but the string values differ. If you keyed off the older labels, map them onto the canonical set with normalizeTeoScoreCategoryLabel(label).
Raw flight search (no score)
teo.flights.search() returns raw flight data without a TEOScore. Use includeCash and/or includeAward to choose which fare types come back.
const result = await teo.flights.search({
origin: 'JFK',
destination: 'LHR',
departureDate: '2026-08-15',
returnDate: '2026-08-22',
cabin: 'business',
travelers: { adults: 1 },
includeCash: true,
includeAward: true,
});
// Response shape:
// {
// queryId: string,
// totalResults: number,
// options: [
// { id, provider, currency, totalPrice, awardPrice, cabin, duration,
// details: { flightLegs: [...] } }
// ]
// }
for (const option of result.options) {
console.log(option.id, option.totalPrice, option.awardPrice, option.cabin);
}Reference data: airports, airlines, aircraft
listAirports(), listAirlines() and listAircraft() return provider reference data. On an airport, only id and name are guaranteed — every other field is null for sparse records, which is most of the table.
const { data } = await teo.flights.listAirports({ limit: 50 });
for (const airport of data) {
// Always present:
console.log(airport.id, airport.name);
// Nullable — a large hub has these, a regional airstrip does not:
console.log(airport.city_name ?? '—');
console.log(airport.iata_code ?? '—');
console.log(airport.city?.name ?? '—');
if (airport.latitude != null && airport.longitude != null) {
plot(airport.latitude, airport.longitude);
}
}Migration (v0.4.0): city_name, iata_city_code, iata_country_code, latitude, longitude, time_zone and city were typed as required or non-nullable through v0.3.0. They are now ?: T | null. Under strictNullChecks this is a compile break: code like const city: string = airport.city_name needs a null check. The old types never described a real response — the same wrong shape on the server made GET /v1/flights/airports return 502 on every call until 2026-08-25, so the break surfaces an assumption that was already unsound rather than changing behaviour.
Retries
The SDK retries idempotent 5xx and 429 responses with exponential backoff. Set maxRetries to 0 to disable.
const teo = new TEO({ apiKey, maxRetries: 5 });Pagination
for await (const key of teo.apiKeys.listAll()) {
// SDK handles cursors automatically.
}List methods return an async iterator. The SDK handles cursors automatically and stops when hasMoreis false.
Errors
The SDK throws typed errors. AuthError for 401, PermissionError for 403, RateLimitError for 429, ValidationError for 422, NotFoundError for 404, ConflictError for 409. All extend TEOError.