# Filters & lists

> Filter a map by housing status or exact addresses, read the breakdown on a view and on each cluster, and build a results list that stays in step with the pins.

- **HTML:** https://offendersearch.app/docs/map/filters-and-lists
- **Base URL:** https://api.offendersearch.app
- **Authentication:** `X-API-Key` request header
- **Map API reference as markdown:** https://offendersearch.app/docs/map.md

## Filters

Two filters work on the viewport and area routes, at every zoom.

| Parameter | Values | Effect |
| --- | --- | --- |
| `housing` | `housed`, `homeless`, `incarcerated` | Only people whose registry states one of the statuses you list. Separate several with commas. |
| `precision` | `street`, `any` | `street`: only people with an exact street address, so approximate-area pins drop out. `any` is the default. |

GET /v1/map/viewport

```bash
curl -G https://api.offendersearch.app/v1/map/viewport \
  -H "X-API-Key: $OFFENDERSEARCH_KEY" \
  -d bbox=-83.2,39.8,-82.8,40.1 \
  -d zoom=10 \
  -d housing=homeless,incarcerated \
  -d precision=street
```

- Counts, clusters and pins all follow the filter, so a filtered cluster shows the filtered count.
- A person whose registry does not state a housing status is not matched by any `housing` value.
- An unknown value answers `422 invalid_filter`.

## Reading the breakdown

Every view and every cluster carries a `breakdown`. It lets you show filter counts before the user picks one, with no extra call.

breakdown

```json
"total": 508,
"breakdown": {
  "street": 508, "housed": 247, "homeless": 96, "incarcerated": 0
}
```

- Label a filter with its number: “Homeless (96)”.
- The numbers are of the view as filtered. With no filter they are of everyone in the view.
- The housing numbers do not add up to `total`, because many registries do not state a status.

## A list beside the map

From zoom 15 the `markers` array is the list. There is no second call.

- **Order.** Markers are sorted by distance from the centre of the view, so the order is stable for a view.
- **Same ids.** A list row and its pin share one marker `id`. Highlight one when the other is hovered.
- **Heading.** Use `total` for “42 people in this view”.
- **Many-people pins.** A pin with a `groupId` is one row with a count. Its `members` are inline for up to 10 people; past that, load them with the groups route.
- **Approximate areas.** List `areas` under their own heading, such as “Approximate location”.
- **Opening a row.** Call the records route with the row’s marker `id`. Opening the same id again is free.

Below zoom 15 there are no names to list. Show the count and ask the user to zoom in.

## Home, work and school

A person can be mapped at more than one address. Each address is its own pin, with `addressType` set to `home`, `work`, `school` or `other`. Mark the type on the pin. `total` counts the person once.

## Finding a named person

The Map API answers “who is here”. To answer “where is this person”, use the search API: `POST /v1/search` with the name.

1. Search by name. This is billed as a search, not as a map request.
2. Each record’s `addresses` carry `lat` and `lng`. Plot them.
3. Fit the map to the results.

See [Search](https://offendersearch.app/docs/search.md) for the request.

---

## Related

- Previous: [Drawn areas & routes](https://offendersearch.app/docs/map/drawn-areas.md)
- Next: [MapLibre](https://offendersearch.app/docs/map/maplibre.md)
- Index: [Map API reference](https://offendersearch.app/docs/map.md)
