/** Shape of the `nvvo_<48 hex>` key validation regex. */
declare const API_KEY_PATTERN: RegExp;
/** SDK semver, embedded in the default User-Agent. Kept in sync with package.json. */
declare const SDK_VERSION = "0.1.0";
/** Default base URL for the Navvo Web Service. */
declare const DEFAULT_BASE_URL = "https://navvo.io/api/v1";
/** Retry / exponential-backoff configuration. */
interface RetryConfig {
    /** Max retry attempts after the first try (so total tries = retries + 1). Default 3. */
    retries: number;
    /** Base delay for backoff in ms. Default 500. */
    baseDelayMs: number;
    /** Exponential growth factor. Default 2. */
    factor: number;
    /** Apply full jitter to each backoff. Default true. */
    jitter: boolean;
    /** Cap on a single backoff sleep in ms. Default 20000. */
    maxDelayMs: number;
    /** Honour the `Retry-After` header on 429/503. Default true. */
    respectRetryAfter: boolean;
    /**
     * Also retry envelope `available:false` responses (treated as a transient
     * upstream outage). Off by default — these surface as
     * `NavvoServiceUnavailableError` immediately.
     */
    retryUnavailable: boolean;
}
/** Per-request telemetry event passed to the optional hooks. */
interface RequestEvent {
    method: string;
    path: string;
    attempt: number;
    statusCode?: number;
    durationMs?: number;
    retryAfter?: number;
    requestId?: string;
    /** Redacted key, never the full value. */
    redactedKey: string;
    error?: unknown;
}
/** Optional observability hooks. All are best-effort and never throw into the caller. */
interface TelemetryConfig {
    enabled?: boolean;
    onRequest?: (e: RequestEvent) => void;
    onResponse?: (e: RequestEvent) => void;
    onRetry?: (e: RequestEvent) => void;
    onError?: (e: RequestEvent) => void;
}
/** User-facing options accepted by the {@link NavvoClient} constructor. */
interface NavvoClientOptions {
    /** The `nvvo_…` key. Falls back to `process.env.NAVVO_API_KEY` when omitted. */
    apiKey?: string;
    /** Override the base URL (staging / self-hosted). Default `https://navvo.io/api/v1`. */
    baseUrl?: string;
    /** Per-attempt request timeout in ms. Default 15000. */
    timeoutMs?: number;
    /** Retry / backoff tuning. Merged over the defaults. */
    retry?: Partial<RetryConfig>;
    /** String appended to the default User-Agent (e.g. your app id). */
    userAgent?: string;
    /** Extra headers added to every request. */
    defaultHeaders?: Record<string, string>;
    /** Observability hooks. */
    telemetry?: TelemetryConfig;
    /**
     * Allow a non-HTTPS `baseUrl` (only for local mock testing). Default false —
     * a plain-HTTP base URL otherwise throws to avoid leaking the key.
     */
    allowInsecure?: boolean;
    /**
     * Inject a custom fetch implementation (advisable only for tests). Defaults
     * to the global `fetch` (Node 18+).
     */
    fetch?: typeof fetch;
}
/** Fully-resolved, immutable client configuration. */
interface ResolvedConfig {
    apiKey: string;
    baseUrl: string;
    timeoutMs: number;
    retry: RetryConfig;
    userAgent: string;
    defaultHeaders: Record<string, string>;
    telemetry: TelemetryConfig;
    fetch: typeof fetch;
    /** `nvvo_****<last4>` — safe to log. */
    redactedKey: string;
}
/** Redact a key to `nvvo_****<last4>` for safe logging. Never returns the full key. */
declare function redactKey(key: string): string;
/**
 * Resolve, validate and freeze user options into a {@link ResolvedConfig}.
 *
 * Throws {@link NavvoConfigError} for a missing/malformed key, a missing
 * `fetch`, or an insecure base URL.
 */
declare function resolveConfig(options?: NavvoClientOptions): ResolvedConfig;

/**
 * Coordinate value types and serialisation helpers.
 *
 * Navvo's coordinate order is **not** uniform across engines. The SDK's job is
 * to stop callers from ever getting lng/lat backwards: you always supply a
 * named {@link LatLng} `{ lat, lng }`, and the SDK serialises it to whatever
 * each endpoint expects (`{ lon, lat }`, `{ lat, lng }`, WKT, bbox string, …).
 */
/** A geographic point with explicit, named fields. Optionally labelled. */
interface LatLng {
    lat: number;
    lng: number;
    /** Optional stop name (used by `/routing/plan` locations). */
    name?: string;
}
/** A bounding box. Longitude-first on the wire, but named here. */
interface BBox {
    /** Minimum longitude. */
    west: number;
    /** Minimum latitude. */
    south: number;
    /** Maximum longitude. */
    east: number;
    /** Maximum latitude. */
    north: number;
}
/** Validate a {@link LatLng} and return it (throws on non-finite/out-of-range). */
declare function assertLatLng(p: LatLng): LatLng;
/** Serialise a {@link BBox} to the wire string `west,south,east,north`. */
declare function bboxToString(b: BBox): string;
/** Parse a GeoJSON `[lng, lat]` pair into a {@link LatLng}. */
declare function fromGeoJSON(coord: [number, number]): LatLng;
/** Convert a {@link LatLng} to a GeoJSON `[lng, lat]` pair. */
declare function toGeoJSON(p: LatLng): [number, number];
/**
 * Parse a WKT `POINT(<lng> <lat>)` string (used by place `center` / entrance
 * `location`) into a {@link LatLng}. Returns `null` for null/empty/malformed
 * input so callers can fall back gracefully.
 */
declare function parseWktPoint(wkt: string | null | undefined): LatLng | null;
/**
 * Decode an encoded polyline into `LatLng[]`.
 *
 * Navvo's routing engine returns leg shapes as polyline6 (precision 1e6).
 * Pass `precision = 5` for classic precision-1e5 polylines if you ever need it.
 */
declare function decodePolyline(encoded: string, precision?: number): LatLng[];

/** Per-call options every public method accepts as an optional last argument. */
interface RequestOptions {
    /** Caller-supplied abort signal for cancellation / external timeouts. */
    signal?: AbortSignal;
    /** Override the per-attempt timeout for this single call. */
    timeoutMs?: number;
    /** Extra one-off headers. */
    headers?: Record<string, string>;
}
/** Build a full URL with a serialised query string from a descriptor. */
declare function buildUrl(baseUrl: string, path: string, query?: Record<string, unknown>): string;

/**
 * Typed request and response models for the Navvo Web Service.
 *
 * These are best-effort shapes derived from the public API reference at
 * https://docs.navvo.io. Every response also surfaces unknown fields, so
 * forward-compatible additions never break callers; where the wire shape is
 * loose (raw routing-engine passthrough) we type the known fields and leave an
 * index signature for the rest.
 */

/** Travel modes accepted by routing/optimization. */
type Costing = "auto" | "pedestrian" | "bicycle" | "motor_scooter" | "truck" | "bus" | "taxi" | "wheelchair";
/** Routing route-shape preference. */
type Preference = "fastest" | "shortest" | "balanced";
/** Things a route may avoid. */
type AvoidOption = "tolls" | "highways" | "ferries" | "unpaved";
/** Optimization quality tiers (search time tradeoff). */
type OptimizeTier = "fast" | "balanced" | "best";
/** Units for distance fields. */
type Units = "kilometers" | "miles";
interface StylesResponse {
    styles?: Array<{
        id?: string;
        name?: string;
        [k: string]: unknown;
    }>;
    [k: string]: unknown;
}
interface MapConfigResponse {
    [k: string]: unknown;
}
interface SearchOptions {
    /** Result language: `en` (default) or `ar`. */
    lang?: string;
    /** Alias for `lang` (the API parameter is `locale`). */
    locale?: string;
    limit?: number;
    page?: number;
    /** Viewbox bias `west,south,east,north`. */
    bbox?: BBox;
}
interface SearchPlaceItem {
    id: string;
    slug: string;
    nameEn?: string;
    nameAr?: string;
    categories?: string[];
    canonicalCategorySlug?: string;
    rawCategories?: string[];
    rating?: number;
    sponsored?: boolean;
    /** WKT `POINT(lng lat)`. */
    center?: string;
    [k: string]: unknown;
}
interface SearchResponse {
    query?: string;
    locale?: string;
    understanding?: Record<string, unknown>;
    places?: {
        items: SearchPlaceItem[];
        total: number;
        page: number;
        limit: number;
    };
    index?: Record<string, unknown>;
    [k: string]: unknown;
}
interface GeocodeOptions {
    locale?: string;
    limit?: number;
    /** Proximity bias point (applied only when both lat & lng present). */
    near?: LatLng;
    bbox?: BBox;
}
/** A forward/reverse geocode hit. `lat`/`lng` are parsed to numbers by the SDK. */
interface GeocodeResult {
    placeId?: number;
    osmType?: string;
    osmId?: number;
    lat: number;
    lng: number;
    name?: string;
    displayName?: string;
    category?: string;
    type?: string;
    address?: Record<string, string>;
    boundingBox?: [number, number, number, number];
    /** The raw, untyped geocoder object for forward-compat. */
    raw: Record<string, unknown>;
}
/** A single result row from `POST /geocode/batch`. */
interface BatchGeocodeResult {
    query: string;
    found: boolean;
    lat: number | null;
    lng: number | null;
    displayName?: string;
    type?: string;
    category?: string;
    [k: string]: unknown;
}
/** A single result row from `POST /geocode/reverse-batch`. */
interface ReverseBatchGeocodeResult {
    lat: number;
    lng: number;
    found: boolean;
    displayName?: string;
    type?: string;
    address?: Record<string, string>;
    [k: string]: unknown;
}
interface PlaceListOptions {
    q?: string;
    page?: number;
    limit?: number;
    category?: string;
    amenities?: string[];
    openNow?: boolean;
    sort?: "relevance" | "rating" | "name" | "newest" | "oldest";
    minRating?: number;
    near?: LatLng;
    radiusKm?: number;
    sponsored?: boolean;
}
interface PlaceEntrance {
    id?: string;
    type?: string;
    label?: string;
    /** WKT `POINT(lng lat)`. */
    location?: string;
    [k: string]: unknown;
}
interface Place {
    id: string;
    slug: string;
    nameEn?: string;
    nameAr?: string;
    logoUrl?: string | null;
    categories?: string[];
    canonicalCategorySlug?: string;
    /** WKT `POINT(lng lat)`. Use {@link parseWktPoint} or the client helper. */
    center?: string;
    contact?: Record<string, unknown>;
    openingHours?: Record<string, unknown>;
    sponsored?: boolean;
    claimStatus?: string;
    /** Raw rating is a string on place objects; SDK exposes a number where it parses. */
    rating?: string | number | null;
    entrances?: PlaceEntrance[];
    distanceKm?: number;
    [k: string]: unknown;
}
interface PlaceDetail extends Place {
    reviews?: Array<Record<string, unknown>>;
    photos?: Array<Record<string, unknown>>;
    questions?: Array<Record<string, unknown>>;
    reports?: Array<unknown>;
    arrivalIntelligence?: ArrivalIntelligence;
}
interface ArrivalCandidate {
    entranceId?: string;
    type?: string;
    coordinates?: {
        lng: number;
        lat: number;
    };
    distanceFromPlaceMeters?: number;
    score?: number;
    recommended?: boolean;
    lastMetersGuidance?: string;
    /** Recommended entrance to route to. */
    routeTarget?: {
        lat: number;
        lng: number;
    };
    [k: string]: unknown;
}
interface ArrivalIntelligence {
    version?: string;
    placeCenter?: {
        lng: number;
        lat: number;
    };
    recommendedEntranceId?: string;
    candidates?: ArrivalCandidate[];
    microMap?: Record<string, unknown>;
    [k: string]: unknown;
}
interface PlacePage {
    items: Place[];
    total: number;
    page: number;
    limit: number;
    [k: string]: unknown;
}
interface PlaceThumb {
    url: string | null;
    source: string | null;
    rating: number | null;
    openState: "open" | "closing" | "closed" | null;
    openText: string | null;
    [k: string]: unknown;
}
interface PlaceCategoriesResponse {
    provider?: string;
    count?: number;
    rootCount?: number;
    categories: PlaceCategoryNode[];
    [k: string]: unknown;
}
interface PlaceCategoryNode {
    slug: string;
    nameEn?: string;
    nameAr?: string;
    iconName?: string;
    color?: string;
    placeCount?: number;
    totalPlaces?: number;
    children?: PlaceCategoryNode[];
    [k: string]: unknown;
}
interface PlaceFacetsResponse {
    scanned?: number;
    capped?: boolean;
    groups: Array<{
        id: string;
        name: string;
        total?: number;
        options: Array<{
            slug: string;
            label: string;
            count: number;
        }>;
    }>;
    [k: string]: unknown;
}
interface PlaceHoursResponse {
    slug: string;
    hasHours: boolean;
    at?: string;
    weekly: Record<string, string> | null;
    openState: "open" | "closing" | "closed" | null;
    openText: string | null;
    nextChange: Record<string, unknown> | null;
    holiday: Record<string, unknown> | null;
    [k: string]: unknown;
}
interface PlacePhotosResponse {
    slug: string;
    name?: string;
    total: number;
    page: number;
    limit: number;
    count: number;
    photos: Array<{
        id?: string;
        url: string;
        caption?: string | null;
        featured?: boolean;
        mediaType?: string;
        createdAt?: string;
        [k: string]: unknown;
    }>;
    [k: string]: unknown;
}
interface PlaceNearbyResponse {
    slug: string;
    center?: {
        lat: number;
        lng: number;
    };
    radiusKm?: number;
    sameCategory?: boolean;
    anchorCategory?: string | null;
    count?: number;
    places: Array<{
        slug: string;
        name?: string;
        category?: string;
        rating?: number;
        distanceKm?: number;
        [k: string]: unknown;
    }>;
    [k: string]: unknown;
}
interface ReachableOptions {
    origin: LatLng;
    minutes?: number;
    costing?: "pedestrian" | "auto" | "bicycle";
    q?: string;
    categories?: string[];
    amenities?: string[];
    limit?: number;
}
interface ReachableResponse {
    provider?: string;
    available?: boolean;
    origin?: {
        lat: number;
        lng: number;
    };
    minutes?: number;
    costing?: string;
    candidatesInBbox?: number;
    count?: number;
    reachable: Array<{
        id?: string;
        slug?: string;
        name?: string;
        category?: string;
        rating?: number;
        lat?: number;
        lng?: number;
        [k: string]: unknown;
    }>;
    isochrone?: Record<string, unknown>;
    [k: string]: unknown;
}
interface RoutePlanRequest {
    /** ≥2 stops. */
    locations: LatLng[];
    costing?: Costing;
    preference?: Preference;
    avoid?: AvoidOption[];
    optimize?: boolean;
    avoidIncidents?: boolean;
    avoidReported?: boolean;
    /** Per-user sign featureKeys to disregard. */
    disregard?: string[];
    /** Free-text delivery constraints, AI-parsed into a constraints block. */
    constraintsText?: string;
    /** Default true; set false to skip the ~1–2s AI label. */
    includeLabels?: boolean;
    language?: string;
    /** Truck dimensions / hazmat. */
    vehicle?: TruckDimensions;
    /** Alias for {@link vehicle} (kept for clarity in delivery code). */
    truck?: TruckDimensions;
    departureTime?: string;
}
interface TruckDimensions {
    heightM?: number;
    widthM?: number;
    lengthM?: number;
    weightT?: number;
    axleLoadT?: number;
    hazmat?: boolean;
}
/** A constraint-application block from a route plan. */
interface ConstraintBlock {
    applied?: boolean;
    blockingCount?: number;
    noEntryCount?: number;
    source?: string;
    [k: string]: unknown;
}
interface RoutePlanResponse {
    provider?: string;
    engine?: {
        provider?: string;
        available?: boolean;
        path?: string;
        data?: {
            trip?: RouteTrip;
            alternates?: Array<{
                trip?: RouteTrip;
            }>;
        };
        [k: string]: unknown;
    };
    labels?: Record<string, unknown>;
    constraints?: Record<string, unknown> | null;
    logistics?: Record<string, unknown>;
    routeProfile?: Record<string, unknown>;
    signConstraints?: ConstraintBlock;
    incidentConstraints?: ConstraintBlock;
    reportedConstraints?: ConstraintBlock;
    roadEditConstraints?: ConstraintBlock;
    [k: string]: unknown;
}
interface RouteTrip {
    legs?: Array<{
        maneuvers?: Array<Record<string, unknown>>;
        summary?: {
            time?: number;
            length?: number;
            [k: string]: unknown;
        };
        shape?: string;
        [k: string]: unknown;
    }>;
    summary?: {
        time?: number;
        length?: number;
        has_toll?: boolean;
        has_highway?: boolean;
        has_ferry?: boolean;
        [k: string]: unknown;
    };
    locations?: Array<Record<string, unknown>>;
    status?: number;
    units?: string;
    language?: string;
    [k: string]: unknown;
}
/** Generic routing-engine passthrough envelope (`{ provider, available, path, data }`). */
interface RoutingEnvelope<D = Record<string, unknown>> {
    provider?: string;
    available?: boolean;
    path?: string;
    data?: D;
    labels?: Record<string, unknown>;
    [k: string]: unknown;
}
/** A simple-route request (passthrough `{ lat, lon }` locations). */
interface SimpleRouteRequest {
    locations: LatLng[];
    costing?: Costing;
    units?: Units;
    language?: string;
    alternates?: number;
    /** Anything else forwarded verbatim to the routing engine. */
    [k: string]: unknown;
}
interface MatrixRequest {
    sources: LatLng[];
    targets: LatLng[];
    costing?: Costing;
    units?: Units;
    [k: string]: unknown;
}
interface IsochroneRequest {
    locations: LatLng[];
    costing?: Costing;
    contours: Array<{
        minutes?: number;
        km?: number;
        color?: string;
    }>;
    polygons?: boolean;
}
interface MapMatchRequest {
    shape?: Array<LatLng & {
        time?: number;
    }>;
    encodedPolyline?: string;
    costing?: Costing;
    shapeMatch?: "map_snap" | "edge_walk" | "walk_or_snap";
    [k: string]: unknown;
}
interface OptimizeOrderRequest {
    locations: LatLng[];
    costing?: Costing;
    [k: string]: unknown;
}
interface RoutingProfilesResponse {
    provider?: string;
    profiles: Array<{
        costing: string;
        label?: string;
        available?: boolean;
        description?: string;
    }>;
    preferences?: string[];
    avoid?: string[];
    constraints?: string[];
    [k: string]: unknown;
}
interface OptimizeRoutesRequest {
    /** Index 0 = depot. */
    stops: LatLng[];
    numVehicles?: number;
    costing?: "auto" | "truck" | "bicycle" | "pedestrian";
    tier?: OptimizeTier;
    demands?: number[];
    vehicleCapacities?: number[];
    /** `[earliest,latest]` seconds per stop. */
    timeWindows?: Array<[number, number]>;
    serviceTimes?: number[];
    pickupsDeliveries?: Array<[number, number]>;
    dropPenalty?: number;
    maxRouteDuration?: number;
    openEnded?: boolean;
}
interface OptimizeReoptimizeRequest {
    vehiclePositions: LatLng[];
    remainingStops: LatLng[];
    costing?: "auto" | "truck" | "bicycle" | "pedestrian";
    tier?: OptimizeTier;
    demands?: number[];
    vehicleCapacities?: number[];
    dropPenalty?: number;
}
interface OptimizeBinpackRequest {
    itemWeights: number[];
    binCapacities: number[];
}
interface OptimizeRosterRequest {
    numDrivers: number;
    numDays: number;
    shiftsPerDay?: number;
    demand: number[][];
    maxShiftsPerDriver?: number;
    minRestDays?: number;
    forbidden?: Array<[number, number]>;
}
interface OptimizeSolution {
    provider?: string;
    feasible: boolean;
    objective?: {
        totalDurationSec?: number;
        vehiclesUsed?: number;
    };
    dropped?: number[];
    routes?: Array<{
        vehicle: number;
        durationSec?: number;
        order?: number[];
        stops?: Array<{
            lat: number;
            lng: number;
        } | string>;
    }>;
    [k: string]: unknown;
}
interface OptimizeBinpackSolution {
    feasible: boolean;
    assignment?: number[];
    binsUsed?: number;
    [k: string]: unknown;
}
interface OptimizeRosterSolution {
    feasible: boolean;
    shifts?: Array<{
        driver: number;
        day: number;
        shift: number;
    }>;
    perDriver?: number[];
    peakLoad?: number;
    [k: string]: unknown;
}
interface OptimizeHealthResponse {
    provider?: string;
    available?: boolean;
    ok?: boolean;
    service?: string;
    solvers?: string[];
    [k: string]: unknown;
}
type OptimizeJobKind = "routes" | "reoptimize" | "roster" | "binpack";
interface OptimizeJobSubmitResponse {
    jobId: string;
    status: string;
    kind: string;
    [k: string]: unknown;
}
interface OptimizeJobStatusResponse {
    id: string;
    kind: string;
    status: "running" | "completed" | "failed" | "unknown";
    createdAt?: number;
    finishedAt?: number;
    result?: OptimizeSolution | OptimizeBinpackSolution | OptimizeRosterSolution;
    error?: string;
    [k: string]: unknown;
}
interface WaitForJobOptions {
    /** Total time to keep polling before giving up, ms. Default 120000. */
    timeoutMs?: number;
    /** Delay between polls, ms. Default 1500. */
    pollMs?: number;
    signal?: AbortSignal;
}
interface TrafficRouteRequest {
    locations: LatLng[];
    costing?: Costing;
    preference?: Preference;
    avoid?: AvoidOption[];
    language?: string;
    [k: string]: unknown;
}
interface TrafficSummaryResponse {
    [k: string]: unknown;
}
interface IncidentsOptions {
    bbox?: BBox;
    type?: string;
    limit?: number;
}
interface GeoJSONFeatureCollection {
    type: "FeatureCollection";
    features: Array<{
        type: "Feature";
        properties: Record<string, unknown>;
        geometry: Record<string, unknown>;
    }>;
    [k: string]: unknown;
}
interface ReportIncidentRequest {
    type: string;
    lat: number;
    lng: number;
    description?: string;
    [k: string]: unknown;
}
interface WeatherPointResponse {
    [k: string]: unknown;
}
interface WeatherForecastResponse {
    [k: string]: unknown;
}
interface WeatherCitiesResponse {
    [k: string]: unknown;
}
interface AirQualityCitiesResponse {
    [k: string]: unknown;
}
interface EvStationsOptions {
    bbox?: BBox;
    limit?: number;
}
interface EvStationsResponse {
    [k: string]: unknown;
}
interface TransitStopsResponse {
    [k: string]: unknown;
}
interface GbfsResponse {
    [k: string]: unknown;
}

/**
 * The Navvo server-side client.
 *
 * One instance per API key/project. Cheap and safe for concurrent use across
 * async tasks. Every method returns a `Promise` and accepts an optional last
 * argument with `{ signal, timeoutMs, headers }` for cancellation and per-call
 * overrides.
 *
 * ```ts
 * import { NavvoClient } from "@navvo/sdk";
 * const navvo = new NavvoClient({ apiKey: process.env.NAVVO_API_KEY });
 * const hits = await navvo.geocode("Abdali Hospital, Amman");
 * ```
 */
declare class NavvoClient {
    /** The resolved, frozen configuration. */
    readonly config: ResolvedConfig;
    private readonly transport;
    constructor(options?: NavvoClientOptions);
    /** Construct a client reading `NAVVO_API_KEY` from the environment. */
    static fromEnv(options?: Omit<NavvoClientOptions, "apiKey">): NavvoClient;
    /** A clone of this client that uses a different API key (multi-tenant servers). */
    withApiKey(apiKey: string): NavvoClient;
    private optionsForClone;
    /** Parse a place's WKT `center` (`POINT(lng lat)`) into a {@link LatLng}. */
    static parseCenter(wkt: string | null | undefined): LatLng | null;
    /** Decode an encoded polyline (polyline6 by default) into `LatLng[]`. */
    static decodePolyline(encoded: string, precision?: number): LatLng[];
    /** List the available map styles. `GET /tiles/styles`. */
    styles(opts?: RequestOptions): Promise<StylesResponse>;
    /**
     * Build a browser-fetchable style URL with the key as a query param.
     *
     * Map tiles/styles are fetched by the browser and can't set headers, so they
     * use `?api_key=` (this is the **only** place the key goes in a URL).
     */
    styleUrl(style?: string): string;
    /** Fetch the runtime map configuration. `GET /map/config`. */
    mapConfig(opts?: RequestOptions): Promise<MapConfigResponse>;
    /** Full-text place search. `GET /search`. Scope `search`. */
    search(q: string, options?: SearchOptions, opts?: RequestOptions): Promise<SearchResponse>;
    /** Forward geocode a free-text query. `GET /geocode/search`. Scope `geocode`. */
    geocode(q: string, options?: GeocodeOptions, opts?: RequestOptions): Promise<GeocodeResult[]>;
    /** Reverse geocode a coordinate to the nearest address. `GET /geocode/reverse`. */
    reverseGeocode(lat: number, lon: number, opts?: RequestOptions): Promise<GeocodeResult | null>;
    /**
     * Bulk forward geocode. `POST /geocode/batch`. Auto-chunks inputs into
     * 50-query requests and stitches the results.
     */
    geocodeBatch(items: string[], options?: {
        locale?: string;
        bbox?: BBox;
    }, opts?: RequestOptions): Promise<BatchGeocodeResult[]>;
    /**
     * Bulk reverse geocode. `POST /geocode/reverse-batch`. Auto-chunks into
     * 50-point requests.
     */
    reverseGeocodeBatch(points: LatLng[], opts?: RequestOptions): Promise<ReverseBatchGeocodeResult[]>;
    /** Paginated, sponsored-first place listing. `GET /places`. Scope `places`. */
    list(options?: PlaceListOptions, opts?: RequestOptions): Promise<PlacePage>;
    /**
     * Async-iterate every place across all pages. Stops when
     * `page*limit >= total`. Errors surface mid-iteration.
     *
     * ```ts
     * for await (const place of navvo.iterate({ category: "restaurants", limit: 100 })) {
     *   await sink(place);
     * }
     * ```
     */
    iterate(options?: PlaceListOptions, opts?: RequestOptions): AsyncGenerator<Place, void, void>;
    /** Lightweight thumbnail + open-state for a place. `GET /places/thumb`. */
    thumb(slug: string, opts?: RequestOptions): Promise<PlaceThumb | null>;
    /** Amenity facet groups (for a filter UI). `GET /places/facets`. */
    facets(options?: {
        q?: string;
    }, opts?: RequestOptions): Promise<PlaceFacetsResponse>;
    /** The full category taxonomy tree. `GET /places/categories`. */
    placeCategories(opts?: RequestOptions): Promise<PlaceCategoriesResponse>;
    /**
     * Full place detail (reviews, photos, Q&A, arrival intelligence).
     * `GET /places/{slug}`.
     *
     * Soft-null getter: an unknown slug yields a genuine HTTP 404 from the API,
     * which this method catches ({@link NavvoNotFoundError}) and returns as
     * `null` — it does **not** throw on not-found:
     *
     * ```ts
     * const place = await navvo.place(slug); // PlaceDetail, or null if unknown
     * if (!place) return; // not found
     * ```
     *
     * (Other errors — auth, rate-limit, validation, outage — still throw.)
     */
    place(slug: string, opts?: RequestOptions): Promise<PlaceDetail | null>;
    /** The recommended entrance to route to for a place detail, else its center. */
    static routeTargetFor(place: PlaceDetail | null): LatLng | null;
    /** Opening-hours engine (holiday-aware). `GET /places/{slug}/hours`. */
    hours(slug: string, options?: {
        at?: string;
    }, opts?: RequestOptions): Promise<PlaceHoursResponse>;
    /** Busyness grid. `GET /places/{slug}/popular-times`. */
    popularTimes(slug: string, opts?: RequestOptions): Promise<Record<string, unknown>>;
    /** Structured About attributes. `GET /places/{slug}/attributes`. */
    attributes(slug: string, opts?: RequestOptions): Promise<Record<string, unknown>>;
    /** Rating distribution. `GET /places/{slug}/reviews-summary`. */
    reviewsSummary(slug: string, opts?: RequestOptions): Promise<Record<string, unknown>>;
    /** Paginated photo gallery (featured first). `GET /places/{slug}/photos`. */
    photos(slug: string, options?: {
        page?: number;
        limit?: number;
    }, opts?: RequestOptions): Promise<PlacePhotosResponse>;
    /** "More like this" nearby places. `GET /places/{slug}/nearby`. */
    nearby(slug: string, options?: {
        radiusKm?: number;
        sameCategory?: boolean;
        limit?: number;
    }, opts?: RequestOptions): Promise<PlaceNearbyResponse>;
    /** Isochrone-bounded "what's reachable". `POST /places/reachable`. */
    reachable(req: ReachableOptions, opts?: RequestOptions): Promise<ReachableResponse>;
    /** High-level corridor-aware route planner. `POST /routing/plan` (HTTP 201). */
    route(req: RoutePlanRequest, opts?: RequestOptions): Promise<RoutePlanResponse>;
    /** Low-level passthrough directions. `POST /routing/route` (HTTP 201). */
    simpleRoute(req: SimpleRouteRequest, opts?: RequestOptions): Promise<RoutingEnvelope>;
    /** Travel-time / distance matrix. `POST /routing/matrix` (HTTP 201). */
    matrix(req: MatrixRequest, opts?: RequestOptions): Promise<RoutingEnvelope>;
    /** Reachability polygons. `POST /routing/isochrone` (HTTP 201). */
    isochrone(req: IsochroneRequest, opts?: RequestOptions): Promise<RoutingEnvelope>;
    /** Snap a GPS trace to roads. `POST /routing/map-match` (HTTP 201). */
    mapMatch(req: MapMatchRequest, opts?: RequestOptions): Promise<RoutingEnvelope>;
    /** TSP stop ordering via the routing engine. `POST /routing/optimize` (HTTP 201). */
    routingOptimize(req: OptimizeOrderRequest, opts?: RequestOptions): Promise<RoutingEnvelope>;
    /** The routing-profile catalog. `GET /routing/profiles`. */
    routingProfiles(opts?: RequestOptions): Promise<RoutingProfilesResponse>;
    /** Optimizer liveness probe. `GET /optimize/health`. */
    optimizeHealth(opts?: RequestOptions): Promise<OptimizeHealthResponse>;
    /** Core VRP/VRPTW solver. `POST /optimize/routes`. Scope `optimize`. */
    optimize(req: OptimizeRoutesRequest, opts?: RequestOptions): Promise<OptimizeSolution>;
    /** Mid-day re-plan from current positions. `POST /optimize/reoptimize`. */
    reoptimize(req: OptimizeReoptimizeRequest, opts?: RequestOptions): Promise<OptimizeSolution>;
    /** CP-SAT bin packing. `POST /optimize/binpack`. */
    binpack(req: OptimizeBinpackRequest, opts?: RequestOptions): Promise<OptimizeBinpackSolution>;
    /** CP-SAT driver/shift rostering. `POST /optimize/roster`. */
    roster(req: OptimizeRosterRequest, opts?: RequestOptions): Promise<OptimizeRosterSolution>;
    /** Enqueue an optimization as an async job. `POST /optimize/jobs`. */
    submitJob(kind: OptimizeJobKind, req: Record<string, unknown>, opts?: RequestOptions): Promise<OptimizeJobSubmitResponse>;
    /** Poll an optimization job once. `GET /optimize/jobs/:id`. */
    job(id: string, opts?: RequestOptions): Promise<OptimizeJobStatusResponse>;
    /**
     * Poll a job until it is `completed`/`failed` (or the timeout elapses).
     * Throws on a `failed` job or on timeout.
     */
    waitForJob(id: string, options?: WaitForJobOptions): Promise<OptimizeJobStatusResponse>;
    private tierTimeout;
    /** Traffic-aware ETA + congestion segments. `POST /traffic/route`. Scopes routing+traffic. */
    trafficRoute(req: TrafficRouteRequest, opts?: RequestOptions): Promise<RoutePlanResponse>;
    /** Traffic summary for a bbox. `GET /traffic/summary`. Scope `traffic`. */
    trafficSummary(bbox: BBox, opts?: RequestOptions): Promise<TrafficSummaryResponse>;
    /** Active incidents as GeoJSON. `GET /incidents/geojson`. */
    incidents(options?: IncidentsOptions, opts?: RequestOptions): Promise<GeoJSONFeatureCollection>;
    /** The catalog of incident types. `GET /incidents/types`. */
    incidentTypes(opts?: RequestOptions): Promise<Record<string, unknown>>;
    /** Report a new incident. `POST /incidents/report`. */
    reportIncident(req: ReportIncidentRequest, opts?: RequestOptions): Promise<Record<string, unknown>>;
    /** Platform road edits as GeoJSON. `GET /road-edits/geojson`. */
    roadEdits(bbox: BBox, opts?: RequestOptions): Promise<GeoJSONFeatureCollection>;
    /** Logistics-zone risk for a route geometry. `POST /map/route-risk`. */
    routeRisk(geometry: GeoJSONFeatureCollection | Record<string, unknown>, opts?: RequestOptions): Promise<Record<string, unknown>>;
    /** Current weather at a point. `GET /map/weather/point`. */
    weatherPoint(lat: number, lng: number, options?: {
        units?: string;
    }, opts?: RequestOptions): Promise<WeatherPointResponse>;
    /** Multi-day forecast at a point. `GET /map/weather/forecast`. */
    weatherForecast(lat: number, lng: number, opts?: RequestOptions): Promise<WeatherForecastResponse>;
    /** City weather pins in a bbox. `GET /map/weather/cities`. */
    weatherCities(bbox: BBox, zoom?: number, opts?: RequestOptions): Promise<WeatherCitiesResponse>;
    /** City air-quality pins in a bbox. `GET /map/airquality/cities`. */
    airQualityCities(bbox: BBox, zoom?: number, opts?: RequestOptions): Promise<AirQualityCitiesResponse>;
    /** EV charging stations. `GET /ev/stations`. */
    evStations(options?: EvStationsOptions, opts?: RequestOptions): Promise<EvStationsResponse>;
    /** Nearby transit stops. `GET /transit/stops`. */
    transitStops(lat: number, lng: number, radius?: number, opts?: RequestOptions): Promise<TransitStopsResponse>;
    /** GBFS shared-mobility feed near a point. `GET /transit/gbfs`. */
    gbfs(lat: number, lng: number, radius?: number, opts?: RequestOptions): Promise<GbfsResponse>;
}

/**
 * Navvo SDK error hierarchy.
 *
 * Every failure surfaces as a subclass of {@link NavvoError}, so callers can
 * narrow with `instanceof`:
 *
 * ```ts
 * try {
 *   await client.geocode("Amman");
 * } catch (e) {
 *   if (e instanceof NavvoRateLimitError) backoff(e.retryAfter);
 *   else if (e instanceof NavvoForbiddenError) console.error(e.reason ?? e.message);
 *   else throw e;
 * }
 * ```
 */
/** Shape of the error payload Navvo may return in a JSON body. */
interface NavvoErrorBody {
    error?: string;
    message?: string;
    reason?: string;
    scope?: string;
    status?: number;
    [k: string]: unknown;
}
/** Options used internally to construct a {@link NavvoError}. */
interface NavvoErrorInit {
    status?: number;
    path?: string;
    method?: string;
    requestId?: string;
    redactedKey?: string;
    body?: unknown;
    cause?: unknown;
}
/**
 * Base class for every error thrown by the SDK.
 *
 * Carries enough context (HTTP status, request path/method, redacted key,
 * server request id and the parsed body) to debug and to correlate with
 * Navvo support, without ever leaking the API key.
 */
declare class NavvoError extends Error {
    /** HTTP status code, when the error originated from a response. */
    readonly status?: number;
    /** Request path (relative to the base URL), e.g. `/geocode/forward`. */
    readonly path?: string;
    /** HTTP method of the failing request. */
    readonly method?: string;
    /** Server-provided request id, when present, for support correlation. */
    readonly requestId?: string;
    /** The API key, redacted to `nvvo_****<last4>` — never the full key. */
    readonly redactedKey?: string;
    /** The parsed response body (untyped) for forward-compat / debugging. */
    readonly body?: unknown;
    constructor(message: string, init?: NavvoErrorInit);
}
/** Client-side misconfiguration: missing/malformed key, bad option, insecure URL. */
declare class NavvoConfigError extends NavvoError {
}
/** `400` — the server rejected the request as invalid. */
declare class NavvoValidationError extends NavvoError {
    /** Offending fields, when the server enumerates them. */
    readonly fields?: unknown;
    constructor(message: string, init?: NavvoErrorInit & {
        fields?: unknown;
    });
}
/** `401` — no key, or an unknown key. */
declare class NavvoAuthError extends NavvoError {
}
/**
 * `403` — revoked key, missing scope, or quota exhausted.
 *
 * When the body distinguishes the cause, {@link reason} carries it (e.g.
 * `missing_scope` vs `quota_exceeded`) and {@link scope} the offending scope.
 */
declare class NavvoForbiddenError extends NavvoError {
    readonly reason?: string;
    readonly scope?: string;
    constructor(message: string, init?: NavvoErrorInit & {
        reason?: string;
        scope?: string;
    });
}
/** `404` — a genuine not-found (distinct from a "soft-null" 200 body). */
declare class NavvoNotFoundError extends NavvoError {
}
/** `429` — rate limited / quota throttled. */
declare class NavvoRateLimitError extends NavvoError {
    /** Seconds to wait before retrying, from `Retry-After` when present. */
    readonly retryAfter?: number;
    readonly limit?: number;
    readonly remaining?: number;
    readonly resetAt?: Date;
    constructor(message: string, init?: NavvoErrorInit & {
        retryAfter?: number;
        limit?: number;
        remaining?: number;
        resetAt?: Date;
    });
}
/**
 * The upstream engine is unreachable.
 *
 * Raised both for `502`/`503` and for the Navvo envelope `available:false`
 * (a `200`/`201` that means "the geocoder/router/etc. is down" — *not* the
 * caller's fault). Retryable.
 */
declare class NavvoServiceUnavailableError extends NavvoError {
}
/** Other `5xx` server errors. */
declare class NavvoServerError extends NavvoError {
}
/** The request (and all retries) exceeded the configured per-attempt timeout. */
declare class NavvoTimeoutError extends NavvoError {
    /** Number of attempts made before giving up. */
    readonly attempts?: number;
    constructor(message: string, init?: NavvoErrorInit & {
        attempts?: number;
    });
}
/** A low-level network failure (DNS, connection reset, TLS, …). */
declare class NavvoNetworkError extends NavvoError {
}
/** The caller aborted the request via an `AbortSignal`. */
declare class NavvoAbortError extends NavvoError {
}

export { API_KEY_PATTERN, type AirQualityCitiesResponse, type ArrivalCandidate, type ArrivalIntelligence, type AvoidOption, type BBox, type BatchGeocodeResult, type ConstraintBlock, type Costing, DEFAULT_BASE_URL, type EvStationsOptions, type EvStationsResponse, type GbfsResponse, type GeoJSONFeatureCollection, type GeocodeOptions, type GeocodeResult, type IncidentsOptions, type IsochroneRequest, type LatLng, type MapConfigResponse, type MapMatchRequest, type MatrixRequest, NavvoAbortError, NavvoAuthError, NavvoClient, type NavvoClientOptions, NavvoConfigError, NavvoError, type NavvoErrorBody, type NavvoErrorInit, NavvoForbiddenError, NavvoNetworkError, NavvoNotFoundError, NavvoRateLimitError, NavvoServerError, NavvoServiceUnavailableError, NavvoTimeoutError, NavvoValidationError, type OptimizeBinpackRequest, type OptimizeBinpackSolution, type OptimizeHealthResponse, type OptimizeJobKind, type OptimizeJobStatusResponse, type OptimizeJobSubmitResponse, type OptimizeOrderRequest, type OptimizeReoptimizeRequest, type OptimizeRosterRequest, type OptimizeRosterSolution, type OptimizeRoutesRequest, type OptimizeSolution, type OptimizeTier, type Place, type PlaceCategoriesResponse, type PlaceCategoryNode, type PlaceDetail, type PlaceEntrance, type PlaceFacetsResponse, type PlaceHoursResponse, type PlaceListOptions, type PlaceNearbyResponse, type PlacePage, type PlacePhotosResponse, type PlaceThumb, type Preference, type ReachableOptions, type ReachableResponse, type ReportIncidentRequest, type RequestEvent, type RequestOptions, type ResolvedConfig, type RetryConfig, type ReverseBatchGeocodeResult, type RoutePlanRequest, type RoutePlanResponse, type RouteTrip, type RoutingEnvelope, type RoutingProfilesResponse, SDK_VERSION, type SearchOptions, type SearchPlaceItem, type SearchResponse, type SimpleRouteRequest, type StylesResponse, type TelemetryConfig, type TrafficRouteRequest, type TrafficSummaryResponse, type TransitStopsResponse, type TruckDimensions, type Units, type WaitForJobOptions, type WeatherCitiesResponse, type WeatherForecastResponse, type WeatherPointResponse, assertLatLng, bboxToString, buildUrl, decodePolyline, fromGeoJSON, parseWktPoint, redactKey, resolveConfig, toGeoJSON };
