declare const WHERABOUTS_API_VERSION: "v1"; declare const WHERABOUTS_SDK_VERSION: "0.4.3"; /** * Error codes the API may return. The server currently emits a subset; the full * union is declared for forward-compatibility with the Phase 2 error envelope * (see docs/CONTRACT.md §4). Unknown codes fall back to `unknown_error`. */ type WheraboutsErrorCode = "bad_request" | "conflict" | "forbidden" | "internal_error" | "not_found" | "rate_limited" | "timeout" | "unauthorized" | "unprocessable"; interface WheraboutsFieldError { message: string; path: string; } interface RequestLogEvent { durationMs: number; method: string; path: string; requestId?: string; status: number; } interface WheraboutsApiErrorPayload { error: { code: WheraboutsErrorCode; message: string; /** Correlation id; also sent as the `X-Request-Id` response header. */ request_id?: string; /** Link to documentation for this error code. */ doc_url?: string; /** Field-level validation detail (validation errors only). */ fields?: WheraboutsFieldError[]; }; } interface WheraboutsClientConfig { /** * Publishable/secret API key sent as `Authorization: Bearer `. * * Optional: when omitted, no `Authorization` header is sent. This supports * the recommended browser pattern of proxying requests through your own * backend (via a custom `baseUrl`/`fetch`) so the real key never reaches the * client — the proxy attaches the key server-side. */ apiKey?: string; baseUrl?: string; fetch?: typeof fetch; headers?: Record; /** Called after every request. Use for debugging or observability. */ logger?: (event: RequestLogEvent) => void; /** Max automatic retries for transient failures. Default 2. */ maxRetries?: number; /** Per-request timeout in milliseconds. Default 30000. */ timeoutMs?: number; } /** * Per-call overrides. Every resource method accepts an optional trailing * `options` argument of this shape. */ interface CallOptions { /** Extra headers merged over (not replacing) the client headers. */ headers?: Record; /** Idempotency key for write requests. Auto-generated on writes if omitted. */ idempotencyKey?: string; /** Override the client's `maxRetries` for this call. */ maxRetries?: number; /** Abort signal — aborting rejects the call (and is not retried). */ signal?: AbortSignal; /** Override the client's `timeoutMs` for this call. */ timeoutMs?: number; } type HttpMethod = "GET" | "POST" | "PUT" | "DELETE"; interface RequestOptions extends CallOptions { body?: unknown; method: HttpMethod; path: string; query?: Record; } type Requester = (opts: RequestOptions) => Promise; interface AddressSuggestion { country: string; formattedAddress: string; id: number; latitude: number; locality: string; longitude: number; postcode: string; state: string; streetAddress: string; } interface AddressRecord { buildingName: string | null; confidence: number | null; country: string; flatNumber: string | null; flatType: string | null; gnafPid: string | null; id: number; latitude: number; levelNumber: string | null; levelType: string | null; locality: string; longitude: number; numberFirst: string | null; numberLast: string | null; postcode: string; state: string; streetName: string; streetSuffix: string | null; streetType: string | null; } interface NearbyAddress { buildingName: string | null; country: string; distance: number; flatNumber: string | null; flatType: string | null; id: number; latitude: number; locality: string; longitude: number; numberFirst: string | null; numberLast: string | null; postcode: string; state: string; streetName: string; streetType: string | null; } interface ReverseGeocodeAddress { confidence: number | null; country: string; formattedAddress: string; id: number; latitude: number; locality: string; longitude: number; postcode: string; state: string; streetAddress: string; } interface AutocompleteParams { country?: string; /** Latitude for proximity boosting (pair with `lng`). */ lat?: number; limit?: number; /** Longitude for proximity boosting (pair with `lat`). Sent to the API as `lon`. */ lng?: number; q: string; /** * Groups a run of keystrokes for one search into a single billable session. * Generate one stable token per search (e.g. on focus), reuse it across * keystrokes, and discard it after a result is selected. See `newSessionToken()`. */ sessionToken?: string; state?: string; } interface NearbyParams { country?: string; lat: number; limit?: number; lng: number; radius?: number; } interface ReverseParams { lat: number; lng: number; } interface AutocompleteResponse { count: number; results: AddressSuggestion[]; } interface NearbyResponse { count: number; query: { lat: number; lng: number; radius: number; }; results: NearbyAddress[]; } interface ReverseResponse { address: ReverseGeocodeAddress; distance: number; query: { lat: number; lng: number; }; } interface AddressesResource { autocomplete(params: AutocompleteParams, options?: CallOptions): Promise; getById(id: number, options?: CallOptions): Promise; nearby(params: NearbyParams, options?: CallOptions): Promise; reverse(params: ReverseParams, options?: CallOptions): Promise; } declare const createAddresses: (request: Requester) => AddressesResource; interface BoundaryCrossing { event: "entry" | "exit"; zoneId: number; zoneName: string; } interface PushLocationBody { lat: number; lng: number; } interface PushLocationResponse { crossings: BoundaryCrossing[]; zones: number[]; } interface DeviceZonesResponse { deviceId: string; latitude: number | null; longitude: number | null; updatedAt: string | null; zoneIds: number[]; } interface DevicesResource { pushLocation(deviceId: string, body: PushLocationBody, options?: CallOptions): Promise; zones(deviceId: string, options?: CallOptions): Promise; } declare const createDevices: (request: Requester) => DevicesResource; /** * Params for forward geocoding. Provide `q` for unstructured free-text search, * OR `street` + `locality` (plus optional `state`, `postcode`, `country`) for * structured mode. Set `structured: "true"` when using structured fields. */ interface ForwardGeocodeParams { /** ISO 3166-1 alpha-2 country code, e.g. "AU". */ country?: string; /** Suburb / locality (structured mode). */ locality?: string; /** Postcode / ZIP. */ postcode?: string; /** Free-text address query (unstructured mode). */ q?: string; /** State abbreviation, e.g. "NSW". */ state?: string; /** Street address (structured mode). */ street?: string; /** Pass `"true"` to enable structured mode. */ structured?: "true" | "false"; } interface GeocodeAddress { country: string; formattedAddress: string; id: number; latitude: number; locality: string; longitude: number; postcode: string; state: string; /** Combined street line, e.g. "34 BOXGROVE AVENUE". */ streetAddress: string; /** G-NAF street name without type, e.g. "BOXGROVE". */ streetName: string | null; /** Street number or "first-last" range, e.g. "34". */ streetNumber: string | null; /** G-NAF street type, e.g. "AVENUE". */ streetType: string | null; } interface ForwardGeocodeResponse { address: GeocodeAddress; matchType: "structured" | "fuzzy"; } interface BatchSubmitBody { addresses: string[]; } interface BatchSubmitResponse { inputCount: number; jobId: string; status: "pending" | "processing"; } interface BatchJobStatus { completedAt: string | null; downloadUrl: string | null; error: string | null; inputCount: number; jobId: string; processedCount: number | null; status: "pending" | "processing" | "completed" | "failed"; } interface BatchResultsResponse { count: number; results: unknown[]; } interface GeocodeResource { batch: { submit(body: BatchSubmitBody, options?: CallOptions): Promise; poll(jobId: string, options?: CallOptions): Promise; results(jobId: string, options?: CallOptions): Promise; }; forward(params: ForwardGeocodeParams, options?: CallOptions): Promise; } declare const createGeocode: (request: Requester) => GeocodeResource; interface RegionsClassifyParams { lat: number; layers?: string; lng: number; } interface RegionMatch { code: string; name: string; } interface RegionsClassifyResponse { query: { lat: number; lng: number; }; regions: Record; } interface RegionsResource { classify(params: RegionsClassifyParams, options?: CallOptions): Promise; } declare const createRegions: (request: Requester) => RegionsResource; type RoutingProfile = "driving" | "walking" | "cycling"; interface LatLng$1 { lat: number; lng: number; } interface DirectionsParams { from?: string; fromAddressId?: number; profile?: RoutingProfile; to?: string; toAddressId?: number; } interface DirectionsGeometry { coordinates: [number, number][]; type: "LineString"; } interface IsochronePolygon { coordinates: [number, number][][]; type: "Polygon"; } interface DirectionsResponse { distance_m: number; duration_s: number; geometry: DirectionsGeometry; query: { from: { lat: number; lng: number; }; profile: string; to: { lat: number; lng: number; }; }; } interface MatrixParams { /** Delimited `"lat,lng|lat,lng|"` (≤25 points). */ destinations: string; profile?: RoutingProfile; /** Delimited `"lat,lng|lat,lng|"` (≤25 points). */ sources: string; } interface MatrixResponse { destinations: LatLng$1[]; /** Row-major distances in metres; unreachable cells are `null`. */ distances: (number | null)[][]; /** Row-major durations in seconds; unreachable cells are `null`. */ durations: (number | null)[][]; query: { profile: string; }; sources: LatLng$1[]; } interface IsochroneParams { /** Travel-distance budget in metres (provide exactly one of duration/distance). */ distanceMeters?: number; /** Travel-time budget in seconds (provide exactly one of duration/distance). */ durationSeconds?: number; /** Also return the ABS regions the isochrone overlaps. */ includeRegions?: boolean; /** CSV of region layers to filter the overlap (e.g. `"sa2,lga"`). */ layers?: string; /** `"lat,lng"` or a G-NAF address id (as a string). */ origin?: string; /** Convenience: a G-NAF address id; mapped to `origin` when `origin` is unset. */ originAddressId?: number; profile?: RoutingProfile; } interface IsochroneResponse { polygon: IsochronePolygon; query: { origin: LatLng$1; profile: string; durationSeconds?: number; distanceMeters?: number; }; regions?: Record; } interface MatchPoint extends LatLng$1 { /** GPS accuracy in metres. */ radius?: number; /** UNIX seconds; all-or-none across points, strictly increasing. */ timestamp?: number; } interface MatchParams { coordinates: MatchPoint[]; gaps?: "split" | "ignore"; profile?: RoutingProfile; tidy?: boolean; } interface Matching { confidence: number; distance_m: number; duration_s: number; geometry: DirectionsGeometry; } interface Tracepoint { location: [number, number]; matchings_index: number; waypoint_index: number; } interface MatchResponse { matchings: Matching[]; query: { profile: string; }; /** One entry per input point; `null` where OSRM dropped it as an outlier. */ tracepoints: (Tracepoint | null)[]; } interface OptimizeWaypoint { addressId?: number; lat?: number; lng?: number; } interface OptimizeParams { destination?: "any" | "last"; profile?: RoutingProfile; roundtrip?: boolean; source?: "any" | "first"; waypoints: OptimizeWaypoint[]; } interface OptimizeTrip { distance_m: number; duration_s: number; geometry: DirectionsGeometry; } interface OptimizeResponse { query: { profile: string; roundtrip: boolean; }; trips: OptimizeTrip[]; /** Each input waypoint with its resolved coords and optimised tour position. */ waypoints: { input_index: number; coords: LatLng$1; order: number | null; }[]; } interface RoutingResource { directions(params: DirectionsParams, options?: CallOptions): Promise; isochrone(params: IsochroneParams, options?: CallOptions): Promise; match(params: MatchParams, options?: CallOptions): Promise; matrix(params: MatrixParams, options?: CallOptions): Promise; optimize(params: OptimizeParams, options?: CallOptions): Promise; } declare const createRouting: (request: Requester) => RoutingResource; type WebhookEvent = "entry" | "exit"; interface CreateWebhookBody { events?: WebhookEvent[]; url: string; zoneId?: number; } interface WebhookSubscription { active: boolean; createdAt: string; events: WebhookEvent[]; id: number; url: string; zoneId: number | null; } interface CreateWebhookResponse extends WebhookSubscription { secret: string; } interface WebhookListItem extends WebhookSubscription { failing: boolean; } interface ListWebhooksResponse { count: number; results: WebhookListItem[]; } interface DeleteWebhookResponse { deleted: true; id: number; } interface ReactivateWebhookResponse { id: number; reactivated: true; } /** Shape of the JSON body POSTed to your webhook endpoint when a device enters a zone. */ interface WebhookEntryPayload { device: { id: string; lat: number; lng: number; }; event: "entry"; timestamp: string; zone: { id: number; name: string; }; } /** Shape of the JSON body POSTed to your webhook endpoint when a device exits a zone. */ interface WebhookExitPayload { device: { id: string; lat: number; lng: number; }; event: "exit"; timestamp: string; zone: { id: number; name: string; }; } /** Discriminated union of all inbound webhook event payloads. */ type WebhookEventPayload = WebhookEntryPayload | WebhookExitPayload; interface WebhooksResource { create(body: CreateWebhookBody, options?: CallOptions): Promise; delete(id: number, options?: CallOptions): Promise; list(options?: CallOptions): Promise; reactivate(id: number, options?: CallOptions): Promise; } declare const createWebhooks: (request: Requester) => WebhooksResource; interface ZoneRecord { createdAt: string; description: string | null; id: number; metadata: Record | null; name: string; projectId: string; updatedAt: string; } interface ZoneWithGeometry extends ZoneRecord { geometry: { type: string; coordinates: number[][][]; }; } interface GeoJsonPolygon { coordinates: number[][][]; type: "Polygon"; } interface ZoneListParams { limit?: number; page?: number; } interface ZoneContainsParams { lat: number; lng: number; } interface ZoneAddressesParams { limit?: number; page?: number; } interface ZoneCreateBody { description?: string; geometry: GeoJsonPolygon; metadata?: Record; name: string; } interface ZoneUpdateBody { description?: string; geometry?: GeoJsonPolygon; metadata?: Record; name?: string; } interface ZoneListResponse { count: number; page: number; zones: ZoneRecord[]; } interface ZoneDeleteResponse { success: true; } interface ZoneContainsResponse { count: number; query: { lat: number; lng: number; }; zones: ZoneRecord[]; } interface ZoneAddressesResponse { count: number; query: { id: number; limit: number; page: number; }; results: Array<{ buildingName: string | null; country: string; flatNumber: string | null; flatType: string | null; id: number; latitude: number; locality: string; longitude: number; numberFirst: string | null; numberLast: string | null; postcode: string; state: string; streetName: string; streetType: string | null; }>; truncated: boolean; } interface ZonesResource { addresses(id: number, params?: ZoneAddressesParams, options?: CallOptions): Promise; contains(params: ZoneContainsParams, options?: CallOptions): Promise; create(body: ZoneCreateBody, options?: CallOptions): Promise; delete(id: number, options?: CallOptions): Promise; get(id: number, options?: CallOptions): Promise; list(params?: ZoneListParams, options?: CallOptions): Promise; paginate(params?: ZoneListParams, options?: CallOptions): AsyncGenerator; update(id: number, body: ZoneUpdateBody, options?: CallOptions): Promise; } declare const createZones: (request: Requester) => ZonesResource; interface WheraboutsClient { addresses: AddressesResource; devices: DevicesResource; geocode: GeocodeResource; regions: RegionsResource; routing: RoutingResource; webhooks: WebhooksResource; zones: ZonesResource; } declare const createWheraboutsClient: (config: WheraboutsClientConfig) => WheraboutsClient; declare class WheraboutsApiError extends Error { readonly code: WheraboutsErrorCode | "unknown_error"; readonly payload: WheraboutsApiErrorPayload | null; readonly status: number; /** Correlation id from the `X-Request-Id` header or error body, if present. */ readonly requestId: string | null; /** Documentation link for this error, if the API provided one. */ readonly docUrl: string | null; /** Field-level validation detail, if the API provided any. */ readonly fields: WheraboutsFieldError[] | null; constructor(options: { code?: WheraboutsApiError["code"]; docUrl?: string | null; fields?: WheraboutsFieldError[] | null; message: string; payload?: WheraboutsApiErrorPayload | null; requestId?: string | null; status: number; }); } interface LatLng { lat: number; lng: number; } interface HasCoords { latitude: number; longitude: number; } /** `{ latitude, longitude }` → `{ lat, lng }` (e.g. for Leaflet/Google Maps). */ declare function getLatLng(point: HasCoords): LatLng; /** `{ latitude, longitude }` → `[lng, lat]` (GeoJSON / MapLibre coordinate order). */ declare function toLngLat(point: HasCoords): [number, number]; /** * ISO 3166-1 country code → display name (e.g. `"US"` → `"United States"`, * `"IS"` → `"Iceland"`). Falls back to the raw code when `Intl.DisplayNames` * is unavailable or the code is malformed. Defaults to English; pass a BCP-47 * `locale` for localized names. */ declare function countryName(code: string, locale?: string): string; /** * Great-circle distance in metres between two points (haversine). Handy for * client-side "how far is this result" without a round-trip. */ declare function distanceMeters(a: HasCoords, b: HasCoords): number; /** * Narrow an unknown thrown value to `WheraboutsApiError`. Uses `instanceof` * with a `name`-based fallback so it still works if two copies of the SDK are * loaded (e.g. duplicate dep versions), where `instanceof` can fail. */ declare function isWheraboutsApiError(error: unknown): error is WheraboutsApiError; /** True when the error is a rate-limit response (HTTP 429 / `rate_limited`). */ declare function isRateLimitError(error: unknown): error is WheraboutsApiError; /** True when the error is a client-side validation/bad-request (HTTP 4xx). */ declare function isClientError(error: unknown): error is WheraboutsApiError; /** * Generate a session token for grouping a run of autocomplete keystrokes into * one billable search (cf. Google Places session tokens). Create one per search * (e.g. on input focus), pass it on every `addresses.autocomplete` call for that * search, and discard it once the user selects a result. * * Uses `crypto.randomUUID()` where available, with a non-cryptographic fallback * (a token only needs to be unique per search, not unguessable). */ declare function newSessionToken(): string; export { type AddressRecord, type AddressSuggestion, type AddressesResource, type AutocompleteParams, type AutocompleteResponse, type BatchJobStatus, type BatchResultsResponse, type BatchSubmitBody, type BatchSubmitResponse, type BoundaryCrossing, type CallOptions, type CreateWebhookBody, type CreateWebhookResponse, type DeleteWebhookResponse, type DeviceZonesResponse, type DevicesResource, type DirectionsGeometry, type DirectionsParams, type DirectionsResponse, type ForwardGeocodeParams, type ForwardGeocodeResponse, type GeoJsonPolygon, type GeocodeAddress, type GeocodeResource, type IsochroneParams, type IsochronePolygon, type IsochroneResponse, type LatLng, type ListWebhooksResponse, type MatchParams, type MatchPoint, type MatchResponse, type Matching, type MatrixParams, type MatrixResponse, type NearbyAddress, type NearbyParams, type NearbyResponse, type OptimizeParams, type OptimizeResponse, type OptimizeTrip, type OptimizeWaypoint, type PushLocationBody, type PushLocationResponse, type ReactivateWebhookResponse, type RegionMatch, type RegionsClassifyParams, type RegionsClassifyResponse, type RegionsResource, type ReverseGeocodeAddress, type ReverseParams, type ReverseResponse, type RoutingProfile, type RoutingResource, type Tracepoint, WHERABOUTS_API_VERSION, WHERABOUTS_SDK_VERSION, type WebhookEntryPayload, type WebhookEvent, type WebhookEventPayload, type WebhookExitPayload, type WebhookListItem, type WebhookSubscription, type WebhooksResource, WheraboutsApiError, type WheraboutsApiErrorPayload, type WheraboutsClient, type WheraboutsClientConfig, type WheraboutsErrorCode, type WheraboutsFieldError, type ZoneAddressesParams, type ZoneAddressesResponse, type ZoneContainsParams, type ZoneContainsResponse, type ZoneCreateBody, type ZoneDeleteResponse, type ZoneListParams, type ZoneListResponse, type ZoneRecord, type ZoneUpdateBody, type ZoneWithGeometry, type ZonesResource, countryName, createAddresses, createDevices, createGeocode, createRegions, createRouting, createWebhooks, createWheraboutsClient, createZones, distanceMeters, getLatLng, isClientError, isRateLimitError, isWheraboutsApiError, newSessionToken, toLngLat };