@picked/client 0.0.56-next.1 → 0.0.56-next.2
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/{api-CNxyQeRM.js → api-DHSz_ruC.js} +1 -1
- package/dist/{api-CtE-gT1L.cjs → api-DVSjNleu.cjs} +1 -1
- package/dist/cjs/index.js +1 -1
- package/dist/cjs/plugins/dynamic-experiences/index.js +1 -1
- package/dist/docs/actions.md +58 -0
- package/dist/docs/api/index.md +32 -0
- package/dist/docs/api-keys.md +33 -0
- package/dist/docs/conditions.md +52 -0
- package/dist/docs/experiences.md +33 -0
- package/dist/docs/features.md +51 -0
- package/dist/docs/fields.md +70 -0
- package/dist/docs/flow-builder/building-flows.md +61 -0
- package/dist/docs/flow-builder/condition-builder.md +54 -0
- package/dist/docs/flow-builder/keyboard-shortcuts.md +66 -0
- package/dist/docs/flow-builder/nodes.md +43 -0
- package/dist/docs/flow-builder/overview.md +43 -0
- package/dist/docs/index.md +79 -0
- package/dist/docs/pickedql/data-sources.md +39 -0
- package/dist/docs/pickedql/dimensions.md +23 -0
- package/dist/docs/pickedql/examples.md +165 -0
- package/dist/docs/pickedql/filtering.md +31 -0
- package/dist/docs/pickedql/index.md +34 -0
- package/dist/docs/pickedql/schema.md +95 -0
- package/dist/docs/pickedql/virtual-functions.md +84 -0
- package/dist/docs/projects.md +30 -0
- package/dist/docs/reference/index.md +11 -0
- package/dist/docs/reports.md +11 -0
- package/dist/docs/sdk/actions.md +7 -0
- package/dist/docs/sdk/conditions.md +131 -0
- package/dist/docs/sdk/content-security-policy.md +31 -0
- package/dist/docs/sdk/experiences.md +41 -0
- package/dist/docs/sdk/features.md +213 -0
- package/dist/docs/sdk/fields.md +263 -0
- package/dist/docs/sdk/index.md +74 -0
- package/dist/docs/sdk/plugins/create-experience.md +133 -0
- package/dist/docs/sdk/plugins/dynamic-experiences.md +59 -0
- package/dist/docs/sdk/plugins/index.md +9 -0
- package/dist/docs/sdk/plugins/window-object.md +20 -0
- package/dist/docs/sdk/predicates.md +113 -0
- package/dist/docs/sdk/steps.md +411 -0
- package/dist/docs/steps.md +35 -0
- package/dist/docs/team-management.md +40 -0
- package/dist/docs/tooling/chrome-extension.md +29 -0
- package/dist/docs/tooling/gtm-template.md +69 -0
- package/dist/docs/tooling/index.md +19 -0
- package/dist/docs/tooling/mcp.md +120 -0
- package/dist/docs/tooling/vite-plugin.md +82 -0
- package/dist/docs/workspaces.md +35 -0
- package/dist/esm/index.js +1 -1
- package/dist/esm/plugins/dynamic-experiences/index.js +1 -1
- package/package.json +2 -2
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
---
|
|
2
|
+
layout: docs
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
# Keyboard shortcuts
|
|
6
|
+
|
|
7
|
+
These shortcuts are available when the flow builder canvas is focused.
|
|
8
|
+
|
|
9
|
+
## Canvas tools
|
|
10
|
+
|
|
11
|
+
| Shortcut (Mac) | Shortcut (PC) | Action |
|
|
12
|
+
| --- | --- | --- |
|
|
13
|
+
| `V` | `V` | Select tool |
|
|
14
|
+
| `H` | `H` | Hand tool (pan) |
|
|
15
|
+
| `Space` (hold) | `Space` (hold) | Temporary hand tool |
|
|
16
|
+
|
|
17
|
+
## Layout
|
|
18
|
+
|
|
19
|
+
| Shortcut (Mac) | Shortcut (PC) | Action |
|
|
20
|
+
| --- | --- | --- |
|
|
21
|
+
| `Shift+L` | `Shift+L` | Auto-layout |
|
|
22
|
+
|
|
23
|
+
## Selection
|
|
24
|
+
|
|
25
|
+
| Shortcut (Mac) | Shortcut (PC) | Action |
|
|
26
|
+
| --- | --- | --- |
|
|
27
|
+
| `Cmd+A` | `Ctrl+A` | Select all nodes |
|
|
28
|
+
| `Escape` | `Escape` | Deselect all |
|
|
29
|
+
|
|
30
|
+
## Editing
|
|
31
|
+
|
|
32
|
+
| Shortcut (Mac) | Shortcut (PC) | Action |
|
|
33
|
+
| --- | --- | --- |
|
|
34
|
+
| `Cmd+D` | `Ctrl+D` | Duplicate selected nodes |
|
|
35
|
+
| `Delete` / `Backspace` | `Delete` / `Backspace` | Delete selected nodes |
|
|
36
|
+
| `Cmd+Z` | `Ctrl+Z` | Undo |
|
|
37
|
+
| `Cmd+Shift+Z` | `Ctrl+Shift+Z` | Redo |
|
|
38
|
+
|
|
39
|
+
## Movement
|
|
40
|
+
|
|
41
|
+
| Shortcut (Mac) | Shortcut (PC) | Action |
|
|
42
|
+
| --- | --- | --- |
|
|
43
|
+
| Arrow keys | Arrow keys | Nudge selected nodes |
|
|
44
|
+
| `Shift`+Arrow keys | `Shift`+Arrow keys | Large nudge |
|
|
45
|
+
|
|
46
|
+
## Zoom
|
|
47
|
+
|
|
48
|
+
| Shortcut (Mac) | Shortcut (PC) | Action |
|
|
49
|
+
| --- | --- | --- |
|
|
50
|
+
| Scroll | Scroll | Zoom in/out |
|
|
51
|
+
| Pinch | Pinch | Zoom in/out (trackpad) |
|
|
52
|
+
| `Cmd+=` | `Ctrl+=` | Zoom in |
|
|
53
|
+
| `Cmd+-` | `Ctrl+-` | Zoom out |
|
|
54
|
+
| `Shift+1` | `Shift+1` | Fit view |
|
|
55
|
+
| `Shift+0` | `Shift+0` | Zoom to 100% |
|
|
56
|
+
|
|
57
|
+
## Panels
|
|
58
|
+
|
|
59
|
+
| Shortcut (Mac) | Shortcut (PC) | Action |
|
|
60
|
+
| --- | --- | --- |
|
|
61
|
+
| `Cmd+\` | `Ctrl+\` | Toggle both side panels |
|
|
62
|
+
| `?` | `?` | Toggle shortcuts |
|
|
63
|
+
|
|
64
|
+
---
|
|
65
|
+
|
|
66
|
+
[Overview](/flow-builder/overview) · [Nodes](/flow-builder/nodes) · [Building Flows](/flow-builder/building-flows) · **Keyboard Shortcuts** · [Condition Builder](/flow-builder/condition-builder)
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
---
|
|
2
|
+
layout: docs
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
# Nodes
|
|
6
|
+
|
|
7
|
+
Nodes are the building blocks of a flow. Each node represents a block in your experience. There are four node types.
|
|
8
|
+
|
|
9
|
+
## Origin
|
|
10
|
+
|
|
11
|
+
Every flow starts with an origin node. It's a gray circle on the left side of the canvas. It has one output handle on its right side.
|
|
12
|
+
|
|
13
|
+
You can't move, delete, or duplicate the origin. It's always present.
|
|
14
|
+
|
|
15
|
+
## Step
|
|
16
|
+
|
|
17
|
+
A step node represents a screen shown to visitors. It appears as a blue rectangle on the canvas.
|
|
18
|
+
|
|
19
|
+
Steps hold fields. Drag a field from the entity browser onto a step node to assign it. The node subtitle shows how many fields are assigned.
|
|
20
|
+
|
|
21
|
+
Each step has a `layoutName` that tells the SDK which visual layout to use when rendering this step. Configure the layout name in the inspector.
|
|
22
|
+
|
|
23
|
+
## Action
|
|
24
|
+
|
|
25
|
+
An action node represents a side effect — something that happens behind the scenes. It appears as a green rectangle.
|
|
26
|
+
|
|
27
|
+
Actions trigger when the flow reaches them. Use actions for tasks like tracking events, sending data, or triggering integrations.
|
|
28
|
+
|
|
29
|
+
## Condition
|
|
30
|
+
|
|
31
|
+
A condition node represents a branching point. It appears as an amber rectangle.
|
|
32
|
+
|
|
33
|
+
Condition nodes have two output handles instead of one. The green handle (top-right) connects to the path taken when the condition is true. The red handle (bottom-right) connects to the path taken when it's false.
|
|
34
|
+
|
|
35
|
+
Define the condition logic in the inspector using the visual condition builder. See [Conditions](/conditions) for details.
|
|
36
|
+
|
|
37
|
+
## Handles
|
|
38
|
+
|
|
39
|
+
Handles are the connection points on nodes. Input handles sit on the left. Output handles sit on the right. Drag from an output handle to an input handle to connect two nodes.
|
|
40
|
+
|
|
41
|
+
---
|
|
42
|
+
|
|
43
|
+
[Overview](/flow-builder/overview) · **Nodes** · [Building Flows](/flow-builder/building-flows) · [Keyboard Shortcuts](/flow-builder/keyboard-shortcuts) · [Condition Builder](/flow-builder/condition-builder)
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
---
|
|
2
|
+
layout: docs
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
# Flow builder
|
|
6
|
+
|
|
7
|
+
The flow builder is a visual editor for designing experience flows. You drag blocks onto a canvas, connect them with arrows, and configure each node in an inspector panel.
|
|
8
|
+
|
|
9
|
+
## Layout
|
|
10
|
+
|
|
11
|
+
The flow builder has three panels arranged left to right.
|
|
12
|
+
|
|
13
|
+
**Entity browser** (left): Lists all steps, actions, conditions, and fields in your project. Drag items from here onto the canvas.
|
|
14
|
+
|
|
15
|
+
**Canvas** (center): The workspace where you build your flow. Nodes represent blocks. Arrows represent connections between them.
|
|
16
|
+
|
|
17
|
+
**Inspector** (right): Shows configuration for the selected node. When nothing is selected, it shows experience-level settings.
|
|
18
|
+
|
|
19
|
+
## Panel controls
|
|
20
|
+
|
|
21
|
+
Drag the dividers between panels to resize them. Press `Cmd/Ctrl+\` to toggle both side panels. Press `Cmd/Ctrl+Shift+\` to toggle just the inspector.
|
|
22
|
+
|
|
23
|
+
## Navigating the canvas
|
|
24
|
+
|
|
25
|
+
**Zoom**: Scroll to zoom in and out.
|
|
26
|
+
|
|
27
|
+
**Pan**: Select the hand tool (press `H`) and drag. Or hold `Space` while dragging. Middle-click drag also pans.
|
|
28
|
+
|
|
29
|
+
**Select tool**: Press `V` to switch back to the select tool. This is the default — click to select nodes, drag on empty space to marquee-select.
|
|
30
|
+
|
|
31
|
+
## Auto-layout
|
|
32
|
+
|
|
33
|
+
Click the auto-layout button in the toolbar to automatically arrange all nodes in a clean hierarchy. Useful after adding many nodes or when the canvas gets messy.
|
|
34
|
+
|
|
35
|
+
## Saving
|
|
36
|
+
|
|
37
|
+
Click **Save** in the toolbar to save your flow. The button is enabled when you have unsaved changes.
|
|
38
|
+
|
|
39
|
+
The flow builder also auto-saves after a period of inactivity. A dot indicator appears on the save button when there are unsaved changes.
|
|
40
|
+
|
|
41
|
+
---
|
|
42
|
+
|
|
43
|
+
**Flow Builder** · [Nodes](/flow-builder/nodes) · [Building Flows](/flow-builder/building-flows) · [Keyboard Shortcuts](/flow-builder/keyboard-shortcuts) · [Condition Builder](/flow-builder/condition-builder)
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
---
|
|
2
|
+
layout: docs
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
# Getting Started
|
|
6
|
+
|
|
7
|
+
Picked lets you build personalized UI flows in a visual editor and deliver them to visitors on your site with a lightweight SDK.
|
|
8
|
+
|
|
9
|
+
## How it works
|
|
10
|
+
|
|
11
|
+
You design experiences in the dashboard using a drag-and-drop flow builder. The SDK fetches your published experiences and renders them on your site.
|
|
12
|
+
|
|
13
|
+
## Quick start
|
|
14
|
+
|
|
15
|
+
### 1. Create a project
|
|
16
|
+
|
|
17
|
+
Sign in to the dashboard and create a project. A project represents one website or app.
|
|
18
|
+
|
|
19
|
+
See [Projects](/projects) for details.
|
|
20
|
+
|
|
21
|
+
### 2. Install the SDK
|
|
22
|
+
|
|
23
|
+
Add the SDK to your site and initialize the client. Copy the snippet from your project home page.
|
|
24
|
+
|
|
25
|
+
```typescript
|
|
26
|
+
import { createClient } from '@picked/client'
|
|
27
|
+
|
|
28
|
+
const picked = createClient({
|
|
29
|
+
organizationId: 'your-organization-id',
|
|
30
|
+
projectId: 'your-project-id',
|
|
31
|
+
plugins: [],
|
|
32
|
+
})
|
|
33
|
+
|
|
34
|
+
picked.start()
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
See [SDK Installation](/sdk) for full setup options.
|
|
38
|
+
|
|
39
|
+
### 3. Register a component
|
|
40
|
+
|
|
41
|
+
Register components when creating the client. Each key in the `components` object must match a component name you set in the dashboard.
|
|
42
|
+
|
|
43
|
+
```typescript
|
|
44
|
+
import { createClient } from '@picked/client'
|
|
45
|
+
|
|
46
|
+
const picked = createClient({
|
|
47
|
+
organizationId: 'your-organization-id',
|
|
48
|
+
projectId: 'your-project-id',
|
|
49
|
+
components: {
|
|
50
|
+
'welcome-survey': YourComponent,
|
|
51
|
+
},
|
|
52
|
+
})
|
|
53
|
+
|
|
54
|
+
picked.start()
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
See [SDK Experiences](/sdk/experiences) for targeting, conditions, and component adapters.
|
|
58
|
+
|
|
59
|
+
### 4. Create an experience
|
|
60
|
+
|
|
61
|
+
In the dashboard, open your project and click **Experiences** > **New Experience**. Enter a name and set the component name to match your registered component (e.g., `welcome-survey`).
|
|
62
|
+
|
|
63
|
+
See [Experiences](/experiences) for configuration options.
|
|
64
|
+
|
|
65
|
+
### 5. Build the flow
|
|
66
|
+
|
|
67
|
+
Open the flow builder and drag steps, actions, and conditions onto the canvas. Connect nodes to define the visitor's path through the experience.
|
|
68
|
+
|
|
69
|
+
See [Flow Builder](/flow-builder/overview) for a full walkthrough.
|
|
70
|
+
|
|
71
|
+
### 6. Save and publish
|
|
72
|
+
|
|
73
|
+
Click **Save** in the flow builder toolbar. The SDK picks up the published experience and renders it to matching visitors on your site.
|
|
74
|
+
|
|
75
|
+
## Next steps
|
|
76
|
+
|
|
77
|
+
- [Flow Builder](/flow-builder/overview) — Build experience flows visually
|
|
78
|
+
- [Steps](/steps), [Fields](/fields), [Actions](/actions), [Conditions](/conditions) — Configure the building blocks of experiences
|
|
79
|
+
- [SDK Installation](/sdk) — Full SDK setup and configuration
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
---
|
|
2
|
+
layout: docs
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
# Data sources
|
|
6
|
+
|
|
7
|
+
PickedQL provides three virtual tables, each optimized for different query patterns.
|
|
8
|
+
|
|
9
|
+
## `metrics` — Pre-aggregated daily data
|
|
10
|
+
|
|
11
|
+
Best for dashboards and trend analysis. One row per unique combination of dimensions per day. Dimension columns (like `device_category`, `country_code`, `utm_source`) are available directly — no joins needed.
|
|
12
|
+
|
|
13
|
+
```sql
|
|
14
|
+
SELECT device_category, control_users(), variant_users()
|
|
15
|
+
FROM metrics
|
|
16
|
+
WHERE project_id = 'your-project-id'
|
|
17
|
+
GROUP BY device_category
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
## `events` — User-level event data
|
|
21
|
+
|
|
22
|
+
Best for deep analysis, funnels, and custom breakdowns. One row per event per user. Dimension columns (like `device_category` or `country_code`) are joined automatically when referenced.
|
|
23
|
+
|
|
24
|
+
```sql
|
|
25
|
+
SELECT user_canonical_id, device_category
|
|
26
|
+
FROM events
|
|
27
|
+
WHERE project_id = 'your-project-id'
|
|
28
|
+
AND variant_type = 'Control'
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
## `features` — Feature flag analysis
|
|
32
|
+
|
|
33
|
+
Best for querying user, session, and event counts per feature flag and bucket. Uses parameterized functions.
|
|
34
|
+
|
|
35
|
+
```sql
|
|
36
|
+
SELECT feature_users('homepage_test', 'control')
|
|
37
|
+
FROM features
|
|
38
|
+
WHERE project_id = 'your-project-id'
|
|
39
|
+
```
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
---
|
|
2
|
+
layout: docs
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
# Dimension columns
|
|
6
|
+
|
|
7
|
+
Dimension columns are available on all data sources. On `metrics`, they are included directly in the table. On `events` and `features`, the required `LEFT JOIN` is added automatically when you reference them — you never write joins yourself.
|
|
8
|
+
|
|
9
|
+
## Available dimensions
|
|
10
|
+
|
|
11
|
+
| Source | Columns |
|
|
12
|
+
|---|---|
|
|
13
|
+
| `dim_variant` | `variant_type`, `ab_feature_name`, `ab_feature_value` |
|
|
14
|
+
| `dim_device` | `device_category`, `browser_name`, `browser_version`, `os_name`, `os_version`, `platform` |
|
|
15
|
+
| `dim_geo` | `country_code`, `country_name`, `region`, `city` |
|
|
16
|
+
| `dim_utm` | `utm_source`, `utm_medium`, `utm_campaign`, `utm_term`, `utm_content` |
|
|
17
|
+
| `dim_product` | `product_name`, `product_category`, `product_page` |
|
|
18
|
+
|
|
19
|
+
## Native event columns
|
|
20
|
+
|
|
21
|
+
These columns are available directly on `events` and require no join:
|
|
22
|
+
|
|
23
|
+
`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`.
|
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
---
|
|
2
|
+
layout: docs
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
# Example queries
|
|
6
|
+
|
|
7
|
+
## Daily A/B test trend
|
|
8
|
+
|
|
9
|
+
```sql
|
|
10
|
+
SELECT
|
|
11
|
+
project_local_date,
|
|
12
|
+
control_users() AS control,
|
|
13
|
+
variant_users() AS variant
|
|
14
|
+
FROM metrics
|
|
15
|
+
WHERE project_id = '{{ your project ID }}'
|
|
16
|
+
AND project_local_date >= '2026-04-01'
|
|
17
|
+
GROUP BY project_local_date
|
|
18
|
+
ORDER BY project_local_date
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
**Result:**
|
|
22
|
+
|
|
23
|
+
| project_local_date | control | variant |
|
|
24
|
+
| ----------------- | ------- | ------- |
|
|
25
|
+
| 2026-04-11 | 4361 | 101 |
|
|
26
|
+
| 2026-04-12 | 4178 | 126 |
|
|
27
|
+
| 2026-04-13 | 5008 | 176 |
|
|
28
|
+
|
|
29
|
+
## Conversion rate uplift by date
|
|
30
|
+
|
|
31
|
+
```sql
|
|
32
|
+
SELECT
|
|
33
|
+
project_local_date,
|
|
34
|
+
control_conversion_rate() AS control_conversion_rate,
|
|
35
|
+
variant_conversion_rate() AS variant_conversion_rate,
|
|
36
|
+
conversion_rate_uplift() AS conversion_rate_uplift_pct
|
|
37
|
+
FROM metrics
|
|
38
|
+
WHERE project_id = '{{ your project ID }}'
|
|
39
|
+
AND project_local_date >= '2026-04-01'
|
|
40
|
+
GROUP BY project_local_date
|
|
41
|
+
ORDER BY project_local_date
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
**Result:**
|
|
45
|
+
|
|
46
|
+
| project_local_date | control_conversion_rate | variant_conversion_rate | conversion_rate_uplift_pct |
|
|
47
|
+
| ----------------- | ----------------------- | ----------------------- | -------------------------- |
|
|
48
|
+
| 2026-04-01 | 0.0322 | 0.0349 | 0.0349 |
|
|
49
|
+
| 2026-04-02 | 0.0398 | 0.0416 | 0.0416 |
|
|
50
|
+
| 2026-04-03 | 0.0462 | 0 | -0.0001 |
|
|
51
|
+
|
|
52
|
+
## A/B test by device
|
|
53
|
+
|
|
54
|
+
```sql
|
|
55
|
+
SELECT
|
|
56
|
+
device_category,
|
|
57
|
+
control_users() AS control,
|
|
58
|
+
variant_users() AS variant
|
|
59
|
+
FROM metrics
|
|
60
|
+
WHERE project_id = '{{ your project ID }}'
|
|
61
|
+
GROUP BY device_category
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
**Result:**
|
|
65
|
+
|
|
66
|
+
| device_category | control | variant |
|
|
67
|
+
| --------------- | ------- | ------- |
|
|
68
|
+
| Phone | 193430 | 1723 |
|
|
69
|
+
| Desktop | 23423 | 309 |
|
|
70
|
+
| Tablet | 13294 | 65 |
|
|
71
|
+
|
|
72
|
+
## Daily A/B test trend by device
|
|
73
|
+
|
|
74
|
+
Combine date and device dimensions to spot device-specific trends:
|
|
75
|
+
|
|
76
|
+
```sql
|
|
77
|
+
SELECT
|
|
78
|
+
project_local_date,
|
|
79
|
+
device_category,
|
|
80
|
+
control_users() AS control,
|
|
81
|
+
variant_users() AS variant
|
|
82
|
+
FROM metrics
|
|
83
|
+
WHERE project_id = '{{ your project ID }}'
|
|
84
|
+
AND project_local_date >= '2026-04-01'
|
|
85
|
+
GROUP BY project_local_date, device_category
|
|
86
|
+
ORDER BY project_local_date, device_category
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
**Result:**
|
|
90
|
+
|
|
91
|
+
| project_local_date | device_category | control | variant |
|
|
92
|
+
| ----------------- | --------------- | ------- | ------- |
|
|
93
|
+
| 2026-04-13 | Tablet | 175 | 2 |
|
|
94
|
+
| 2026-04-14 | Desktop | 37 | 1 |
|
|
95
|
+
| 2026-04-14 | Phone | 244 | 1 |
|
|
96
|
+
|
|
97
|
+
## Purchase by UTM source
|
|
98
|
+
|
|
99
|
+
```sql
|
|
100
|
+
SELECT
|
|
101
|
+
utm_source,
|
|
102
|
+
all_users() AS users,
|
|
103
|
+
total_purchase_users() AS purchasers
|
|
104
|
+
FROM metrics
|
|
105
|
+
WHERE project_id = '{{ your project ID }}'
|
|
106
|
+
GROUP BY utm_source
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
**Result:**
|
|
110
|
+
|
|
111
|
+
| utm_source | users | purchasers |
|
|
112
|
+
| ---------- | ------ | ---------- |
|
|
113
|
+
| meta | 12031 | 101 |
|
|
114
|
+
| fb | 3656 | 31 |
|
|
115
|
+
| an | 100366 | 299 |
|
|
116
|
+
|
|
117
|
+
## Step funnel for variant users
|
|
118
|
+
|
|
119
|
+
Count unique variant users per step to understand the conversion funnel:
|
|
120
|
+
|
|
121
|
+
```sql
|
|
122
|
+
SELECT
|
|
123
|
+
step_id,
|
|
124
|
+
variant_users() AS variant
|
|
125
|
+
FROM metrics
|
|
126
|
+
WHERE project_id = '{{ your project ID }}'
|
|
127
|
+
AND project_local_date >= '2026-04-01'
|
|
128
|
+
GROUP BY step_id
|
|
129
|
+
ORDER BY variant DESC
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
**Result:**
|
|
133
|
+
|
|
134
|
+
| step_id | variant |
|
|
135
|
+
| ------------------------------ | ------- |
|
|
136
|
+
| who-are-you-protecting-step | 1093 |
|
|
137
|
+
| about-yourself-step | 533 |
|
|
138
|
+
| date-of-birth-step | 435 |
|
|
139
|
+
| employment-status-step | 408 |
|
|
140
|
+
| nicotine-usage-step | 407 |
|
|
141
|
+
| coverage-motivation-step | 405 |
|
|
142
|
+
| lead-capture-step | 398 |
|
|
143
|
+
|
|
144
|
+
|
|
145
|
+
## List all control users for mobile (user-level)
|
|
146
|
+
|
|
147
|
+
Use `events` when you need data at the individual user level:
|
|
148
|
+
|
|
149
|
+
```sql
|
|
150
|
+
SELECT
|
|
151
|
+
device_category,
|
|
152
|
+
user_canonical_id
|
|
153
|
+
FROM events
|
|
154
|
+
WHERE project_id = '{{ your project ID }}'
|
|
155
|
+
AND device_category = 'Mobile'
|
|
156
|
+
AND variant_type = 'Control'
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
**Result:**
|
|
160
|
+
|
|
161
|
+
| device_category | user_canonical_id |
|
|
162
|
+
| --------------- | ------------------------------------ |
|
|
163
|
+
| Mobile | 019cc336-5a6a-7c32-b638-cdcc983b3e70 |
|
|
164
|
+
| Mobile | 019cc336-5a6a-7d8f-994c-69bc28e5f550 |
|
|
165
|
+
| Mobile | 019cc80f-503c-7181-b2c6-986b1f76d496 |
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
---
|
|
2
|
+
layout: docs
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
# Filtering
|
|
6
|
+
|
|
7
|
+
Add `WHERE` clauses as usual. Every query must include a `project_id` filter — PickedQL extracts it and verifies you have permission to access that project. Queries without a `project_id` filter are rejected.
|
|
8
|
+
|
|
9
|
+
```sql
|
|
10
|
+
-- Date range
|
|
11
|
+
SELECT control_users() FROM metrics
|
|
12
|
+
WHERE project_id = 'your-project-id'
|
|
13
|
+
AND project_local_date BETWEEN '2026-03-01' AND '2026-03-31'
|
|
14
|
+
|
|
15
|
+
-- By experience
|
|
16
|
+
SELECT step_enter_users() FROM events
|
|
17
|
+
WHERE project_id = 'your-project-id'
|
|
18
|
+
AND experience_id = 'my-experience'
|
|
19
|
+
GROUP BY step_id
|
|
20
|
+
|
|
21
|
+
-- Combined filters
|
|
22
|
+
SELECT control_users(), variant_users() FROM metrics
|
|
23
|
+
WHERE project_id = 'your-project-id'
|
|
24
|
+
AND project_local_date >= '2026-03-01'
|
|
25
|
+
AND experience_id = 'my-experience'
|
|
26
|
+
AND device_category = 'Mobile'
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
:::warning
|
|
30
|
+
Each query can only filter on a single `project_id`. Queries that reference multiple projects will be rejected.
|
|
31
|
+
:::
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
---
|
|
2
|
+
layout: docs
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
# PickedQL
|
|
6
|
+
|
|
7
|
+
PickedQL is a SQL query language for querying your Picked analytics data. Write simple SQL using virtual tables and functions — PickedQL expands them into optimized queries with automatic joins and A/B test aggregations.
|
|
8
|
+
|
|
9
|
+
## Quick start
|
|
10
|
+
|
|
11
|
+
```sql
|
|
12
|
+
-- How many users are in the control vs variant group?
|
|
13
|
+
SELECT control_users(), variant_users()
|
|
14
|
+
FROM metrics
|
|
15
|
+
WHERE project_id = 'your-project-id'
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
PickedQL handles table mapping and dimension joins automatically. You write concise, readable SQL — PickedQL does the rest.
|
|
19
|
+
|
|
20
|
+
## How PickedQL works
|
|
21
|
+
|
|
22
|
+
1. **Virtual table expansion**: Table names like `metrics` map to underlying data tables
|
|
23
|
+
2. **Virtual function expansion**: Shorthand functions like `control_users()` expand to full aggregate expressions
|
|
24
|
+
3. **Auto dimension joins**: References to dimension columns (like `device_category` or `country_code`) trigger automatic `LEFT JOIN` clauses — you never write joins yourself
|
|
25
|
+
4. **Tenant isolation**: Every query must include a `project_id` filter in the `WHERE` clause. PickedQL extracts it and verifies you have permission to access that project
|
|
26
|
+
5. **SQL passthrough**: Standard SQL (including `CASE WHEN`, window functions, and subqueries) works alongside virtual functions
|
|
27
|
+
|
|
28
|
+
## Best practices
|
|
29
|
+
|
|
30
|
+
- **Use `metrics` for dashboards**: Pre-aggregated data is significantly faster than raw events for standard reporting
|
|
31
|
+
- **Use `events` for deep dives**: Raw event-level data gives full flexibility for custom breakdowns and funnels
|
|
32
|
+
- **Don't write JOINs**: PickedQL injects them automatically when you reference dimension columns
|
|
33
|
+
- **Group by any dimension**: Add dimension columns to `SELECT` and `GROUP BY` freely — required joins are handled for you
|
|
34
|
+
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
---
|
|
2
|
+
layout: docs
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
# Schema
|
|
6
|
+
|
|
7
|
+
Column reference for each PickedQL data source.
|
|
8
|
+
|
|
9
|
+
## `metrics`
|
|
10
|
+
|
|
11
|
+
Pre-aggregated daily data. One row per unique combination of dimensions per day.
|
|
12
|
+
|
|
13
|
+
| Column | Type | Description |
|
|
14
|
+
|---|---|---|
|
|
15
|
+
| `project_id` | String | Project identifier (required in `WHERE`) |
|
|
16
|
+
| `project_local_date` | Date | Date in project timezone |
|
|
17
|
+
| `experience_id` | String | Experience identifier |
|
|
18
|
+
| `step_id` | String | Step identifier |
|
|
19
|
+
| `event_type` | String | Event type (e.g., `page_view`, `click`) |
|
|
20
|
+
| `interaction_type` | String | Interaction type (e.g., `Button Click`) |
|
|
21
|
+
| `variant_type` | String | `Control`, `Variant`, or `Unknown` |
|
|
22
|
+
| `device_category` | String | Device category (e.g., `Desktop`, `Mobile`) |
|
|
23
|
+
| `country_code` | String | ISO country code |
|
|
24
|
+
| `utm_source` | String | UTM source |
|
|
25
|
+
| `utm_medium` | String | UTM medium |
|
|
26
|
+
| `product_name` | String | Product name |
|
|
27
|
+
| `product_category` | String | Product category |
|
|
28
|
+
| `landing_page_url` | String | Landing page URL |
|
|
29
|
+
|
|
30
|
+
:::note
|
|
31
|
+
Aggregate columns (`users`, `sessions`, `events`, etc.) are not queried directly — use [virtual functions](./virtual-functions) instead.
|
|
32
|
+
:::
|
|
33
|
+
|
|
34
|
+
## `events`
|
|
35
|
+
|
|
36
|
+
User-level event data. One row per event per user. Dimension columns are joined automatically when referenced.
|
|
37
|
+
|
|
38
|
+
### Native columns
|
|
39
|
+
|
|
40
|
+
| Column | Type | Description |
|
|
41
|
+
|---|---|---|
|
|
42
|
+
| `project_id` | String | Project identifier (required in `WHERE`) |
|
|
43
|
+
| `event_id` | String | Unique event identifier |
|
|
44
|
+
| `user_canonical_id` | String | Canonical user identifier |
|
|
45
|
+
| `session_id` | String | Session identifier |
|
|
46
|
+
| `experience_id` | String | Experience identifier |
|
|
47
|
+
| `step_id` | String | Step identifier |
|
|
48
|
+
| `event_type` | String | Event type (e.g., `page_view`, `click`) |
|
|
49
|
+
| `interaction_type` | String | Interaction type (e.g., `Button Click`) |
|
|
50
|
+
| `client_local_date` | Date | Date in client timezone |
|
|
51
|
+
| `is_purchase` | UInt8 | `1` if checkout complete event |
|
|
52
|
+
| `is_cart_add` | UInt8 | `1` if cart add event |
|
|
53
|
+
| `is_first_session` | UInt8 | `1` if first session for this user |
|
|
54
|
+
| `landing_page_url` | String | Landing page URL |
|
|
55
|
+
| `features` | Map(String, String) | Feature flag assignments |
|
|
56
|
+
| `feature_keys` | Map(String, String) | Feature key assignments |
|
|
57
|
+
| `event_meta` | String | Event metadata |
|
|
58
|
+
|
|
59
|
+
### Dimension columns (auto-joined)
|
|
60
|
+
|
|
61
|
+
These columns are joined automatically when referenced — no `JOIN` syntax needed.
|
|
62
|
+
|
|
63
|
+
| Column | Source | Description |
|
|
64
|
+
|---|---|---|
|
|
65
|
+
| `variant_type` | dim_variant | `Control`, `Variant`, or `Unknown` |
|
|
66
|
+
| `ab_feature_name` | dim_variant | A/B feature name |
|
|
67
|
+
| `ab_feature_value` | dim_variant | A/B feature value |
|
|
68
|
+
| `device_category` | dim_device | Device category |
|
|
69
|
+
| `browser_name` | dim_device | Browser name |
|
|
70
|
+
| `browser_version` | dim_device | Browser version |
|
|
71
|
+
| `os_name` | dim_device | Operating system name |
|
|
72
|
+
| `os_version` | dim_device | Operating system version |
|
|
73
|
+
| `platform` | dim_device | Platform |
|
|
74
|
+
| `country_code` | dim_geo | ISO country code |
|
|
75
|
+
| `country_name` | dim_geo | Country name |
|
|
76
|
+
| `region` | dim_geo | Region |
|
|
77
|
+
| `city` | dim_geo | City |
|
|
78
|
+
| `utm_source` | dim_utm | UTM source |
|
|
79
|
+
| `utm_medium` | dim_utm | UTM medium |
|
|
80
|
+
| `utm_campaign` | dim_utm | UTM campaign |
|
|
81
|
+
| `utm_term` | dim_utm | UTM term |
|
|
82
|
+
| `utm_content` | dim_utm | UTM content |
|
|
83
|
+
| `product_name` | dim_product | Product name |
|
|
84
|
+
| `product_category` | dim_product | Product category |
|
|
85
|
+
| `product_page` | dim_product | Product page |
|
|
86
|
+
|
|
87
|
+
## `features`
|
|
88
|
+
|
|
89
|
+
The `features` table provides [parameterized virtual functions](./virtual-functions#feature-functions-features--events) for querying feature flag assignments:
|
|
90
|
+
|
|
91
|
+
| Function | Description |
|
|
92
|
+
|---|---|
|
|
93
|
+
| `feature_users('name', 'bucket' [, 'key'])` | Unique users in a feature bucket |
|
|
94
|
+
| `feature_sessions('name', 'bucket' [, 'key'])` | Unique sessions in a feature bucket |
|
|
95
|
+
| `feature_events('name', 'bucket' [, 'key'])` | Unique events in a feature bucket |
|