---
title: "Errors and limits"
description: "Error format, status codes, rate limits and validation rules."
---

> Documentation Index
> Fetch the complete documentation index at: https://docs.deathspot.org/llms.txt
> Use this file to discover all available pages before exploring further.

# Errors and limits

## Error format

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

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

Validation failures on `POST /api/spots` also include `issues`, in
[zod's issue format](https://zod.dev/), so you can highlight the field:

```json
{
  "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](/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](/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]`.

Source: https://docs.deathspot.org/errors-and-limits/index.mdx
