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

# Walks

> List your campaign's block walks and read a walk's stops.

<Note>**Live.** Requires the `walks:read` scope.</Note>

A **walk** is a route of door-to-door stops. These endpoints let you list a campaign's walks and
read the stops of any one walk.

***

## List walks

```http theme={null}
GET /api/v1/walks
```

Returns the campaign's active walks (archived and deleted walks are excluded).

### Query parameters

<ParamField query="limit" type="integer" default="50">
  Maximum walks to return. Between `1` and `200`.
</ParamField>

### Response

<ResponseField name="id" type="string">The walk's unique id (use it with the detail endpoint).</ResponseField>
<ResponseField name="name" type="string">Human-readable walk name.</ResponseField>
<ResponseField name="lat" type="number | null">Centroid latitude of the walk's stops.</ResponseField>
<ResponseField name="lng" type="number | null">Centroid longitude of the walk's stops.</ResponseField>
<ResponseField name="count" type="integer">Total number of stops on the walk.</ResponseField>

<ResponseField name="counts" type="object">
  Stop counts broken down by status. Every status key is always present (`0` when none). See
  [stop statuses](#stop-statuses).
</ResponseField>

<ResponseField name="web_url" type="string">Link to open the walk in the Culper dashboard.</ResponseField>

<ResponseField name="app_link" type="string">
  Universal link to open the walk in the mobile app (falls back to the web view when the app isn't
  installed).
</ResponseField>

<RequestExample>
  ```bash cURL theme={null}
  curl https://theculpernetwork.com/api/v1/walks?limit=50 \
    -H "Authorization: Bearer culper_sk_live_…"
  ```
</RequestExample>

<ResponseExample>
  ```json 200 theme={null}
  {
    "ok": true,
    "data": [
      {
        "id": "b7c3e9d2-1a4f-4c88-9e21-6f0a2b5d7c10",
        "name": "Riverstone — AM",
        "lat": 29.6011,
        "lng": -95.6339,
        "count": 42,
        "counts": {
          "not_visited": 30,
          "visited_home_answered": 7,
          "visited_no_answer": 3,
          "visited_left_lit": 1,
          "dropped_hanger": 1,
          "visited_refused": 0,
          "visited_wrong_address": 0,
          "visited_moved_away": 0
        },
        "web_url": "https://theculpernetwork.com/dashboard/alexander-hale-for-congress-y39t2rsm/walks/b7c3e9d2-1a4f-4c88-9e21-6f0a2b5d7c10",
        "app_link": "https://theculpernetwork.com/open/alexander-hale-for-congress-y39t2rsm/walks/b7c3e9d2-1a4f-4c88-9e21-6f0a2b5d7c10"
      }
    ],
    "meta": { "count": 1 }
  }
  ```
</ResponseExample>

<Note>
  A campaign with no walks returns `{ "ok": true, "data": [], "meta": { "count": 0 } }` — that's a
  valid, successful response, not an error.
</Note>

***

## Get a walk

```http theme={null}
GET /api/v1/walks/{id}
```

Returns a single walk and its ordered stops. Returns `404 not_found` if the walk doesn't exist or
isn't part of your campaign.

### Path parameters

<ParamField path="id" type="string" required>
  The walk id from the list endpoint (a UUID).
</ParamField>

### Response

<ResponseField name="id" type="string">The walk's id.</ResponseField>
<ResponseField name="name" type="string">The walk's name.</ResponseField>

<ResponseField name="stops" type="object[]">
  Ordered list of stops on the walk.

  <Expandable title="stop">
    <ResponseField name="id" type="string">The stop's unique id.</ResponseField>
    <ResponseField name="lat" type="number | null">Stop latitude.</ResponseField>
    <ResponseField name="lng" type="number | null">Stop longitude.</ResponseField>
    <ResponseField name="status" type="string">Canvass result. See [stop statuses](#stop-statuses).</ResponseField>
    <ResponseField name="position" type="integer">1-based order of the stop in the walk.</ResponseField>
  </Expandable>
</ResponseField>

<RequestExample>
  ```bash cURL theme={null}
  curl https://theculpernetwork.com/api/v1/walks/b7c3e9d2-1a4f-4c88-9e21-6f0a2b5d7c10 \
    -H "Authorization: Bearer culper_sk_live_…"
  ```
</RequestExample>

<ResponseExample>
  ```json 200 theme={null}
  {
    "ok": true,
    "data": {
      "id": "b7c3e9d2-1a4f-4c88-9e21-6f0a2b5d7c10",
      "name": "Riverstone — AM",
      "stops": [
        { "id": "3f1a…", "lat": 29.6012, "lng": -95.6341, "status": "visited_home_answered", "position": 1 },
        { "id": "9c22…", "lat": 29.6014, "lng": -95.6338, "status": "not_visited", "position": 2 }
      ]
    }
  }
  ```

  ```json 404 theme={null}
  { "ok": false, "error": { "code": "not_found", "message": "Walk not found." } }
  ```
</ResponseExample>

***

## Stop statuses

`counts` keys and a stop's `status` field use these values:

| Status                  | Meaning                        |
| ----------------------- | ------------------------------ |
| `not_visited`           | Not yet canvassed.             |
| `visited_home_answered` | Someone answered the door.     |
| `visited_no_answer`     | No one answered.               |
| `visited_left_lit`      | No answer; literature left.    |
| `dropped_hanger`        | Door hanger left.              |
| `visited_refused`       | Occupant declined to talk.     |
| `visited_wrong_address` | Address was wrong / not found. |
| `visited_moved_away`    | Voter no longer lives there.   |
