---
title: "Confirm or deny a spot"
description: "Records the caller's answer to \"Is this place still dangerous?\".\n\n- `1` means **still dangerous**. It also refreshes `last_confirmed_at`.\n- `-1` means **not anymore**.\n\nEach visitor has one vote per spot. Sending the opposite value changes the vote, and\nsending the same value again returns `409`. After every vote the community `status` is\nrecalculated:\n\n| Condition | `status` |\n| --- | --- |\n| `confirmations − denials ≥ 3` | `confirmed` |\n| `denials > confirmations + 2` | `disputed` |\n| otherwise | `unverified` |\n\nRate limit: **60 votes per hour** per visitor.\n"
---

> 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.

Path: Deathspot UG API › Community

`POST /api/spots/{id}/vote`

Records the caller's answer to "Is this place still dangerous?".

- `1` means **still dangerous**. It also refreshes `last_confirmed_at`.
- `-1` means **not anymore**.

Each visitor has one vote per spot. Sending the opposite value changes the vote, and
sending the same value again returns `409`. After every vote the community `status` is
recalculated:

| Condition | `status` |
| --- | --- |
| `confirmations − denials ≥ 3` | `confirmed` |
| `denials > confirmations + 2` | `disputed` |
| otherwise | `unverified` |

Rate limit: **60 votes per hour** per visitor.

## Path parameters

- `voteOnSpot.path.id` (integer, required) — The spot's numeric id.
  - example `1`

## Request body

- `voteOnSpot.value` (integer, required) — `1` = still dangerous, `-1` = not anymore.
  - one of `1`, `-1`

## Example request

```json
{
  "value": 1
}
```

## Code samples

### cURL

```curl
curl --request POST \
  --url https://deathspot.org/api/spots/1/vote \
  --header 'Content-Type: application/json' \
  --data '{
  "value": 1
}'
```

### TypeScript

```typescript
const url = 'https://deathspot.org/api/spots/1/vote';
const options = {
  method: 'POST',
  headers: {'Content-Type': 'application/json'},
  body: JSON.stringify({value: 1})
};

fetch(url, options)
  .then(res => res.json())
  .then(json => console.log(json))
  .catch(err => console.error(err));
```

### Python

```python
import requests

url = "https://deathspot.org/api/spots/1/vote"

payload = { "value": 1 }
headers = {"Content-Type": "application/json"}

response = requests.post(url, json=payload, headers=headers)

print(response.text)
```

## Responses

### 200

The vote was recorded. Returns the updated spot.

#### Example

```json
{
  "spot": {
    "id": 1,
    "title": "Mukwano Road (near CID HQ)",
    "description": "string",
    "lat": 0.30827,
    "lng": 32.58721,
    "area": "Kibuli, Makindye",
    "category": "murder",
    "severity": 5,
    "time_of_day": "day",
    "incident_date": "2026-09-23",
    "source_url": "http://example.com",
    "created_at": "2019-08-24T14:15:22Z",
    "last_confirmed_at": "2019-08-24T14:15:22Z",
    "confirmations": 0,
    "denials": 0,
    "status": "unverified",
    "moderator_verified": true,
    "seeded": true
  }
}
```

- `voteOnSpot.response.200.spot` (object, required) — A reported danger spot on the public map.
  - `voteOnSpot.response.200.spot.id` (integer, required)
    - example `1`
  - `voteOnSpot.response.200.spot.title` (string, required)
    - maxLength 80; example `"Mukwano Road (near CID HQ)"`
  - `voteOnSpot.response.200.spot.description` (string, required) — What people should know about the place. It may be empty.
    - maxLength 600
  - `voteOnSpot.response.200.spot.lat` (number, required)
    - format `double`; min -1.6; max 4.3; example `0.30827`
  - `voteOnSpot.response.200.spot.lng` (number, required)
    - format `double`; min 29.5; max 35.1; example `32.58721`
  - `voteOnSpot.response.200.spot.area` (string, required) — Neighbourhood, division or landmark. It may be empty.
    - maxLength 80; example `"Kibuli, Makindye"`
  - `voteOnSpot.response.200.spot.category` (string, required) — What happens at the spot: `murder` (killing), `mob_action`, `boda_gang`, `robbery` (robbery or snatching), `stabbing` (stabbing or hacking), `kidnapping`, `other`.
    - one of `"murder"`, `"mob_action"`, `"boda_gang"`, `"robbery"`, `"stabbing"`, `"kidnapping"`, `"other"`
  - `voteOnSpot.response.200.spot.severity` (integer, required) — 1 = feels unsafe, 2 = harassment or threats, 3 = robbery or snatching, 4 = violent attack, 5 = someone was killed.
    - min 1; max 5; example `5`
  - `voteOnSpot.response.200.spot.time_of_day` (string, required) — When the spot is dangerous.
    - one of `"day"`, `"night"`, `"any"`
  - `voteOnSpot.response.200.spot.incident_date` (string | null, required)
    - format `date`; example `"2026-09-23"`
  - `voteOnSpot.response.200.spot.source_url` (string | null, required) — A news, police or court source, if the reporter gave one.
    - format `uri`
  - `voteOnSpot.response.200.spot.created_at` (string, required)
    - format `date-time`
  - `voteOnSpot.response.200.spot.last_confirmed_at` (string | null, required) — When someone last voted "still dangerous".
    - format `date-time`
  - `voteOnSpot.response.200.spot.confirmations` (integer, required) — Number of "still dangerous" votes.
    - min 0
  - `voteOnSpot.response.200.spot.denials` (integer, required) — Number of "not anymore" votes.
    - min 0
  - `voteOnSpot.response.200.spot.status` (string, required) — The community's verdict from votes. `confirmed` needs at least 3 more confirmations than denials, and `disputed` means denials outnumber confirmations by more than 2.
    - one of `"unverified"`, `"confirmed"`, `"disputed"`
  - `voteOnSpot.response.200.spot.moderator_verified` (boolean, required) — `true` when a moderator has checked the spot against a reliable source. Shown as "Verified by moderators".
  - `voteOnSpot.response.200.spot.seeded` (boolean, required) — `true` for spots loaded from the project's sourced seed data rather than reported through the app.

### 400

The id isn't an integer, or `value` isn't `1` or `-1`.

#### Example

```json
{
  "error": "Vote must be 1 or -1"
}
```

- `voteOnSpot.response.400.error` (string, required) — A human-readable message you can show to users.

### 404

No approved spot has this id. Pending and rejected spots can't be voted on.

#### Example

```json
{
  "error": "Spot not found"
}
```

- `voteOnSpot.response.404.error` (string, required) — A human-readable message you can show to users.

### 409

The caller already voted this way on this spot.

#### Example

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

- `voteOnSpot.response.409.error` (string, required) — A human-readable message you can show to users.

### 429

The caller exceeded a rate limit. Wait `Retry-After` seconds before retrying.

#### Example

```json
{
  "error": "You have reported a lot of spots recently. Please try again in an hour."
}
```

- `voteOnSpot.response.429.error` (string, required) — A human-readable message you can show to users.


Source: https://docs.deathspot.org/api/Community/voteOnSpot/index.md
