Navvo
API Reference

Traffic Intelligence & Feedback

Historical traffic profiles, congestion labels, departure timing, area insights, privacy-safe popularity, change analytics, and in-app feedback.

Traffic Intelligence & Feedback

Navvo learns typical traffic patterns from anonymized, demand-driven probe data and exposes them as calendar-aware profiles (holiday / Ramadan / weekend / typical), human congestion labels, departure-time guidance, area insights, and a privacy-safe popularity heatmap. It also exposes platform change & freshness analytics and an in-app feedback intake.

Scope required: tiles (traffic model), insights (Navvo Insights), places (feedback).

All responses are Navvo-branded aggregates. Individual trips are never exposed — popularity and any exported counts pass through a differential-privacy layer (Laplace noise + k-anonymity suppression).

GET /traffic/profile

The calendar-aware typical congestion for one road segment at a time. Falls back most-specific → general: ramadan → holiday → weekend → typical.

QueryTypeNotes
segmentKeystringrequired — a Navvo road-segment id
atISO datetimeoptional, defaults to now
countrystringoptional ISO-2, defaults JO
{
  "segmentKey": "e:3518657574394",
  "profileType": "typical",
  "dow": 4, "todBucket": 84,
  "congestion": "light", "speedRatio": 1.08, "sampleCount": 3,
  "calendar": { "isHoliday": false, "isWeekend": false, "isRamadan": false }
}

GET /traffic/labels

Explainable 4-class congestion labels (Heavy / High / Normal / Low) for every known segment in a bbox, with a plain-language reason.

?bbox=minLng,minLat,maxLng,maxLat&at=<ISO>&country=JO

{ "count": 65, "labels": [
  { "segmentKey": "e:736821794312", "label": "High", "congestion": "moderate",
    "speedRatio": 0.466, "profileType": "typical", "reason": "Typical for this time (high congestion)" }
]}

GET /traffic/forecast

Predictive congestion for one segment at now + each horizon — "what will this road look like in 15/30/60 minutes?". Predictions come from the calendar-aware typical profile (holiday/Ramadan/weekend aware).

QueryTypeNotes
segmentKeystringrequired — a Navvo road-segment id (e.g. from /traffic/labels)
horizonsstringoptional comma-separated minutes, default 0,15,30,60
countrystringoptional ISO-2, defaults JO
curl -s "https://navvo.io/api/v1/traffic/forecast?segmentKey=e:736821794312&horizons=0,30,60" \
  -H "x-api-key: $NAVVO_API_KEY"
{
  "provider": "navvo-traffic-model", "segmentKey": "e:736821794312", "model": "knn-profile",
  "forecast": [
    { "horizonMin": 0,  "at": "2026-07-09T08:00:00.000Z", "congestion": "moderate", "label": "High",
      "speedRatio": 0.47, "profileType": "typical", "sampleCount": 18 },
    { "horizonMin": 30, "at": "2026-07-09T08:30:00.000Z", "congestion": "light", "label": "Normal",
      "speedRatio": 0.71, "profileType": "typical", "sampleCount": 12 }
  ]
}

A horizon with no learned profile returns congestion: "unknown" with label/speedRatio null and sampleCount: 0 — treat it as "no prediction", not free-flow.

GET /traffic/depart-optimizer

"Leave at the right time" — the least-congested departure hour for an area within a window.

?bbox=...&from=6&to=22

{ "window": { "from": "06:00", "to": "22:00" }, "recommendedDeparture": "12:00",
  "worstDeparture": "17:00", "vsWorstFasterPct": 29,
  "summary": "Leaving around 12:00 is ~29% freer-flowing than the worst time (17:00)." }

POST /commute/advice

The proactive commute advisor — "when should I leave?". It routes home→work for the free-flow ETA, applies the historical traffic model over the corridor to get a traffic-adjusted ETA, and (given a target arrival) works backwards to a leave-by time and a leave_now / leave_soon / on_track status. Poll it for a saved commute to raise a proactive alert. Scope routing.

FieldTypeNotes
home / work{lat,lng}required
arriveBystringoptional HH:MM (Jordan time) target arrival — enables the leave-by backsolve
bufferMinnumberoptional arrival buffer (default 5)
costingstringtravel profile (default auto)
curl -s -X POST "https://navvo.io/api/v1/commute/advice" \
  -H "x-api-key: $NAVVO_API_KEY" -H "content-type: application/json" \
  -d '{ "home": {"lat":31.99,"lng":35.87}, "work": {"lat":31.95,"lng":35.93}, "arriveBy": "08:45" }'
{
  "provider": "navvo-commute", "available": true, "distanceKm": 9.6,
  "freeFlowEtaMin": 12, "trafficEtaMin": 16, "delayMin": 4,
  "congestion": "moderate", "basedOnHistory": true, "segmentsSampled": 23,
  "arriveBy": "08:45", "recommendedDepart": "08:24", "leaveInMin": 9,
  "status": "leave_soon", "message": "Leave in 9 min to arrive by 08:45.",
  "bestDepartureWindow": { "recommendedDeparture": "12:00", "worstDeparture": "17:00" }
}

trafficEtaMin scales the free-flow ETA by the corridor's typical congestion (capped 2.5×); when no history covers the corridor, basedOnHistory is false and the free-flow ETA is used. bestDepartureWindow carries the /traffic/depart-optimizer result for context.

GET /traffic/dna

A congestion fingerprint for an area/commute: normalized 24h curve, AM/PM peak detection, weekday/weekend delta, and a human pattern label.

?bbox=...{ "pattern": "evening-heavy", "peakHour": "17:00", "quietHour": "12:00", "curve": [ … ] }

GET /traffic/insights

City-planner analytics: busiest segments, hour-of-day curve, weekday-vs-weekend split. ?bbox=...

GET /traffic/popularity

A privacy-safe activity heatmap — counts bucketed to a coarse grid and released through differential privacy (Laplace ε≈1, k≥3 suppression, grid-snap).

?bbox=...&z=11{ "mechanism": "DP (Laplace ε=1, k≥3) + grid", "cells": [ { "key": "614/415", "count": 426, "lat": …, "lng": … } ] }

GET /traffic/model/status · /traffic/model/validation

Operational counts and model-quality metrics (coverage, mean sample count, trustworthy %, in-sample MAE/RMSE) — used to gate model changes.


GET /insights/summary · scope insights

Navvo Insights — change & freshness analytics over the platform's audited edit history. PII-free aggregates: changes by entity-type / action / day, plus per-dataset freshness (hours since last change).

?days=30

{ "windowDays": 30, "changesInWindow": 128,
  "byEntityType": [ { "entityType": "place", "count": 64 } ],
  "freshness": [ { "entityType": "place", "lastChange": "", "ageHours": 5 } ] }

POST /feedback · scope places

Submit an in-context feedback report (in-nav chip, voice, quest, beta…). Carries an auto-context payload so reports are reproducible without typing.

{ "source": "nav_chip", "category": "road_closed", "severity": 4,
  "lat": 31.95, "lng": 35.91,
  "context": { "activeStepIndex": 0, "stepType": 3, "etaSec": 193, "speedLimit": 60 } }

{ "ok": true, "id": "…", "status": "open" }. Categories: GET /feedback/categories.

POST /feedback/implicit · scope places

Record a behavioral signal that implies a map/road problem — emitted automatically by the navigation loop (fire-and-forget), no user typing. On their own these are noise; clustered, they reveal real issues (a closed road, a wrong one-way, a missing turn restriction) without anyone filing a report.

FieldTypeNotes
signalstringone of reroute, u_turn, dead_end, hard_brake, long_stop, gps_lost, failed_arrival
lat / lngnumberwhere it happened
contextobjectoptional extra payload
curl -X POST "https://navvo.io/api/v1/feedback/implicit" \
  -H "content-type: application/json" \
  -d '{ "signal": "reroute", "lat": 31.9500, "lng": 35.9100 }'

{ "ok": true, "signal": "reroute" }. An unknown signal returns { "ok": false, "error": "unknown signal", "signals": [ … ] }.

GET /admin/feedback/problem-spots

Ranked geographic problem-spots — clusters all open feedback (explicit and implicit) by ~110 m cell and scores each by severity × source-trust × recency. Deliberate reports outweigh passive signals; quests barely count. Each spot surfaces a dominant reason for an ops map overlay. Admin only (Bearer JWT, admin/super_admin).

?bbox=minLng,minLat,maxLng,maxLat&limit=100

{ "provider": "navvo-feedback", "scanned": 5, "spots": [
  { "lat": 31.9500, "lng": 35.9100, "count": 5, "score": 8.35,
    "dominantCategory": "implicit:reroute", "reason": "Frequent reroutes here",
    "signals": { "implicit:reroute": 3, "implicit:dead_end": 1, "road_closed": 1 },
    "sources": ["implicit", "nav_chip"], "lastAt": "2026-06-27T11:00:00.000Z" }
]}

GET /admin/feedback/routing-avoidances

The close-the-loop view: blocking reports an editor has confirmed (status: ack) that are now steering routes. When a report is acknowledged it becomes a live routing avoidance (within ~30 m of any corridor that passes it); marking it fixed/unactionable — or 60 days elapsing — removes it. The routing engine consults these automatically (avoidReported, default on) and reports hits in its reportedConstraints block. Admin only.

{ "provider": "navvo-feedback", "count": 1, "ttlDays": 60, "avoidances": [
  { "id": "", "category": "road_closed", "lat": 31.95, "lng": 35.91, "source": "nav_chip", "since": "2026-06-26T08:00:00.000Z" }
]}
Copyright © 2026