Navvo
API Reference

Atlas Agent (NL control)

Turn natural-language commands into structured map actions — search, directions, pins, layer control, and now day-plan itineraries and fleet route optimization.

Atlas Agent

Atlas resolves a free-text command into a structured, executable action your client runs against the map. Under the hood it is a tool-calling AI agent: it understands natural language in any language (first-class English and Arabic, including Jordanian dialect), picks the right action, and — for factual questions — grounds its answer in live Navvo data (real places, ratings, and current traffic) rather than guessing. One endpoint covers search, navigation, pins, layer/style control, day-plan itineraries, fleet optimization, and grounded conversational answers.

The response contract is unchanged and backward-compatible — you still switch on action exactly as before. Replies come back in the same language the user wrote in. Atlas is resilient: if the primary model is briefly unavailable it automatically falls back to a local model and a deterministic parser, so the endpoint keeps working. Provider health is tracked across the whole platform, so a primary that is failing is skipped straight away — an outage costs one fast fallback rather than a timeout on every request — and every request has a fixed overall time limit.

Atlas only states facts that came from Navvo's own data in the same conversation: places, distances, routes, traffic. Where that data does not cover something — opening hours, for example — the reply says so instead of guessing, so treat a reply that declines a detail as a correct answer, not an error.

Scope required: places.

Authentication: Atlas requires an identified caller — either a signed-in Navvo user (Bearer token, as on navvo.io) or your API key (x-api-key). Anonymous requests receive 401.

Atlas is model-neutral: every response reports "model": "navvo-ai". The underlying engine is a Navvo implementation detail and may change without notice — never depend on a specific model name.
Arabic replies, always. When message contains Arabic script, every reply — including the deterministic-fallback confirmations and the "service busy" static messages — comes back in Arabic. English (or any non-Arabic-script) messages get the English strings.
Privacy. Prompts, any history you send, and replies for the chat AI endpoints are stored server-side for up to 30 days and then deleted. Say so in your app's privacy notice. Don't send secrets in message/context/history.

POST /ai/atlas

FieldTypeNotes
messagestringrequired — the user's natural-language command, up to 8,000 characters (longer → 400)
contextstringoptional — short conversation/context hint, up to 32,000 characters (longer → 400). The Navvo map sends the live camera, visible street names and nearby businesses here so Atlas answers about what the user sees
userNamestringoptional — display name of your signed-in end user; Atlas addresses them by first name
historyarrayoptional — prior turns for multi-turn context, max 12 items of { role, content } where role is "user" or "assistant" and content is a string (max 2000 chars). Oldest first. Omitting it (or []) is identical to the previous single-turn behavior. Over-limit / bad roles / over-long content → 400.
{
  "message": "take me to the second one",
  "context": "Camera: 31.95,35.91 z15 …",
  "history": [
    { "role": "user",      "content": "find pharmacies near Abdoun" },
    { "role": "assistant", "content": "Here's what I found for \"pharmacies near Abdoun\"." }
  ]
}

Both POST /ai/atlas and POST /ai/assistant accept history with the same rules.

curl -s -X POST "https://navvo.io/api/v1/ai/atlas" \
  -H "x-api-key: $NAVVO_API_KEY" -H "content-type: application/json" \
  -d '{ "message": "plan a 3 hour trip with cafes and museums" }'

Every response has a reply (a short human sentence, in the user's language), an action, a model (always navvo-ai), and unavailable. The other fields depend on the action:

actionExtra fieldsMeaning — what your client should do
searchqueryrun a place search for query and show results
directionsquerystart routing to query
navigatequerystart turn-by-turn guidance to query immediately ("start navigation to…", "drive me to…")
pinquerydrop a pin at query
locatequerycenter/zoom the map on query
controltarget, valuetoggle a layer/style/panel — target e.g. traffic/satellite/3d/transit/weather; value is on/off/toggle
itinerarytimeBudgetMin, interestsbuild a day plan — call POST /itinerary/auto with these + the user's location
optimize_fleet—optimize the user's delivery stops — call the fleet optimizer
report_incidentincidentType (accident/hazard/police/camera/closure/jam), query (legacy duplicate)hands-free crowd incident report — file it at the user's location via POST /incidents ("there's an accident ahead"). Prefer the new incidentType field (present only on this action; defaults to hazard); query still mirrors it for older clients.
answer—open-ended — reply is a conversational answer

Planning examples

// "plan a 3 hour trip with cafes and museums"
{ "action": "itinerary", "timeBudgetMin": 180, "interests": ["cafe","museum"],
  "reply": "Planning a 3-hour itinerary around cafe, museum near you." }

// "what can I do in 90 minutes near here"
{ "action": "itinerary", "timeBudgetMin": 90, "interests": [], "reply": "Planning a 1.5-hour itinerary near you." }

// "optimize my deliveries"
{ "action": "optimize_fleet", "reply": "Optimizing your stops into the fastest route order." }

Duration is parsed from the text (3 hours, 90 minutes, half-day → 240, afternoon → 240); interests are matched against a category vocabulary (cafe, restaurant, museum, park, shopping, historic, art, market, nature, …).

Other examples

{ "action": "directions", "query": "the airport", "reply": "Routing you to the airport." }   // "directions to the airport"
{ "action": "search", "query": "cafes", "reply": "Here's what I found for \"cafes\"." }        // "find cafes nearby"
{ "action": "control", "target": "traffic", "value": "on", "reply": "Turning on traffic." }    // "turn on traffic"

What Atlas answers

Atlas is a map assistant. It answers questions about places and businesses, directions, navigation, traffic, parking, the map and its layers, trips and day plans, Navvo itself, and the place or area the user is in or looking at, including its history and what it is known for. Anything else, such as poems, homework, general trivia, sports results or unrelated code, gets one friendly sentence in the user's language saying what Atlas can help with. Requests to drop these rules are declined the same way.

// "write me a poem about love"
{ "action": "answer", "query": "", "reply": "I can only help with places, routes, traffic and the map. Try asking me to find a place, plan a route or check the traffic near you." }

// "tell me about the history of the area I am in"  (context: the user is in Amman)
{ "action": "answer", "reply": "Amman, historically known as Rabbath Ammon, was the capital of the Ammonite kingdom..." }

A decline is an ordinary answer, so show reply as you would any other answer.

Grounded answers

For factual questions Atlas fetches real Navvo data before replying — it never invents places, ratings, coordinates, or traffic:

// "is there a pharmacy near me?"  → answered from live place search
{ "action": "answer", "reply": "Yes — the closest is Airport Bridge Pharmacy (4.8), with Airport Pharmacy nearby too." }

// "كيف حالة السير الآن؟"  (how is traffic now?) → answered from live traffic, in Arabic
{ "action": "answer", "reply": "لا توجد تقارير مرور حية في منطقتك الآن. أخبرني باسم الشارع وسأتحقق لك." }

// "what will traffic be like tomorrow at 8?" → answered from analysed (expected) traffic, never as live
{ "action": "answer", "reply": "Tomorrow at 08:00 traffic around you is usually moderate, mostly because it is the first workday of the week. It is expected to be lightest between 10:00 and 12:00." }

Questions about usual or expected traffic, another time ("tomorrow at 8", "on Friday evening", "during Ramadan"), what-if weather ("if it rains") or the best time to leave are answered from analysed traffic, in the user's local time. Those replies always present the result as typical or expected traffic, never as a live reading.

places — the records an answer was built from

When Atlas consulted the place index to answer, the response also carries places: the records it was shown. This is additive and optional — omit it and nothing changes — but it is what lets a client show its work instead of asking the user to trust a sentence. For an Arabic message, name is the place's Arabic name when Navvo has one (otherwise the English name), so the reply and the records match. Traffic questions about a named road or area are looked up near the user's position when you send one.

FieldTypeNotes
slugstringthe place's Navvo slug — use it to open, route to, or save the record
namestring
categorystring | null
ratingnumber | null
lat / lngnumber | nullplot these; a client with a map should
// "is there a pharmacy near me?"
{
  "action": "answer",
  "reply": "Yes — the closest is Airport Bridge Pharmacy (4.8), with Airport Pharmacy nearby too.",
  "places": [
    { "slug": "airport-bridge-pharmacy-1a2b3c", "name": "Airport Bridge Pharmacy",
      "category": "pharmacy", "rating": 4.8, "lat": 31.7226, "lng": 35.9932 }
  ]
}

The field is absent, not [], when no lookup happened — so presence is a reliable signal that an answer has something to plot. It can also appear alongside an action (a search whose reply was informed by a lookup first).

The Navvo map itself uses this to plot an answer's places and frame the view around them while the conversation stays open beside them. If your client owns a map, doing the same turns an answer from a paragraph into something the user can see, check and act on.
When the request is a map action (find, directions, navigate, locate, pin, layer control, itinerary, fleet), Atlas returns that action with its fields — your client executes it exactly as documented above. Only genuinely open-ended or factual messages return action: "answer". Because the schema is unchanged, existing integrations need no code changes.
Copyright © 2026