Reporting wrong data

Canadian open data is uneven. A municipality renames a street and the provincial extract catches up two quarters later; a rural address exists on a survey plan and in no machine-readable file anywhere. We publish the gaps we know about on Coverage, and the ones we do not know about are the reason this endpoint exists.

POST /feedback files a data-correction report. It is authenticated like every other endpoint and it is never metered. Telling us our data is wrong must not cost you a call.

The smallest report

curl -X POST https://api.unmap.dev/feedback \
  -H "Authorization: Bearer $UNMAP_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "product": "geocoding",
    "category": "incorrect_location",
    "description": "\"17 Ave SW, Calgary\" returns a street in Edmonton."
  }'
{
  "id": "fb_20260917143055_9f3ab201",
  "status": "new",
  "created_at": "2026-09-17T14:30:55.114Z",
  "context_stored": false
}

Keep the id. It is what to quote if you write to us about the report later.

A report needs a description, a result_id, or both. One with neither says a product is wrong somewhere, which nobody can act on, and is refused with a 400.

From the SDK

await unmap.feedback.submit({
  product: "geocoding",
  category: "incorrect_location",
  description: '"17 Ave SW, Calgary" returns a street in Edmonton.',
});
 
await unmap.feedback.aboutPlace("um:place:1234", {
  category: "wrong_place_name",
  description: "Listed under its 1968 name.",
});

The client never sets include_context on its own. Pass a context only when the person submitting has agreed to it, and the flag goes with it.

Fields

FieldRequiredNotes
productyestiles, terrain, names, geocoding, places, routing, layers, transit, roads, ev
categoryyesSee the list below
descriptionone ofUp to 2000 characters, stored exactly as you write it
result_idone ofThe unmap id of the result, where the product has stable ids
include_contextnoMust be true for context to be accepted
contextnoThe request you are reporting, up to 4 KB encoded

Categories: incorrect_location, incorrect_address, missing_place, wrong_place_name, wrong_category, bad_route, missing_road_closure, incorrect_road_condition, incorrect_transit_result, other.

The category list is ours and it will be slightly wrong for your case. description is the field that matters, it is stored verbatim, and other is always available.

Reporting a place

curl -X POST https://api.unmap.dev/places/um:place:calgary-tower/feedback \
  -H "Authorization: Bearer $UNMAP_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "category": "wrong_place_name", "description": "Listed under its 1968 name." }'

product and result_id come from the path. A body that disagrees with the URL is overridden rather than honoured.

What we do not collect

The gateway redacts query strings from its own logs. A feedback endpoint that quietly attached your query and coordinates to every report would undo that with a friendlier label on it, so it does not.

Nothing about your request is stored unless you send context and set include_context: true. The API refuses context without that flag rather than silently dropping it, so a client that believed it was attaching a request finds out that it was not.

{
  "product": "geocoding",
  "category": "incorrect_location",
  "description": "Wrong city.",
  "include_context": true,
  "context": { "endpoint": "/geocode/search", "q": "17 Ave SW, Calgary", "limit": 3 }
}

context_stored on the response tells you what was actually kept.

If you are building your own reporting control on top of this, ask the question out loud and default it to off. Feedback is voluntary diagnostic data. It is not telemetry, and the difference is entirely in whether the person submitting it decided.

What happens to a report

Every report starts at new. From there:

StatusMeans
confirmedReproduced.
needs-source-fixOur ingestion is right, our source selection is not.
needs-ranking-fixThe record is correct and comes back in the wrong order.
upstreamCorrect in our pipeline, wrong in the publisher's data. Filed with them.
fixedShipped.
wont-fixDeclined, or not a defect.

upstream is a real outcome and not a polite decline. A good share of what gets reported is faithfully ingested from a provincial or municipal file that is itself wrong, and the honest thing to say is which.

A confirmed regression becomes a permanent test fixture wherever it can. That is the loop the whole thing is for:

report → reproduce → fix → regression test → changelog

Limits

200 reports per account per day. Past that the endpoint answers 429 with a Retry-After.

There is no GET /feedback. You cannot read back your own reports yet, which is a real gap and is listed as one.