@picked/client 0.0.71-next.1 → 0.0.71-next.3

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.
Files changed (149) hide show
  1. package/dist/.tsbuildinfo +1 -1
  2. package/dist/{api-CH2FNa6S.cjs → api-CnjBi6JG.cjs} +1 -1
  3. package/dist/{api-CgqRvuKL.js → api-vBVGLtvU.js} +1 -1
  4. package/dist/cjs/index.js +2 -2
  5. package/dist/cjs/plugins/dynamic-experiences/index.js +1 -1
  6. package/dist/cjs/server/index.js +1 -1
  7. package/dist/docs/explanation/conditions-and-the-logic-engine.md +94 -0
  8. package/dist/docs/explanation/feature-flag-allocation.md +176 -0
  9. package/dist/docs/explanation/how-picked-works.md +102 -0
  10. package/dist/docs/explanation/how-pickedql-works.md +76 -0
  11. package/dist/docs/explanation/pages-and-flows.md +64 -0
  12. package/dist/docs/explanation/the-content-model.md +77 -0
  13. package/dist/docs/explanation/the-two-apis.md +68 -0
  14. package/dist/docs/explanation/why-server-side-rendering.md +76 -0
  15. package/dist/docs/explanation/workspaces-and-versions.md +71 -0
  16. package/dist/docs/how-to/add-a-step-field-or-action.md +43 -0
  17. package/dist/docs/{pickedql/examples.md → how-to/analytics/index.md} +19 -6
  18. package/dist/docs/how-to/archive-or-delete-a-workspace.md +46 -0
  19. package/dist/docs/how-to/authenticate-with-a-magic-link.md +40 -0
  20. package/dist/docs/how-to/authenticate-with-a-password.md +51 -0
  21. package/dist/docs/how-to/authenticate-with-an-api-key.md +51 -0
  22. package/dist/docs/how-to/authenticate-with-oauth.md +40 -0
  23. package/dist/docs/{flow-builder/building-flows.md → how-to/build-a-flow.md} +13 -9
  24. package/dist/docs/how-to/connect-the-mcp-server.md +38 -0
  25. package/dist/docs/how-to/create-a-project.md +29 -0
  26. package/dist/docs/how-to/create-an-experience.md +42 -0
  27. package/dist/docs/how-to/create-and-revoke-an-api-key.md +37 -0
  28. package/dist/docs/how-to/debug-with-the-chrome-extension.md +57 -0
  29. package/dist/docs/how-to/define-a-page-layout.md +39 -0
  30. package/dist/docs/how-to/fill-and-publish-a-page.md +50 -0
  31. package/dist/docs/{gtm-template.md → how-to/install-the-gtm-template.md} +9 -3
  32. package/dist/docs/how-to/install-the-sdk.md +68 -0
  33. package/dist/docs/how-to/install-the-vite-plugin.md +56 -0
  34. package/dist/docs/how-to/invite-and-remove-members.md +34 -0
  35. package/dist/docs/how-to/preview-a-workspace.md +28 -0
  36. package/dist/docs/how-to/publish-a-workspace.md +30 -0
  37. package/dist/docs/how-to/read-a-feature-flag.md +101 -0
  38. package/dist/docs/how-to/register-a-component.md +55 -0
  39. package/dist/docs/how-to/register-an-action-handler.md +67 -0
  40. package/dist/docs/how-to/render-a-step-form.md +132 -0
  41. package/dist/docs/how-to/render-an-unpublished-preview.md +41 -0
  42. package/dist/docs/how-to/reuse-a-section.md +37 -0
  43. package/dist/docs/how-to/reuse-a-step-field-or-action.md +28 -0
  44. package/dist/docs/how-to/roll-back-a-published-version.md +26 -0
  45. package/dist/docs/how-to/run-an-ab-test.md +49 -0
  46. package/dist/docs/how-to/run-code-on-a-form-submission.md +125 -0
  47. package/dist/docs/how-to/server-render-a-page.md +81 -0
  48. package/dist/docs/how-to/set-a-content-security-policy.md +32 -0
  49. package/dist/docs/how-to/set-up-mfa.md +69 -0
  50. package/dist/docs/how-to/upload-and-use-an-asset.mdx +73 -0
  51. package/dist/docs/how-to/validate-a-field.md +52 -0
  52. package/dist/docs/how-to/write-a-condition.md +45 -0
  53. package/dist/docs/how-to/write-a-predicate.md +60 -0
  54. package/dist/docs/index.md +41 -70
  55. package/dist/docs/reference/dashboard/actions.mdx +53 -0
  56. package/dist/docs/{api-keys.mdx → reference/dashboard/api-keys.mdx} +7 -15
  57. package/dist/docs/reference/dashboard/conditions.mdx +42 -0
  58. package/dist/docs/reference/dashboard/content/asset-library.mdx +63 -0
  59. package/dist/docs/{content → reference/dashboard/content}/content-entries.mdx +11 -3
  60. package/dist/docs/{content → reference/dashboard/content}/layouts.mdx +11 -35
  61. package/dist/docs/reference/dashboard/content/pages.mdx +35 -0
  62. package/dist/docs/reference/dashboard/content/sections.mdx +28 -0
  63. package/dist/docs/{experiences.mdx → reference/dashboard/experiences.mdx} +9 -16
  64. package/dist/docs/{features.mdx → reference/dashboard/features.mdx} +26 -41
  65. package/dist/docs/{fields.mdx → reference/dashboard/fields.mdx} +26 -20
  66. package/dist/docs/{flow-builder/overview.mdx → reference/dashboard/flow-builder/canvas.mdx} +8 -13
  67. package/dist/docs/{flow-builder → reference/dashboard/flow-builder}/condition-builder.md +5 -13
  68. package/dist/docs/{flow-builder → reference/dashboard/flow-builder}/keyboard-shortcuts.md +7 -1
  69. package/dist/docs/{flow-builder → reference/dashboard/flow-builder}/nodes.md +10 -3
  70. package/dist/docs/reference/dashboard/projects.mdx +44 -0
  71. package/dist/docs/reference/dashboard/reports.mdx +43 -0
  72. package/dist/docs/reference/dashboard/steps.mdx +37 -0
  73. package/dist/docs/{team-management.md → reference/dashboard/team-management.md} +5 -22
  74. package/dist/docs/{workspace-versioning.mdx → reference/dashboard/workspace-versioning.mdx} +6 -10
  75. package/dist/docs/reference/dashboard/workspaces.mdx +76 -0
  76. package/dist/docs/{delivery-api → reference/delivery-api}/experience-content.md +11 -4
  77. package/dist/docs/reference/delivery-api/index.md +45 -0
  78. package/dist/docs/{delivery-api → reference/delivery-api}/preview-caching-crawling.md +12 -5
  79. package/dist/docs/{delivery-api → reference/delivery-api}/project-config.md +11 -4
  80. package/dist/docs/reference/glossary.md +173 -0
  81. package/dist/docs/reference/management-api/authentication.md +74 -0
  82. package/dist/docs/{api → reference/management-api}/authorization-and-scopes.md +10 -3
  83. package/dist/docs/{api → reference/management-api}/error-handling.md +9 -3
  84. package/dist/docs/{api → reference/management-api}/pagination.md +6 -0
  85. package/dist/docs/{pickedql → reference/pickedql}/data-sources.md +16 -9
  86. package/dist/docs/{pickedql → reference/pickedql}/dimensions.md +7 -0
  87. package/dist/docs/{pickedql → reference/pickedql}/filtering.md +7 -0
  88. package/dist/docs/reference/pickedql/index.md +18 -0
  89. package/dist/docs/{pickedql → reference/pickedql}/schema.md +13 -6
  90. package/dist/docs/{pickedql → reference/pickedql}/virtual-functions.md +7 -0
  91. package/dist/docs/reference/sdk/actions.md +30 -0
  92. package/dist/docs/{sdk → reference/sdk}/conditions.md +8 -1
  93. package/dist/docs/reference/sdk/content-security-policy.md +21 -0
  94. package/dist/docs/reference/sdk/experiences.md +51 -0
  95. package/dist/docs/{sdk → reference/sdk}/features.md +30 -117
  96. package/dist/docs/{sdk → reference/sdk}/fields.md +10 -88
  97. package/dist/docs/reference/sdk/index.md +68 -0
  98. package/dist/docs/{sdk → reference/sdk}/plugins/create-experience.md +10 -22
  99. package/dist/docs/reference/sdk/plugins/dynamic-experiences.md +26 -0
  100. package/dist/docs/reference/sdk/plugins/index.md +29 -0
  101. package/dist/docs/{sdk → reference/sdk}/plugins/window-object.md +6 -0
  102. package/dist/docs/reference/sdk/predicates.md +43 -0
  103. package/dist/docs/reference/sdk/ssr/index.md +33 -0
  104. package/dist/docs/{sdk → reference/sdk}/ssr/rendering-and-hydration.md +4 -63
  105. package/dist/docs/{sdk → reference/sdk}/ssr/serialize.md +6 -33
  106. package/dist/docs/{sdk → reference/sdk}/ssr/slots-and-placements.md +7 -1
  107. package/dist/docs/reference/sdk/steps.md +87 -0
  108. package/dist/docs/reference/tools/chrome-extension.md +16 -0
  109. package/dist/docs/{image-optimisation-service.md → reference/tools/image-optimisation-service.md} +8 -0
  110. package/dist/docs/{mcp.md → reference/tools/mcp.md} +5 -45
  111. package/dist/docs/{vite-plugin.md → reference/tools/vite-plugin.md} +8 -38
  112. package/dist/docs/{api/index.md → tutorials/first-api-call.md} +27 -15
  113. package/dist/docs/tutorials/first-experience-in-the-dashboard.mdx +143 -0
  114. package/dist/docs/tutorials/first-experience.mdx +255 -0
  115. package/dist/docs/tutorials/first-server-rendered-page.mdx +186 -0
  116. package/dist/esm/index.js +468 -426
  117. package/dist/esm/plugins/dynamic-experiences/index.js +2 -2
  118. package/dist/esm/server/index.js +1 -1
  119. package/dist/{plugin-DCW-tnjO.cjs → plugin-CSmD1gPl.cjs} +1 -1
  120. package/dist/{plugin-D2UqFikQ.js → plugin-GOTtoDlC.js} +1 -1
  121. package/dist/types/entities/feature/feature.d.ts +25 -2
  122. package/dist/types/entities/feature/feature.d.ts.map +1 -1
  123. package/dist/types/picked.d.ts +2 -1
  124. package/dist/types/picked.d.ts.map +1 -1
  125. package/package.json +1 -1
  126. package/dist/docs/actions.mdx +0 -98
  127. package/dist/docs/api/authentication.md +0 -403
  128. package/dist/docs/chrome-extension.md +0 -68
  129. package/dist/docs/conditions.mdx +0 -72
  130. package/dist/docs/content/asset-library.mdx +0 -124
  131. package/dist/docs/content/pages.mdx +0 -82
  132. package/dist/docs/content/sections.mdx +0 -44
  133. package/dist/docs/delivery-api/index.md +0 -53
  134. package/dist/docs/guides/build-a-personalized-page.mdx +0 -161
  135. package/dist/docs/pickedql/index.md +0 -54
  136. package/dist/docs/projects.mdx +0 -44
  137. package/dist/docs/reports.mdx +0 -20
  138. package/dist/docs/sdk/actions.md +0 -82
  139. package/dist/docs/sdk/content-security-policy.md +0 -33
  140. package/dist/docs/sdk/experiences.md +0 -64
  141. package/dist/docs/sdk/feature-allocation.md +0 -161
  142. package/dist/docs/sdk/index.md +0 -98
  143. package/dist/docs/sdk/plugins/dynamic-experiences.md +0 -84
  144. package/dist/docs/sdk/plugins/index.md +0 -9
  145. package/dist/docs/sdk/predicates.md +0 -128
  146. package/dist/docs/sdk/ssr/index.md +0 -79
  147. package/dist/docs/sdk/steps.md +0 -479
  148. package/dist/docs/steps.mdx +0 -53
  149. package/dist/docs/workspaces.mdx +0 -133
@@ -0,0 +1,45 @@
1
+ ---
2
+ type: reference
3
+ layout: docs
4
+ ---
5
+
6
+ # Delivery API
7
+
8
+ The Delivery API is a public REST API. It is read-only, and it serves the published
9
+ configuration of your project together with your page content. It is separate from the
10
+ GraphQL management API.
11
+
12
+ ## Base URL and versioning
13
+
14
+ All Delivery API routes are versioned under `/api/v1`:
15
+
16
+ ```
17
+ https://api.picked.app/api/v1
18
+ ```
19
+
20
+ ## Published content and preview content
21
+
22
+ Each endpoint serves two surfaces:
23
+
24
+ - **Published** content is anonymous. Anybody can read your published configuration and
25
+ your published content.
26
+ - **Preview** content needs a `preview_token` query parameter. With it you can render
27
+ an unpublished draft before you make it live.
28
+
29
+ The management API holds the preview token of a workspace in the `previewToken`
30
+ field. The preview action in the dashboard also makes one for you.
31
+
32
+ ## Endpoints
33
+
34
+ | Endpoint | Description |
35
+ | --- | --- |
36
+ | [Project Config](/reference/delivery-api/project-config) | `GET /api/v1/projects/:projectId` returns the published configuration of the project, with the content link of each step. |
37
+ | [Experience Content](/reference/delivery-api/experience-content) | `GET /api/v1/projects/:projectId/experiences/:id/content` returns the Content Entries of an experience. |
38
+
39
+ Both endpoints share some behaviour. See
40
+ [Preview, cache, and crawlers](/reference/delivery-api/preview-caching-crawling).
41
+
42
+ ## Related
43
+
44
+ - [About the two APIs](/explanation/the-two-apis) — which one to use, and why they are
45
+ separate.
@@ -1,4 +1,5 @@
1
1
  ---
2
+ type: reference
2
3
  layout: docs
3
4
  ---
4
5
 
@@ -16,10 +17,10 @@ and both return `versionId: null` for a preview. An invalid token returns `401`.
16
17
  curl "https://api.picked.app/api/v1/projects/proj_123?preview_token=<token>"
17
18
  ```
18
19
 
19
- The [management API](/api) holds the preview token of a workspace in the
20
+ The [management API](/tutorials/first-api-call) holds the preview token of a workspace in the
20
21
  `previewToken` field. The preview action in the dashboard also makes one for you.
21
22
 
22
- Use the same token for the project options request and for the experience content
23
+ Use the same token for the project configuration request and for the experience content
23
24
  request. Both then come from the same preview.
24
25
 
25
26
  ## Cache
@@ -57,7 +58,7 @@ the `robots.txt` rules:
57
58
  ```
58
59
  User-agent: *
59
60
 
60
- # Let a crawler read the public project options and experience content.
61
+ # Let a crawler read the public project configuration and experience content.
61
62
  Allow: /api/v1/projects
62
63
  Allow: /api/v1/projects/*/experiences/*/content
63
64
 
@@ -68,5 +69,11 @@ Disallow: /api/v1/projects/*preview_token=
68
69
  Disallow: /
69
70
  ```
70
71
 
71
- See [Project Config](/delivery-api/project-config) and
72
- [Experience Content](/delivery-api/experience-content) for the endpoints.
72
+ See [Project Config](/reference/delivery-api/project-config) and
73
+ [Experience Content](/reference/delivery-api/experience-content) for the endpoints.
74
+
75
+ ## Related
76
+
77
+ - [About the two APIs](/explanation/the-two-apis) — how a preview stays out of the search
78
+ index.
79
+ - [How to render an unpublished preview](/how-to/render-an-unpublished-preview)
@@ -1,4 +1,5 @@
1
1
  ---
2
+ type: reference
2
3
  layout: docs
3
4
  ---
4
5
 
@@ -15,11 +16,11 @@ GET /api/v1/projects/:projectId
15
16
  | Parameter | In | Description |
16
17
  | --- | --- | --- |
17
18
  | `projectId` | path | The project to fetch config for. |
18
- | `preview_token` | query | Optional. With it, the endpoint returns the preview options, which are unpublished. |
19
+ | `preview_token` | query | Optional. With it, the endpoint returns the preview configuration, which are unpublished. |
19
20
 
20
21
  ## Response
21
22
 
22
- The response carries the project's experiences and steps. Each step includes `layoutContentId`, the reference to the Content Entry that backs that step's layout. Use it to know which experiences have content to fetch from the [Experience Content](/delivery-api/experience-content) endpoint.
23
+ The response carries the project's experiences and steps. Each step includes `layoutContentId`, the reference to the Content Entry that backs that step's layout. Use it to know which experiences have content to fetch from the [Experience Content](/reference/delivery-api/experience-content) endpoint.
23
24
 
24
25
  | Field | Type | Description |
25
26
  | --- | --- | --- |
@@ -31,7 +32,7 @@ The response carries the project's experiences and steps. Each step includes `la
31
32
 
32
33
  For published content, `versionId` holds the ID of the published version. For preview
33
34
  content, which you read with `?preview_token=...`, `versionId` is `null`, because
34
- there is no published version. See [Preview, cache, and crawlers](/delivery-api/preview-caching-crawling).
35
+ there is no published version. See [Preview, cache, and crawlers](/reference/delivery-api/preview-caching-crawling).
35
36
 
36
37
  ## Example
37
38
 
@@ -55,4 +56,10 @@ curl https://api.picked.app/api/v1/projects/proj_123
55
56
  }
56
57
  ```
57
58
 
58
- Pass the config to `serialize()` on your server to produce an SSR snapshot. See [Server Snapshot](/sdk/ssr/serialize).
59
+ Pass the config to `serialize()` on your server to produce an SSR snapshot. See [Server Snapshot](/reference/sdk/ssr/serialize).
60
+
61
+ ## Related
62
+
63
+ - [About the two APIs](/explanation/the-two-apis)
64
+ - [Experience content](/reference/delivery-api/experience-content)
65
+ - [How to server-render a page](/how-to/server-render-a-page)
@@ -0,0 +1,173 @@
1
+ ---
2
+ type: reference
3
+ layout: docs
4
+ ---
5
+
6
+ # Glossary
7
+
8
+ Every term that Picked uses, and what each one means. The dashboard, the API, and the SDK
9
+ sometimes use different words for the same thing. This page gives the word that the
10
+ documentation uses, and it names the others.
11
+
12
+ ## Accounts and access
13
+
14
+ | Term | What it is |
15
+ | --- | --- |
16
+ | **Organization** | The top level. It holds your projects, your members, and your settings. You can belong to more than one. |
17
+ | **Member** | A person in an organization. Each member holds one role. |
18
+ | **Role** | What a member can reach. It decides whether a member can create a project, edit an experience, or read a report. |
19
+ | **API key** | A credential for a server-to-server integration. It belongs to an organization, it can belong to one project, and it carries scopes. |
20
+ | **Scope** | One permission, written `resource/action`, such as `organization/read`. A scope decides which operations a caller can do. |
21
+ | **Session** | The result of a sign-in. It holds an access token, a refresh token, and the time at which the access token expires. |
22
+ | **User** | A person who signs in to the Picked dashboard. A user is not a visitor. |
23
+ | **Invitation** | An offer to join an organization, sent to an email address. It waits until the person accepts it. |
24
+ | **MFA factor** | A second credential on an account, such as a telephone number. |
25
+
26
+ ## Projects and versions
27
+
28
+ | Term | What it is |
29
+ | --- | --- |
30
+ | **Project** | One site or one application. Each project has its own experiences, content, and configuration. |
31
+ | **Project configuration** | The published settings of a project: its experiences and steps, and the content link on each step. The Delivery API serves it, and the SDK reads it. The SDK parameter is `projectConfig`. |
32
+ | **Workspace** | One version of the configuration of a project. You hold a change in a workspace, see a preview of it, and publish it. |
33
+ | **Draft** | A workspace that no visitor sees. |
34
+ | **Live** | The workspace whose snapshot the SDK serves. Each project has exactly one. |
35
+ | **Archived** | A draft that you put to one side. It is still editable, and it is out of the default list. |
36
+ | **Version** | An immutable snapshot of a workspace, made when you publish. The **Publish history** page lists them. |
37
+ | **Preview** | A view of an unpublished workspace on your own site. It reaches your browser only. |
38
+ | **Preview environment** | A named target that a preview opens against. |
39
+ | **Project settings** | The settings of one project, which you edit in the dashboard. These are not the project configuration that the Delivery API serves. |
40
+
41
+ ## Experiences
42
+
43
+ | Term | What it is |
44
+ | --- | --- |
45
+ | **Experience** | Personalized content that Picked serves to a visitor. It is a Flow or a Page. |
46
+ | **Flow** | An interactive experience of more than one step, which the browser renders. |
47
+ | **Page** | A standalone experience that your server renders from a content entry, for content that a search engine must read. |
48
+ | **Step** | One screen that a visitor sees. It holds fields. |
49
+ | **Field** | A data input inside a step. It collects a name, an email address, a preference, or a choice. |
50
+ | **Field option** | One choice in a field that has a fixed set of choices. Each option carries a value, and it can carry a condition. |
51
+ | **Action** | A side effect that starts when the flow reaches it. Your application registers a handler for it. |
52
+ | **Condition** | A rule that decides whether a visitor sees something, or which branch a flow takes. |
53
+ | **Predicate** | A function that you register on the client, so a condition can read data that only your application holds. |
54
+ | **Response** | A value that a visitor sends through a field. |
55
+ | **Origin** | The node where every flow starts. |
56
+ | **Node** | One part of a flow on the canvas: an origin, a step, an action, or a condition. |
57
+ | **Handle** | A connection point on a node. An input handle is on the left, an output handle on the right. |
58
+ | **Key** | The stable identifier of a step, a field, an action, or a condition. Your application and your API calls both use it. You set it one time, and you cannot change it. |
59
+ | **Layout name** | The name of the component that renders a step, such as `card` or `modal`. |
60
+ | **Target** | The element that an experience renders against, found by its target selector. |
61
+
62
+ ## Feature flags
63
+
64
+ | Term | What it is |
65
+ | --- | --- |
66
+ | **Feature flag** | A control that decides which visitors see a change, so you can run an A/B test or release in stages. The API type is `Feature`. |
67
+ | **Weight** | The percentage of visitors that Picked allocates to a feature flag, from 0 to 100. |
68
+ | **Allocation** | The act that puts a visitor in a feature flag. It happens when something first reads the bucket. |
69
+ | **Bucket** | The value a feature flag resolves to for one visitor. |
70
+ | **Exposure** | The moment a visitor enters a test. It is the same moment as the allocation. |
71
+ | **Version** | A number on a feature flag that forms part of the cache key. It is not part of the allocation. |
72
+
73
+ ## Content
74
+
75
+ | Term | What it is |
76
+ | --- | --- |
77
+ | **Page layout** | A reusable schema that sets which fields a Page can hold. The API type is `ContentModel`, and the dashboard list page is titled **Models**. |
78
+ | **Step layout** | The same, for one Step inside a Flow. |
79
+ | **Section** | A reusable schema fragment that you put inside one or more layouts. The API type is `ContentBlock`, and the dashboard list page is titled **Blocks**. |
80
+ | **Content entry** | One instance of a layout, filled with real values. The dashboard list page is titled **Content**. |
81
+ | **Asset** | A file that your content points at: an image, a video, a document, or HTML. |
82
+ | **Asset library** | The project-level store that holds your assets. |
83
+ | **Design system** | A set of shared design decisions for a project. |
84
+ | **Content schema** | The set of fields that a layout or a section defines. |
85
+ | **Asset version** | One file that somebody uploaded for an asset. The library keeps the earlier versions. |
86
+ | **Validation error** | A report that one field in a content entry does not match its schema. It carries the path to the exact field. |
87
+
88
+ ## The SDK
89
+
90
+ | Term | What it is |
91
+ | --- | --- |
92
+ | **Client** | The object that `createClient()` returns. It holds your configuration and runs the experiences. |
93
+ | **Plugin** | A piece of behaviour that you pass to the `plugins` array of the client. |
94
+ | **Component name** | The identifier that points an experience at a component in your application. |
95
+ | **Adapter** | The function that lets the client render a framework component: `adaptReactComponent` or `adaptSvelteComponent`. |
96
+ | **Slot** | A named mount point, rendered by `<ExperienceSlot name="…" />`. It maps to the `.picked-slot-<name>` selector. |
97
+ | **Placement** | Where an experience renders against its target: `replace`, `before`, `prepend`, `append`, or `after`. |
98
+ | **Target selector** | The selector that an experience renders into. |
99
+ | **Snapshot** | The plain JSON that `serialize()` returns on your server, and that seeds the client in the browser. |
100
+ | **Precondition** | A gate that decides whether Picked starts at all. |
101
+ | **Visitor** | The person on your site. Picked gives each one a stable ID. A visitor is not a user. |
102
+ | **Framework plugin** | The plugin that lets the client render a React or a Svelte component. |
103
+
104
+ ## APIs and analytics
105
+
106
+ | Term | What it is |
107
+ | --- | --- |
108
+ | **Delivery API** | The public, anonymous, read-only REST API that serves your published configuration and content. |
109
+ | **Management API** | The authenticated GraphQL API that controls your projects, experiences, and content. |
110
+ | **Preview token** | A token that lets a Delivery API request read unpublished content. |
111
+ | **PickedQL** | The SQL query language for your Picked analytics data. |
112
+ | **Virtual table** | A table name in PickedQL, such as `metrics`, that maps to the real tables below it. |
113
+ | **Virtual function** | A short function in PickedQL, such as `control_users()`, that expands to a full aggregate expression. |
114
+ | **Dimension** | A column that PickedQL joins for you, such as `device_category`. |
115
+ | **Report** | An embedded analytics dashboard or question, attached to a project. |
116
+
117
+ ## Tools
118
+
119
+ | Term | What it is |
120
+ | --- | --- |
121
+ | **MCP connection** | A link between a Picked project and an AI tool, over the Model Context Protocol. The dashboard calls this **MCP connections**. |
122
+ | **Integration** | A connection between Picked and another service. |
123
+ | **Tag ID** | The identifier of a project, which the template for Google Tag Manager uses. |
124
+
125
+ ## Verbs
126
+
127
+ The actions that Picked names, and what each one does. Where an API mutation uses the
128
+ word exactly, the table says so.
129
+
130
+ ### You act on the dashboard
131
+
132
+ | Verb | What it does |
133
+ | --- | --- |
134
+ | **Create** | Makes a new record. |
135
+ | **Update** | Changes a record that exists. |
136
+ | **Delete** | Removes a record permanently. You cannot reverse it. |
137
+ | **Publish** | Makes an immutable snapshot of a workspace and serves it to your visitors. |
138
+ | **Archive** | Moves a draft workspace out of the default list. It stays editable. |
139
+ | **Unarchive** | Returns an archived workspace to the default list. |
140
+ | **Duplicate** | Copies a workspace, and everything in it, into a new draft. |
141
+ | **Restore** | Moves the live pointer of a project to an earlier version. It changes no data. |
142
+ | **Preview** | Opens your site with an unpublished workspace applied, for your browser only. |
143
+ | **Invite** | Sends an invitation to join an organization. |
144
+ | **Revoke** | Invalidates an API key or an invitation immediately. |
145
+ | **Install** | Connects an integration to your project. |
146
+
147
+ ### Picked acts on a visitor
148
+
149
+ | Verb | What it does |
150
+ | --- | --- |
151
+ | **Allocate** | Puts a visitor in a feature flag. |
152
+ | **Resolve** | Gives a feature flag its bucket for one visitor. The first read resolves it. |
153
+ | **Decide** | Runs the `decide` function of a feature flag. |
154
+ | **Evaluate** | Runs a condition against the current state. |
155
+ | **Invoke** | Calls a predicate from inside a condition. |
156
+ | **Serve** | Sends published content to a visitor. |
157
+
158
+ ### Your code acts on the SDK
159
+
160
+ | Verb | What it does |
161
+ | --- | --- |
162
+ | **Register** | Adds a component, an action, a predicate, or a feature flag to the client. |
163
+ | **Start** | Runs the client. `start()` is idempotent. |
164
+ | **Adapt** | Wraps a framework component so the client can render it. |
165
+ | **Serialize** | Builds a snapshot on your server, with `serialize()`. |
166
+ | **Seed** | Gives the client a snapshot, so the first render matches the server. |
167
+ | **Hydrate** | Takes over the server markup in the browser. |
168
+ | **Render** | Puts a component into the page. |
169
+
170
+ ## Related
171
+
172
+ - [About how Picked works](/explanation/how-picked-works) — how these parts fit together.
173
+ - [Projects](/reference/dashboard/projects) — the dashboard surface.
@@ -0,0 +1,74 @@
1
+ ---
2
+ type: reference
3
+ layout: docs
4
+ ---
5
+
6
+ # Authentication
7
+
8
+ The Picked API supports four ways to authenticate. They are a session from an email
9
+ address and a password, an OAuth provider, a magic link, and an API key. This guide
10
+ covers each one. It also covers how to control a session and how to use multi-factor
11
+ authentication (MFA).
12
+
13
+ ## Use a session
14
+
15
+ After the caller has a session, it puts the access token in the `Authorization`
16
+ header of every request that needs authentication:
17
+
18
+ ```
19
+ Authorization: Bearer <accessToken>
20
+ ```
21
+
22
+ The `expiresAt` field of the session gives the time at which the access token
23
+ expires. The caller must refresh the session before that time.
24
+
25
+ ### Authenticator assurance levels
26
+
27
+ The session holds an `aal` field, and it gives the strength of the authentication:
28
+
29
+ | Level | Meaning |
30
+ |-------|---------|
31
+ | `AAL1` | One factor: an email address and a password, OAuth, or a magic link |
32
+ | `AAL2` | More than one factor: the user completed an MFA challenge |
33
+
34
+ Some operations need `AAL2`. When a caller at `AAL1` tries one of them, the API
35
+ returns an authorization error.
36
+
37
+ ## The mutations
38
+
39
+ | Mutation | What it does |
40
+ | --- | --- |
41
+ | `sessionCreate` | Authenticates an email address and a password. Returns a session, or `requiresMfa`. |
42
+ | `sessionRefresh` | Exchanges a refresh token for a new session. Needs no `Authorization` header. |
43
+ | `accountCreate` | Creates an account. `metadata` takes any JSON. |
44
+ | `accountVerifyEmail` | Completes email verification with the token from the email. |
45
+ | `accountResendVerification` | Sends the verification email again. |
46
+ | `oauthAuthorize` | Returns the authorization URL for a provider. Google is supported. |
47
+ | `oauthCallback` | Exchanges an OAuth code for a session. |
48
+ | `magicLinkSend` | Sends a sign-in link to an email address. |
49
+ | `magicLinkVerify` | Exchanges a magic-link token for a session. |
50
+ | `passwordResetSend` | Sends a password reset email. |
51
+ | `passwordReset` | Completes a reset with the token from the email. |
52
+ | `passwordUpdate` | Changes a password. Needs authentication. |
53
+ | `mfaFactorEnroll` | Adds an MFA factor. A new factor is `UNVERIFIED`. |
54
+ | `mfaChallengeSend` | Sends a code to the telephone number of the factor. |
55
+ | `mfaChallengeVerify` | Verifies a challenge. Moves the session to `AAL2`. |
56
+ | `mfaFactorUnenroll` | Removes an MFA factor. |
57
+ | `apiKeyCreate` | Creates an API key. Only a user with a session can call it. |
58
+ | `apiKeyRevoke` | Invalidates a key immediately. |
59
+
60
+ ## Credentials
61
+
62
+ | Credential | Header |
63
+ | --- | --- |
64
+ | Session access token | `Authorization: Bearer <accessToken>` |
65
+ | API key | `x-api-key: pk_live_abc123...` |
66
+
67
+ ## Related
68
+
69
+ - [How to authenticate with a password](/how-to/authenticate-with-a-password)
70
+ - [How to authenticate with OAuth](/how-to/authenticate-with-oauth)
71
+ - [How to authenticate with a magic link](/how-to/authenticate-with-a-magic-link)
72
+ - [How to set up MFA](/how-to/set-up-mfa)
73
+ - [How to authenticate with an API key](/how-to/authenticate-with-an-api-key)
74
+ - [Authorization and scopes](/reference/management-api/authorization-and-scopes)
@@ -1,4 +1,5 @@
1
1
  ---
2
+ type: reference
2
3
  layout: docs
3
4
  ---
4
5
 
@@ -11,7 +12,7 @@ and how the API resolves a permission.
11
12
 
12
13
  ## The format of a scope name
13
14
 
14
- A scope has the form `entity/action`:
15
+ A scope has the form `resource/action`:
15
16
 
16
17
  ```
17
18
  organization/read
@@ -19,7 +20,7 @@ organization_members/create
19
20
  organization_projects/delete
20
21
  ```
21
22
 
22
- - **entity** — a lowercase name. It uses an underscore between words, as in
23
+ - **resource** — a lowercase name. It uses an underscore between words, as in
23
24
  `organization_members` and `organization_api_keys`.
24
25
  - **action** — one of `create`, `read`, `update`, or `delete`.
25
26
 
@@ -150,7 +151,7 @@ the scope inside that organization. For a root-level operation such as
150
151
  `organizationCreate`, the API resolves the scope at the account level.
151
152
 
152
153
  When the caller does not hold the scope that an operation needs, the API returns an
153
- authorization error with the code `FORBIDDEN`. See [Errors](./error-handling.md).
154
+ authorization error with the code `FORBIDDEN`. See [Errors](/reference/management-api/error-handling).
154
155
 
155
156
  ## Operations and required scopes
156
157
 
@@ -276,3 +277,9 @@ Response:
276
277
  Use this to build a UI that changes with the permissions of the caller. An example is
277
278
  a **Delete Organization** button that the UI hides when the caller does not hold
278
279
  `ORGANIZATION_DELETE`.
280
+
281
+ ## Related
282
+
283
+ - [Authentication](/reference/management-api/authentication)
284
+ - [How to authenticate with an API key](/how-to/authenticate-with-an-api-key)
285
+ - [API keys](/reference/dashboard/api-keys) — the dashboard surface.
@@ -1,4 +1,5 @@
1
1
  ---
2
+ type: reference
2
3
  layout: docs
3
4
  ---
4
5
 
@@ -45,7 +46,7 @@ operation, or MFA. They match the `AuthErrorCode` enum in the schema.
45
46
  | Code | Description |
46
47
  |------|-------------|
47
48
  | `INVALID_CREDENTIALS` | The email address and the password do not match. |
48
- | `EMAIL_NOT_CONFIRMED` | The account is there, but nobody verified the email address. See [Authentication](/api/authentication#verify-an-email-address). |
49
+ | `EMAIL_NOT_CONFIRMED` | The account is there, but nobody verified the email address. See [Authentication](/reference/management-api/authentication#verify-an-email-address). |
49
50
  | `USER_NOT_FOUND` | There is no account with that email address. |
50
51
  | `USER_ALREADY_EXISTS` | An account with that email address is there already. The API returns this when you create an account. |
51
52
  | `WEAK_PASSWORD` | The password is not strong enough. |
@@ -82,7 +83,7 @@ operation, or MFA. They match the `AuthErrorCode` enum in the schema.
82
83
  ## Authorization error codes
83
84
 
84
85
  An authorization error happens when the caller does not hold the
85
- [scope](./authorization-and-scopes.md) that an operation needs.
86
+ [scope](/reference/management-api/authorization-and-scopes) that an operation needs.
86
87
 
87
88
  | Code | Description |
88
89
  |------|-------------|
@@ -198,7 +199,7 @@ if (result.errors) {
198
199
  ### Refresh a token that expired
199
200
 
200
201
  A request can return `UNAUTHORIZED` while the caller holds a refresh token. Try a
201
- [session refresh](/api/authentication#refresh-a-session) first. Do not treat it as a
202
+ [session refresh](/reference/management-api/authentication#refresh-a-session) first. Do not treat it as a
202
203
  failure to sign in:
203
204
 
204
205
  ```javascript
@@ -225,3 +226,8 @@ both.
225
226
  `INTERNAL_ERROR` and `RATE_LIMITED` are both transient. For `RATE_LIMITED`, use an
226
227
  exponential backoff before you try again. For `INTERNAL_ERROR`, one more try is
227
228
  usually enough.
229
+
230
+ ## Related
231
+
232
+ - [Authentication](/reference/management-api/authentication)
233
+ - [Your first API call](/tutorials/first-api-call)
@@ -1,4 +1,5 @@
1
1
  ---
2
+ type: reference
2
3
  layout: docs
3
4
  ---
4
5
 
@@ -184,3 +185,8 @@ All of these fields accept the same `first` and `after` arguments and return the
184
185
  - **Use them with other fields** — you can use the pagination arguments together with
185
186
  other query fields. One request that reads an organization and the first page of
186
187
  its members is common, and it is efficient.
188
+
189
+ ## Related
190
+
191
+ - [Your first API call](/tutorials/first-api-call)
192
+ - [Authorization and scopes](/reference/management-api/authorization-and-scopes)
@@ -1,4 +1,5 @@
1
1
  ---
2
+ type: reference
2
3
  layout: docs
3
4
  ---
4
5
 
@@ -61,8 +62,8 @@ are optional, and each has a sensible default.
61
62
  | `experience_id` | Limits the rows to one `fact_events.experience_id`. |
62
63
  | `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
64
  | `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`. |
65
+ | `num_nodes_after_start` | The size of the forward window from the start step. |
66
+ | `num_nodes_before_target` | The size of the backward window from the target step. It needs `targeting_step`. |
66
67
  | `top_n_path` | Keeps the paths with the most users, and drops the rest. |
67
68
  | `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
69
  | `client_local_date` | A filter on the date. It takes `=`, `<`, `<=`, `>`, `>=`, and `BETWEEN`. PickedQL puts it into the `fact_events` read below. |
@@ -72,7 +73,7 @@ When you set both `num_nodes_after_start` and `num_nodes_before_target`, both te
72
73
  apply. The result is the intersection of the two.
73
74
 
74
75
  ```sql
75
- -- The "overall user journey" sankey, as in card 4129.
76
+ -- The "overall user journey" sankey.
76
77
  -- It uses a forward window. The target step is optional.
77
78
  SELECT source, target, users FROM experience_journey
78
79
  WHERE project_id = 'your-project-id'
@@ -84,7 +85,7 @@ WHERE project_id = 'your-project-id'
84
85
  ```
85
86
 
86
87
  ```sql
87
- -- The "paths to a target" sankey, as in card 2740.
88
+ -- The "paths to a target" sankey.
88
89
  -- It uses a backward window and it ranks the top paths.
89
90
  SELECT source, target, users FROM experience_journey
90
91
  WHERE project_id = 'your-project-id'
@@ -96,7 +97,7 @@ WHERE project_id = 'your-project-id'
96
97
  ```
97
98
 
98
99
  ```sql
99
- -- The "drop-off" sankey, as in card 2744. Leave the target step out.
100
+ -- The "drop-off" sankey. Leave the target step out.
100
101
  SELECT source, target, users FROM experience_journey
101
102
  WHERE project_id = 'your-project-id'
102
103
  AND experience_id = 'exp-123'
@@ -105,7 +106,7 @@ WHERE project_id = 'your-project-id'
105
106
  ```
106
107
 
107
108
  ```sql
108
- -- A cohort sankey, as in card 3961. It holds the users who reached the goal only.
109
+ -- A cohort sankey. It holds the users who reached the goal only.
109
110
  SELECT source, target, users FROM experience_journey
110
111
  WHERE project_id = 'your-project-id'
111
112
  AND starting_step = 'step-start'
@@ -132,7 +133,7 @@ transitions yourself.
132
133
 
133
134
  ## Reference tables — `steps`, `experiences`, `projects`
134
135
 
135
- These reference tables hold the options of your Picked project. They have two uses:
136
+ These reference tables hold the configuration of your Picked project. They have two uses:
136
137
 
137
138
  - **PickedQL joins them onto `events`** when you point at one of their analyst
138
139
  columns: `step_title`, `experience_title`, `project_name`, or `project_timezone`.
@@ -163,5 +164,11 @@ WHERE project_id = 'your-project-id'
163
164
  GROUP BY experience_title, step_title
164
165
  ```
165
166
 
166
- See [Schema, reference tables](./schema#steps-experiences-projects) for the full
167
- column list and the join keys.
167
+ See [Schema, reference tables](/reference/pickedql/schema#steps-experiences-projects) for the full
168
+ column list and the join keys.
169
+
170
+ ## Related
171
+
172
+ - [About PickedQL](/explanation/how-pickedql-works) — what the layer expands for you.
173
+ - [Schema](/reference/pickedql/schema)
174
+ - [Analytics queries](/how-to/analytics)
@@ -1,4 +1,5 @@
1
1
  ---
2
+ type: reference
2
3
  layout: docs
3
4
  ---
4
5
 
@@ -78,3 +79,9 @@ SELECT step_title, n FROM (
78
79
  These columns are on `events` directly, and they need no join:
79
80
 
80
81
  `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`.
82
+
83
+ ## Related
84
+
85
+ - [About PickedQL](/explanation/how-pickedql-works) — why you write no join.
86
+ - [Data sources](/reference/pickedql/data-sources)
87
+ - [Analytics queries](/how-to/analytics)
@@ -1,4 +1,5 @@
1
1
  ---
2
+ type: reference
2
3
  layout: docs
3
4
  ---
4
5
 
@@ -55,3 +56,9 @@ SELECT id, name, timezone FROM projects WHERE id = 'your-project-id'
55
56
  ```
56
57
 
57
58
  The small lookup tables (`dim_variant`, `dim_device`, `dim_geo`, `dim_utm`, `dim_product`) are still exempt — they contain no tenant data.
59
+
60
+ ## Related
61
+
62
+ - [Virtual functions](/reference/pickedql/virtual-functions) — the functions that take a
63
+ filter.
64
+ - [Analytics queries](/how-to/analytics)
@@ -0,0 +1,18 @@
1
+ ---
2
+ type: reference
3
+ layout: docs
4
+ ---
5
+
6
+ # PickedQL
7
+
8
+ PickedQL is a SQL query language for your Picked analytics data. Write short SQL with
9
+ a virtual table and a virtual function. PickedQL expands them into a full query, and
10
+ it adds the joins and the A/B test aggregations for you.
11
+
12
+ ## Related
13
+
14
+ - [About PickedQL](/explanation/how-pickedql-works) — what the layer expands, and why a
15
+ tenant filter is required.
16
+ - [Analytics queries](/how-to/analytics) — worked examples.
17
+ - [Data sources](/reference/pickedql/data-sources) — every table.
18
+ - [Filters](/reference/pickedql/filtering) — the filter string a virtual function takes.
@@ -1,4 +1,5 @@
1
1
  ---
2
+ type: reference
2
3
  layout: docs
3
4
  ---
4
5
 
@@ -28,7 +29,7 @@ Pre-aggregated daily data. One row per unique combination of dimensions per day.
28
29
  | `landing_page_url` | `String` | Landing page URL |
29
30
 
30
31
  :::note
31
- Aggregate columns (`users`, `sessions`, `events`, and so on) are not queried directly — use [virtual functions](./virtual-functions) instead.
32
+ Aggregate columns (`users`, `sessions`, `events`, and so on) are not queried directly — use [virtual functions](/reference/pickedql/virtual-functions) instead.
32
33
  :::
33
34
 
34
35
  ## `events`
@@ -90,7 +91,7 @@ These columns are joined automatically when referenced — no `JOIN` syntax need
90
91
 
91
92
  ## `steps`, `experiences`, `projects`
92
93
 
93
- These reference tables hold the options of your Picked project. PickedQL joins them
94
+ These reference tables hold the configuration of your Picked project. PickedQL joins them
94
95
  onto `events` when you point at one of their analyst-facing columns. Each one needs
95
96
  its own tenant filter when you read it directly.
96
97
 
@@ -119,7 +120,7 @@ GROUP BY experience_title, step_title
119
120
  ## `features`
120
121
 
121
122
  The `features` table gives you
122
- [parameterized virtual functions](./virtual-functions#feature-functions-on-features-and-on-events).
123
+ [parameterized virtual functions](/reference/pickedql/virtual-functions#feature-functions-on-features-and-on-events).
123
124
  Use them to read which visitors each feature flag holds:
124
125
 
125
126
  | Function | Description |
@@ -150,8 +151,8 @@ outer `WHERE` clause. PickedQL reads them and puts them into the query below.
150
151
  | `experience_id` | `String` | | Limits the rows to one `fact_events.experience_id`. |
151
152
  | `starting_step` | `String` | | Anchors each edge at the first time that a user reaches this `step_id`. The default is the first step of each user. |
152
153
  | `targeting_step` | `String` | | 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 the journey up to that point. |
153
- | `num_nodes_after_start` | Integer | | The forward window from the start. It keeps a step where `seq_pos < start_seq + N`. This is what card 4129 does. |
154
- | `num_nodes_before_target` | Integer | | The backward window from the target. It keeps a step where `seq_pos >= target_seq - N`. This is what card 2740 does. It needs `targeting_step`. |
154
+ | `num_nodes_after_start` | Integer | | The forward window from the start. It keeps a step where `seq_pos < start_seq + N`. |
155
+ | `num_nodes_before_target` | Integer | | The backward window from the target. It keeps a step where `seq_pos >= target_seq - N`. It needs `targeting_step`. |
155
156
  | `top_n_path` | Integer | | Keeps the paths that the most users take, and drops the rest. The default is no limit. |
156
157
  | `user_cohort_event` | `String` | | Limits the rows to a user with at least one `fact_events` row of this `event_type`. PickedQL writes it as `user_canonical_id IN (SELECT DISTINCT user_canonical_id FROM fact_events WHERE event_type = '…')`. |
157
158
  | `client_local_date` | `Date` | | A filter on a range of dates. PickedQL puts it into the read below. It takes `=`, `<`, `<=`, `>`, `>=`, and `BETWEEN`. |
@@ -161,5 +162,11 @@ When you set both window parameters, both tests apply, and the result is their
161
162
  intersection. A date filter joins the other parameters with `AND`.
162
163
 
163
164
  See
164
- [data sources, `experience_journey`](./data-sources#experience_journey--step-transitions-for-a-sankey-chart)
165
+ [data sources, `experience_journey`](/reference/pickedql/data-sources#experience_journey--step-transitions-for-a-sankey-chart)
165
166
  for examples.
167
+
168
+ ## Related
169
+
170
+ - [Data sources](/reference/pickedql/data-sources)
171
+ - [Dimensions](/reference/pickedql/dimensions)
172
+ - [About PickedQL](/explanation/how-pickedql-works)