Documentation Index
Fetch the complete documentation index at: https://maps.solvice.io/llms.txt
Use this file to discover all available pages before exploring further.
Solvice Maps: API Services Guide
API Architecture Overview
Solvice Maps provides a comprehensive suite of RESTful APIs designed for high-performance routing, distance calculations, and geospatial analysis. The API architecture is built around three core service categories, each optimized for specific use cases and performance requirements.
Base URL and Authentication
Production API Base URL:
https://routing.solvice.io
Staging API Base URL:
https://mapr-gateway-staging-181354976021.europe-west1.run.app
Authentication:
All API requests require authentication via API key in the header:
X-API-Key: your-api-key-here
Content-Type: application/json
Core API Services
1. Route API - Turn-by-Turn Directions
Purpose: Generate detailed turn-by-turn directions with geometry between two or more points.
Single Route Calculation
Endpoint: POST /route
Request Body:
{
"coordinates": [
[4.3517, 50.8503], // Brussels (longitude, latitude)
[2.3522, 48.8566] // Paris
],
"profile": "car",
"options": {
"steps": true,
"geometries": "geojson",
"overview": "full",
"continue_straight": true
}
}
Response:
{
"routes": [
{
"geometry": {
"type": "LineString",
"coordinates": [[4.3517, 50.8503], ...]
},
"legs": [
{
"distance": 264.1,
"duration": 87.9,
"steps": [
{
"distance": 50.3,
"duration": 12.1,
"geometry": {
"type": "LineString",
"coordinates": [[4.3517, 50.8503], ...]
},
"name": "Rue de la Loi",
"maneuver": {
"type": "turn",
"modifier": "left",
"location": [4.3517, 50.8503]
}
}
]
}
],
"distance": 264100,
"duration": 8790,
"weight": 8790
}
],
"waypoints": [
{
"hint": "...",
"location": [4.3517, 50.8503],
"name": "Rue de la Loi"
}
]
}
Batch Route Processing
Endpoint: POST /route/batch
Request Body:
{
"requests": [
{
"coordinates": [[4.3517, 50.8503], [2.3522, 48.8566]],
"profile": "car"
},
{
"coordinates": [[2.3522, 48.8566], [3.0686, 50.6365]],
"profile": "car"
}
],
"options": {
"steps": false,
"geometries": "geojson"
}
}
Response:
{
"routes": [
{
"success": true,
"route": {
"distance": 264100,
"duration": 8790,
"geometry": {...}
}
},
{
"success": true,
"route": {
"distance": 123400,
"duration": 5420,
"geometry": {...}
}
}
]
}
2. Table API - Distance Matrix
Purpose: Calculate travel times and distances between multiple origins and destinations.
Synchronous Table (Real-time)
Endpoint: POST /table/sync
Use Case: Small matrices requiring immediate response (< 1000 coordinate pairs)
Request Body:
{
"sources": [
[4.3517, 50.8503], // Brussels
[2.3522, 48.8566], // Paris
[3.0686, 50.6365] // Lille
],
"destinations": [
[1.0952, 49.4431], // Rouen
[7.7521, 48.5734], // Strasbourg
[5.3698, 43.2965] // Marseille
],
"profile": "car",
"annotations": ["duration", "distance"]
}
Response:
{
"durations": [
[6420, 12300, 25200], // From Brussels
[4320, 9840, 22680], // From Paris
[5280, 11400, 24120] // From Lille
],
"distances": [
[324000, 567000, 1032000], // From Brussels (meters)
[256000, 487000, 923000], // From Paris
[298000, 534000, 978000] // From Lille
],
"sources": [
{"hint": "...", "location": [4.3517, 50.8503]},
{"hint": "...", "location": [2.3522, 48.8566]},
{"hint": "...", "location": [3.0686, 50.6365]}
],
"destinations": [
{"hint": "...", "location": [1.0952, 49.4431]},
{"hint": "...", "location": [7.7521, 48.5734]},
{"hint": "...", "location": [5.3698, 43.2965]}
]
}
Asynchronous Table (Large datasets)
Endpoint: POST /table
Use Case: Large matrices requiring background processing (> 1000 coordinate pairs)
Request Body:
{
"sources": [...], // Array of up to 10,000 coordinates
"destinations": [...], // Array of up to 10,000 coordinates
"profile": "car",
"annotations": ["duration", "distance"],
"engine": "osm",
"fallback_speed": 50.0
}
Response:
{
"id": "table_123456789",
"status": "IN_PROGRESS",
"created_at": "2024-01-15T10:30:00Z",
"estimated_completion": "2024-01-15T10:35:00Z",
"progress_url": "/table/123456789/progress",
"result_url": "/table/123456789/response"
}
Monitor Table Progress
Endpoint: GET /table/{id}/progress
Response:
{
"id": "table_123456789",
"status": "IN_PROGRESS",
"progress": {
"completed_requests": 45,
"total_requests": 100,
"percentage": 45.0,
"estimated_completion": "2024-01-15T10:33:00Z"
},
"created_at": "2024-01-15T10:30:00Z",
"updated_at": "2024-01-15T10:32:15Z"
}
Retrieve Table Results
Endpoint: GET /table/{id}/response
Response: Same format as synchronous table response, but potentially much larger.
For very large responses (> 10MB):
Endpoint: GET /table/{id}/response/signed-url
Response:
{
"signed_url": "https://storage.googleapis.com/mapr-results/table_123456789.json?X-Goog-Algorithm=...",
"expires_at": "2024-01-15T11:30:00Z",
"size_bytes": 52428800,
"content_type": "application/json"
}
3. Cube API - Time-Dependent Travel Matrix
Purpose: Generate travel time matrices across multiple time periods throughout the day.
Create Cube Request
Endpoint: POST /cube
Request Body:
{
"sources": [
[4.3517, 50.8503],
[2.3522, 48.8566]
],
"destinations": [
[1.0952, 49.4431],
[7.7521, 48.5734],
[5.3698, 43.2965]
],
"profile": "car",
"time_slices": [
{"slice": 0, "time": "06:00"},
{"slice": 1, "time": "08:00"},
{"slice": 2, "time": "10:00"},
{"slice": 3, "time": "12:00"},
{"slice": 4, "time": "14:00"},
{"slice": 5, "time": "16:00"},
{"slice": 6, "time": "18:00"},
{"slice": 7, "time": "20:00"}
],
"day_type": "weekday",
"generate_polynomials": true
}
Response:
{
"id": "cube_987654321",
"status": "IN_PROGRESS",
"created_at": "2024-01-15T10:30:00Z",
"time_slices": 8,
"sources_count": 2,
"destinations_count": 3,
"total_tables": 8,
"estimated_completion": "2024-01-15T10:45:00Z",
"progress_url": "/cube/987654321/progress",
"result_url": "/cube/987654321/response"
}
Monitor Cube Progress
Endpoint: GET /cube/{id}/progress
Response:
{
"id": "cube_987654321",
"status": "IN_PROGRESS",
"progress": {
"completed_tables": 3,
"total_tables": 8,
"percentage": 37.5,
"current_slice": 3,
"estimated_completion": "2024-01-15T10:42:00Z"
},
"table_progress": [
{"slice": 0, "status": "SUCCEEDED", "duration": 45.2},
{"slice": 1, "status": "SUCCEEDED", "duration": 52.1},
{"slice": 2, "status": "SUCCEEDED", "duration": 48.7},
{"slice": 3, "status": "IN_PROGRESS", "progress": 0.6},
{"slice": 4, "status": "PENDING"},
{"slice": 5, "status": "PENDING"},
{"slice": 6, "status": "PENDING"},
{"slice": 7, "status": "PENDING"}
]
}
Retrieve Cube Results
Endpoint: GET /cube/{id}/response
Response:
{
"id": "cube_987654321",
"status": "SUCCEEDED",
"sources": [...],
"destinations": [...],
"time_slices": [
{
"slice": 0,
"time": "06:00",
"durations": [
[6420, 12300, 25200],
[4320, 9840, 22680]
],
"distances": [
[324000, 567000, 1032000],
[256000, 487000, 923000]
]
},
// ... additional time slices
],
"polynomials": {
"duration_coefficients": [
[
// Polynomial coefficients for source 0 → destination 0
[6420, 1200, -300, 50], // a₀ + a₁t + a₂t² + a₃t³
// Coefficients for source 0 → destination 1
[12300, 2400, -600, 100],
// ... more destinations
],
// ... more sources
]
},
"created_at": "2024-01-15T10:30:00Z",
"completed_at": "2024-01-15T10:43:22Z",
"processing_duration": 802.3
}
Advanced Features
1. Request Splitting and Optimization
Automatic Request Splitting:
The API automatically splits large requests that exceed routing engine limits:
- OSRM: 1000 coordinates per request
- TomTom: 1000 coordinates per request
- AnyMap: 100 coordinates per request
- Google Maps: 1000 coordinates per request
Split Strategy:
// Original request: 2000 sources × 1500 destinations = 3M combinations
{
"sources": [...], // 2000 coordinates
"destinations": [...] // 1500 coordinates
}
// Automatically split into 6 child requests:
// Child 1: 1000 sources × 1000 destinations
// Child 2: 1000 sources × 500 destinations
// Child 3: 1000 sources × 1000 destinations
// Child 4: 1000 sources × 500 destinations
// etc.
2. Content-Based Caching
Cache Key Generation:
The system generates cache keys based on request content, enabling efficient deduplication:
// These requests will use the same cached result:
{
"sources": [[4.3517, 50.8503], [2.3522, 48.8566]],
"destinations": [[1.0952, 49.4431], [7.7521, 48.5734]],
"profile": "car"
}
{
"sources": [[2.3522, 48.8566], [4.3517, 50.8503]], // Different order
"destinations": [[7.7521, 48.5734], [1.0952, 49.4431]], // Different order
"profile": "car"
}
Cache Benefits:
- Immediate response for duplicate requests (< 10ms)
- 60-80% cache hit rate for typical workloads
- Significant cost reduction for repeated calculations
3. Multi-Engine Support
Engine Selection:
{
"sources": [...],
"destinations": [...],
"engine": "osm", // Explicitly specify engine
"fallback_engine": "tomtom", // Fallback if primary fails
"profile": "car"
}
Available Engines:
osm: OpenStreetMap/OSRM (free, good coverage)
tomtom: TomTom API (commercial, real-time traffic)
anymap: AnyMap service (European focus)
google: Google Maps API (premium coverage)
4. Time-Dependent Routing
Traffic Slice Selection:
{
"sources": [...],
"destinations": [...],
"profile": "car",
"traffic_slice": 2.5, // Decimal slice (interpolated)
"day_type": "weekday" // "weekday" or "weekend"
}
Traffic Slice Mapping:
Slice 0: 06:00 (Early morning)
Slice 1: 07:00 (Morning commute start)
Slice 2: 08:00 (Peak morning traffic)
Slice 3: 09:00 (Late morning)
Slice 4: 10:00 (Mid-morning)
Slice 5: 11:00 (Pre-lunch)
Slice 6: 12:00 (Lunch hour)
Slice 7: 13:00 (Post-lunch)
Slice 8: 14:00 (Afternoon)
Slice 9: 15:00 (Pre-evening)
Slice 10: 16:00 (Evening commute start)
Slice 11: 17:00 (Peak evening traffic)
Slice 12: 18:00 (Late evening)
Error Handling
{
"error": {
"code": "INVALID_COORDINATES",
"message": "One or more coordinates are invalid or unreachable",
"details": {
"invalid_coordinates": [
{"index": 5, "coordinate": [0.0, 0.0], "reason": "Ocean location"}
]
},
"timestamp": "2024-01-15T10:30:00Z",
"request_id": "req_123456789"
}
}
Common Error Codes
Authentication Errors:
INVALID_API_KEY: API key is missing or invalid
RATE_LIMIT_EXCEEDED: Request rate limit exceeded
QUOTA_EXCEEDED: Monthly quota exceeded
Request Errors:
INVALID_REQUEST: Malformed request body
INVALID_COORDINATES: Invalid coordinate format or unreachable locations
REQUEST_TOO_LARGE: Request exceeds maximum size limits
INVALID_PROFILE: Unsupported transportation profile
Processing Errors:
ROUTING_ENGINE_ERROR: External routing engine failure
TIMEOUT: Request processing timeout
INTERNAL_ERROR: Unexpected server error
Resource Errors:
RESOURCE_NOT_FOUND: Requested table/cube ID not found
RESOURCE_EXPIRED: Results have expired and been deleted
Retry Logic
Recommended Retry Strategy:
import time
import random
def retry_with_backoff(func, max_retries=3):
for attempt in range(max_retries):
try:
return func()
except Exception as e:
if attempt == max_retries - 1:
raise e
if e.status_code in [429, 502, 503, 504]: # Retriable errors
backoff = (2 ** attempt) + random.uniform(0, 1)
time.sleep(backoff)
else:
raise e # Don't retry client errors
Rate Limits and Quotas
Request Rate Limits
Standard Limits:
- Authenticated requests: 1000 requests/minute
- Table requests: 100 requests/minute
- Cube requests: 10 requests/minute
Enterprise Limits:
- Custom rate limits: Configurable per customer
- Burst allowance: Handle traffic spikes
- Priority queues: Faster processing for enterprise customers
Usage Quotas
Monthly Quotas:
- Route calculations: Unlimited for standard plans
- Table requests: Based on coordinate combinations
- Storage: 30-day retention for results
Quota Headers:
X-RateLimit-Limit: 1000
X-RateLimit-Remaining: 987
X-RateLimit-Reset: 1642251600
X-Quota-Limit: 1000000
X-Quota-Remaining: 876543
X-Quota-Reset: 1644843600
Request Optimization Tips
-
Batch Similar Requests:
// Instead of multiple single requests
POST /route (request 1)
POST /route (request 2)
// Use batch endpoint
POST /route/batch (both requests)
-
Use Appropriate Endpoints:
- Small tables (< 100 coords): Use
/table/sync
- Large tables (> 1000 coords): Use
/table (async)
- Time analysis: Use
/cube for multiple time periods
-
Leverage Caching:
// Order coordinates consistently for better cache hits
{
"sources": [[2.3522, 48.8566], [4.3517, 50.8503]], // Sorted
"destinations": [[1.0952, 49.4431], [7.7521, 48.5734]] // Sorted
}
-
Choose Optimal Engines:
- Development/Testing: Use
osm (free)
- Production (Europe): Use
anymap for best accuracy
- Global Coverage: Use
google or tomtom
- Real-time Traffic: Use
tomtom or google
Response Size Optimization
Large Response Handling:
- Responses > 10MB automatically use signed URLs
- Use compression for data transfer
- Consider pagination for very large datasets
Selective Data Retrieval:
{
"annotations": ["duration"], // Only duration, not distance
"geometries": "false", // Skip geometry data
"steps": false // Skip turn-by-turn steps
}
SDK and Integration Examples
JavaScript/Node.js
const SolviceMaps = require('@solvice/maps-sdk');
const client = new SolviceMaps({
apiKey: 'your-api-key',
baseURL: 'https://routing.solvice.io'
});
// Simple route
const route = await client.route.calculate({
coordinates: [[4.3517, 50.8503], [2.3522, 48.8566]],
profile: 'car',
steps: true
});
// Distance matrix
const table = await client.table.calculate({
sources: [[4.3517, 50.8503], [2.3522, 48.8566]],
destinations: [[1.0952, 49.4431], [7.7521, 48.5734]],
profile: 'car'
});
// Async table with polling
const largeTable = await client.table.calculateAsync({
sources: largeSourceArray,
destinations: largeDestinationArray,
profile: 'car'
});
// Wait for completion
const result = await client.table.waitForCompletion(largeTable.id, {
pollInterval: 5000, // 5 seconds
timeout: 300000 // 5 minutes
});
Python
from solvice_maps import SolviceMapsClient
client = SolviceMapsClient(
api_key='your-api-key',
base_url='https://routing.solvice.io'
)
# Simple route
route = client.route.calculate(
coordinates=[[4.3517, 50.8503], [2.3522, 48.8566]],
profile='car',
steps=True
)
# Distance matrix
table = client.table.calculate(
sources=[[4.3517, 50.8503], [2.3522, 48.8566]],
destinations=[[1.0952, 49.4431], [7.7521, 48.5734]],
profile='car'
)
# Async table processing
large_table = client.table.calculate_async(
sources=large_source_array,
destinations=large_destination_array,
profile='car'
)
# Poll for results
result = client.table.wait_for_completion(
large_table.id,
poll_interval=5,
timeout=300
)
cURL Examples
Simple Route:
curl -X POST https://routing.solvice.io/route \
-H "X-API-Key: your-api-key" \
-H "Content-Type: application/json" \
-d '{
"coordinates": [[4.3517, 50.8503], [2.3522, 48.8566]],
"profile": "car",
"steps": true
}'
Distance Matrix:
curl -X POST https://routing.solvice.io/table/sync \
-H "X-API-Key: your-api-key" \
-H "Content-Type: application/json" \
-d '{
"sources": [[4.3517, 50.8503], [2.3522, 48.8566]],
"destinations": [[1.0952, 49.4431], [7.7521, 48.5734]],
"profile": "car",
"annotations": ["duration", "distance"]
}'
Check Progress:
curl -X GET https://routing.solvice.io/table/123456789/progress \
-H "X-API-Key: your-api-key"
This comprehensive API guide provides all the technical details needed to effectively integrate with and utilize the Solvice Maps routing services.