# Flow reports

Discover flows and their versions, then report on them: a flow's time series covers every version at once, or a single version when you scope it, which is how an A/B test is measured before it is promoted.

**Language:** en
**Audience:** developer
**TLDR:** Flows are built in the dashboard; the API is read-only. List them with GET /project/{project}/flow and get version ids from .../flow/{id}/versions. GET /project/{project}/analytics/flow/{flow}/series returns time-bucketed statistics: without filter[version] it is the flow total across all versions; with it, every statistic — deliveries, clicks, conversions, revenue — is scoped to that one version.
**Search keywords:** flow, flows, flow report, flow analytics, flow series, flow version, flow versions, version id, filter version, A/B test, AB test, split test, canary, live-test, live test, sequence, version number, promote a version, flow id, discovery, PROJECT_AUTOMATION_READ
**Related pages:** /developers/product-api/analytics/building-queries, /developers/product-api/analytics/statistics
**Docs index (every page):** https://docs.instasent.com/llms.txt
**This zone's index:** https://docs.instasent.com/developers/product-api/llms-full.txt
**This page:** https://docs.instasent.com/developers/product-api/analytics/flows/ (HTML) · https://docs.instasent.com/developers/product-api/analytics/flows.md (Markdown)

Flows are the branching journeys you build in the dashboard. The Product API does not build them — it exposes them **read-only**, so an integration can find a flow, enumerate its versions, and report on how it is performing. This page covers both halves: the discovery endpoints that hand you the ids, and the flow report that turns them into numbers.

Everything on this page is governed by a single scope, `PROJECT_AUTOMATION_READ`.

> **Note**: There is no API to create, edit, activate or promote a flow. Authoring and version promotion happen in the dashboard; the API is for reading and measuring.

## Finding a flow

The list endpoint is the entry point: it returns the flows of a project, newest first, and the `id` it gives you is exactly the value the report endpoint takes.

[`GET /project/{project}/flow` - List the project's flows.](/developers/product-api/reference)

[`GET /project/{project}/flow/{id}` - Retrieve a single flow.](/developers/product-api/reference)

The listing accepts the standard [Query Filter](/developers/further-reading/query-filter) syntax for filtering, sorting and pagination, so you can narrow it to the flows you care about:

#### url

```text
GET /project/{project}/flow
  ?status_eq=enabled
```

- `id` — `string`
  The flow id — the value `/project/{project}/analytics/flow/{flow}/series` takes.
- `name` — `string`
  The flow's name, as it reads in the dashboard.
- `status` — `string`
  One of `enabled`, `disabled` or `archived`.
- `archivedAt` — `string`
  When the flow was archived, or `null` while it is still active. It also bounds what the report can cover — see [Timeframe](#timeframe-and-freshness).

## Versions

A flow evolves through **versions**, and the versions endpoint is where you find the ids the report scopes to. It returns every version of the flow, newest first, archived ones included.

[`GET /project/{project}/flow/{id}/versions` - List a flow's versions.](/developers/product-api/reference)

Two fields carry the meaning:

- **`status` is the version's role, and it is permanent for the version's life.** A version never changes role: promoting a test version to production produces a **new** version with its own id rather than rewriting the old one. So a version id is also a stable label for the cohort its traffic belongs to.
- **`sequence` is the permanent version number** — v1, v2, v3 — assigned when a version first goes live. A `0` means unnumbered: a draft or a manual preview that has never gone live.

| `status`    | What it is                                                                                           | In analytics                            |
| ----------- | ---------------------------------------------------------------------------------------------------- | --------------------------------------- |
| `live`      | The production version, running for the full audience.                                               | Counted                                 |
| `live-test` | The A/B cohort running in parallel on a small share of the audience. Real messages to real contacts. | Counted, and included in the flow total |
| `draft`     | The single editable work in progress.                                                                | Not counted                             |
| `test`      | A manual preview run of the draft.                                                                   | Not counted                             |

- `id` — `string`
  The version id — the value `filter[version]` takes on the flow report.
- `name` — `string`
  The version's name.
- `sequence` — `integer`
  Permanent version number (1, 2, 3 …). `0` for an unnumbered draft or preview.
- `status` — `string`
  The permanent role: `live`, `live-test`, `draft` or `test`.
- `liveAt` — `string`
  When the version first went live, or `null` if it never did.
- `archivedAt` — `string`
  When the version was archived, or `null` while it is still in use.

Manual previews never send to your audience, so `draft` and `test` versions produce no analytics traffic. The reports only ever carry data for `live` and `live-test` versions.

## The flow report

One report covers flows: a **series** — the statistics you ask for, bucketed over time.

[`GET /project/{project}/analytics/flow/{flow}/series` - Flow report — time series.](/developers/product-api/reference)

It follows the same grammar as every other family ([Building queries](/developers/product-api/analytics/building-queries)) and returns the same series shape ([Reading results](/developers/product-api/analytics/reading-results#time-series)). The specifics:

|            |                                                                                                                                                                                  |
| ---------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Statistics | The same catalog the automation report exposes — delivery, engagement, conversion, cost and suppression. See [Statistics catalog](/developers/product-api/analytics/statistics). |
| `interval` | Defaults to `day`.                                                                                                                                                               |
| `group_by` | `channel`, `country` — one dimension at a time.                                                                                                                                  |
| `filter`   | `channel`, `country`, `version`.                                                                                                                                                 |
| Comparison | Not applicable: `compare_to` is a values-report parameter and flows have no values report. To compare, see [Totals versus one version](#totals-versus-one-version).              |

#### url

```text
GET /project/{project}/analytics/flow/{flow}/series
  ?statistics=delivered,clicks_first,conversions,conversion_value
  &timeframe=last_30_days
  &interval=day
```

`group_by=channel` gives you the per-leg series of a fallback chain, and pairing one `group_by` with a `filter` on another dimension cross-cuts the report the same way it does elsewhere — `filter[country]=ES` with `group_by=channel`, for example.

### Timeframe and freshness

A flow report is always **computed on demand** — its `freshness.source` is `live`, with no cached value to age.

The window is clamped to the flow's own lifetime: from the day the flow was created to the day it was archived. An active flow (no `archivedAt`) is served exactly as you asked for it. When the clamp trims your window, the response carries a `timeframe_clamped_to_entity_lifetime` warning and echoes the window it actually used.

## Totals versus one version

`filter[version]` is the parameter flows have and no other family does, and it changes what the whole report means.

**Without `filter[version]`, the report is the flow total across every version** — the `live` version and the `live-test` cohort added together. That is the honest business number: the A/B cohort is real traffic to real contacts, with real deliveries, real clicks and real revenue, so leaving it out would under-report what the flow actually did.

**With `filter[version]=<versionId>`, every statistic is scoped to that single version.** Not just the delivery figures: clicks, conversions and revenue are scoped too, because attribution keeps the version alongside the flow on the events it credits. That is what makes the parameter useful — it is how you judge a test version on its own merits before deciding whether to promote it.

#### url

```text
GET /project/{project}/analytics/flow/{flow}/series
  ?statistics=delivered,click_rate,conversions,conversion_value,roas
  &timeframe=last_30_days
  &filter[version]=66b1f2a4e5a6b7c8d9e0f1b3
```

### Comparing two versions

There is no `group_by=version` and no compare endpoint for flows. You compare by issuing the **same request twice**, changing only the version id:

#### 1. List the flow's versions

Call `GET /project/{project}/flow/{id}/versions` and pick the `live` version and the `live-test` version.

#### 2. Report on each one

Issue two identical series requests — same statistics, same timeframe, same interval — differing only in `filter[version]`.

#### 3. Compare like for like

Read the rates rather than the raw counts. The A/B cohort runs on a small share of the audience, so its volumes are smaller by design; `click_rate`, `conversion_rate` and `roas` are what put the two versions on the same footing.

#### 4. Optionally, take the total

The same request with no `filter[version]` gives you the flow as a whole, both cohorts included — the number to report to the business.

> **Warning**: A malformed or empty `filter[version]` is **rejected**, never quietly ignored. Serving the all-versions total as though it were scoped to one version would be a silently wrong A/B result, so the request fails instead.

## Next

- [Building queries](/developers/product-api/analytics/building-queries) - Timeframes, intervals, breakdowns and filters, shared by every report.
- [Statistics catalog](/developers/product-api/analytics/statistics) - Every statistic a flow report can return.
- [Reading results](/developers/product-api/analytics/reading-results) - The series shape, freshness, warnings and errors.

---

This is one page of the Instasent documentation. For the complete machine-readable index of every guide and API reference, fetch https://docs.instasent.com/llms.txt — start there for full context.
