@liftitinc/geocoding
v0.2.0
Published
JavaScript/TypeScript SDK for Liftit Geocoding API
Maintainers
Readme
@liftit/geocoding
JavaScript/TypeScript SDK for the Liftit Geocoding API.
Installation
npm install @liftit/geocoding
# or
pnpm add @liftit/geocoding
# or
yarn add @liftit/geocodingQuick Start
import { GeocodingClient } from '@liftit/geocoding';
const client = new GeocodingClient({
apiKey: 'your-api-key',
// Optional configuration:
// baseUrl: 'https://geocoding.liftit.co',
// timeout: 10000,
// maxRetries: 3,
});
// Forward geocoding - convert address to coordinates
const result = await client.geocode({
country: 'co',
city: 'Bogota',
address: 'Calle 100 # 19-61',
// Optional parameters:
// region: 'Cundinamarca',
// custom_zone: true,
});
console.log(result.location); // { lat: 4.6097, lng: -74.0817 }
console.log(result.geocode.formatted_address);
// Reverse geocoding - convert coordinates to address
const address = await client.reverseGeocode({
lat: 4.6097,
lng: -74.0817,
});
console.log(address.geocode.formatted_address);
console.log(address.address_components?.city);Features
- TypeScript Support: Full type definitions with comprehensive type safety
- Zero Dependencies: Uses native
fetchAPI (Node.js 18+ required) - Automatic Retry: Exponential backoff with full jitter for transient errors
- Rate Limit Handling: Respects
Retry-Afterheaders automatically - Error Hierarchy: Typed error classes for precise error handling
- Zod Schemas: Exported schemas for request/response validation
Configuration
| Parameter | Type | Default | Description |
|-----------|------|---------|-------------|
| apiKey | string | Required | Your Liftit Geocoding API key |
| baseUrl | string | "https://geocoding.liftit.co" | API base URL |
| timeout | number | 10000 | Request timeout in milliseconds |
| maxRetries | number | 3 | Maximum retry attempts for transient errors |
| baseDelay | number | 1000 | Initial retry delay in milliseconds |
| maxDelay | number | 30000 | Maximum retry delay cap in milliseconds |
Example:
const client = new GeocodingClient({
apiKey: 'your-api-key',
timeout: 15000,
maxRetries: 5,
baseDelay: 2000,
maxDelay: 60000,
});Retry Behavior
The SDK automatically retries requests for transient errors:
| Error Type | Retryable | Strategy |
|------------|-----------|----------|
| Rate limit (429) | Yes | Uses Retry-After header if present |
| Server error (500, 502, 503, 504) | Yes | Exponential backoff with full jitter |
| Timeout | Yes | Exponential backoff with full jitter |
| Network errors | Yes | Exponential backoff with full jitter |
| Validation (400) | No | Fails immediately |
| Authentication (401) | No | Fails immediately |
| User abort | No | Fails immediately |
Retry Timing
- Initial delay: 1 second (configurable via
baseDelay) - Maximum delay: 30 seconds (configurable via
maxDelay) - Multiplier: 2x exponential growth
- Jitter: Full random jitter (0 to calculated delay)
- Default attempts: 3 retries (configurable via
maxRetries)
Formula: delay = min(baseDelay * 2^attempt * random(), maxDelay)
Disabling Retries
// Disable retries for testing or special cases
const client = new GeocodingClient({
apiKey: 'your-api-key',
maxRetries: 0,
});Error Handling
The SDK provides a comprehensive error hierarchy:
import {
GeocodingClient,
GeocodeError,
ValidationError,
AuthenticationError,
RateLimitError,
UpstreamError,
} from '@liftit/geocoding';
const client = new GeocodingClient({ apiKey: 'your-api-key' });
try {
const result = await client.geocode({
country: 'co',
city: 'Bogota',
address: 'Calle 100 # 19-61',
});
} catch (error) {
if (error instanceof ValidationError) {
// Invalid request parameters (400)
console.error(`Validation error: ${error.message}`);
console.error(`Request ID: ${error.requestId}`);
} else if (error instanceof AuthenticationError) {
// Invalid API key (401)
console.error(`Authentication failed: ${error.message}`);
} else if (error instanceof RateLimitError) {
// Rate limit exceeded (429)
console.error(`Rate limited. Retry after ${error.retryAfter} seconds`);
console.error(`Limit: ${error.limit}, Remaining: ${error.remaining}`);
// Calculate optimal retry delay
const delayMs = error.getRetryDelay();
await new Promise(resolve => setTimeout(resolve, delayMs));
// Retry request...
} else if (error instanceof UpstreamError) {
// API server error (500-599)
console.error(`Upstream error: ${error.message}`);
console.error(`Status code: ${error.statusCode}`);
} else if (error instanceof GeocodeError) {
// Base class catches all SDK errors
console.error(`Geocoding error [${error.code}]: ${error.message}`);
}
}Error Properties:
| Error Class | Properties |
|-------------|------------|
| GeocodeError | message, code, requestId |
| ValidationError | Inherits from GeocodeError |
| AuthenticationError | Inherits from GeocodeError |
| RateLimitError | Inherits + retryAfter, limit, remaining, getRetryDelay() |
| UpstreamError | Inherits + statusCode |
API Reference
Forward Geocoding
Convert an address to geographic coordinates.
Method: client.geocode(request, options?)
Parameters:
| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| request.country | string | Yes | ISO 3166-1 alpha-2 country code (ar, br, cl, co, ec, mx, pe) |
| request.address | string | Yes | Street address to geocode |
| request.city | string | No | City name (recommended for accuracy) |
| request.region | string | No | State/department name |
| request.custom_zone | boolean | No | Include zone information (default: false) |
| options.signal | AbortSignal | No | AbortSignal for request cancellation |
Response:
{
success: true,
data: {
location: { lat: number, lng: number },
geocode: { formatted_address: string },
cleaned_address: boolean,
zone?: { id: number, name: string, type: string }
},
requestId: string
}Example:
const result = await client.geocode({
country: 'co',
city: 'Bogota',
address: 'Calle 100 # 19-61',
custom_zone: true,
});
console.log(result.location); // { lat: 4.6097, lng: -74.0817 }
console.log(result.zone?.name); // "Zone 1"Reverse Geocoding
Convert geographic coordinates to an address.
Method: client.reverseGeocode(request, options?)
Parameters:
| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| request.lat | number | Yes | Latitude (-90 to 90) |
| request.lng | number | Yes | Longitude (-180 to 180) |
| options.signal | AbortSignal | No | AbortSignal for request cancellation |
Response:
{
success: true,
data: {
geocode: { formatted_address: string },
location: { lat: number, lng: number },
address_components: {
city: string,
country: string
}
},
requestId: string
}Example:
const address = await client.reverseGeocode({
lat: 4.6097,
lng: -74.0817,
});
console.log(address.geocode.formatted_address);
console.log(address.address_components?.city); // "Bogota"Supported Countries
The SDK supports geocoding in the following countries:
| Country | Code | Example City |
|---------|------|--------------|
| Argentina | ar | Buenos Aires |
| Brazil | br | Sao Paulo |
| Chile | cl | Santiago |
| Colombia | co | Bogota |
| Ecuador | ec | Quito |
| Mexico | mx | Mexico City |
| Peru | pe | Lima |
Requirements
- Node.js: >= 18.0.0 (required for native
fetchAPI) - Runtime Dependencies: None (zero dependencies)
- TypeScript: >= 5.0 (for TypeScript projects)
Development
# Clone the repository
git clone https://github.com/Liftitapp/geocoding-enterprise.git
cd geocoding-enterprise
# Install dependencies
pnpm install
# Build the SDK
pnpm --filter @liftit/geocoding build
# Run tests
pnpm --filter @liftit/geocoding test
# Type checking
pnpm --filter @liftit/geocoding typecheck
# Lint
pnpm --filter @liftit/geocoding lintLicense
MIT - see LICENSE for details.
Support
- GitHub Issues: Report bugs and request features
- API Reference: View API documentation
- Homepage: https://geocoding.liftit.co
