---
title: "List charts for a board"
method: GET
path: "/v0/boards/{boardId}/charts"
tags: ["Charts"]
---

# List charts for a board

`GET /v0/boards/{boardId}/charts`

## Request

- Base URL: `https://api.formo.so`
- URL: `https://api.formo.so/v0/boards/{boardId}/charts`
- Auth: HTTP bearer

List charts in a board. By default returns lightweight chart summaries (no queries executed). Pass `include=results` to execute each chart’s stored query server-side and receive full charts with `results`, the parent `board`, and an optional `warnings` sidecar carrying per-chart query failures (failing charts are excluded from `data` so the page renders cleanly).

## Path parameters

- `boardId` string, required

## Query parameters

- `include` 'results' | 'meta'
- `page` integer
- `size` integer

## Response `200`

Paginated chart summaries (default), or full charts with results when `include=results`

- union
  - object: Pagination cursor returned alongside `data` on every paginated list endpoint. Use these to walk pages: `has_more` is true while `page * size < total`. Combine with the matching `Page` and `Size` query parameters to request the next page.
    - `page` integer, required: 1-indexed page number echoed from the request.
    - `size` integer, required: Page size echoed from the request.
    - `total` integer, required: Total row count across all pages.
    - `has_more` boolean, required: True when more pages remain (`page * size < total`).
    - `data` ChartSummary[], required
      - `id` string, required
      - `project_id` string, required
      - `board_id` string, required
      - `chart_type` string, required
      - `title` string, required
      - `description` string, nullable
      - `position` integer, required: Display position of the chart on its board.
      - `created_at` string, date-time, required
      - `updated_at` string, date-time, nullable
  - object: Pagination cursor returned alongside `data` on every paginated list endpoint. Use these to walk pages: `has_more` is true while `page * size < total`. Combine with the matching `Page` and `Size` query parameters to request the next page.
    - `page` integer, required: 1-indexed page number echoed from the request.
    - `size` integer, required: Page size echoed from the request.
    - `total` integer, required: Total row count across all pages.
    - `has_more` boolean, required: True when more pages remain (`page * size < total`).
    - `data` Chart[], required
      - `id` string, required
      - `chart_type` 'table' | 'number' | 'funnel' | 'bar' | 'line' | 'area' | 'pie' | 'stacked' | 'user_paths' | 'retention', required: Visualization type.
      - `title` string, required
      - `description` string, nullable
      - `query` string, required: SQL query powering the chart. For `funnel` and `retention` charts this is a system-managed placeholder.
      - `project_id` string, required
      - `board_id` string, required
      - `x_axis` string, nullable: Column used as the X axis.
      - `y_axis` string[], nullable: Column(s) used as Y axis metric(s).
      - `group_by` string, nullable: Column used to group/stack series.
      - `steps` FunnelStep[], nullable: Ordered list of funnel steps. Only present when `chart_type` is `funnel`.
        - `type` 'event' | 'track' | 'decoded_log', required: `event`: built-in page/connect/transaction events; `track`: custom tracked events; `decoded_log`: decoded smart-contract events.
        - `event` string, required: Event name (e.g. `page`, `connect`, `transaction`, or a custom track event name).
        - `events` FunnelStepEvent[]: Optional OR group (funnel steps only, max 10). When present and non-empty the step matches any of these events, e.g. `[{"type":"track","event":"Swap Initiated"},{"type":"track","event":"Limit Order Placed"}]`. The primary `type`/`event` is always included.
          - `type` 'event' | 'track' | 'decoded_log', required
          - `event` string, required
          - `filters` StepFilterCondition[]: Member-scoped predicates, AND-joined within this member.
            - `field` string, required: Column or property targeted by this filter.
            - `op` 'eq' | 'neq' | 'gt' | 'lt' | 'gte' | 'lte' | 'in' | 'nin' | 'startsWith' | 'endsWith' | 'contains' | 'notEmpty' | 'isEmpty', required: Canonical comparison operator token.
            - `value` union: Value to compare against. Omit for `notEmpty` and `isEmpty`. For `in` / `nin`, pass a non-empty array or a pipe-delimited string. Array string members cannot contain a literal `|`, which is reserved as the Tinybird membership separator.
              - …
        - `filters` StepFilterCondition[]
          - `field` string, required: Column or property targeted by this filter.
          - `op` 'eq' | 'neq' | 'gt' | 'lt' | 'gte' | 'lte' | 'in' | 'nin' | 'startsWith' | 'endsWith' | 'contains' | 'notEmpty' | 'isEmpty', required: Canonical comparison operator token.
          - `value` union: Value to compare against. Omit for `notEmpty` and `isEmpty`. For `in` / `nin`, pass a non-empty array or a pipe-delimited string. Array string members cannot contain a literal `|`, which is reserved as the Tinybird membership separator.
            - string
            - number
            - boolean
            - union[]
              - …
      - `settings` ChartSettings: Chart-type-specific configuration. The fields that apply depend on `chart_type`: - **funnel**: `funnelType`, `conversionWindow`, `breakdown` - **user_paths**: `anchors`, `maxSteps`, `nodesPerStep`, `conversionWindow`, `filters` - **retention**: `entryFilter`, `retentionFilter`, `retentionUserFilters`, `retentionSignalType`, `retentionLabelSignal` Fields are optional at the schema level except where the selected chart type requires them. User Paths require at least one `anchors` entry. Retention requests must explicitly include `entryFilter`; use `null` for any event.
        - `funnelType` 'closed' | 'open': **Funnel only.** `closed`: users must complete steps in strict order with no intervening events. `open`: users may complete steps in order but other events may occur between steps.
        - `conversionWindow` ConversionWindow: Time window within which a user must complete all funnel steps (measured from Step 1). Defaults to 2 hours if omitted.
          - `value` integer, required: Number of time units.
          - `unit` 'hour' | 'day' | 'week', required: Time unit. `week` = 7 days.
        - `breakdown` 'device' | 'browser' | 'os' | 'location' | 'referrer' | 'ref' | 'utm_source' | 'utm_medium' | 'utm_campaign' | 'utm_term' | 'utm_content' | 'builder_codes': **Funnel only.** Split each funnel bar by this dimension. The top categories are shown individually; the rest are collapsed into 'Others'.
        - `anchors` FunnelStep[]: **user_paths (required).** Ordered path anchors. The first entry starts the flow; the last entry ends it. A single entry creates an open-ended flow.
          - `type` 'event' | 'track' | 'decoded_log', required: `event`: built-in page/connect/transaction events; `track`: custom tracked events; `decoded_log`: decoded smart-contract events.
          - `event` string, required: Event name (e.g. `page`, `connect`, `transaction`, or a custom track event name).
          - `events` FunnelStepEvent[]: Optional OR group (funnel steps only, max 10). When present and non-empty the step matches any of these events, e.g. `[{"type":"track","event":"Swap Initiated"},{"type":"track","event":"Limit Order Placed"}]`. The primary `type`/`event` is always included.
            - `type` 'event' | 'track' | 'decoded_log', required
            - `event` string, required
            - `filters` StepFilterCondition[]: Member-scoped predicates, AND-joined within this member.
              - …
          - `filters` StepFilterCondition[]
            - `field` string, required: Column or property targeted by this filter.
            - `op` 'eq' | 'neq' | 'gt' | 'lt' | 'gte' | 'lte' | 'in' | 'nin' | 'startsWith' | 'endsWith' | 'contains' | 'notEmpty' | 'isEmpty', required: Canonical comparison operator token.
            - `value` union: Value to compare against. Omit for `notEmpty` and `isEmpty`. For `in` / `nin`, pass a non-empty array or a pipe-delimited string. Array string members cannot contain a literal `|`, which is reserved as the Tinybird membership separator.
              - …
        - `maxSteps` integer: **user_paths.** Maximum number of steps to show in the flow (2 to 5). Values above 5 are clamped to 5.
        - `nodesPerStep` integer: **user_paths.** Maximum number of unique event nodes visible per step (2 to 8). Values above 8 are clamped to 8.
        - `filters` string: **user_paths.** JSON-encoded string of additional filters applied to the path query.
        - `retentionFilter` FunnelStep: A single funnel or user-path step. Event-property predicates are stored in `filters`, using the same canonical `{field, op, value}` envelope as every other filter surface. Funnel steps (not user-path anchors or retention filters) may also carry `events`, an OR group: the step then matches any listed event. `type`/`event` stay the step's primary event and are always part of the group; `filters` apply to the whole group.
          - `type` 'event' | 'track' | 'decoded_log', required: `event`: built-in page/connect/transaction events; `track`: custom tracked events; `decoded_log`: decoded smart-contract events.
          - `event` string, required: Event name (e.g. `page`, `connect`, `transaction`, or a custom track event name).
          - `events` FunnelStepEvent[]: Optional OR group (funnel steps only, max 10). When present and non-empty the step matches any of these events, e.g. `[{"type":"track","event":"Swap Initiated"},{"type":"track","event":"Limit Order Placed"}]`. The primary `type`/`event` is always included.
            - `type` 'event' | 'track' | 'decoded_log', required
            - `event` string, required
            - `filters` StepFilterCondition[]: Member-scoped predicates, AND-joined within this member.
              - …
          - `filters` StepFilterCondition[]
            - `field` string, required: Column or property targeted by this filter.
            - `op` 'eq' | 'neq' | 'gt' | 'lt' | 'gte' | 'lte' | 'in' | 'nin' | 'startsWith' | 'endsWith' | 'contains' | 'notEmpty' | 'isEmpty', required: Canonical comparison operator token.
            - `value` union: Value to compare against. Omit for `notEmpty` and `isEmpty`. For `in` / `nin`, pass a non-empty array or a pipe-delimited string. Array string members cannot contain a literal `|`, which is reserved as the Tinybird membership separator.
              - …
        - `entryFilter` FunnelStep: A single funnel or user-path step. Event-property predicates are stored in `filters`, using the same canonical `{field, op, value}` envelope as every other filter surface. Funnel steps (not user-path anchors or retention filters) may also carry `events`, an OR group: the step then matches any listed event. `type`/`event` stay the step's primary event and are always part of the group; `filters` apply to the whole group.
          - `type` 'event' | 'track' | 'decoded_log', required: `event`: built-in page/connect/transaction events; `track`: custom tracked events; `decoded_log`: decoded smart-contract events.
          - `event` string, required: Event name (e.g. `page`, `connect`, `transaction`, or a custom track event name).
          - `events` FunnelStepEvent[]: Optional OR group (funnel steps only, max 10). When present and non-empty the step matches any of these events, e.g. `[{"type":"track","event":"Swap Initiated"},{"type":"track","event":"Limit Order Placed"}]`. The primary `type`/`event` is always included.
            - `type` 'event' | 'track' | 'decoded_log', required
            - `event` string, required
            - `filters` StepFilterCondition[]: Member-scoped predicates, AND-joined within this member.
              - …
          - `filters` StepFilterCondition[]
            - `field` string, required: Column or property targeted by this filter.
            - `op` 'eq' | 'neq' | 'gt' | 'lt' | 'gte' | 'lte' | 'in' | 'nin' | 'startsWith' | 'endsWith' | 'contains' | 'notEmpty' | 'isEmpty', required: Canonical comparison operator token.
            - `value` union: Value to compare against. Omit for `notEmpty` and `isEmpty`. For `in` / `nin`, pass a non-empty array or a pipe-delimited string. Array string members cannot contain a literal `|`, which is reserved as the Tinybird membership separator.
              - …
        - `retentionUserFilters` RetentionUserFilter[]: **retention.** Zero or more user-segment filters that narrow the cohort (e.g. only desktop users, only users from a specific UTM source).
          - `value` union: The value to compare against. Omit for `notEmpty` and `isEmpty`.
            - string
            - number
          - `field` string, required: The user property to filter on (e.g. `device`, `browser`, `os`, `location`, `utm_source`, `utm_medium`, `utm_campaign`).
          - `op` 'eq' | 'neq' | 'in' | 'nin' | 'gt' | 'gte' | 'lt' | 'lte' | 'notEmpty' | 'isEmpty', required: Comparison operator. Only the canonical terse tokens are accepted (the retired long forms `greater`/`greaterOrEqual`/`less`/`lessOrEqual` are rejected). `notEmpty` ("is not empty") and `isEmpty` ("is empty") are value-less existence checks on a string user property; the `value` is ignored. Substring operators (`startsWith` / `endsWith` / `contains`) are not supported on retention user filters.
        - `retentionSignalType` 'event' | 'label': **retention.** `event` (default): cohort and retention are driven by events. `label`: driven by a label value over time (see `retentionLabelSignal`); when `label`, the event fields are ignored.
        - `retentionLabelSignal` RetentionLabelSignal: The label predicate for label-based retention. The cohort is wallets grouped by the week they FIRST crossed this predicate on their label value; a wallet is retained in a later week if its latest value as of that week's end still satisfies it (as-of / carry-forward, evaluated against label history).
          - `field` string, required: The label tag to evaluate (the value of `tag_id` set via `POST /v0/profiles/:address/labels`).
          - `op` 'gt' | 'gte' | 'lt' | 'lte' | 'eq', required: Comparison operator. Numeric operators coerce both sides via toFloat64OrZero, so a numeric op on a non-numeric value yields no match (not an error).
          - `value` string, required: The threshold/value to compare against. Always a string; numeric ops coerce it.
          - `chain_id` string: Optional chain scope. Empty string matches across all chains.
        - `retentionCohortLabelFilters` RetentionCohortLabelFilter[]: **retention.** Label predicates that restrict an event-based cohort.
          - `field` string, required: The label tag to evaluate.
          - `op` 'eq' | 'neq' | 'contains' | 'gt' | 'gte' | 'lt' | 'lte', required
          - `value` string, required
          - `chain_id` string: Optional chain scope. Empty string matches across all chains.
    - `board` Board, required
      - `id` string, required
      - `created_at` string, date-time
      - `updated_at` string, date-time, nullable
      - `project_id` string, required
      - `enabled` boolean, required: Whether the board is publicly accessible
      - `title` string
      - `description` string, nullable
    - `warnings` object: Present only if some charts failed to execute. Failures are excluded from `data`.
      - `failedCharts` integer
      - `errors` object[]
        - `chartId` string
        - `error` string

---

[API](https://skmtc.dev/formo/apis/formo-public-api.md) · [All operations](https://skmtc.dev/formo/apis/formo-public-api/llms.txt) · [OpenAPI document](https://skmtc.dev/formo/apis/formo-public-api/revisions/67ada57df63c?raw)
