@picked/client 0.0.70-next.6 → 0.0.71-next.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/.tsbuildinfo +1 -0
- package/dist/api-CH2FNa6S.cjs +1 -0
- package/dist/api-CgqRvuKL.js +38 -0
- package/dist/cjs/form/index.js +1 -1
- package/dist/cjs/index.js +2 -2
- package/dist/cjs/plugins/dom-observer/index.js +1 -1
- package/dist/cjs/plugins/dynamic-experiences/index.js +1 -1
- package/dist/cjs/server/index.js +1 -1
- package/dist/docs/actions.mdx +38 -18
- package/dist/docs/api/authentication.md +75 -48
- package/dist/docs/api/authorization-and-scopes.md +63 -47
- package/dist/docs/api/error-handling.md +70 -54
- package/dist/docs/api/index.md +41 -22
- package/dist/docs/api/pagination.md +30 -20
- package/dist/docs/api-keys.mdx +11 -6
- package/dist/docs/chrome-extension.md +22 -5
- package/dist/docs/conditions.mdx +32 -19
- package/dist/docs/content/asset-library.mdx +65 -34
- package/dist/docs/content/content-entries.mdx +8 -2
- package/dist/docs/content/layouts.mdx +45 -29
- package/dist/docs/content/pages.mdx +29 -14
- package/dist/docs/content/sections.mdx +19 -8
- package/dist/docs/delivery-api/experience-content.md +10 -5
- package/dist/docs/delivery-api/index.md +19 -12
- package/dist/docs/delivery-api/preview-caching-crawling.md +27 -14
- package/dist/docs/delivery-api/project-config.md +6 -4
- package/dist/docs/experiences.mdx +26 -10
- package/dist/docs/features.mdx +66 -25
- package/dist/docs/fields.mdx +42 -27
- package/dist/docs/flow-builder/building-flows.md +38 -20
- package/dist/docs/flow-builder/condition-builder.md +32 -21
- package/dist/docs/flow-builder/keyboard-shortcuts.md +18 -18
- package/dist/docs/flow-builder/nodes.md +26 -13
- package/dist/docs/flow-builder/overview.mdx +28 -15
- package/dist/docs/gtm-template.md +35 -26
- package/dist/docs/guides/build-a-personalized-page.mdx +36 -18
- package/dist/docs/image-optimisation-service.md +33 -17
- package/dist/docs/index.md +28 -17
- package/dist/docs/mcp.md +46 -38
- package/dist/docs/pickedql/data-sources.md +65 -43
- package/dist/docs/pickedql/dimensions.md +27 -12
- package/dist/docs/pickedql/examples.md +38 -26
- package/dist/docs/pickedql/filtering.md +10 -6
- package/dist/docs/pickedql/index.md +32 -14
- package/dist/docs/pickedql/schema.md +85 -76
- package/dist/docs/pickedql/virtual-functions.md +62 -36
- package/dist/docs/projects.mdx +14 -7
- package/dist/docs/reports.mdx +5 -3
- package/dist/docs/sdk/actions.md +33 -17
- package/dist/docs/sdk/conditions.md +8 -5
- package/dist/docs/sdk/content-security-policy.md +5 -4
- package/dist/docs/sdk/experiences.md +29 -11
- package/dist/docs/sdk/feature-allocation.md +79 -47
- package/dist/docs/sdk/features.md +130 -76
- package/dist/docs/sdk/fields.md +66 -42
- package/dist/docs/sdk/index.md +22 -13
- package/dist/docs/sdk/plugins/create-experience.md +18 -15
- package/dist/docs/sdk/plugins/dynamic-experiences.md +42 -16
- package/dist/docs/sdk/predicates.md +53 -37
- package/dist/docs/sdk/ssr/index.md +25 -8
- package/dist/docs/sdk/ssr/rendering-and-hydration.md +37 -16
- package/dist/docs/sdk/ssr/serialize.md +38 -20
- package/dist/docs/sdk/ssr/slots-and-placements.md +28 -10
- package/dist/docs/sdk/steps.md +100 -55
- package/dist/docs/steps.mdx +20 -11
- package/dist/docs/team-management.md +17 -11
- package/dist/docs/vite-plugin.md +26 -19
- package/dist/docs/workspace-versioning.mdx +14 -8
- package/dist/docs/workspaces.mdx +55 -24
- package/dist/{dom-BwmTHeT7.js → dom-BqcToNL0.js} +1 -3
- package/dist/{dom-CDrHc_j9.cjs → dom-DlLH3FxV.cjs} +1 -1
- package/dist/esm/form/index.js +2 -4
- package/dist/esm/index.js +50 -45
- package/dist/esm/plugins/dom-observer/index.js +1 -1
- package/dist/esm/plugins/dynamic-experiences/index.js +2 -2
- package/dist/esm/preview/index.js +1 -1
- package/dist/esm/server/index.js +12 -10
- package/dist/{experience-instance-DOJShRk5.js → experience-instance-DGk11d8a.js} +3 -3
- package/dist/experience-instance-Dej3P1sE.cjs +1 -0
- package/dist/{plugin-BxMR7fOV.js → plugin-D2UqFikQ.js} +2 -2
- package/dist/plugin-DCW-tnjO.cjs +1 -0
- package/dist/{preview-channel-DW9J8t4B.js → preview-channel-CSr96XAo.js} +1 -1
- package/dist/{protocol-DSqOlW2r.js → protocol-C5KkkiZc.js} +1 -1
- package/dist/types/client.d.ts +7 -6
- package/dist/types/entities/action/action.d.ts +5 -4
- package/dist/types/entities/action/action.d.ts.map +1 -1
- package/dist/types/entities/component/component.d.ts +6 -5
- package/dist/types/entities/component/component.d.ts.map +1 -1
- package/dist/types/entities/condition/condition.d.ts +5 -5
- package/dist/types/entities/content/content.d.ts +4 -3
- package/dist/types/entities/experience/experience.d.ts +11 -10
- package/dist/types/entities/experience/experience.d.ts.map +1 -1
- package/dist/types/entities/experience-instance/experience-instance.d.ts +10 -9
- package/dist/types/entities/feature/feature.d.ts +3 -2
- package/dist/types/entities/feature/feature.d.ts.map +1 -1
- package/dist/types/entities/field/field.d.ts +7 -6
- package/dist/types/entities/framework/framework.d.ts +7 -6
- package/dist/types/entities/framework/framework.d.ts.map +1 -1
- package/dist/types/entities/history/history.d.ts +6 -6
- package/dist/types/entities/plugin/plugin.d.ts +3 -2
- package/dist/types/entities/plugin/plugin.d.ts.map +1 -1
- package/dist/types/entities/predicate/predicate.d.ts +4 -3
- package/dist/types/entities/predicate/predicate.d.ts.map +1 -1
- package/dist/types/entities/response/response-validation.d.ts +3 -2
- package/dist/types/entities/response/response.d.ts +12 -11
- package/dist/types/entities/session/session.d.ts +2 -1
- package/dist/types/entities/step/step.d.ts +6 -5
- package/dist/types/exports.d.ts +2 -1
- package/dist/types/exports.d.ts.map +1 -1
- package/dist/types/form/build-responses.d.ts +2 -1
- package/dist/types/form/create-field-evaluator.d.ts +4 -3
- package/dist/types/form/create-field-validation.d.ts +5 -4
- package/dist/types/form/create-form.d.ts +7 -6
- package/dist/types/form/create-submit-pipeline.d.ts +7 -6
- package/dist/types/form/get-step-fields.d.ts +3 -2
- package/dist/types/lifecycle/condition-selection.d.ts +14 -4
- package/dist/types/lifecycle/lifecycle.d.ts +4 -3
- package/dist/types/lifecycle/rules-logic.d.ts +4 -3
- package/dist/types/lifecycle/state-snapshot.d.ts +4 -3
- package/dist/types/picked.d.ts +64 -62
- package/dist/types/picked.d.ts.map +1 -1
- package/dist/types/ping.d.ts +1 -1
- package/dist/types/ping.d.ts.map +1 -1
- package/dist/types/plugins/create-experience/create-experience.d.ts +9 -8
- package/dist/types/plugins/create-experience/create-experience.d.ts.map +1 -1
- package/dist/types/plugins/create-experience/plugin.d.ts +3 -2
- package/dist/types/plugins/create-experience/plugin.d.ts.map +1 -1
- package/dist/types/plugins/create-experience/serialization.d.ts.map +1 -1
- package/dist/types/plugins/dom-observer/plugin.d.ts +1 -1
- package/dist/types/plugins/dynamic-experiences/plugin.d.ts +3 -3
- package/dist/types/plugins/dynamic-experiences/types.d.ts +8 -5
- package/dist/types/plugins/experience-browser-storage/plugin.d.ts +1 -1
- package/dist/types/plugins/experience-browser-storage/plugin.d.ts.map +1 -1
- package/dist/types/plugins/history-browser-storage/plugin.d.ts +1 -1
- package/dist/types/plugins/history-browser-storage/plugin.d.ts.map +1 -1
- package/dist/types/plugins/responses-browser-storage/plugin.d.ts +1 -1
- package/dist/types/plugins/responses-browser-storage/plugin.d.ts.map +1 -1
- package/dist/types/plugins/responses-indexeddb/plugin.d.ts +1 -1
- package/dist/types/plugins/single-page-app/plugin.d.ts +1 -1
- package/dist/types/plugins/single-page-app/plugin.d.ts.map +1 -1
- package/dist/types/plugins/web-components/plugin.d.ts +2 -1
- package/dist/types/plugins/window-object/plugin.d.ts +2 -2
- package/dist/types/preview-channel.d.ts +5 -1
- package/dist/types/preview-receiver/index.d.ts +18 -1
- package/dist/types/preview-receiver/protocol.d.ts +10 -1
- package/dist/types/server/index.d.ts +3 -3
- package/dist/types/server/serialize.d.ts +2 -2
- package/dist/types/utils/dom.d.ts +2 -1
- package/dist/types/utils/events.d.ts +6 -6
- package/dist/types/utils/events.d.ts.map +1 -1
- package/dist/types/utils/global-obj.d.ts +1 -1
- package/dist/types/utils/global-obj.d.ts.map +1 -1
- package/dist/types/utils/id.d.ts.map +1 -1
- package/dist/types/utils/logger.d.ts +2 -1
- package/dist/types/utils/logger.d.ts.map +1 -1
- package/dist/types/utils/node-tree/get-next-node-from-action.d.ts +2 -1
- package/dist/types/utils/node-tree/get-next-node-from-condition.d.ts +2 -1
- package/dist/types/utils/node-tree/get-next-node.d.ts +1 -1
- package/dist/types/utils/node-tree/get-next-node.d.ts.map +1 -1
- package/dist/types/utils/node-tree/get-origin-node.d.ts +1 -1
- package/dist/types/utils/node-tree/get-origin-node.d.ts.map +1 -1
- package/dist/types/utils/node-tree/min-max-steps-to-leaf.d.ts +1 -1
- package/dist/types/utils/node-tree/min-max-steps-to-leaf.d.ts.map +1 -1
- package/dist/types/utils/node-tree/min-max-steps-to-origin.d.ts +1 -1
- package/dist/types/utils/node-tree/min-max-steps-to-origin.d.ts.map +1 -1
- package/dist/types/utils/node-tree/next-reachable-step-nodes.d.ts +1 -1
- package/dist/types/utils/node-tree/next-reachable-step-nodes.d.ts.map +1 -1
- package/dist/types/utils/nodes.d.ts +1 -1
- package/dist/types/utils/picked-config.d.ts +2 -1
- package/dist/types/utils/rules-logic.d.ts +6 -2
- package/dist/types/utils/storage.d.ts +1 -1
- package/dist/types/utils/storage.d.ts.map +1 -1
- package/package.json +22 -23
- package/dist/api-CoUkIxIr.cjs +0 -1
- package/dist/api-ahdSBQ3Y.js +0 -40
- package/dist/experience-instance-DurC3pE-.cjs +0 -1
- package/dist/plugin-CASdGtTX.cjs +0 -1
package/dist/docs/mcp.md
CHANGED
|
@@ -4,21 +4,23 @@ layout: docs
|
|
|
4
4
|
|
|
5
5
|
# MCP server
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
Control your Picked workspace from an AI tool that writes code, with the Model
|
|
8
|
+
Context Protocol (MCP).
|
|
8
9
|
|
|
9
|
-
##
|
|
10
|
+
## Connect
|
|
10
11
|
|
|
11
12
|
The server URL is `https://api.picked.app/mcp`.
|
|
12
13
|
|
|
13
14
|
### Claude Desktop
|
|
14
15
|
|
|
15
|
-
1. Open **Settings > Connectors > Add custom connector
|
|
16
|
-
2. Set **Name** to `Picked` and **URL** to `https://api.picked.app/mcp
|
|
17
|
-
3. Click **Connect** and
|
|
16
|
+
1. Open **Settings > Connectors > Add custom connector**.
|
|
17
|
+
2. Set **Name** to `Picked` and **URL** to `https://api.picked.app/mcp`.
|
|
18
|
+
3. Click **Connect** and answer the authorization prompt.
|
|
18
19
|
|
|
19
|
-
### Project configuration
|
|
20
|
+
### Project configuration in `.mcp.json`
|
|
20
21
|
|
|
21
|
-
Add to your repository
|
|
22
|
+
Add this file to the root of your repository. It works with Claude Code, Cursor,
|
|
23
|
+
Windsurf, and other tools that support MCP.
|
|
22
24
|
|
|
23
25
|
:::code-group
|
|
24
26
|
|
|
@@ -37,7 +39,7 @@ Add to your repository root. Works with Claude Code, Cursor, Windsurf, and other
|
|
|
37
39
|
|
|
38
40
|
### Cursor
|
|
39
41
|
|
|
40
|
-
Add to `.cursor/mcp.json` in your project
|
|
42
|
+
Add this file to `.cursor/mcp.json` in the root of your project:
|
|
41
43
|
|
|
42
44
|
```json
|
|
43
45
|
{
|
|
@@ -50,25 +52,25 @@ Add to `.cursor/mcp.json` in your project root:
|
|
|
50
52
|
}
|
|
51
53
|
```
|
|
52
54
|
|
|
53
|
-
##
|
|
55
|
+
## Tools
|
|
54
56
|
|
|
55
57
|
### Discovery
|
|
56
58
|
|
|
57
59
|
| Tool | Description |
|
|
58
60
|
| ------------------------ | ------------------------------------------------------------ |
|
|
59
|
-
| `list_projects` |
|
|
60
|
-
| `get_workspace_overview` |
|
|
61
|
-
| `get_schema_info` |
|
|
62
|
-
| `get_picked_docs` |
|
|
61
|
+
| `list_projects` | Lists your organizations and projects |
|
|
62
|
+
| `get_workspace_overview` | Reads the full workspace state |
|
|
63
|
+
| `get_schema_info` | Reads the documentation for Picked concepts and the data model |
|
|
64
|
+
| `get_picked_docs` | Reads the complete Picked documentation, as text for an agent |
|
|
63
65
|
|
|
64
66
|
### Experiences
|
|
65
67
|
|
|
66
68
|
| Tool | Description |
|
|
67
69
|
| ------------------------ | ----------------------------------------------------------------------------------------- |
|
|
68
|
-
| `create_experience` |
|
|
69
|
-
| `get_experience` |
|
|
70
|
-
| `list_experiences` |
|
|
71
|
-
| `update_experience_flow` |
|
|
70
|
+
| `create_experience` | Creates an experience |
|
|
71
|
+
| `get_experience` | Reads an experience, with its flow graph |
|
|
72
|
+
| `list_experiences` | Lists your experiences |
|
|
73
|
+
| `update_experience_flow` | Creates, updates, or deletes steps, conditions, actions, fields, nodes, and edges as one operation |
|
|
72
74
|
|
|
73
75
|
### Steps, fields, conditions, and actions
|
|
74
76
|
|
|
@@ -81,40 +83,46 @@ Add to `.cursor/mcp.json` in your project root:
|
|
|
81
83
|
|
|
82
84
|
### Feature flags
|
|
83
85
|
|
|
84
|
-
| Tool | Description
|
|
85
|
-
| ---------------- |
|
|
86
|
-
| `create_feature` |
|
|
87
|
-
| `get_feature` |
|
|
88
|
-
| `list_features` |
|
|
89
|
-
| `update_feature` |
|
|
86
|
+
| Tool | Description |
|
|
87
|
+
| ---------------- | ---------------------------------------------------- |
|
|
88
|
+
| `create_feature` | Creates a feature flag |
|
|
89
|
+
| `get_feature` | Reads a feature flag |
|
|
90
|
+
| `list_features` | Lists your feature flags |
|
|
91
|
+
| `update_feature` | Updates the name, description, state, or weight |
|
|
90
92
|
|
|
91
93
|
### Analytics
|
|
92
94
|
|
|
93
95
|
| Tool | Description |
|
|
94
96
|
| ---------------- | ---------------------------------------------------------------- |
|
|
95
|
-
| `query_pickedql` |
|
|
97
|
+
| `query_pickedql` | Runs a PickedQL analytics query and returns the rows as a table |
|
|
96
98
|
|
|
97
|
-
|
|
99
|
+
Call `get_schema_info` with the topic `pickedql` to see the tables, the virtual
|
|
100
|
+
functions, and the dimension columns before you write a query.
|
|
98
101
|
|
|
99
|
-
###
|
|
102
|
+
### Publish
|
|
100
103
|
|
|
101
104
|
| Tool | Description |
|
|
102
105
|
| ------------------- | ---------------------------------------------- |
|
|
103
|
-
| `get_preview_url` |
|
|
104
|
-
| `publish_workspace` |
|
|
106
|
+
| `get_preview_url` | Makes a preview URL for your unpublished work |
|
|
107
|
+
| `publish_workspace` | Publishes the workspace |
|
|
105
108
|
|
|
106
109
|
## Example prompts
|
|
107
110
|
|
|
108
|
-
- "List my Picked projects and show me
|
|
109
|
-
- "Create a feature flag called 'new-checkout'
|
|
110
|
-
- "Create an experience with a step that collects email
|
|
111
|
-
- "Show me control
|
|
112
|
-
- "
|
|
111
|
+
- "List my Picked projects and show me the options on each one"
|
|
112
|
+
- "Create a feature flag called 'new-checkout' at 50% traffic"
|
|
113
|
+
- "Create an experience with a step that collects an email address"
|
|
114
|
+
- "Show me control and variant users by the device type for the last 30 days"
|
|
115
|
+
- "Make a preview URL for my workspace on `https://example.com`"
|
|
113
116
|
|
|
114
117
|
## Tips
|
|
115
118
|
|
|
116
|
-
- Ask your agent
|
|
117
|
-
|
|
118
|
-
-
|
|
119
|
-
|
|
120
|
-
-
|
|
119
|
+
- Ask your agent for a list of your projects first. Then ask it to read your
|
|
120
|
+
workspace and report the options on each record.
|
|
121
|
+
- For a large experience, ask your agent about flow graphs and JSON Logic. The agent
|
|
122
|
+
can read the documentation for you.
|
|
123
|
+
- An update to an experience flow is atomic. Your agent can create steps, fields,
|
|
124
|
+
nodes, and edges in one operation.
|
|
125
|
+
- See a preview of your work on your site before you publish, to check that each page
|
|
126
|
+
is correct.
|
|
127
|
+
- Ask your agent to run a PickedQL query on your analytics data. The agent can read
|
|
128
|
+
the schema, write the SQL, and explain the rows.
|
|
@@ -4,11 +4,14 @@ layout: docs
|
|
|
4
4
|
|
|
5
5
|
# Data sources
|
|
6
6
|
|
|
7
|
-
PickedQL
|
|
7
|
+
PickedQL gives you four virtual tables. Each table is fast for one kind of work. It also gives you three reference tables, and those hold the options of your
|
|
8
|
+
Picked project.
|
|
8
9
|
|
|
9
|
-
## `metrics` —
|
|
10
|
+
## `metrics` — data that PickedQL aggregates each day
|
|
10
11
|
|
|
11
|
-
|
|
12
|
+
Use it for a dashboard and to study a trend. There is one row for each unique set of
|
|
13
|
+
dimensions on each day. The dimension columns are there directly, and they need no
|
|
14
|
+
join. Examples are `device_category`, `country_code`, and `utm_source`.
|
|
12
15
|
|
|
13
16
|
```sql
|
|
14
17
|
SELECT device_category, control_users(), variant_users()
|
|
@@ -17,9 +20,11 @@ WHERE project_id = 'your-project-id'
|
|
|
17
20
|
GROUP BY device_category
|
|
18
21
|
```
|
|
19
22
|
|
|
20
|
-
## `events` —
|
|
23
|
+
## `events` — one row for each event of each user
|
|
21
24
|
|
|
22
|
-
|
|
25
|
+
Use it for a deep study, for a funnel, and for a breakdown of your own. There is one
|
|
26
|
+
row for each event of each user. PickedQL joins a dimension column, such as
|
|
27
|
+
`device_category` or `country_code`, when you point at it.
|
|
23
28
|
|
|
24
29
|
```sql
|
|
25
30
|
SELECT user_canonical_id, device_category
|
|
@@ -28,9 +33,10 @@ WHERE project_id = 'your-project-id'
|
|
|
28
33
|
AND variant_type = 'Control'
|
|
29
34
|
```
|
|
30
35
|
|
|
31
|
-
## `features` —
|
|
36
|
+
## `features` — one row for each feature flag
|
|
32
37
|
|
|
33
|
-
|
|
38
|
+
Use it to count the users, the sessions, and the events for each feature flag and
|
|
39
|
+
bucket. It uses parameterized functions.
|
|
34
40
|
|
|
35
41
|
```sql
|
|
36
42
|
SELECT feature_users('homepage_test', 'control')
|
|
@@ -38,40 +44,48 @@ FROM features
|
|
|
38
44
|
WHERE project_id = 'your-project-id'
|
|
39
45
|
```
|
|
40
46
|
|
|
41
|
-
## `experience_journey` —
|
|
47
|
+
## `experience_journey` — step transitions for a sankey chart
|
|
42
48
|
|
|
43
|
-
|
|
49
|
+
It returns one `source, target, users` row for each edge. You can put those rows
|
|
50
|
+
directly into a sankey chart or a funnel chart. It holds the eight common table
|
|
51
|
+
expressions that a card carried before. Those call `lagInFrame`, remove a duplicate
|
|
52
|
+
between two steps that follow each other, and rank the top paths.
|
|
44
53
|
|
|
45
|
-
|
|
54
|
+
Every filter goes in the **outer `WHERE`** clause. PickedQL reads each one as a
|
|
55
|
+
parameter and puts it into the query below. Only `project_id` is necessary. The rest
|
|
56
|
+
are optional, and each has a sensible default.
|
|
46
57
|
|
|
47
|
-
|
|
|
58
|
+
| Parameter, as a WHERE key | What it does |
|
|
48
59
|
|---|---|
|
|
49
|
-
| `project_id` |
|
|
50
|
-
| `experience_id` |
|
|
51
|
-
| `starting_step` |
|
|
52
|
-
| `targeting_step` |
|
|
53
|
-
| `num_nodes_after_start` |
|
|
54
|
-
| `num_nodes_before_target` |
|
|
55
|
-
| `top_n_path` |
|
|
56
|
-
| `user_cohort_event` |
|
|
57
|
-
| `client_local_date` |
|
|
58
|
-
| `event_timestamp` |
|
|
59
|
-
|
|
60
|
-
When `num_nodes_after_start` and `num_nodes_before_target
|
|
60
|
+
| `project_id` | The tenant filter. It is necessary. |
|
|
61
|
+
| `experience_id` | Limits the rows to one `fact_events.experience_id`. |
|
|
62
|
+
| `starting_step` | Anchors each edge at the first time that a user reaches this `step_id`. With no value, it anchors at the first `step_enter` event of that user. |
|
|
63
|
+
| `targeting_step` | Trims the window of each user at the first time that the user reaches this `step_id`. A user who never reaches it still gives a journey, up to `num_nodes_after_start`. |
|
|
64
|
+
| `num_nodes_after_start` | The size of the forward window from the start step. This is what card 4129 does. |
|
|
65
|
+
| `num_nodes_before_target` | The size of the backward window from the target step. This is what card 2740 does. It needs `targeting_step`. |
|
|
66
|
+
| `top_n_path` | Keeps the paths with the most users, and drops the rest. |
|
|
67
|
+
| `user_cohort_event` | Limits the rows to a user with at least one `fact_events` row of this `event_type`, such as `'lead_capture'`. Use it for the paths of the users who reached a goal. |
|
|
68
|
+
| `client_local_date` | A filter on the date. It takes `=`, `<`, `<=`, `>`, `>=`, and `BETWEEN`. PickedQL puts it into the `fact_events` read below. |
|
|
69
|
+
| `event_timestamp` | A filter on the timestamp from the server. It takes the same operators as `client_local_date`. |
|
|
70
|
+
|
|
71
|
+
When you set both `num_nodes_after_start` and `num_nodes_before_target`, both tests
|
|
72
|
+
apply. The result is the intersection of the two.
|
|
61
73
|
|
|
62
74
|
```sql
|
|
63
|
-
-- "
|
|
75
|
+
-- The "overall user journey" sankey, as in card 4129.
|
|
76
|
+
-- It uses a forward window. The target step is optional.
|
|
64
77
|
SELECT source, target, users FROM experience_journey
|
|
65
78
|
WHERE project_id = 'your-project-id'
|
|
66
79
|
AND starting_step = 'step-start'
|
|
67
80
|
AND targeting_step = 'step-target'
|
|
68
81
|
AND num_nodes_after_start = 10
|
|
69
|
-
AND client_local_date >= '2026-04-01' -- optional
|
|
82
|
+
AND client_local_date >= '2026-04-01' -- An optional range of dates.
|
|
70
83
|
AND client_local_date <= '2026-04-30'
|
|
71
84
|
```
|
|
72
85
|
|
|
73
86
|
```sql
|
|
74
|
-
-- "
|
|
87
|
+
-- The "paths to a target" sankey, as in card 2740.
|
|
88
|
+
-- It uses a backward window and it ranks the top paths.
|
|
75
89
|
SELECT source, target, users FROM experience_journey
|
|
76
90
|
WHERE project_id = 'your-project-id'
|
|
77
91
|
AND experience_id = 'exp-123'
|
|
@@ -82,7 +96,7 @@ WHERE project_id = 'your-project-id'
|
|
|
82
96
|
```
|
|
83
97
|
|
|
84
98
|
```sql
|
|
85
|
-
-- "
|
|
99
|
+
-- The "drop-off" sankey, as in card 2744. Leave the target step out.
|
|
86
100
|
SELECT source, target, users FROM experience_journey
|
|
87
101
|
WHERE project_id = 'your-project-id'
|
|
88
102
|
AND experience_id = 'exp-123'
|
|
@@ -91,55 +105,63 @@ WHERE project_id = 'your-project-id'
|
|
|
91
105
|
```
|
|
92
106
|
|
|
93
107
|
```sql
|
|
94
|
-
--
|
|
108
|
+
-- A cohort sankey, as in card 3961. It holds the users who reached the goal only.
|
|
95
109
|
SELECT source, target, users FROM experience_journey
|
|
96
110
|
WHERE project_id = 'your-project-id'
|
|
97
111
|
AND starting_step = 'step-start'
|
|
98
112
|
AND targeting_step = 'step-target'
|
|
99
113
|
AND num_nodes_after_start = 10
|
|
100
|
-
AND user_cohort_event = 'lead_capture' --
|
|
114
|
+
AND user_cohort_event = 'lead_capture' -- Users with one or more of these events.
|
|
101
115
|
```
|
|
102
116
|
|
|
103
|
-
|
|
117
|
+
The columns that it returns:
|
|
104
118
|
|
|
105
119
|
| Column | Type | Description |
|
|
106
120
|
|---|---|---|
|
|
107
|
-
| `source` | String |
|
|
108
|
-
| `target` | String |
|
|
109
|
-
| `users` | UInt64 |
|
|
121
|
+
| `source` | String | The start of the edge, in the form `NN. <step title>`, such as `001. Welcome screen`. PickedQL joins `steps` to find the title. |
|
|
122
|
+
| `target` | String | The end of the edge, in the form `NN. <step title>`. |
|
|
123
|
+
| `users` | `UInt64` | The number of different `user_canonical_id` values that went along this edge. |
|
|
110
124
|
|
|
111
125
|
:::note
|
|
112
|
-
`experience_journey`
|
|
126
|
+
`experience_journey` returns data that PickedQL aggregates first. It does **not**
|
|
127
|
+
support a dimension filter such as `variant_type`, `device_category`, or
|
|
128
|
+
`country_code`. To use one of those, query
|
|
129
|
+
[`events`](#events--one-row-for-each-event-of-each-user) directly and build the
|
|
130
|
+
transitions yourself.
|
|
113
131
|
:::
|
|
114
132
|
|
|
115
133
|
## Reference tables — `steps`, `experiences`, `projects`
|
|
116
134
|
|
|
117
|
-
|
|
135
|
+
These reference tables hold the options of your Picked project. They have two uses:
|
|
118
136
|
|
|
119
|
-
- **
|
|
120
|
-
|
|
137
|
+
- **PickedQL joins them onto `events`** when you point at one of their analyst
|
|
138
|
+
columns: `step_title`, `experience_title`, `project_name`, or `project_timezone`.
|
|
139
|
+
- **You can read them directly.** Each one then needs its own tenant filter, so that
|
|
140
|
+
you see only the rows of a project that you can reach.
|
|
121
141
|
|
|
122
|
-
| Source |
|
|
142
|
+
| Source | The tenant filter that it needs |
|
|
123
143
|
|---|---|
|
|
124
144
|
| `steps` | `WHERE project_id = '<project_id>'` |
|
|
125
145
|
| `experiences` | `WHERE project_id = '<project_id>'` |
|
|
126
146
|
| `projects` | `WHERE id = '<project_id>'` |
|
|
127
147
|
|
|
128
148
|
```sql
|
|
129
|
-
--
|
|
149
|
+
-- A direct query that reads the experiences of a project.
|
|
130
150
|
SELECT id, title FROM experiences WHERE project_id = 'your-project-id'
|
|
131
151
|
|
|
132
|
-
--
|
|
152
|
+
-- A direct query that reads the metadata of one project.
|
|
133
153
|
SELECT id, name, timezone FROM projects WHERE id = 'your-project-id'
|
|
134
154
|
```
|
|
135
155
|
|
|
136
156
|
```sql
|
|
137
|
-
--
|
|
138
|
-
--
|
|
157
|
+
-- Pointed at from events. PickedQL adds each LEFT JOIN for you.
|
|
158
|
+
-- The reference tables need no separate tenant filter, because
|
|
159
|
+
-- the event table already limits the join.
|
|
139
160
|
SELECT experience_title, step_title, count(*)
|
|
140
161
|
FROM events
|
|
141
162
|
WHERE project_id = 'your-project-id'
|
|
142
163
|
GROUP BY experience_title, step_title
|
|
143
164
|
```
|
|
144
165
|
|
|
145
|
-
See [Schema
|
|
166
|
+
See [Schema, reference tables](./schema#steps-experiences-projects) for the full
|
|
167
|
+
column list and the join keys.
|
|
@@ -4,9 +4,11 @@ layout: docs
|
|
|
4
4
|
|
|
5
5
|
# Dimension columns
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
Every data source has dimension columns. The `metrics` table holds them directly. On
|
|
8
|
+
`events` and on `features`, PickedQL adds the `LEFT JOIN` that it needs when you
|
|
9
|
+
point at one. You write no join.
|
|
8
10
|
|
|
9
|
-
##
|
|
11
|
+
## The dimensions
|
|
10
12
|
|
|
11
13
|
| Source | Columns |
|
|
12
14
|
|---|---|
|
|
@@ -19,29 +21,42 @@ Dimension columns are available on all data sources. On `metrics`, they are incl
|
|
|
19
21
|
| `experiences` | `experience_title` |
|
|
20
22
|
| `projects` | `project_name`, `project_timezone` |
|
|
21
23
|
|
|
22
|
-
The `steps`, `experiences`, and `projects` sources are reference tables
|
|
24
|
+
The `steps`, `experiences`, and `projects` sources are reference tables, and they come
|
|
25
|
+
from the operational database. PickedQL joins them onto `events` and `fact_events`
|
|
26
|
+
when you point at one of their analyst-facing columns. Each one **also** needs its own
|
|
27
|
+
tenant filter when you query it directly:
|
|
23
28
|
|
|
24
|
-
| Source |
|
|
29
|
+
| Source | The tenant filter that it needs |
|
|
25
30
|
|---|---|
|
|
26
31
|
| `steps`, `experiences` | `WHERE project_id = '<project_id>'` |
|
|
27
|
-
| `projects` | `WHERE id = '<project_id>'
|
|
32
|
+
| `projects` | `WHERE id = '<project_id>'`, because the `id` of the row is the project ID |
|
|
28
33
|
|
|
29
|
-
|
|
34
|
+
PickedQL also puts a tenant equality in the `ON` clause of each join that it adds.
|
|
35
|
+
Examples are `AND st.project_id = '<project_id>'` and `AND pr.id = '<project_id>'`.
|
|
36
|
+
ClickHouse then reads part of the dimension table and not all of it. PickedQL puts
|
|
37
|
+
the test in `ON` and not in `WHERE`, because a test in `WHERE` would change a
|
|
38
|
+
`LEFT JOIN` into an inner join.
|
|
30
39
|
|
|
31
|
-
|
|
40
|
+
Each analyst-facing column name carries a prefix, such as `step_title` and
|
|
41
|
+
`project_name`. The prefix stops a collision between two sources. Both `steps.title`
|
|
42
|
+
and `experiences.title` are there, and you point at them as `step_title` and
|
|
43
|
+
`experience_title`.
|
|
32
44
|
|
|
33
45
|
```sql
|
|
34
|
-
-- Group events by experience and step name
|
|
46
|
+
-- Group the events by experience and by step name.
|
|
47
|
+
-- PickedQL joins both `experiences` and `steps` for you.
|
|
35
48
|
SELECT experience_title, step_title, count(*)
|
|
36
49
|
FROM events
|
|
37
50
|
WHERE project_id = 'your-project-id'
|
|
38
51
|
GROUP BY experience_title, step_title
|
|
39
52
|
```
|
|
40
53
|
|
|
41
|
-
|
|
54
|
+
An automatic join also works inside a subquery and inside a common table expression.
|
|
55
|
+
Point at a dimension column where you need it, and PickedQL adds the `LEFT JOIN` at
|
|
56
|
+
that level:
|
|
42
57
|
|
|
43
58
|
```sql
|
|
44
|
-
-- Dimension columns inside a
|
|
59
|
+
-- Dimension columns inside a common table expression.
|
|
45
60
|
WITH per_step AS (
|
|
46
61
|
SELECT step_title, count(*) AS n
|
|
47
62
|
FROM events
|
|
@@ -50,7 +65,7 @@ WITH per_step AS (
|
|
|
50
65
|
)
|
|
51
66
|
SELECT * FROM per_step ORDER BY n DESC
|
|
52
67
|
|
|
53
|
-
-- Dimension columns inside a nested
|
|
68
|
+
-- Dimension columns inside a nested query.
|
|
54
69
|
SELECT step_title, n FROM (
|
|
55
70
|
SELECT step_title, count(*) AS n FROM events
|
|
56
71
|
WHERE project_id = 'your-project-id'
|
|
@@ -60,6 +75,6 @@ SELECT step_title, n FROM (
|
|
|
60
75
|
|
|
61
76
|
## Native event columns
|
|
62
77
|
|
|
63
|
-
These columns are
|
|
78
|
+
These columns are on `events` directly, and they need no join:
|
|
64
79
|
|
|
65
80
|
`event_type`, `interaction_type`, `experience_id`, `step_id`, `event_id`, `user_canonical_id`, `session_id`, `client_local_date`, `is_purchase`, `is_cart_add`, `event_meta`.
|
|
@@ -51,7 +51,9 @@ ORDER BY project_local_date
|
|
|
51
51
|
|
|
52
52
|
## Custom conversion rate definition
|
|
53
53
|
|
|
54
|
-
Override the default
|
|
54
|
+
Override the default conversion, which counts a `purchase` event, with your own
|
|
55
|
+
numerator and denominator. Use this when a form submission, a lead capture, or
|
|
56
|
+
another event of your own defines a conversion.
|
|
55
57
|
|
|
56
58
|
```sql
|
|
57
59
|
-- Lead capture conversion: form submissions / lead-capture step entries
|
|
@@ -75,7 +77,7 @@ ORDER BY project_local_date
|
|
|
75
77
|
You can also combine multiple events with `OR` and group with parentheses:
|
|
76
78
|
|
|
77
79
|
```sql
|
|
78
|
-
--
|
|
80
|
+
-- A `checkout_complete` event or an `order_create` event counts as a conversion.
|
|
79
81
|
SELECT
|
|
80
82
|
control_conversion_rate(
|
|
81
83
|
'event_type=checkout_complete OR event_type=order_create'
|
|
@@ -87,12 +89,15 @@ FROM events
|
|
|
87
89
|
WHERE project_id = '{{ your project ID }}'
|
|
88
90
|
```
|
|
89
91
|
|
|
90
|
-
##
|
|
92
|
+
## Your own segment with `control_users` and `variant_users`
|
|
91
93
|
|
|
92
|
-
On `events`,
|
|
94
|
+
On `events`, four functions take an optional filter string: `control_users`,
|
|
95
|
+
`variant_users`, `control_sessions`, and `variant_sessions`. The filter counts only a
|
|
96
|
+
user or a session that matches your expression. It applies together with the
|
|
97
|
+
`variant_type` filter that PickedQL adds.
|
|
93
98
|
|
|
94
99
|
```sql
|
|
95
|
-
--
|
|
100
|
+
-- The control users who fired an `app_initialize` event, by step.
|
|
96
101
|
SELECT
|
|
97
102
|
step_id,
|
|
98
103
|
control_users('event_type=app_initialize') AS control_initialized,
|
|
@@ -113,10 +118,13 @@ WHERE project_id = '{{ your project ID }}'
|
|
|
113
118
|
|
|
114
119
|
## Conversion rate from nested virtual functions
|
|
115
120
|
|
|
116
|
-
|
|
121
|
+
The numerator and the denominator can come from different segments. An example is the
|
|
122
|
+
control users who fired an event of your own, divided by **all** users and not by the
|
|
123
|
+
control users alone. For that, pass a virtual function call directly as an argument
|
|
124
|
+
of the conversion rate:
|
|
117
125
|
|
|
118
126
|
```sql
|
|
119
|
-
--
|
|
127
|
+
-- The control users who fired `app_initialize`, over all users of every variant.
|
|
120
128
|
SELECT
|
|
121
129
|
control_conversion_rate(
|
|
122
130
|
control_users('event_type=app_initialize'),
|
|
@@ -188,9 +196,9 @@ GROUP BY utm_source
|
|
|
188
196
|
|
|
189
197
|
| utm_source | users | purchasers |
|
|
190
198
|
| ---------- | ------ | ---------- |
|
|
191
|
-
| meta | 12031 | 101 |
|
|
192
|
-
| fb | 3656 | 31 |
|
|
193
|
-
| an | 100366 | 299 |
|
|
199
|
+
| `meta` | 12031 | 101 |
|
|
200
|
+
| `fb` | 3656 | 31 |
|
|
201
|
+
| `an` | 100366 | 299 |
|
|
194
202
|
|
|
195
203
|
## Step funnel for variant users
|
|
196
204
|
|
|
@@ -211,18 +219,20 @@ ORDER BY variant DESC
|
|
|
211
219
|
|
|
212
220
|
| step_id | variant |
|
|
213
221
|
| ------------------------------ | ------- |
|
|
214
|
-
| who-are-you-protecting-step | 1093 |
|
|
215
|
-
| about-yourself-step | 533 |
|
|
216
|
-
| date-of-birth-step | 435 |
|
|
217
|
-
| employment-status-step | 408 |
|
|
218
|
-
| nicotine-usage-step | 407 |
|
|
219
|
-
| coverage-motivation-step | 405 |
|
|
220
|
-
| lead-capture-step | 398 |
|
|
222
|
+
| `who-are-you-protecting-step` | 1093 |
|
|
223
|
+
| `about-yourself-step` | 533 |
|
|
224
|
+
| `date-of-birth-step` | 435 |
|
|
225
|
+
| `employment-status-step` | 408 |
|
|
226
|
+
| `nicotine-usage-step` | 407 |
|
|
227
|
+
| `coverage-motivation-step` | 405 |
|
|
228
|
+
| `lead-capture-step` | 398 |
|
|
221
229
|
|
|
222
230
|
|
|
223
231
|
## Sankey — overall user journey
|
|
224
232
|
|
|
225
|
-
|
|
233
|
+
A forward window from the starting step. A user who never reaches `targeting_step`
|
|
234
|
+
still gives edges, up to `num_nodes_after_start`. This does what card 4129 on
|
|
235
|
+
dashboard 1156 does.
|
|
226
236
|
|
|
227
237
|
```sql
|
|
228
238
|
SELECT source, target, users FROM experience_journey
|
|
@@ -236,13 +246,15 @@ WHERE project_id = '{{ your project ID }}'
|
|
|
236
246
|
|
|
237
247
|
| source | target | users |
|
|
238
248
|
| ------------------------- | ------------------------- | ----- |
|
|
239
|
-
| 001. step-start | 002. step-questionnaire-1 | 182 |
|
|
240
|
-
| 002. step-questionnaire-1 | 003. step-quote | 144 |
|
|
241
|
-
| 003. step-quote | 004. step-target | 121 |
|
|
249
|
+
| `001. step-start` | `002. step-questionnaire-1` | 182 |
|
|
250
|
+
| `002. step-questionnaire-1` | `003. step-quote` | 144 |
|
|
251
|
+
| `003. step-quote` | `004. step-target` | 121 |
|
|
242
252
|
|
|
243
|
-
## Sankey — top paths
|
|
253
|
+
## Sankey — the top paths to a target step
|
|
244
254
|
|
|
245
|
-
|
|
255
|
+
A backward window anchored at the target. It also ranks the paths and keeps the ones
|
|
256
|
+
with the most users. This does what card 3961 on dashboard 1156 and card 2740 on
|
|
257
|
+
dashboard 991 do.
|
|
246
258
|
|
|
247
259
|
```sql
|
|
248
260
|
SELECT source, target, users FROM experience_journey
|
|
@@ -284,6 +296,6 @@ WHERE project_id = '{{ your project ID }}'
|
|
|
284
296
|
|
|
285
297
|
| device_category | user_canonical_id |
|
|
286
298
|
| --------------- | ------------------------------------ |
|
|
287
|
-
| Mobile | 019cc336-5a6a-7c32-b638-cdcc983b3e70 |
|
|
288
|
-
| Mobile | 019cc336-5a6a-7d8f-994c-69bc28e5f550 |
|
|
289
|
-
| Mobile | 019cc80f-503c-7181-b2c6-986b1f76d496 |
|
|
299
|
+
| Mobile | `019cc336-5a6a-7c32-b638-cdcc983b3e70` |
|
|
300
|
+
| Mobile | `019cc336-5a6a-7d8f-994c-69bc28e5f550` |
|
|
301
|
+
| Mobile | `019cc80f-503c-7181-b2c6-986b1f76d496` |
|
|
@@ -2,17 +2,19 @@
|
|
|
2
2
|
layout: docs
|
|
3
3
|
---
|
|
4
4
|
|
|
5
|
-
#
|
|
5
|
+
# Filters
|
|
6
6
|
|
|
7
|
-
Add `WHERE`
|
|
7
|
+
Add a `WHERE` clause in the usual way. Every query must hold a `project_id` filter.
|
|
8
|
+
PickedQL reads that filter and checks that you have permission for the project.
|
|
9
|
+
PickedQL rejects a query with no `project_id` filter.
|
|
8
10
|
|
|
9
11
|
```sql
|
|
10
|
-
--
|
|
12
|
+
-- A range of dates.
|
|
11
13
|
SELECT control_users() FROM metrics
|
|
12
14
|
WHERE project_id = 'your-project-id'
|
|
13
15
|
AND project_local_date BETWEEN '2026-03-01' AND '2026-03-31'
|
|
14
16
|
|
|
15
|
-
-- By experience
|
|
17
|
+
-- By experience.
|
|
16
18
|
SELECT step_enter_users() FROM events
|
|
17
19
|
WHERE project_id = 'your-project-id'
|
|
18
20
|
AND experience_id = 'my-experience'
|
|
@@ -30,9 +32,11 @@ WHERE project_id = 'your-project-id'
|
|
|
30
32
|
Each query can only filter on a single `project_id`. Queries that reference multiple projects will be rejected.
|
|
31
33
|
:::
|
|
32
34
|
|
|
33
|
-
## Reference tables
|
|
35
|
+
## Reference tables, each with its own tenant filter
|
|
34
36
|
|
|
35
|
-
|
|
37
|
+
A query against a reference table needs its own tenant filter. The reference tables
|
|
38
|
+
are `steps`, `experiences`, and `projects`. The filter makes sure that you see only
|
|
39
|
+
the rows of a project that you can reach:
|
|
36
40
|
|
|
37
41
|
| Source | Tenant filter |
|
|
38
42
|
|---|---|
|