Voice & Speech-to-Text
Voice & Speech-to-Text
Navvo hosts its own speech-to-text engine — upload a short audio clip and get the transcript back, in English or Arabic. This is the same endpoint behind the Navvo map's voice search and hands-free Atlas conversations; pair it with POST /ai/atlas to build a full voice assistant.
model field always reads "navvo-ai". The underlying engines are Navvo implementation details and may change without notice.POST /ai/transcribe
Speech-to-text over a multipart audio upload. Send the clip as the multipart file part; webm, ogg, and mp4/m4a audio are accepted (a browser MediaRecorder blob works as-is).
Query parameters
en, ar, or auto (default). With auto the language is detected from the audio.curl -s -X POST "https://navvo.io/api/v1/ai/transcribe?language=auto" \
-H "x-api-key: $NAVVO_API_KEY" \
-F "file=@clip.webm;type=audio/webm"
Response
{ "text": "أقرب صيدلية مفتوحة الآن", "language": "ar", "unavailable": false }
| Field | Type | Notes |
|---|---|---|
text | string | the transcript (empty string when nothing was recognized) |
language | string | null | the detected/used language, when reported |
unavailable | boolean | true when the speech engine is unreachable or the clip is empty — always check it before using text |
Keep clips short (a spoken search phrase, a command); requests time out after ~20 s of processing. An upload with no file part returns 400.
MediaRecorder (audio/webm), POST /ai/transcribe, then feed text into GET /search or POST /ai/atlas for a structured map action.Direct AI helpers
Two small, deterministic-contract helpers used by the Navvo map itself. Both return the standard brand-neutral AI envelope — { model: "navvo-ai", unavailable, purpose, content } — where content is the model's reply text.
POST /ai/search-understanding
Turns a free-text place query into a structured query plan (filters, category hints, locale, urgency) for smarter search UX.
curl -s -X POST "https://navvo.io/api/v1/ai/search-understanding" \
-H "x-api-key: $NAVVO_API_KEY" -H "content-type: application/json" \
-d '{ "query": "quiet cafe with wifi near Abdoun open now" }'
→ { "model": "navvo-ai", "unavailable": false, "purpose": "search_understanding", "content": "{ \"filters\": [\"wifi\"], \"categoryHints\": [\"cafe\"], \"locale\": \"en\", \"urgency\": \"now\" }" }
content is a strict-JSON string — parse it client-side, and fall back to a plain search when unavailable is true.
POST /ai/route-labels
Summarizes a raw routing response into a short human label + tip — the same block POST /routing/route attaches automatically.
| Field | Type | Notes |
|---|---|---|
payload | object | required — the raw routing response envelope you got from /routing/route or /routing/plan |
→ { "model": "navvo-ai", "purpose": "route_labels", "content": "…", "parsed": { "label": "Fast city route", "tip": "Light traffic, mostly highways" } }
parsed is the best-effort structured extraction — it is null when the model's reply couldn't be parsed. Prefer parsed and treat content as the raw fallback.