API Documentation
The open developer gateway for Davao City's Interim Bus Service (DIBS). Connect directly to live bus telemetry, route polylines, station coordinates, and operating schedules.
About the Platform & API Gateway
DavaoBus is an independent open civic transit gateway created by Kurzyrio to power the SkwelaDabaw commuter mobile app and assist commuters, researchers, and developers across Davao City and Region XI.
The gateway bridges official Davao transit feeds through an in-memory 12-second micro-cache, protecting upstream telemetry infrastructure while delivering sub-50ms JSON, GeoJSON, CSV, and KML responses.
How to Connect to the API
Pick the transit resource: /buses for live GPS coordinates, /routes for corridor polylines, /stops for bus stops, or /schedules for timetables.
Append ?format=geojson for instant mapping in Leaflet, Mapbox, or Google Maps; use ?format=json (default) for web and mobile state management.
Send a straightforward HTTP GET request. No Authorization header, no API token, and no pre-registration required. Poll every 12–15 seconds for live telemetry updates.
const res = await fetch('https://busapi.kurzyrio.site/api/v1/buses?format=geojson');
const data = await res.json();
Interactive API Console
// Select an endpoint and click Execute to test live
Client Code Examples
# GeoJSON FeatureCollection with Cyber Neon Theme
curl -s "https://busapi.kurzyrio.site/api/v1/buses?format=geojson&theme=neon"
# Proximity Search: Nearest buses within 3 km of Davao City Hall
curl -s "https://busapi.kurzyrio.site/api/v1/buses?near=7.065,125.608&radius=3&fields=fleet,route_code,distance_km,speed_kmh"
# 24/7 Resilient query with auto-fallback to simulation during off-peak
curl -s "https://busapi.kurzyrio.site/api/v1/buses?fallback=simulate&theme=accessible"
# Custom per-route color override for R102 and R402
curl -s "https://busapi.kurzyrio.site/api/v1/routes?colors=R102:#00f0ff,R402:#ff007f"
Schema Reference
GET /api/v1/buses
Live vehicle telemetry feed. Updated every 10–12 seconds with automatic stale-while-revalidate safety and off-peak operational state intelligence.
fleet(string): Unique vehicle fleet identifier (e.g."DCBUS 01")route_code(string): Service route code (e.g."R102")route_name(string): Full origin & destination descriptorroute_color(string): Official corridor hex color (e.g."#e11d48")latitude/longitude(float): WGS84 GPS coordinate pairspeed_kmh(float): Real-time speed in kilometers per hourheading_deg(integer): Bearing angle in degrees (0–360°)is_online(boolean): Reporting connection statusis_stale(boolean): Flags buses without updates for >5 minutesis_simulated(boolean):truewhen running under developer simulation modereport_clock(string): Local device timestamp
service_status):
state(string): Current window:"ACTIVE_PEAK","MIDDAY_OFF_PEAK", or"NIGHT_OFF_PEAK"is_service_hours(boolean):trueduring 06:00–10:00 & 16:00–21:00 UTC+8next_window(object): Next opening shift name, time (opens_at), and countdown (countdown_human)notice(string): Clear operational notice for users and commutersdeveloper_rules(object): Direct instructions for client app developers during off-peak hours
GET /api/v1/schedules
Official Davao City Government DIBS schedules, designated route colors, operating windows, and outbound/inbound stop sequences for all 9 corridors.
?route=CODE: Filter by corridor code (R102,R103,R402,R403,R503,R603,R763,R783,R793)?shift=AM|PM: Filter by shift window (AM: 6:00–10:00 AM |PM: 4:00–9:00 PM)?search=QUERY: Search routes by stop name or corridor keyword?format=json|csv|xml|ndjson: Multi-format serialization (CSV outputs flattened stop order sequence)
?format=json to retrieve complete stop sequences with outbound and inbound pathways.
GET /api/v1/routes
Route polyline geometry, corridor metadata, and designated transit colors for mapping overlays.
?format=geojson to receive a standard GeoJSON FeatureCollection directly consumable by MapLibre, Mapbox, Leaflet, or QGIS. Each line feature contains its official color property.
GET /api/v1/stops
Official bus stop coordinates and name registry across Davao City corridors (125 stops).
?format=kml for Google Earth, ?format=csv for spreadsheet analysis, and ?route=R102 to filter stops for a specific corridor.
Zero-Bus Policy & Client Rules
Official DIBS buses operate on split-peak shifts: 06:00–10:00 (AM) and 16:00–21:00 (PM). Outside these hours (midday and night), fleets are parked at municipal depots, resulting in zero active GPS units. Rather than throwing HTTP errors or blank arrays, the API returns a structured service_status operational payload.
Client apps (e.g. SkwelaDabaw) should inspect service_status.state. If MIDDAY_OFF_PEAK or NIGHT_OFF_PEAK, display a countdown to the next shift using service_status.next_window.countdown_human instead of an error.
When service_status.is_service_hours === false, query /api/v1/schedules to display official stop sequences and trip planning information.
Pass ?simulate=1 to test vehicle markers, bearings, and dead-reckoning at any hour. Or use ?fallback=simulate to automatically simulate buses only when real fleet count is zero.
async function fetchTransitStatus() {
// ?fallback=simulate ensures developers always see bus movement 24/7
const res = await fetch('https://busapi.kurzyrio.site/api/v1/buses?fallback=simulate');
const data = await res.json();
if (data.count === 0 && !data.service_status.is_service_hours) {
// Gracefully handle off-peak hiatus: show next shift countdown
const next = data.service_status.next_window;
document.getElementById('statusBanner').textContent =
`${next.name} starts at ${next.opens_at} (${next.countdown_human})`;
// Fetch static DIBS schedules for offline trip planning
const sched = await fetch('https://busapi.kurzyrio.site/api/v1/schedules').then(r => r.json());
renderScheduleList(sched.routes);
} else {
// Normal operation: plot live or simulated vehicles
renderBusMarkers(data.buses);
}
}
API Flexibility & Customization Guide
Dynamic EngineThe DavaoBus platform is engineered for complete developer customization. Query real-time buses, routes, schedules, and stops with dynamic color palettes, WCAG contrast tokens, geospatial radial search, field projection, unit conversions, and realistic simulation controls.
🎨 1. Multi-Theme Color Engine & Custom Overrides
Switch between 5 built-in palette themes or pass custom hex overrides. Color tokens are computed server-side with WCAG AAA luminance calculations ($L = 0.2126R + 0.7152G + 0.0722B$), guaranteeing legible contrast text for badges and HUDs.
?colors[R102]=#00f0ff or delimited string ?colors=R102:#00f0ff,R103:#ff003c.
"color_token": {
"hex": "#ff2d55",
"name": "Electric Coral",
"rgb": "rgb(255, 45, 85)",
"rgb_array": [255, 45, 85],
"hsl": "hsl(349, 100%, 59%)",
"luminance": 0.363,
"contrast_text": "#ffffff",
"gradient": "linear-gradient(135deg, #ff2d55 0%, #ff5374 100%)",
"glow": "rgba(255, 45, 85, 0.45)",
"badge_css": "background: #ff2d55; color: #ffffff;"
}
📍 2. Geospatial Proximity & Viewport Bounding Box
Filter buses or bus stops relative to the user's GPS coordinates using great-circle Haversine computation, or clip query results to a map client's current screen viewport.
?near=LAT,LNG&radius=KM: Returns only units/stops withinradiuskilometers (default: 5 km). Automatically calculates and injectsdistance_kminto each record.?bbox=MIN_LNG,MIN_LAT,MAX_LNG,MAX_LAT: Bounding box filter for map viewport culling (e.g.?bbox=125.50,7.00,125.65,7.15).?sort=distance_asc: Orders records starting from the nearest vehicle or stop to the user's location.
# Find closest bus stops within 3 km of Davao City Hall (7.065, 125.608)
curl -s "https://busapi.kurzyrio.site/api/v1/stops?near=7.065,125.608&radius=3&fields=name,route,distance_km,color"
⚡ 3. Payload Shaping: Field Projection, Units & Sorting
Save mobile bandwidth on 4G/LTE transit trackers by requesting only the exact fields required by your view models.
?fields=fleet,route_code,speed_kmh,latitude,longitude: Whitelists only requested attributes per entity.?units=kmh|mph|mps: Speed units. Returns converted speed values along with unit metadata (e.g.,speed_unit: "mph").?sort=speed_desc|speed_asc|fleet_asc|distance_asc|name_asc: Server-side record sorting.?limit=N: Restricts maximum array elements returned (e.g.?limit=10).
# Minimalist 5-field lightweight payload sorted by speed
curl -s "https://busapi.kurzyrio.site/api/v1/buses?fields=fleet,route_code,speed_kmh,latitude,longitude&sort=speed_desc"
🎮 4. Developer Simulation Engine Controls
Develop and test client applications anytime—even during nighttime off-peak hours—with high-precision synthetic telemetry adhering to actual Davao City road geometry.
?simulate=1: Activates synthetic vehicle simulation across all corridors.?fallback=simulate: Recommended for client apps: Automatically generates simulated buses only when real fleet count is zero during off-peak hours.?sim_count=N: Number of simulated units to spawn (1 to 45, default: 18).?sim_speed=slow|normal|fast: Calibrated velocity (slow: 14–18 km/h urban crawl,normal: 20–26 km/h city cruise,fast: 32–38 km/h express).?sim_routes=R102,R402: Confines simulated fleet strictly to specified corridor routes.
# Spawn 35 synthetic units moving fast along the Toril and Mintal corridors with Cyber Neon colors
curl -s "https://busapi.kurzyrio.site/api/v1/buses?simulate=1&sim_count=35&sim_speed=fast&sim_routes=R102,R402&theme=neon"
Client-Side Motion & Dead Reckoning
The raw API serves pure, unpolluted telemetry every 10–12 seconds. To achieve fluid 60fps vehicle gliding on mobile and web applications (as demonstrated on BusMap), developers can implement Dead Reckoning and Coordinate LERP.
1. The Kinematic Formula
Between telemetry intervals, advance the vehicle coordinate along its bearing vector using spherical displacement:
speed_mps = speed_kmh * (1000 / 3600);
distance_meters = speed_mps * dt;
delta_lat = (distance_meters * cos(heading_rad)) / 111139;
delta_lng = (distance_meters * sin(heading_rad)) / (111139 * cos(lat_rad));
2. Implementation Snippet (JavaScript)
let lastTime = performance.now();
function animateVehicles(now) {
const dt = Math.min((now - lastTime) / 1000, 0.15);
lastTime = now;
for (const bus of busTracker.values()) {
// 1. Smoothly interpolate (LERP) towards reported GPS target
bus.currentLng += (bus.targetLng - bus.currentLng) * Math.min(dt * 3.5, 0.35);
bus.currentLat += (bus.targetLat - bus.currentLat) * Math.min(dt * 3.5, 0.35);
// 2. Dead reckoning along bearing vector if bus is moving
const age = (now - bus.lastUpdate) / 1000;
if (bus.speedKmh > 2 && age < 18) {
const damping = Math.max(0, 1 - (age / 18));
const dist = (bus.speedKmh * 1000 / 3600) * damping * dt;
const rad = (bus.headingDeg * Math.PI) / 180;
bus.currentLat += (dist * Math.cos(rad)) / 111139;
bus.currentLng += (dist * Math.sin(rad)) / (111139 * Math.cos(bus.currentLat * Math.PI / 180));
}
// 3. Update marker coordinate
bus.marker.setLngLat([bus.currentLng, bus.currentLat]);
}
requestAnimationFrame(animateVehicles);
}
requestAnimationFrame(animateVehicles);
Multi-Format Integration Guides
The gateway natively encodes public transit telemetry into 6 industry-standard formats. Select a format to view real-world use cases, production URLs, and developer integration snippets.
Best For: Native iOS/Android mobile apps (Flutter, React Native, Swift, Kotlin), web application state stores (React, Vue, Svelte), and lightweight cloud functions.
GET https://busapi.kurzyrio.site/api/v1/buses?format=json
# Content negotiation alternative:
curl -s -H "Accept: application/json" "https://busapi.kurzyrio.site/api/v1/buses"
const res = await fetch('https://busapi.kurzyrio.site/api/v1/buses?format=json&route=R102');
const data = await res.json();
// Direct array mapping
data.buses.forEach(bus => {
console.log(`${bus.fleet}: ${bus.speed_kmh} km/h @ [${bus.latitude}, ${bus.longitude}]`);
});
Filter Parameters Matrix
All filter query parameters are universally compatible across all 6 output formats:
R102 (Toril Sandawa), R103 (Toril Roxas), R402 (Mintal GE Torres), R403 (Mintal Roxas), R503 (Bangkal), R603 (Buhangin), R763, R783, R793 (Panacan corridors).
speed_kmh > 0), excluding idling or parked units.
DCBUS 01), corridor descriptors (e.g. Toril), and stop points.
?limit=5).