Create Chart
Add a new chart to a dashboard board with a SQL query and chart type. Supports line, bar, pie, funnel, and other visualization types.
Overview
Creates a new chart and attaches it to a board. Returns the new chart’s ID on success. Thechart_type field controls which other request body fields are required or validated. Funnel charts are special - their SQL is auto-generated from the steps array, so pass "SELECT 1" as the query placeholder.
Request Fields
| Field | Type | Required | Description |
|---|---|---|---|
projectId | string | Yes | Project the chart belongs to |
query | string | Conditional | SQL query. Required for all types except retention. For funnel, pass "SELECT 1" |
chart_type | string | Yes | table · number · bar · line · pie · stacked · funnel · user_paths · retention |
title | string | Yes | Display name (minimum 1 character) |
description | string | No | Optional description |
x_axis | string | Conditional | Column for the X axis. Required for bar, line, stacked |
y_axis | string[] | Conditional | Column(s) for Y axis metrics. See per-type rules below |
group_by | string | Conditional | Column to group/stack series by. Required for stacked |
steps | FunnelStep[] | Conditional | Ordered funnel steps. Required for funnel (minimum 2) |
settings | ChartSettings | No | Type-specific configuration object |
Chart Types
table
Renders query results in a paginated table. No axis fields needed.
number
Renders a single scalar value (KPI card). The query must return exactly 1 row × 1 column.
bar and line
Both require x_axis and at least 1 column in y_axis.
pie
Requires exactly 1 column in y_axis. x_axis identifies the label column.
stacked
Requires x_axis, exactly 1 column in y_axis, and group_by.
Funnel Charts
Funnel charts measure step-by-step user conversion. The SQL is auto-generated fromsteps, so query must be the placeholder "SELECT 1". At least 2 steps are required.
The FunnelStep Object
Each step in the steps array has the following shape:
| Field | Type | Required | Description |
|---|---|---|---|
type | string | Yes | event - built-in events (page, connect, transaction); track - custom tracked events; decoded_log - decoded smart-contract events |
event | string | Yes | Event name (e.g. page, connect, transaction) |
<propertyKey> | StepFilterCondition | No | One or more property filters. Any extra key on the step object is treated as a filter. Standard columns (device, browser, os, location, referrer, ref, utm_*) are filtered directly; all other keys are extracted from properties via JSONExtractString |
Filter Operators (StepFilterCondition)
op | SQL equivalent | Notes |
|---|---|---|
equals | = 'value' | Exact match |
notEquals | != 'value' | Inverse match |
in | IN (...) | Pipe-delimited value: "metamask|rainbow|coinbase" |
notIn | NOT IN (...) | Pipe-delimited value |
gt | > value | Numeric comparison |
gte | >= value | Numeric comparison |
lt | < value | Numeric comparison |
lte | <= value | Numeric comparison |
startsWith | startsWith(col, 'v') | String prefix |
endsWith | endsWith(col, 'v') | String suffix |
includes | like '%v%' | Substring match |
settings for Funnel Charts
| Field | Type | Default | Description |
|---|---|---|---|
funnelType | "closed" | "open" | "closed" | closed - strict ordering, no events between steps; open - ordered but other events may occur between steps |
conversionWindow | ConversionWindow | 1 day | Max time from Step 1 for a user to complete all steps |
breakdown | string | - | Split each funnel bar by this dimension |
ConversionWindow
unit must be one of: minute · hour · day · week (7 days) · month (30 days).
breakdown values
device · browser · os · referrer · ref · utm_source · utm_medium · utm_campaign · utm_term · utm_content
The top categories are shown individually. The rest collapse into “Others”.
Funnel Examples
Basic 3-step closed funnel
With per-step property filters
Filter step 2 to MetaMask wallet connections on Ethereum mainnet:With breakdown by device
Open funnel with multi-value in filter
User Paths Charts
Visualize how users navigate your app after a starting event.settings.startStep is required.
settings for User Paths Charts
| Field | Type | Default | Description |
|---|---|---|---|
startStep | FunnelStep | - | Required. Event where the flow begins |
endStep | FunnelStep | null | null | Optional ending event. null = open-ended |
maxSteps | integer (2–10) | 3 | Max steps to show in the flow. Values above 10 are clamped to 10 |
nodesPerStep | integer (2–10) | 5 | Max unique event nodes per step. Values above 10 are clamped to 10 |
conversionWindow | ConversionWindow | - | Time window to group the flow |
filters | string | - | JSON-encoded string of additional path filters |
Retention Charts
Measures how often users return over time. Thequery field is not used - pass "" or omit it.
settings for Retention Charts
| Field | Type | Description |
|---|---|---|
retentionFilter | FunnelStep | null | Event that qualifies a returning visit as “retained”. null = any event counts |
retentionUserFilters | RetentionUserFilter[] | User-segment filters that narrow the retention cohort |
RetentionUserFilter:
| Field | Type | Description |
|---|---|---|
field | string | User property (e.g. device, browser, os, utm_source, location) |
op | string | Comparison operator (same set as StepFilterCondition.op) |
value | string | number | Value to compare against |
settings:
Validation Reference
| Chart Type | Validation Rule |
|---|---|
table | query must execute successfully |
number | query must return exactly 1 row × 1 column |
bar | x_axis required; y_axis requires ≥ 1 element |
line | x_axis required; y_axis requires ≥ 1 element |
pie | y_axis requires exactly 1 element |
stacked | x_axis required; y_axis requires exactly 1 element; group_by required |
funnel | steps requires ≥ 2 FunnelStep objects; query must be "SELECT 1" or any valid SQL |
user_paths | settings.startStep required; query must execute and return valid path data |
retention | No query validation - query is ignored |
Response
201 Created - returns the new chart’s ID as a bare JSON string.
400 Bad Request - validation failed (missing required fields, invalid SQL, wrong step count, etc.). Branch on error.code; see Errors.
Overview
Creates a new chart and attaches it to a board. Returns the new chart’s ID on success. Thechart_type field controls which other request body fields are required or validated. Funnel charts are special - their SQL is auto-generated from the steps array, so pass "SELECT 1" as the query placeholder.
Request Fields
| Field | Type | Required | Description |
|---|---|---|---|
projectId | string | Yes | Project the chart belongs to |
query | string | Conditional | SQL query. Required for all types except retention. For funnel, pass "SELECT 1" |
chart_type | string | Yes | table · number · bar · line · pie · stacked · funnel · user_paths · retention |
title | string | Yes | Display name (minimum 1 character) |
description | string | No | Optional description |
x_axis | string | Conditional | Column for the X axis. Required for bar, line, stacked |
y_axis | string[] | Conditional | Column(s) for Y axis metrics. See per-type rules below |
group_by | string | Conditional | Column to group/stack series by. Required for stacked |
steps | FunnelStep[] | Conditional | Ordered funnel steps. Required for funnel (minimum 2) |
settings | ChartSettings | No | Type-specific configuration object |
Chart Types
table
Renders query results in a paginated table. No axis fields needed.
number
Renders a single scalar value (KPI card). The query must return exactly 1 row × 1 column.
bar and line
Both require x_axis and at least 1 column in y_axis.
pie
Requires exactly 1 column in y_axis. x_axis identifies the label column.
stacked
Requires x_axis, exactly 1 column in y_axis, and group_by.
Funnel Charts
Funnel charts measure step-by-step user conversion. The SQL is auto-generated fromsteps, so query must be the placeholder "SELECT 1". At least 2 steps are required.
The FunnelStep Object
Each step in the steps array has the following shape:
| Field | Type | Required | Description |
|---|---|---|---|
type | string | Yes | event - built-in events (page, connect, transaction); track - custom tracked events; decoded_log - decoded smart-contract events |
event | string | Yes | Event name (e.g. page, connect, transaction) |
<propertyKey> | StepFilterCondition | No | One or more property filters. Any extra key on the step object is treated as a filter. Standard columns (device, browser, os, location, referrer, ref, utm_*) are filtered directly; all other keys are extracted from properties via JSONExtractString |
Filter Operators (StepFilterCondition)
op | SQL equivalent | Notes |
|---|---|---|
equals | = 'value' | Exact match |
notEquals | != 'value' | Inverse match |
in | IN (...) | Pipe-delimited value: "metamask|rainbow|coinbase" |
notIn | NOT IN (...) | Pipe-delimited value |
gt | > value | Numeric comparison |
gte | >= value | Numeric comparison |
lt | < value | Numeric comparison |
lte | <= value | Numeric comparison |
startsWith | startsWith(col, 'v') | String prefix |
endsWith | endsWith(col, 'v') | String suffix |
includes | like '%v%' | Substring match |
settings for Funnel Charts
| Field | Type | Default | Description |
|---|---|---|---|
funnelType | "closed" | "open" | "closed" | closed - strict ordering, no events between steps; open - ordered but other events may occur between steps |
conversionWindow | ConversionWindow | 1 day | Max time from Step 1 for a user to complete all steps |
breakdown | string | - | Split each funnel bar by this dimension |
ConversionWindow
unit must be one of: minute · hour · day · week (7 days) · month (30 days).
breakdown values
device · browser · os · referrer · ref · utm_source · utm_medium · utm_campaign · utm_term · utm_content
The top categories are shown individually. The rest collapse into “Others”.
Funnel Examples
Basic 3-step closed funnel
With per-step property filters
Filter step 2 to MetaMask wallet connections on Ethereum mainnet:With breakdown by device
Open funnel with multi-value in filter
User Paths Charts
Visualize how users navigate your app after a starting event.settings.startStep is required.
settings for User Paths Charts
| Field | Type | Default | Description |
|---|---|---|---|
startStep | FunnelStep | - | Required. Event where the flow begins |
endStep | FunnelStep | null | null | Optional ending event. null = open-ended |
maxSteps | integer (2–10) | 3 | Max steps to show in the flow. Values above 10 are clamped to 10 |
nodesPerStep | integer (2–10) | 5 | Max unique event nodes per step. Values above 10 are clamped to 10 |
conversionWindow | ConversionWindow | 2 weeks | Time window to group the flow |
filters | string | - | JSON-encoded string of additional path filters |
Retention Charts
Measures how often users return over time. Thequery field is not used - pass "" or omit it.
settings for Retention Charts
| Field | Type | Description |
|---|---|---|
retentionFilter | FunnelStep | null | Event that qualifies a returning visit as “retained”. null = any event counts |
retentionUserFilters | RetentionUserFilter[] | User-segment filters that narrow the retention cohort |
RetentionUserFilter:
| Field | Type | Description |
|---|---|---|
field | string | User property (e.g. device, browser, os, utm_source, location) |
op | string | Comparison operator (same set as StepFilterCondition.op) |
value | string | number | Value to compare against |
settings:
Validation Reference
| Chart Type | Validation Rule |
|---|---|
table | query must execute successfully |
number | query must return exactly 1 row × 1 column |
bar | x_axis required; y_axis requires ≥ 1 element |
line | x_axis required; y_axis requires ≥ 1 element |
pie | y_axis requires exactly 1 element |
stacked | x_axis required; y_axis requires exactly 1 element; group_by required |
funnel | steps requires ≥ 2 FunnelStep objects; query must be "SELECT 1" or any valid SQL |
user_paths | settings.startStep required; query must execute and return data in the expected user-path format (columns: user identifier, event name, timestamp) |
retention | No query validation - query is ignored |
Response
201 Created - returns the new chart’s ID as a bare JSON string.
400 Bad Request - validation failed (missing required fields, invalid SQL, wrong step count, etc.). Branch on error.code; see Errors.
Authorizations
Workspace API key (e.g. formo_xxx). Create one in the Formo dashboard under Team Settings > API Keys.
Path Parameters
Body
Request body for creating a chart.
Project the chart belongs to.
Visualization type. Determines which other fields are required:
chart_type | Extra required fields |
|---|---|
table | query |
number | query (must return 1 row × 1 column) |
bar | query, x_axis, y_axis (≥ 1) |
line | query, x_axis, y_axis (≥ 1) |
pie | query, y_axis (exactly 1) |
stacked | query, x_axis, y_axis (exactly 1), group_by |
funnel | steps (≥ 2), query placeholder "SELECT 1" |
user_paths | query, settings.startStep |
retention | none (query ignored) |
table, number, funnel, bar, line, pie, stacked, user_paths, retention Display name shown on the chart and board.
1SQL query that powers the chart.
funnel: pass"SELECT 1"; the actual query is auto-generated fromsteps.retention: can be omitted or pass""; data is fetched from the retention pipe directly.- All other types: required; must be a valid SQL string.
1Optional description.
Column name for the X axis. Required for bar, line, and stacked.
Column name(s) used as Y axis metrics.
bar/line: at least 1 element required.pie/stacked: exactly 1 element required.
Column to group / stack series by. Required for stacked.
Ordered list of funnel steps. Required for funnel (minimum 2 steps).
Each element is a FunnelStep; add property filters as extra keys on the step object (e.g. "rdns": { "op": "equals", "value": "io.metamask" }).
2Chart-type-specific configuration. The fields that apply depend on chart_type:
- funnel:
funnelType,conversionWindow,breakdown - user_paths:
startStep,endStep,maxSteps,nodesPerStep,conversionWindow,filters - retention:
retentionFilter,retentionUserFilters
All fields are optional at the schema level; see per-type validation rules for which are functionally required.
Response
Chart created
A saved chart attached to a board.
Visualization type.
table, number, funnel, bar, line, pie, stacked, user_paths, retention SQL query powering the chart. For funnel and retention charts this is a system-managed placeholder.
Column used as the X axis.
Column(s) used as Y axis metric(s).
Column used to group/stack series.
Ordered list of funnel steps. Only present when chart_type is funnel.
Type-specific configuration. See ChartSettings for all fields.