# Funnel

Source: https://docs.mirafive.io/rest-api/funnel

> Run a saved MIRA FIVE funnel, or two to six steps given in order, over a period and read how many reached each step.

The funnel endpoint counts how many people (or visits) reached each step of an ordered journey, and where they dropped off. Run a saved funnel by its id, or pass the steps yourself. Nothing is saved. Funnels follow people and visits, so they need traffic collected with consent: on a consentless project every step counts 0 and `meta.availability` says why.

## Run a funnel

```text
GET /api/v1/projects/{project_id}/funnel
```

Pass either `funnel` or `steps`, not both.

| Name | Type | Default | Description |
| --- | --- | --- | --- |
| `funnel` | string | none | A saved funnel's id. Takes its steps, window and basis; `steps`, `window` and `basis` are then refused. |
| `steps[]` | string | none | Two to six action or goal ids of this project, in order. Repeat the parameter for each step. **Required** without `funnel`. |
| `window` | string | `7` | With `steps`: days after the first step within which the others count. `1`, `7`, `14` or `30`. |
| `basis` | string | `person` | With `steps`: `person` follows people across visits; `visit` counts steps within one visit. |
| `period` | string | `30d` | `1h`, `24h`, `7d`, `30d`, `90d`, `12m` or `custom`. See [Periods](https://docs.mirafive.io/rest-api#periods). |
| `from` | string | none | First day of a custom period, `YYYY-MM-DD`. **Required** with `period=custom`. |
| `to` | string | none | Last day of a custom period, inclusive. **Required** with `period=custom`. |

`compare` is refused. Filters are not read. Take action and goal ids from [List goals](https://docs.mirafive.io/rest-api/goals#list-goals) or the MCP server's `list_goals`.

Steps must happen in order but need not be adjacent: other events in between are fine. Someone counts in the period their first step fell in.

```bash
curl -G https://app.mirafive.io/api/v1/projects/01932c4e-8a7b-7c3d-9e2f-4b5a6c7d8e9f/funnel \
  -H "Authorization: Bearer $MIRAFIVE_API_KEY" \
  --data-urlencode 'period=30d' \
  --data-urlencode 'steps[]=01948d31-8c9d-7e0f-8a1b-2c3d4e5f6a7b' \
  --data-urlencode 'steps[]=01948d30-7b8c-7d9e-9f0a-1b2c3d4e5f6a' \
  --data-urlencode 'steps[]=01948d2e-5f6a-7b8c-9d0e-1f2a3b4c5d6e' \
  --data-urlencode 'window=7'
```

```json title="200 OK"
{
  "data": {
    "id": "01948d31-8c9d-7e0f-8a1b-2c3d4e5f6a7b,01948d30-7b8c-7d9e-9f0a-1b2c3d4e5f6a,01948d2e-5f6a-7b8c-9d0e-1f2a3b4c5d6e",
    "type": "funnel-reports",
    "attributes": {
      "name": null,
      "window": 7,
      "basis": "person",
      "steps": [
        {
          "action": "01948d31-8c9d-7e0f-8a1b-2c3d4e5f6a7b",
          "name": "Viewed product",
          "archived": false,
          "count": 9840,
          "conversion": 1,
          "dropoff": null
        },
        {
          "action": "01948d30-7b8c-7d9e-9f0a-1b2c3d4e5f6a",
          "name": "Started checkout",
          "archived": false,
          "count": 1312,
          "conversion": 0.1333,
          "dropoff": 0.8667
        },
        {
          "action": "01948d2e-5f6a-7b8c-9d0e-1f2a3b4c5d6e",
          "name": "Order completed",
          "archived": false,
          "count": 547,
          "conversion": 0.0556,
          "dropoff": 0.5831
        }
      ]
    }
  },
  "meta": {
    "period": {
      "preset": "30d",
      "from": "2026-08-29T00:00:00+02:00",
      "to": "2026-09-28T00:00:00+02:00",
      "timezone": "Europe/Berlin",
      "interval": "day",
      "comparison": null,
      "clampedToRetention": false
    },
    "availability": "ready"
  }
}
```

| Field | Type | Description |
| --- | --- | --- |
| `id` | string | The saved funnel's id, or the step ids joined by commas. |
| `attributes.name` | string or null | The saved funnel's name, `null` for steps given ad hoc. |
| `attributes.window` | integer | Days the last step may follow the first. |
| `attributes.basis` | string | `person` or `visit`. |
| `attributes.steps[].action` | string | The step's action or goal id. |
| `attributes.steps[].name` | string | Its name. |
| `attributes.steps[].archived` | boolean | Whether the action is archived. |
| `attributes.steps[].count` | integer | People (or visits) who got at least this far. |
| `attributes.steps[].conversion` | number | Share of the first step who got this far, 0–1. The first step is `1`, or `0` when nobody started. |
| `attributes.steps[].dropoff` | number or null | Share of the step before who did not get this far, 0–1. `null` on the first step. |
| `meta.period` | object | The window read. See [Periods](https://docs.mirafive.io/rest-api#periods). |
| `meta.availability` | string | `ready`; `consentless_only` (no people or visits to follow, so every count is 0); `no_sources`. |

To run a saved funnel, pass its id alone:

```bash
curl -G https://app.mirafive.io/api/v1/projects/01932c4e-8a7b-7c3d-9e2f-4b5a6c7d8e9f/funnel \
  -H "Authorization: Bearer $MIRAFIVE_API_KEY" \
  --data-urlencode 'funnel=0197c4d5-e6f7-7a8b-9c0d-1e2f3a4b5c6d'
```

The answer has the same shape, with the funnel's `id` and `name`. An unknown funnel or step id, an action of another project, one step or seven steps get `422` naming the parameter.
