Navvo
API Reference

Quests (crowd data)

Gamified, crowd-sourced data improvement — surface nearby data-gap micro-tasks, collect answers into the moderation queue, and award contributor points.

Quests

Navvo Quests turns map data improvement into one-tap micro-tasks. The engine detects data gaps in nearby places — missing opening hours, Arabic name, category, description, or accessibility info — and surfaces each as a small question worth points. Answers flow into the same moderation queue as other feedback (source: quest), where an editor reviews them before they're applied to a place.

Scope required: places (for GET /quests and the leaderboard). Answering is anonymous-friendly.


GET /quests

Nearby data-gap quests, highest-value first.

QueryTypeNotes
bboxstringminLng,minLat,maxLng,maxLat — scope to the map view (recommended)
limitnumbermax quests to return (default 20, max 100)
typesstringoptional filter, comma-separated: hours,accessibility,name_ar,category,description
curl -s "https://navvo.io/api/v1/quests?bbox=35.8,31.9,36.0,32.05&limit=6" \
  -H "x-api-key: $NAVVO_API_KEY"
{
  "count": 6,
  "candidatesScanned": 226,
  "quests": [
    {
      "id": "a1b2c3d4-…:hours",
      "placeId": "a1b2c3d4-…",
      "slug": "abo-shosha-taxi-85dc70",
      "placeName": "Abo Shosha Taxi",
      "type": "hours",
      "action": "Add opening hours",
      "question": "What are the opening hours of Abo Shosha Taxi?",
      "points": 15,
      "location": { "lat": 31.95, "lng": 35.91 }
    }
  ]
}
Quest typePointsDetected when
hours15place has no opening hours
accessibility10no Accessibility attribute group
category10no category assigned
name_ar10missing Arabic name
description5no description (EN or AR)

The id is stable ({placeId}:{type}) — pass it straight to POST /quests/solve.


POST /quests/solve

Submit an answer. Anonymous is allowed; pass reporterUserId to accrue points toward the leaderboard. The answer is not applied directly — it enters the moderation queue.

FieldTypeNotes
questIdstringthe quest id (or supply placeId + type separately)
answeranythe contributed value (string, or structured for hours) — required
lat / lngnumberoptional, where the contributor answered from
reporterUserIdstringoptional, the logged-in user id
curl -X POST "https://navvo.io/api/v1/quests/solve" \
  -H "content-type: application/json" \
  -d '{ "questId": "a1b2c3d4-…:hours", "answer": "Mo-Fr 09:00-17:00", "reporterUserId": "user-123" }'
{ "ok": true, "points": 15, "total": 35, "message": "Thanks! +15 points" }

total is the contributor's running points (omitted/equal to points for anonymous). Invalid requests return { "ok": false, "error": "answer required" | "unknown quest type" | "placeId required" }.


GET /quests/leaderboard

Top contributors by points (ids are anonymized to a short prefix).

{
  "contributors": [
    { "contributor": "user-1…", "points": 35, "solved": 3 },
    { "contributor": "anonymous", "points": 5, "solved": 1 }
  ],
  "totalSolved": 4
}

GET /quests/me

A logged-in contributor's own totals (requires a user session — Bearer JWT, not an API key).

{ "userId": "user-123", "solved": 3, "points": 35 }
Quest answers are crowd-sourced and reviewed before publication. They appear in /platform-admin → Feedback filtered by source: quest for editors to verify and apply.
Copyright © 2026