Skip to content

Errors and limits

Error format, status codes, rate limits and validation rules.

Updated View as Markdown

Error format

Every error response is JSON with a human-readable error message that’s safe to show to users:

{ "error": "You already voted this way on this spot" }

Validation failures on POST /api/spots also include issues, in zod’s issue format, so you can highlight the field:

{
  "error": "Location must be inside Uganda",
  "issues": [{ "code": "custom", "path": ["lat"], "message": "Location must be inside Uganda" }]
}

Status codes

Code Meaning What to do
200 / 201 Success
400 Invalid input: bad JSON, a missing field, out-of-range values, or a location outside Uganda Fix the request. Don’t retry unchanged.
404 The spot doesn’t exist or isn’t public (pending or rejected) Refresh your spot list.
409 Already voted this way, or already flagged Treat it as success in your UI.
429 Rate limit reached Wait Retry-After seconds. See Rate limits.
502 The routing service (OSRM) is unavailable Retry later with backoff. Search degrades instead: it returns spots with an error note.
503 The health check can’t reach the database Check the deployment.

Rate limits

Every endpoint except /api/health is rate limited, and responses carry RateLimit-* headers. See Rate limits for the limits per endpoint and how to back off.

Validation rules

Field Rule
title 3–80 characters
description, area Up to 600 and 80 characters. Optional.
lat, lng Inside Uganda: lat −1.6 to 4.3, lng 29.5 to 35.1
category One of murder, mob_action, boda_gang, robbery, stabbing, kidnapping, other
severity Integer 1–5
time_of_day day, night or any
incident_date YYYY-MM-DD, or null
source_url An http(s) URL up to 300 characters, "" or null
note (flags) Up to 300 characters

Phone numbers in title, description, area and flag notes are replaced with [removed].

Navigation

Type to search…

↑↓ navigate↵ selectEsc close