curl --request GET \
--url https://api.bookovia.com/v1/trips/{trip_id}/route \
--header 'X-API-Key: <api-key>'{
"error": {
"code": "trip_not_found",
"message": "Trip not found or no route data available",
"details": "Trip 'trip_1234567890abcdef' does not exist or has insufficient location data"
}
}
Retrieve detailed route information including path optimization, traffic analysis, and efficiency metrics
curl --request GET \
--url https://api.bookovia.com/v1/trips/{trip_id}/route \
--header 'X-API-Key: <api-key>'{
"error": {
"code": "trip_not_found",
"message": "Trip not found or no route data available",
"details": "Trip 'trip_1234567890abcdef' does not exist or has insufficient location data"
}
}
Documentation Index
Fetch the complete documentation index at: https://docs.bookovia.com/llms.txt
Use this file to discover all available pages before exploring further.
X-API-Key header.
Required permissions: trips:read
curl -X GET "https://api.bookovia.com/v1/trips/trip_1234567890abcdef/route?include_waypoints=true&include_alternatives=true" \
-H "X-API-Key: bkv_test_your_api_key_here"
Show route_geometry properties
Show route_analytics properties
Show waypoint properties
Show traffic_analysis properties
{
"trip_id": "trip_1234567890abcdef",
"route_status": "completed",
"route_geometry": {
"type": "LineString",
"coordinates": [
[-74.0060, 40.7128],
[-74.0055, 40.7132],
[-74.0050, 40.7135],
[-73.9851, 40.7589]
],
"total_points": 426,
"simplified": true,
"precision": 6
},
"route_analytics": {
"total_distance_km": 45.2,
"estimated_duration_minutes": 98,
"actual_duration_minutes": 105,
"efficiency_score": 87,
"deviation_percentage": 3.2,
"fuel_efficiency_rating": "good",
"route_complexity": "moderate",
"elevation_gain_meters": 125,
"highway_percentage": 68.5,
"city_driving_percentage": 31.5
},
"waypoints": [
{
"waypoint_id": "wp_start_001",
"latitude": 40.7128,
"longitude": -74.0060,
"waypoint_type": "start",
"address": "New York, NY",
"distance_from_start_km": 0.0,
"estimated_arrival_time": "2024-04-13T10:30:00Z",
"actual_arrival_time": "2024-04-13T10:30:00Z"
},
{
"waypoint_id": "wp_turn_001",
"latitude": 40.7312,
"longitude": -73.9942,
"waypoint_type": "turn",
"address": "Broadway & 14th St",
"distance_from_start_km": 15.8,
"estimated_arrival_time": "2024-04-13T11:05:00Z",
"actual_arrival_time": "2024-04-13T11:08:00Z",
"delay_minutes": 3
},
{
"waypoint_id": "wp_end_001",
"latitude": 40.7589,
"longitude": -73.9851,
"waypoint_type": "end",
"address": "Central Park, New York, NY",
"distance_from_start_km": 45.2,
"estimated_arrival_time": "2024-04-13T12:08:00Z",
"actual_arrival_time": "2024-04-13T12:15:00Z",
"delay_minutes": 7
}
],
"traffic_analysis": {
"average_congestion_level": "moderate",
"traffic_delay_minutes": 12,
"fuel_cost_impact_usd": 1.85,
"congested_segments": [
{
"segment_id": "seg_001",
"start_km": 8.2,
"end_km": 12.7,
"congestion_level": "heavy",
"delay_minutes": 8,
"average_speed_kmh": 15.2
}
],
"peak_hours_impact": {
"is_peak_hours": true,
"peak_period": "morning_rush",
"additional_delay_minutes": 5,
"congestion_factor": 1.4
},
"incident_reports": [
{
"incident_id": "inc_001",
"type": "construction",
"location": "Broadway & Houston St",
"impact_minutes": 4,
"active": false
}
]
},
"alternative_routes": [
{
"route_id": "alt_route_001",
"name": "Highway 95 Route",
"distance_km": 42.1,
"estimated_duration_minutes": 88,
"fuel_savings_liters": 0.4,
"time_savings_minutes": 10,
"efficiency_score": 92,
"trade_offs": {
"toll_cost_usd": 8.50,
"highway_driving_percentage": 85,
"scenic_value": "low"
}
},
{
"route_id": "alt_route_002",
"name": "Scenic Coastal Route",
"distance_km": 52.8,
"estimated_duration_minutes": 125,
"fuel_cost_difference_usd": 2.10,
"time_difference_minutes": 20,
"efficiency_score": 75,
"trade_offs": {
"toll_cost_usd": 0.00,
"scenic_value": "high",
"traffic_likelihood": "low"
}
}
],
"optimization_suggestions": [
{
"suggestion_id": "opt_001",
"type": "route_optimization",
"title": "Alternative highway route available",
"description": "Taking Highway 95 could save 10 minutes and reduce fuel consumption",
"potential_savings": {
"time_minutes": 10,
"fuel_liters": 0.4,
"cost_usd": 1.20
},
"implementation_complexity": "low"
},
{
"suggestion_id": "opt_002",
"type": "timing_optimization",
"title": "Avoid peak hours",
"description": "Departing 45 minutes earlier could reduce travel time by 15%",
"potential_savings": {
"time_minutes": 16,
"fuel_liters": 0.3
}
}
]
}
{
"error": {
"code": "trip_not_found",
"message": "Trip not found or no route data available",
"details": "Trip 'trip_1234567890abcdef' does not exist or has insufficient location data"
}
}
import Bookovia from '@bookovia/javascript-sdk';
const client = new Bookovia('bkv_test_your_api_key');
// Get comprehensive route data
const routeData = await client.trips.getRoute('trip_1234567890abcdef', {
includeWaypoints: true,
includeTrafficData: true,
includeAlternatives: true
});
console.log(`Route efficiency: ${routeData.routeAnalytics.efficiencyScore}%`);
console.log(`Total distance: ${routeData.routeAnalytics.totalDistanceKm} km`);
// Analyze route optimization opportunities
const analyzeRouteOptimization = (routeData) => {
const suggestions = routeData.optimizationSuggestions || [];
suggestions.forEach(suggestion => {
console.log(`💡 ${suggestion.title}`);
console.log(` ${suggestion.description}`);
if (suggestion.potentialSavings.timeMinutes > 5) {
console.log(` ⏱️ Could save ${suggestion.potentialSavings.timeMinutes} minutes`);
}
if (suggestion.potentialSavings.costUsd > 1.0) {
console.log(` 💰 Could save $${suggestion.potentialSavings.costUsd}`);
}
});
};
analyzeRouteOptimization(routeData);
// Generate route report for fleet management
const generateRouteReport = async (tripId) => {
const route = await client.trips.getRoute(tripId, {
includeWaypoints: true,
includeTrafficData: true
});
return {
tripId: route.tripId,
distance: route.routeAnalytics.totalDistanceKm,
duration: route.routeAnalytics.actualDurationMinutes,
efficiency: route.routeAnalytics.efficiencyScore,
trafficDelay: route.trafficAnalysis?.trafficDelayMinutes || 0,
waypoints: route.waypoints.map(wp => ({
type: wp.waypointType,
address: wp.address,
delay: wp.delayMinutes || 0
})),
alternativeRoutes: route.alternativeRoutes?.length || 0
};
};
// Delivery route optimization system
class DeliveryRouteOptimizer {
constructor(client) {
this.client = client;
this.optimizationCache = new Map();
}
async optimizeDeliveryRoute(tripId, deliveryWindows) {
const routeData = await this.client.trips.getRoute(tripId, {
includeWaypoints: true,
includeTrafficData: true,
includeAlternatives: true
});
// Analyze current route efficiency
const currentEfficiency = this.analyzeRouteEfficiency(routeData);
// Check alternative routes
const bestAlternative = this.findBestAlternative(
routeData.alternativeRoutes,
deliveryWindows
);
// Generate optimization recommendations
const recommendations = this.generateOptimizationPlan(
routeData,
bestAlternative,
deliveryWindows
);
return {
currentRoute: {
efficiency: currentEfficiency,
estimatedDeliveryTime: this.calculateDeliveryTime(routeData),
trafficImpact: routeData.trafficAnalysis?.trafficDelayMinutes || 0
},
recommendedRoute: bestAlternative,
optimizations: recommendations,
potentialSavings: this.calculateSavings(routeData, bestAlternative)
};
}
analyzeRouteEfficiency(routeData) {
const analytics = routeData.routeAnalytics;
return {
efficiencyScore: analytics.efficiencyScore,
fuelEfficiency: analytics.fuelEfficiencyRating,
deviation: analytics.deviationPercentage,
complexity: analytics.routeComplexity
};
}
findBestAlternative(alternatives, deliveryWindows) {
if (!alternatives || alternatives.length === 0) return null;
return alternatives.reduce((best, current) => {
const currentScore = this.scoreAlternativeRoute(current, deliveryWindows);
const bestScore = best ? this.scoreAlternativeRoute(best, deliveryWindows) : 0;
return currentScore > bestScore ? current : best;
}, null);
}
scoreAlternativeRoute(route, deliveryWindows) {
let score = route.efficiencyScore || 0;
// Bonus for time savings
if (route.timeSavingsMinutes > 0) {
score += Math.min(route.timeSavingsMinutes / 5, 20);
}
// Penalty for toll costs
if (route.tradeOffs?.tollCostUsd > 0) {
score -= Math.min(route.tradeOffs.tollCostUsd, 10);
}
// Bonus for meeting delivery windows
if (this.meetsDeliveryWindows(route, deliveryWindows)) {
score += 15;
}
return score;
}
meetsDeliveryWindows(route, windows) {
// Implementation would check if route timing aligns with delivery windows
return true; // Simplified for example
}
}
// Usage
const optimizer = new DeliveryRouteOptimizer(client);
const deliveryWindows = [
{ address: "123 Main St", timeWindow: "09:00-11:00" },
{ address: "456 Oak Ave", timeWindow: "14:00-16:00" }
];
const optimization = await optimizer.optimizeDeliveryRoute('trip_123', deliveryWindows);
console.log('Route optimization suggestions:', optimization.optimizations);
# Fleet route performance analysis system
import pandas as pd
import numpy as np
from datetime import datetime, timedelta
class FleetRouteAnalytics:
def __init__(self, client):
self.client = client
async def analyze_fleet_performance(self, vehicle_ids, date_range):
"""Comprehensive fleet route performance analysis"""
all_routes = []
for vehicle_id in vehicle_ids:
# Get trips for vehicle in date range
trips = await self.client.trips.list(
vehicle_id=vehicle_id,
start_date=date_range['start'],
end_date=date_range['end'],
status='completed'
)
for trip in trips.trips:
try:
route = await self.client.trips.get_route(
trip_id=trip.trip_id,
include_traffic_data=True,
include_alternatives=True
)
route_metrics = self.extract_route_metrics(route, vehicle_id)
all_routes.append(route_metrics)
except Exception as e:
print(f"Failed to analyze route {trip.trip_id}: {e}")
return self.generate_performance_report(all_routes)
def extract_route_metrics(self, route, vehicle_id):
"""Extract key metrics from route data"""
analytics = route.route_analytics
traffic = route.traffic_analysis or {}
return {
'trip_id': route.trip_id,
'vehicle_id': vehicle_id,
'distance_km': analytics.total_distance_km,
'duration_minutes': analytics.actual_duration_minutes,
'efficiency_score': analytics.efficiency_score,
'traffic_delay_minutes': traffic.get('traffic_delay_minutes', 0),
'fuel_rating': analytics.fuel_efficiency_rating,
'deviation_percentage': analytics.deviation_percentage,
'highway_percentage': analytics.highway_percentage,
'alternative_routes_count': len(route.alternative_routes or []),
'optimization_potential': self.calculate_optimization_potential(route)
}
def calculate_optimization_potential(self, route):
"""Calculate potential improvements from alternative routes"""
if not route.alternative_routes:
return 0
best_alternative = max(route.alternative_routes,
key=lambda r: r.get('efficiency_score', 0))
current_score = route.route_analytics.efficiency_score
best_score = best_alternative.get('efficiency_score', current_score)
return max(0, best_score - current_score)
def generate_performance_report(self, routes_data):
"""Generate comprehensive performance report"""
df = pd.DataFrame(routes_data)
if df.empty:
return {'error': 'No route data available'}
# Fleet-wide statistics
fleet_stats = {
'total_trips': len(df),
'total_distance_km': df['distance_km'].sum(),
'total_duration_hours': df['duration_minutes'].sum() / 60,
'avg_efficiency_score': df['efficiency_score'].mean(),
'avg_traffic_delay_minutes': df['traffic_delay_minutes'].mean(),
'total_optimization_potential': df['optimization_potential'].sum()
}
# Vehicle performance ranking
vehicle_performance = df.groupby('vehicle_id').agg({
'efficiency_score': 'mean',
'traffic_delay_minutes': 'mean',
'optimization_potential': 'mean',
'distance_km': 'sum'
}).round(2)
# Route efficiency distribution
efficiency_distribution = {
'excellent': len(df[df['efficiency_score'] >= 90]),
'good': len(df[(df['efficiency_score'] >= 75) & (df['efficiency_score'] < 90)]),
'average': len(df[(df['efficiency_score'] >= 60) & (df['efficiency_score'] < 75)]),
'poor': len(df[df['efficiency_score'] < 60])
}
# Optimization opportunities
high_potential = df[df['optimization_potential'] > 10].sort_values(
'optimization_potential', ascending=False
)
return {
'fleet_statistics': fleet_stats,
'vehicle_rankings': vehicle_performance.to_dict('index'),
'efficiency_distribution': efficiency_distribution,
'optimization_opportunities': high_potential[['trip_id', 'vehicle_id', 'optimization_potential']].to_dict('records'),
'recommendations': self.generate_recommendations(df)
}
def generate_recommendations(self, df):
"""Generate actionable recommendations"""
recommendations = []
# High traffic delay vehicles
high_delay = df.groupby('vehicle_id')['traffic_delay_minutes'].mean()
for vehicle_id, avg_delay in high_delay[high_delay > 15].items():
recommendations.append({
'type': 'traffic_optimization',
'vehicle_id': vehicle_id,
'issue': f'Average traffic delay of {avg_delay:.1f} minutes',
'suggestion': 'Consider route timing optimization or alternative routes'
})
# Low efficiency vehicles
low_efficiency = df.groupby('vehicle_id')['efficiency_score'].mean()
for vehicle_id, avg_score in low_efficiency[low_efficiency < 70].items():
recommendations.append({
'type': 'efficiency_improvement',
'vehicle_id': vehicle_id,
'issue': f'Low efficiency score of {avg_score:.1f}',
'suggestion': 'Review route planning and driver behavior'
})
return recommendations
# Usage
analytics = FleetRouteAnalytics(client)
# Analyze last 30 days
date_range = {
'start': (datetime.now() - timedelta(days=30)).isoformat() + 'Z',
'end': datetime.now().isoformat() + 'Z'
}
fleet_report = await analytics.analyze_fleet_performance(
vehicle_ids=['vehicle_001', 'vehicle_002', 'vehicle_003'],
date_range=date_range
)
print("Fleet Performance Report:")
print(f"Total trips: {fleet_report['fleet_statistics']['total_trips']}")
print(f"Average efficiency: {fleet_report['fleet_statistics']['avg_efficiency_score']:.1f}%")
print(f"Optimization potential: {fleet_report['fleet_statistics']['total_optimization_potential']:.1f} points")
// Construction/service route planning with real-time optimization
package main
import (
"context"
"fmt"
"time"
"github.com/bookovia/go-sdk"
)
type ServiceRouteManager struct {
client *bookovia.Client
jobSites map[string]JobSite
}
type JobSite struct {
ID string
Address string
Coordinates [2]float64 // [longitude, latitude]
TimeWindow TimeWindow
Priority string
Equipment []string
}
type TimeWindow struct {
Start time.Time
End time.Time
}
func NewServiceRouteManager(client *bookovia.Client) *ServiceRouteManager {
return &ServiceRouteManager{
client: client,
jobSites: make(map[string]JobSite),
}
}
func (s *ServiceRouteManager) OptimizeServiceRoute(ctx context.Context, tripID string, scheduledJobs []string) (*ServiceRouteOptimization, error) {
// Get current route data
currentRoute, err := s.client.Trips.GetRoute(ctx, tripID, &bookovia.GetRouteOptions{
IncludeWaypoints: true,
IncludeTrafficData: true,
IncludeAlternatives: true,
})
if err != nil {
return nil, fmt.Errorf("failed to get route data: %v", err)
}
// Analyze job site accessibility
jobSiteAnalysis := s.analyzeJobSiteAccessibility(currentRoute, scheduledJobs)
// Check for route optimizations
optimizations := s.identifyOptimizations(currentRoute, jobSiteAnalysis)
// Calculate service efficiency metrics
efficiency := s.calculateServiceEfficiency(currentRoute, scheduledJobs)
return &ServiceRouteOptimization{
TripID: tripID,
CurrentEfficiency: efficiency,
JobSiteAnalysis: jobSiteAnalysis,
OptimizationOptions: optimizations,
Recommendations: s.generateServiceRecommendations(currentRoute, scheduledJobs),
}, nil
}
func (s *ServiceRouteManager) analyzeJobSiteAccessibility(route *bookovia.RouteData, jobIDs []string) []JobSiteAnalysis {
var analysis []JobSiteAnalysis
for _, jobID := range jobIDs {
jobSite, exists := s.jobSites[jobID]
if !exists {
continue
}
accessibility := s.calculateAccessibility(route, jobSite)
analysis = append(analysis, JobSiteAnalysis{
JobSiteID: jobID,
Address: jobSite.Address,
AccessibilityScore: accessibility.Score,
EstimatedArrival: accessibility.EstimatedArrival,
TrafficImpact: accessibility.TrafficDelay,
Challenges: accessibility.Challenges,
})
}
return analysis
}
func (s *ServiceRouteManager) calculateAccessibility(route *bookovia.RouteData, jobSite JobSite) AccessibilityMetrics {
// Find closest waypoint to job site
var closestWaypoint *bookovia.Waypoint
minDistance := float64(999999)
for _, wp := range route.Waypoints {
distance := s.calculateDistance(
wp.Latitude, wp.Longitude,
jobSite.Coordinates[1], jobSite.Coordinates[0],
)
if distance < minDistance {
minDistance = distance
closestWaypoint = wp
}
}
metrics := AccessibilityMetrics{
Score: s.scoreAccessibility(minDistance, route.TrafficAnalysis),
}
if closestWaypoint != nil && closestWaypoint.EstimatedArrivalTime != "" {
arrivalTime, _ := time.Parse(time.RFC3339, closestWaypoint.EstimatedArrivalTime)
metrics.EstimatedArrival = arrivalTime
// Check if arrival is within job site time window
if arrivalTime.Before(jobSite.TimeWindow.Start) || arrivalTime.After(jobSite.TimeWindow.End) {
metrics.Challenges = append(metrics.Challenges, "Outside time window")
}
}
return metrics
}
func (s *ServiceRouteManager) scoreAccessibility(distance float64, traffic *bookovia.TrafficAnalysis) int {
score := 100
// Distance penalty
if distance > 5.0 { // > 5km from route
score -= int(distance * 2)
}
// Traffic penalty
if traffic != nil {
switch traffic.AverageCongestionLevel {
case "heavy":
score -= 20
case "moderate":
score -= 10
case "light":
score -= 5
}
}
if score < 0 {
score = 0
}
return score
}
func (s *ServiceRouteManager) identifyOptimizations(route *bookovia.RouteData, jobAnalysis []JobSiteAnalysis) []OptimizationOption {
var options []OptimizationOption
// Check for poor accessibility scores
for _, job := range jobAnalysis {
if job.AccessibilityScore < 50 {
options = append(options, OptimizationOption{
Type: "route_modification",
Description: fmt.Sprintf("Modify route to improve access to %s", job.Address),
Impact: "Reduce service time and fuel consumption",
Effort: "moderate",
})
}
}
// Check alternative routes
if route.AlternativeRoutes != nil {
for _, alt := range route.AlternativeRoutes {
if alt.TimeSavingsMinutes > 15 {
options = append(options, OptimizationOption{
Type: "alternative_route",
Description: fmt.Sprintf("Use %s for better efficiency", alt.Name),
Impact: fmt.Sprintf("Save %d minutes", alt.TimeSavingsMinutes),
Effort: "low",
})
}
}
}
return options
}
func (s *ServiceRouteManager) calculateDistance(lat1, lng1, lat2, lng2 float64) float64 {
// Simplified distance calculation (replace with proper implementation)
dlat := lat2 - lat1
dlng := lng2 - lng1
return math.Sqrt(dlat*dlat + dlng*dlng) * 111.0 // Rough km conversion
}
// Data structures
type ServiceRouteOptimization struct {
TripID string `json:"trip_id"`
CurrentEfficiency ServiceEfficiency `json:"current_efficiency"`
JobSiteAnalysis []JobSiteAnalysis `json:"job_site_analysis"`
OptimizationOptions []OptimizationOption `json:"optimization_options"`
Recommendations []string `json:"recommendations"`
}
type JobSiteAnalysis struct {
JobSiteID string `json:"job_site_id"`
Address string `json:"address"`
AccessibilityScore int `json:"accessibility_score"`
EstimatedArrival time.Time `json:"estimated_arrival"`
TrafficImpact float64 `json:"traffic_impact"`
Challenges []string `json:"challenges"`
}
type AccessibilityMetrics struct {
Score int `json:"score"`
EstimatedArrival time.Time `json:"estimated_arrival"`
TrafficDelay float64 `json:"traffic_delay"`
Challenges []string `json:"challenges"`
}
type OptimizationOption struct {
Type string `json:"type"`
Description string `json:"description"`
Impact string `json:"impact"`
Effort string `json:"effort"`
}
type ServiceEfficiency struct {
OverallScore int `json:"overall_score"`
JobSiteAccessibility int `json:"job_site_accessibility"`
RouteOptimization int `json:"route_optimization"`
TimeWindowCompliance int `json:"time_window_compliance"`
}
func main() {
client := bookovia.NewClient("bkv_test_your_api_key")
manager := NewServiceRouteManager(client)
// Add sample job sites
manager.jobSites["job_001"] = JobSite{
ID: "job_001",
Address: "123 Construction Ave",
Coordinates: [-74.0060, 40.7128],
TimeWindow: TimeWindow{
Start: time.Now().Add(time.Hour * 2),
End: time.Now().Add(time.Hour * 6),
},
Priority: "high",
Equipment: []string{"crane", "tools"},
}
ctx := context.Background()
optimization, err := manager.OptimizeServiceRoute(ctx, "trip_service_123", []string{"job_001"})
if err != nil {
fmt.Printf("Error optimizing service route: %v\n", err)
return
}
fmt.Printf("Service Route Optimization:\n")
fmt.Printf("Overall Efficiency: %d%%\n", optimization.CurrentEfficiency.OverallScore)
fmt.Printf("Job Site Accessibility: %d%%\n", optimization.CurrentEfficiency.JobSiteAccessibility)
fmt.Printf("Available Optimizations: %d\n", len(optimization.OptimizationOptions))
}
Data Volume Management
simplify_geometry=true for large routes to reduce payloadgeometry_precision based on your use case (4-6 for most applications)Caching Strategy
Real-time Updates
Visualization
Was this page helpful?