@picked/client 0.0.1-dev.1785305085063 → 0.0.1-dev.1785908062293
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-03c5jvVk.js +38 -0
- package/dist/api-CQxCVIrm.cjs +1 -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/explanation/conditions-and-the-logic-engine.md +94 -0
- package/dist/docs/explanation/feature-flag-allocation.md +176 -0
- package/dist/docs/explanation/how-picked-works.md +124 -0
- package/dist/docs/explanation/how-pickedql-works.md +76 -0
- package/dist/docs/explanation/pages-and-flows.md +64 -0
- package/dist/docs/explanation/the-content-model.md +77 -0
- package/dist/docs/explanation/the-two-apis.md +68 -0
- package/dist/docs/explanation/why-server-side-rendering.md +76 -0
- package/dist/docs/explanation/workspaces-and-versions.md +71 -0
- package/dist/docs/how-to/add-a-step-field-or-action.md +43 -0
- package/dist/docs/{pickedql/examples.md → how-to/analytics/index.md} +53 -28
- package/dist/docs/how-to/archive-or-delete-a-workspace.md +46 -0
- package/dist/docs/how-to/authenticate-with-a-magic-link.md +40 -0
- package/dist/docs/how-to/authenticate-with-a-password.md +51 -0
- package/dist/docs/how-to/authenticate-with-an-api-key.md +51 -0
- package/dist/docs/how-to/authenticate-with-oauth.md +40 -0
- package/dist/docs/how-to/build-a-flow.md +83 -0
- package/dist/docs/how-to/connect-the-mcp-server.md +38 -0
- package/dist/docs/how-to/create-a-project.md +29 -0
- package/dist/docs/how-to/create-an-experience.md +42 -0
- package/dist/docs/how-to/create-and-revoke-an-api-key.md +37 -0
- package/dist/docs/how-to/debug-with-the-chrome-extension.md +57 -0
- package/dist/docs/how-to/define-a-page-layout.md +39 -0
- package/dist/docs/how-to/fill-and-publish-a-page.md +50 -0
- package/dist/docs/how-to/install-the-gtm-template.md +84 -0
- package/dist/docs/how-to/install-the-sdk.md +68 -0
- package/dist/docs/how-to/install-the-vite-plugin.md +56 -0
- package/dist/docs/how-to/invite-and-remove-members.md +34 -0
- package/dist/docs/how-to/preview-a-workspace.md +28 -0
- package/dist/docs/how-to/publish-a-workspace.md +30 -0
- package/dist/docs/how-to/read-a-feature-flag.md +101 -0
- package/dist/docs/how-to/register-a-component.md +55 -0
- package/dist/docs/how-to/register-an-action-handler.md +67 -0
- package/dist/docs/how-to/render-a-step-form.md +132 -0
- package/dist/docs/how-to/render-an-unpublished-preview.md +41 -0
- package/dist/docs/how-to/reuse-a-section.md +37 -0
- package/dist/docs/how-to/reuse-a-step-field-or-action.md +28 -0
- package/dist/docs/how-to/roll-back-a-published-version.md +26 -0
- package/dist/docs/how-to/run-an-ab-test.md +49 -0
- package/dist/docs/how-to/run-code-on-a-form-submission.md +125 -0
- package/dist/docs/how-to/server-render-a-page.md +81 -0
- package/dist/docs/how-to/set-a-content-security-policy.md +32 -0
- package/dist/docs/how-to/set-up-mfa.md +69 -0
- package/dist/docs/how-to/upload-and-use-an-asset.mdx +73 -0
- package/dist/docs/how-to/validate-a-field.md +52 -0
- package/dist/docs/how-to/write-a-condition.md +45 -0
- package/dist/docs/how-to/write-a-predicate.md +60 -0
- package/dist/docs/index.md +41 -59
- package/dist/docs/reference/dashboard/actions.mdx +53 -0
- package/dist/docs/reference/dashboard/api-keys.mdx +37 -0
- package/dist/docs/reference/dashboard/conditions.mdx +42 -0
- package/dist/docs/reference/dashboard/content/asset-library.mdx +63 -0
- package/dist/docs/reference/dashboard/content/content-entries.mdx +44 -0
- package/dist/docs/reference/dashboard/content/layouts.mdx +62 -0
- package/dist/docs/reference/dashboard/content/pages.mdx +35 -0
- package/dist/docs/reference/dashboard/content/sections.mdx +28 -0
- package/dist/docs/reference/dashboard/experiences.mdx +51 -0
- package/dist/docs/reference/dashboard/features.mdx +114 -0
- package/dist/docs/reference/dashboard/fields.mdx +100 -0
- package/dist/docs/reference/dashboard/flow-builder/canvas.mdx +58 -0
- package/dist/docs/reference/dashboard/flow-builder/condition-builder.md +57 -0
- package/dist/docs/reference/dashboard/flow-builder/keyboard-shortcuts.md +72 -0
- package/dist/docs/reference/dashboard/flow-builder/nodes.md +63 -0
- package/dist/docs/reference/dashboard/projects.mdx +44 -0
- package/dist/docs/reference/dashboard/reports.mdx +43 -0
- package/dist/docs/reference/dashboard/steps.mdx +37 -0
- package/dist/docs/reference/dashboard/team-management.md +29 -0
- package/dist/docs/reference/dashboard/workspace-versioning.mdx +30 -0
- package/dist/docs/reference/dashboard/workspaces.mdx +76 -0
- package/dist/docs/{delivery-api → reference/delivery-api}/experience-content.md +17 -5
- package/dist/docs/reference/delivery-api/index.md +45 -0
- package/dist/docs/reference/delivery-api/preview-caching-crawling.md +79 -0
- package/dist/docs/{delivery-api → reference/delivery-api}/project-config.md +15 -6
- package/dist/docs/reference/glossary.md +173 -0
- package/dist/docs/reference/management-api/authentication.md +74 -0
- package/dist/docs/{api → reference/management-api}/authorization-and-scopes.md +70 -47
- package/dist/docs/reference/management-api/error-handling.md +233 -0
- package/dist/docs/{api → reference/management-api}/pagination.md +36 -20
- package/dist/docs/reference/pickedql/data-sources.md +174 -0
- package/dist/docs/reference/pickedql/dimensions.md +87 -0
- package/dist/docs/{pickedql → reference/pickedql}/filtering.md +17 -6
- package/dist/docs/reference/pickedql/index.md +18 -0
- package/dist/docs/reference/pickedql/schema.md +172 -0
- package/dist/docs/reference/pickedql/virtual-functions.md +237 -0
- package/dist/docs/reference/sdk/actions.md +30 -0
- package/dist/docs/{sdk → reference/sdk}/conditions.md +15 -5
- package/dist/docs/reference/sdk/content-security-policy.md +21 -0
- package/dist/docs/reference/sdk/experiences.md +51 -0
- package/dist/docs/reference/sdk/features.md +233 -0
- package/dist/docs/reference/sdk/fields.md +209 -0
- package/dist/docs/reference/sdk/index.md +68 -0
- package/dist/docs/{sdk → reference/sdk}/plugins/create-experience.md +25 -34
- package/dist/docs/reference/sdk/plugins/dynamic-experiences.md +74 -0
- package/dist/docs/reference/sdk/plugins/index.md +29 -0
- package/dist/docs/{sdk → reference/sdk}/plugins/window-object.md +6 -0
- package/dist/docs/reference/sdk/predicates.md +43 -0
- package/dist/docs/reference/sdk/ssr/index.md +33 -0
- package/dist/docs/reference/sdk/ssr/rendering-and-hydration.md +103 -0
- package/dist/docs/reference/sdk/ssr/serialize.md +77 -0
- package/dist/docs/reference/sdk/ssr/slots-and-placements.md +59 -0
- package/dist/docs/reference/sdk/steps.md +87 -0
- package/dist/docs/reference/tools/chrome-extension.md +16 -0
- package/dist/docs/reference/tools/image-optimisation-service.md +104 -0
- package/dist/docs/reference/tools/mcp.md +88 -0
- package/dist/docs/reference/tools/vite-plugin.md +88 -0
- package/dist/docs/tutorials/first-api-call.md +228 -0
- package/dist/docs/tutorials/first-experience-in-the-dashboard.mdx +143 -0
- package/dist/docs/tutorials/first-experience.mdx +255 -0
- package/dist/docs/tutorials/first-server-rendered-page.mdx +186 -0
- 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 +225 -186
- package/dist/esm/plugins/dom-observer/index.js +1 -1
- package/dist/esm/plugins/dynamic-experiences/index.js +3 -3
- package/dist/esm/preview/index.js +1 -1
- package/dist/esm/server/index.js +33 -31
- package/dist/{experience-instance-DOJShRk5.js → experience-instance-DGk11d8a.js} +3 -3
- package/dist/experience-instance-Dej3P1sE.cjs +1 -0
- package/dist/plugin-CHOVsx7Z.js +287 -0
- package/dist/plugin-DsaGXQHx.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/data-source/api.d.ts +60 -0
- package/dist/types/data-source/api.d.ts.map +1 -0
- package/dist/types/data-source/provider.d.ts +97 -0
- package/dist/types/data-source/provider.d.ts.map +1 -0
- 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 +19 -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 +79 -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/hash.d.ts +40 -5
- package/dist/types/plugins/dynamic-experiences/hash.d.ts.map +1 -1
- package/dist/types/plugins/dynamic-experiences/index.d.ts +2 -0
- package/dist/types/plugins/dynamic-experiences/index.d.ts.map +1 -1
- package/dist/types/plugins/dynamic-experiences/plugin.d.ts +4 -36
- package/dist/types/plugins/dynamic-experiences/plugin.d.ts.map +1 -1
- package/dist/types/plugins/dynamic-experiences/types.d.ts +42 -11
- package/dist/types/plugins/dynamic-experiences/types.d.ts.map +1 -1
- 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 +8 -2
- package/dist/types/server/serialize.d.ts.map +1 -1
- 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/rehydrate-scripts.d.ts +6 -0
- package/dist/types/utils/rehydrate-scripts.d.ts.map +1 -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-CPL40b7A.js +0 -40
- package/dist/api-Dz5rgRgQ.cjs +0 -1
- package/dist/docs/actions.mdx +0 -78
- package/dist/docs/api/authentication.md +0 -376
- package/dist/docs/api/error-handling.md +0 -211
- package/dist/docs/api/index.md +0 -197
- package/dist/docs/api-keys.mdx +0 -40
- package/dist/docs/chrome-extension.md +0 -51
- package/dist/docs/conditions.mdx +0 -59
- package/dist/docs/content/asset-library.mdx +0 -93
- package/dist/docs/content/content-entries.mdx +0 -30
- package/dist/docs/content/layouts.mdx +0 -70
- package/dist/docs/content/pages.mdx +0 -67
- package/dist/docs/content/sections.mdx +0 -33
- package/dist/docs/delivery-api/index.md +0 -46
- package/dist/docs/delivery-api/preview-caching-crawling.md +0 -59
- package/dist/docs/experiences.mdx +0 -42
- package/dist/docs/features.mdx +0 -58
- package/dist/docs/fields.mdx +0 -79
- package/dist/docs/flow-builder/building-flows.md +0 -61
- package/dist/docs/flow-builder/condition-builder.md +0 -54
- package/dist/docs/flow-builder/keyboard-shortcuts.md +0 -66
- package/dist/docs/flow-builder/nodes.md +0 -43
- package/dist/docs/flow-builder/overview.mdx +0 -50
- package/dist/docs/gtm-template.md +0 -69
- package/dist/docs/guides/build-a-personalized-page.mdx +0 -143
- package/dist/docs/image-optimisation-service.md +0 -80
- package/dist/docs/mcp.md +0 -120
- package/dist/docs/pickedql/data-sources.md +0 -145
- package/dist/docs/pickedql/dimensions.md +0 -65
- package/dist/docs/pickedql/index.md +0 -36
- package/dist/docs/pickedql/schema.md +0 -156
- package/dist/docs/pickedql/virtual-functions.md +0 -204
- package/dist/docs/projects.mdx +0 -37
- package/dist/docs/reports.mdx +0 -18
- package/dist/docs/sdk/actions.md +0 -66
- package/dist/docs/sdk/content-security-policy.md +0 -32
- package/dist/docs/sdk/experiences.md +0 -46
- package/dist/docs/sdk/features.md +0 -212
- package/dist/docs/sdk/fields.md +0 -263
- package/dist/docs/sdk/index.md +0 -83
- package/dist/docs/sdk/plugins/dynamic-experiences.md +0 -58
- package/dist/docs/sdk/plugins/index.md +0 -9
- package/dist/docs/sdk/predicates.md +0 -112
- package/dist/docs/sdk/ssr/index.md +0 -62
- package/dist/docs/sdk/ssr/rendering-and-hydration.md +0 -141
- package/dist/docs/sdk/ssr/serialize.md +0 -86
- package/dist/docs/sdk/ssr/slots-and-placements.md +0 -35
- package/dist/docs/sdk/steps.md +0 -434
- package/dist/docs/steps.mdx +0 -44
- package/dist/docs/team-management.md +0 -40
- package/dist/docs/vite-plugin.md +0 -82
- package/dist/docs/workspace-versioning.mdx +0 -28
- package/dist/docs/workspaces.mdx +0 -102
- package/dist/experience-instance-DurC3pE-.cjs +0 -1
- package/dist/plugin-CFXwbXeM.js +0 -247
- package/dist/plugin-m4qekgtA.cjs +0 -1
|
@@ -1,211 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
layout: docs
|
|
3
|
-
---
|
|
4
|
-
|
|
5
|
-
# Error handling
|
|
6
|
-
|
|
7
|
-
The Picked API returns errors using the standard GraphQL error format. This guide covers the error response shape, all error codes, and practical strategies for handling errors.
|
|
8
|
-
|
|
9
|
-
## Error response shape
|
|
10
|
-
|
|
11
|
-
When an operation fails, the API returns an `errors` array in the response body. Each error object contains:
|
|
12
|
-
|
|
13
|
-
```json
|
|
14
|
-
{
|
|
15
|
-
"data": null,
|
|
16
|
-
"errors": [
|
|
17
|
-
{
|
|
18
|
-
"message": "A human-readable description of the error",
|
|
19
|
-
"path": ["mutationName"],
|
|
20
|
-
"extensions": {
|
|
21
|
-
"code": "ERROR_CODE"
|
|
22
|
-
}
|
|
23
|
-
}
|
|
24
|
-
]
|
|
25
|
-
}
|
|
26
|
-
```
|
|
27
|
-
|
|
28
|
-
| Field | Description |
|
|
29
|
-
|-------|-------------|
|
|
30
|
-
| `message` | A human-readable error description. Suitable for logging but not for programmatic handling. |
|
|
31
|
-
| `path` | The path to the field in the query that caused the error. |
|
|
32
|
-
| `extensions.code` | A machine-readable error code. Use this for programmatic error handling. |
|
|
33
|
-
|
|
34
|
-
Multiple errors may appear in a single response. The `data` field may be `null` if the entire operation failed, or it may contain partial data if only some fields failed.
|
|
35
|
-
|
|
36
|
-
## Authentication error codes
|
|
37
|
-
|
|
38
|
-
These errors relate to session creation, account management, OAuth, magic links, password operations, and MFA. They map to the `AuthErrorCode` enum in the schema.
|
|
39
|
-
|
|
40
|
-
| Code | Description |
|
|
41
|
-
|------|-------------|
|
|
42
|
-
| `INVALID_CREDENTIALS` | The email/password combination is incorrect. |
|
|
43
|
-
| `EMAIL_NOT_CONFIRMED` | The account exists but the email address has not been verified. See [Authentication](/api/authentication#email-verification). |
|
|
44
|
-
| `USER_NOT_FOUND` | No account exists with the provided email address. |
|
|
45
|
-
| `USER_ALREADY_EXISTS` | An account with this email already exists. Returned during account creation. |
|
|
46
|
-
| `WEAK_PASSWORD` | The provided password does not meet strength requirements. |
|
|
47
|
-
| `INVALID_TOKEN` | The token (verification, reset, or magic link) is invalid or malformed. |
|
|
48
|
-
| `TOKEN_EXPIRED` | The token has expired. The caller should request a new one. |
|
|
49
|
-
| `MFA_CHALLENGE_FAILED` | The MFA verification code is incorrect. |
|
|
50
|
-
| `MFA_FACTOR_NOT_FOUND` | The specified MFA factor does not exist or does not belong to the caller. |
|
|
51
|
-
| `OAUTH_PROVIDER_ERROR` | An error occurred communicating with the OAuth provider (e.g., Google). |
|
|
52
|
-
| `RATE_LIMITED` | Too many requests in a short period. The caller should wait and retry. |
|
|
53
|
-
|
|
54
|
-
### Example: invalid credentials
|
|
55
|
-
|
|
56
|
-
```json
|
|
57
|
-
{
|
|
58
|
-
"data": {
|
|
59
|
-
"sessionCreate": {
|
|
60
|
-
"session": null,
|
|
61
|
-
"requiresMfa": false,
|
|
62
|
-
"mfaFactors": null
|
|
63
|
-
}
|
|
64
|
-
},
|
|
65
|
-
"errors": [
|
|
66
|
-
{
|
|
67
|
-
"message": "Invalid credentials",
|
|
68
|
-
"path": ["sessionCreate"],
|
|
69
|
-
"extensions": {
|
|
70
|
-
"code": "INVALID_CREDENTIALS"
|
|
71
|
-
}
|
|
72
|
-
}
|
|
73
|
-
]
|
|
74
|
-
}
|
|
75
|
-
```
|
|
76
|
-
|
|
77
|
-
## Authorization error codes
|
|
78
|
-
|
|
79
|
-
Authorization errors occur when the caller lacks the required [scope](./authorization-and-scopes.md) for an operation.
|
|
80
|
-
|
|
81
|
-
| Code | Description |
|
|
82
|
-
|------|-------------|
|
|
83
|
-
| `UNAUTHORIZED` | No valid authentication was provided. The request is missing the `Authorization` header or the `x-api-key` header, or the token/key is invalid. |
|
|
84
|
-
| `FORBIDDEN` | The caller is authenticated but does not have the required scope for the operation. |
|
|
85
|
-
|
|
86
|
-
### Example: insufficient scope
|
|
87
|
-
|
|
88
|
-
A caller with only `organization/read` attempting to delete an organization receives:
|
|
89
|
-
|
|
90
|
-
```json
|
|
91
|
-
{
|
|
92
|
-
"data": {
|
|
93
|
-
"organizationDelete": null
|
|
94
|
-
},
|
|
95
|
-
"errors": [
|
|
96
|
-
{
|
|
97
|
-
"message": "Insufficient permissions",
|
|
98
|
-
"path": ["organizationDelete"],
|
|
99
|
-
"extensions": {
|
|
100
|
-
"code": "FORBIDDEN"
|
|
101
|
-
}
|
|
102
|
-
}
|
|
103
|
-
]
|
|
104
|
-
}
|
|
105
|
-
```
|
|
106
|
-
|
|
107
|
-
## Organization, member, and invitation error codes
|
|
108
|
-
|
|
109
|
-
These errors relate to organization management, member operations, and invitation workflows. They map to the `ErrorCode` enum in the schema.
|
|
110
|
-
|
|
111
|
-
### Organization errors
|
|
112
|
-
|
|
113
|
-
| Code | Description |
|
|
114
|
-
|------|-------------|
|
|
115
|
-
| `ORGANIZATION_NOT_FOUND` | The specified organization does not exist or the caller does not have access to it. |
|
|
116
|
-
| `ORGANIZATION_ALREADY_EXISTS` | An organization with this name already exists. |
|
|
117
|
-
| `SLUG_ALREADY_EXISTS` | The requested slug is already in use by another organization. |
|
|
118
|
-
| `INVALID_SLUG` | The slug contains invalid characters. Slugs must be lowercase alphanumeric with hyphens. |
|
|
119
|
-
|
|
120
|
-
### Member errors
|
|
121
|
-
|
|
122
|
-
| Code | Description |
|
|
123
|
-
|------|-------------|
|
|
124
|
-
| `MEMBER_NOT_FOUND` | The specified user is not a member of the organization. |
|
|
125
|
-
| `MEMBER_ALREADY_EXISTS` | The user is already a member of the organization. |
|
|
126
|
-
| `CANNOT_REMOVE_PRIMARY_OWNER` | The primary owner of an organization cannot be removed. |
|
|
127
|
-
| `CANNOT_CHANGE_OWN_ROLE` | A member cannot change their own role. Another owner must perform this action. |
|
|
128
|
-
|
|
129
|
-
### Invitation errors
|
|
130
|
-
|
|
131
|
-
| Code | Description |
|
|
132
|
-
|------|-------------|
|
|
133
|
-
| `INVITATION_NOT_FOUND` | The specified invitation does not exist. |
|
|
134
|
-
| `INVITATION_EXPIRED` | The invitation has expired and can no longer be accepted. |
|
|
135
|
-
| `INVITATION_ALREADY_ACCEPTED` | The invitation has already been accepted. |
|
|
136
|
-
|
|
137
|
-
### Project errors
|
|
138
|
-
|
|
139
|
-
| Code | Description |
|
|
140
|
-
|------|-------------|
|
|
141
|
-
| `PROJECT_NOT_FOUND` | The specified project does not exist or the caller does not have access. |
|
|
142
|
-
|
|
143
|
-
### General errors
|
|
144
|
-
|
|
145
|
-
| Code | Description |
|
|
146
|
-
|------|-------------|
|
|
147
|
-
| `VALIDATION_ERROR` | The input failed validation. Check the `message` field for details about which field is invalid. |
|
|
148
|
-
| `INTERNAL_ERROR` | An unexpected server error occurred. Retry the request or contact support if the issue persists. |
|
|
149
|
-
|
|
150
|
-
## Handling errors in practice
|
|
151
|
-
|
|
152
|
-
### Check for errors first
|
|
153
|
-
|
|
154
|
-
Every response should be checked for the presence of an `errors` array before processing `data`:
|
|
155
|
-
|
|
156
|
-
```javascript
|
|
157
|
-
const response = await fetch('/graphql', {
|
|
158
|
-
method: 'POST',
|
|
159
|
-
headers: {
|
|
160
|
-
'Content-Type': 'application/json',
|
|
161
|
-
'Authorization': `Bearer ${accessToken}`,
|
|
162
|
-
},
|
|
163
|
-
body: JSON.stringify({ query, variables }),
|
|
164
|
-
});
|
|
165
|
-
|
|
166
|
-
const result = await response.json();
|
|
167
|
-
|
|
168
|
-
if (result.errors) {
|
|
169
|
-
for (const error of result.errors) {
|
|
170
|
-
const code = error.extensions?.code;
|
|
171
|
-
|
|
172
|
-
switch (code) {
|
|
173
|
-
case 'UNAUTHORIZED':
|
|
174
|
-
// Redirect to login
|
|
175
|
-
break;
|
|
176
|
-
case 'FORBIDDEN':
|
|
177
|
-
// Show a permissions error
|
|
178
|
-
break;
|
|
179
|
-
case 'RATE_LIMITED':
|
|
180
|
-
// Wait and retry
|
|
181
|
-
break;
|
|
182
|
-
default:
|
|
183
|
-
// Log or display the error message
|
|
184
|
-
console.error(error.message);
|
|
185
|
-
}
|
|
186
|
-
}
|
|
187
|
-
}
|
|
188
|
-
```
|
|
189
|
-
|
|
190
|
-
### Refresh expired tokens
|
|
191
|
-
|
|
192
|
-
If a request returns `UNAUTHORIZED` and the caller has a refresh token, attempt a [session refresh](/api/authentication#session-refresh) before treating it as a login failure:
|
|
193
|
-
|
|
194
|
-
```javascript
|
|
195
|
-
if (code === 'UNAUTHORIZED' && refreshToken) {
|
|
196
|
-
const refreshResult = await sessionRefresh(refreshToken);
|
|
197
|
-
if (refreshResult.session) {
|
|
198
|
-
// Retry the original request with the new access token
|
|
199
|
-
} else {
|
|
200
|
-
// Redirect to login
|
|
201
|
-
}
|
|
202
|
-
}
|
|
203
|
-
```
|
|
204
|
-
|
|
205
|
-
### Handle partial data
|
|
206
|
-
|
|
207
|
-
GraphQL can return partial data alongside errors. For example, a query that fetches an organization and its members might succeed for the organization but fail for the members if the caller lacks `organization_members/read`. In this case, the response contains both `data` (with the organization) and `errors` (for the members field). Always check both.
|
|
208
|
-
|
|
209
|
-
### Retry transient failures
|
|
210
|
-
|
|
211
|
-
`INTERNAL_ERROR` and `RATE_LIMITED` are transient. For `RATE_LIMITED`, implement exponential backoff before retrying. For `INTERNAL_ERROR`, a single retry is usually sufficient.
|
package/dist/docs/api/index.md
DELETED
|
@@ -1,197 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
layout: docs
|
|
3
|
-
---
|
|
4
|
-
|
|
5
|
-
# Getting started
|
|
6
|
-
|
|
7
|
-
This guide walks you through your first interactions with the Picked GraphQL API, from sending a simple ping to making authenticated queries and mutations.
|
|
8
|
-
|
|
9
|
-
:::note
|
|
10
|
-
This reference covers the authenticated GraphQL management API. To serve your published config and page content to your app, use the public, read-only [Delivery API](/delivery-api) instead.
|
|
11
|
-
:::
|
|
12
|
-
|
|
13
|
-
## Playground
|
|
14
|
-
|
|
15
|
-
Explore the API and run queries interactively in the [GraphQL Playground](https://api.picked.app/api/graphql).
|
|
16
|
-
|
|
17
|
-
## API endpoint
|
|
18
|
-
|
|
19
|
-
All requests go to a single endpoint:
|
|
20
|
-
|
|
21
|
-
```
|
|
22
|
-
POST https://api.picked.app/api/graphql
|
|
23
|
-
```
|
|
24
|
-
|
|
25
|
-
Every request must use the `POST` method with a JSON body containing a `query` field and an optional `variables` field:
|
|
26
|
-
|
|
27
|
-
```json
|
|
28
|
-
{
|
|
29
|
-
"query": "query { ... }",
|
|
30
|
-
"variables": { }
|
|
31
|
-
}
|
|
32
|
-
```
|
|
33
|
-
|
|
34
|
-
Set the `Content-Type` header to `application/json` on every request.
|
|
35
|
-
|
|
36
|
-
```bash
|
|
37
|
-
curl -X POST https://api.picked.app/api/graphql \
|
|
38
|
-
-H "Content-Type: application/json" \
|
|
39
|
-
-d '{"query": "{ ping }"}'
|
|
40
|
-
```
|
|
41
|
-
|
|
42
|
-
## Ping the API
|
|
43
|
-
|
|
44
|
-
Verify that the API is reachable with the `ping` query. This query does not require authentication.
|
|
45
|
-
|
|
46
|
-
```graphql
|
|
47
|
-
query {
|
|
48
|
-
ping
|
|
49
|
-
}
|
|
50
|
-
```
|
|
51
|
-
|
|
52
|
-
Response:
|
|
53
|
-
|
|
54
|
-
```json
|
|
55
|
-
{
|
|
56
|
-
"data": {
|
|
57
|
-
"ping": "pong"
|
|
58
|
-
}
|
|
59
|
-
}
|
|
60
|
-
```
|
|
61
|
-
|
|
62
|
-
If you receive this response, the API is up and ready.
|
|
63
|
-
|
|
64
|
-
## Authenticate
|
|
65
|
-
|
|
66
|
-
Most operations require an access token. You obtain one by creating a session with your email and password.
|
|
67
|
-
|
|
68
|
-
```graphql
|
|
69
|
-
mutation {
|
|
70
|
-
sessionCreate(input: {
|
|
71
|
-
email: "you@example.com"
|
|
72
|
-
password: "your-password"
|
|
73
|
-
}) {
|
|
74
|
-
session {
|
|
75
|
-
accessToken
|
|
76
|
-
refreshToken
|
|
77
|
-
expiresAt
|
|
78
|
-
}
|
|
79
|
-
requiresMfa
|
|
80
|
-
}
|
|
81
|
-
}
|
|
82
|
-
```
|
|
83
|
-
|
|
84
|
-
A successful response returns a `Session` containing an `accessToken` and a `refreshToken`:
|
|
85
|
-
|
|
86
|
-
```json
|
|
87
|
-
{
|
|
88
|
-
"data": {
|
|
89
|
-
"sessionCreate": {
|
|
90
|
-
"session": {
|
|
91
|
-
"accessToken": "eyJhbGciOiJIUzI1NiIs...",
|
|
92
|
-
"refreshToken": "v1.refresh-token...",
|
|
93
|
-
"expiresAt": "2025-01-15T12:00:00Z"
|
|
94
|
-
},
|
|
95
|
-
"requiresMfa": false
|
|
96
|
-
}
|
|
97
|
-
}
|
|
98
|
-
}
|
|
99
|
-
```
|
|
100
|
-
|
|
101
|
-
If `requiresMfa` is `true`, you need to complete the MFA challenge before receiving a session. See the [Authentication](./authentication.md) guide for details.
|
|
102
|
-
|
|
103
|
-
For server-to-server integrations, prefer [API key authentication](/api/authentication#api-key-authentication) over session tokens.
|
|
104
|
-
|
|
105
|
-
## Make an authenticated query
|
|
106
|
-
|
|
107
|
-
Pass the access token in the `Authorization` header as a Bearer token:
|
|
108
|
-
|
|
109
|
-
```
|
|
110
|
-
Authorization: Bearer eyJhbGciOiJIUzI1NiIs...
|
|
111
|
-
```
|
|
112
|
-
|
|
113
|
-
Now you can query resources that require authentication. For example, fetch your user profile:
|
|
114
|
-
|
|
115
|
-
```graphql
|
|
116
|
-
query {
|
|
117
|
-
user {
|
|
118
|
-
id
|
|
119
|
-
email
|
|
120
|
-
createdAt
|
|
121
|
-
organizations(first: 5) {
|
|
122
|
-
edges {
|
|
123
|
-
node {
|
|
124
|
-
id
|
|
125
|
-
name
|
|
126
|
-
}
|
|
127
|
-
}
|
|
128
|
-
}
|
|
129
|
-
}
|
|
130
|
-
}
|
|
131
|
-
```
|
|
132
|
-
|
|
133
|
-
## Make a mutation
|
|
134
|
-
|
|
135
|
-
Mutations follow the same pattern: send a `POST` request with the `Authorization` header. For example, create an organization:
|
|
136
|
-
|
|
137
|
-
```graphql
|
|
138
|
-
mutation {
|
|
139
|
-
organizationCreate(input: {
|
|
140
|
-
name: "My Company"
|
|
141
|
-
slug: "my-company"
|
|
142
|
-
}) {
|
|
143
|
-
organization {
|
|
144
|
-
id
|
|
145
|
-
name
|
|
146
|
-
slug
|
|
147
|
-
}
|
|
148
|
-
}
|
|
149
|
-
}
|
|
150
|
-
```
|
|
151
|
-
|
|
152
|
-
Response:
|
|
153
|
-
|
|
154
|
-
```json
|
|
155
|
-
{
|
|
156
|
-
"data": {
|
|
157
|
-
"organizationCreate": {
|
|
158
|
-
"organization": {
|
|
159
|
-
"id": "org_abc123",
|
|
160
|
-
"name": "My Company",
|
|
161
|
-
"slug": "my-company"
|
|
162
|
-
}
|
|
163
|
-
}
|
|
164
|
-
}
|
|
165
|
-
}
|
|
166
|
-
```
|
|
167
|
-
|
|
168
|
-
Every mutation accepts an `input` argument and returns a payload object. The payload contains the created or updated resource on success, or errors in the top-level `errors` array on failure.
|
|
169
|
-
|
|
170
|
-
## Error handling basics
|
|
171
|
-
|
|
172
|
-
When something goes wrong, the API returns errors in the standard GraphQL `errors` array:
|
|
173
|
-
|
|
174
|
-
```json
|
|
175
|
-
{
|
|
176
|
-
"data": null,
|
|
177
|
-
"errors": [
|
|
178
|
-
{
|
|
179
|
-
"message": "Invalid credentials",
|
|
180
|
-
"extensions": {
|
|
181
|
-
"code": "INVALID_CREDENTIALS"
|
|
182
|
-
}
|
|
183
|
-
}
|
|
184
|
-
]
|
|
185
|
-
}
|
|
186
|
-
```
|
|
187
|
-
|
|
188
|
-
Check the `extensions.code` field for a machine-readable error code you can use to handle specific failures programmatically. See the [Error Handling](./error-handling.md) guide for the full list of error codes.
|
|
189
|
-
|
|
190
|
-
## Next steps
|
|
191
|
-
|
|
192
|
-
Now that you can authenticate and make requests, explore these guides to go deeper:
|
|
193
|
-
|
|
194
|
-
- [Authentication](./authentication.md) — email/password, OAuth, magic links, MFA, API keys, and session management
|
|
195
|
-
- [Authorization and Scopes](./authorization-and-scopes.md) — understand what each role can access and how scopes control permissions
|
|
196
|
-
- [Pagination](./pagination.md) — navigate large result sets with cursor-based pagination
|
|
197
|
-
- [Error Handling](./error-handling.md) — handle every error code the API can return
|
package/dist/docs/api-keys.mdx
DELETED
|
@@ -1,40 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
layout: docs
|
|
3
|
-
---
|
|
4
|
-
|
|
5
|
-
import { Screenshot } from '../../components/Screenshot'
|
|
6
|
-
|
|
7
|
-
# API keys
|
|
8
|
-
|
|
9
|
-
API keys let you access Picked's API programmatically. Use them for server-side integrations or CI/CD workflows.
|
|
10
|
-
|
|
11
|
-
<Screenshot
|
|
12
|
-
route="/{orgSlug}/api-keys"
|
|
13
|
-
alt="The API keys list for an organization on the Picked dashboard"
|
|
14
|
-
/>
|
|
15
|
-
|
|
16
|
-
## Create an API key
|
|
17
|
-
|
|
18
|
-
1. Open your organization.
|
|
19
|
-
2. Click **API Keys**.
|
|
20
|
-
3. Click **Create Key**.
|
|
21
|
-
4. Enter a description.
|
|
22
|
-
5. Click **Create**.
|
|
23
|
-
|
|
24
|
-
Copy the key immediately — it won't be shown again.
|
|
25
|
-
|
|
26
|
-
## Using an API key
|
|
27
|
-
|
|
28
|
-
Include your API key in the `Authorization` header when making requests to the [Picked API](/api).
|
|
29
|
-
|
|
30
|
-
```
|
|
31
|
-
Authorization: Bearer your-api-key
|
|
32
|
-
```
|
|
33
|
-
|
|
34
|
-
## Scopes
|
|
35
|
-
|
|
36
|
-
API keys can be scoped to limit what they can access. When creating a key, select the scopes that match your integration's needs. A key can only perform actions allowed by its assigned scopes.
|
|
37
|
-
|
|
38
|
-
## Revoke a key
|
|
39
|
-
|
|
40
|
-
Revoke a key at any time from the API keys list. Click the revoke button next to the key you want to disable. Revoked keys stop working immediately.
|
|
@@ -1,51 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
layout: docs
|
|
3
|
-
---
|
|
4
|
-
|
|
5
|
-
# Chrome Extension
|
|
6
|
-
|
|
7
|
-
The Picked Developer Tools extension adds a Picked panel to Chrome DevTools for inspecting and debugging your Picked integration on any page running the SDK.
|
|
8
|
-
|
|
9
|
-

|
|
10
|
-
|
|
11
|
-
## Installation
|
|
12
|
-
|
|
13
|
-
Install from the [Chrome Web Store](https://chromewebstore.google.com/detail/picked-developer-tools/nimmdamgnhlhdpngnalkpmnleebngidh).
|
|
14
|
-
|
|
15
|
-
## Setup
|
|
16
|
-
|
|
17
|
-
Add the `svelteDevtoolsPlugin` to your Picked client so the extension can connect to the SDK.
|
|
18
|
-
|
|
19
|
-
```typescript
|
|
20
|
-
import { createPicked } from '@picked/client'
|
|
21
|
-
import { svelteDevtoolsPlugin } from '@picked/svelte/plugins/devtools'
|
|
22
|
-
|
|
23
|
-
const picked = createPicked({
|
|
24
|
-
projectId: 'your-project-id',
|
|
25
|
-
plugins: [
|
|
26
|
-
svelteDevtoolsPlugin(),
|
|
27
|
-
],
|
|
28
|
-
})
|
|
29
|
-
```
|
|
30
|
-
|
|
31
|
-
## Custom Tools
|
|
32
|
-
|
|
33
|
-
You can extend the Developer Tools with your own project-specific tools, surfaced under a **Custom Tools** tab. Each tool is a framework-adapted component — authored with the same `adaptReactComponent` / `adaptSvelteComponent` helpers you already use — so you can build it in your app's framework and it receives the live Picked client exactly like an experience component does (React: `usePicked()`; Svelte: `getPicked()`). Tools can both read client state and call client methods.
|
|
34
|
-
|
|
35
|
-
```typescript
|
|
36
|
-
import { createPicked } from '@picked/client'
|
|
37
|
-
import { adaptReactComponent } from '@picked/react'
|
|
38
|
-
import { svelteDevtoolsPlugin } from '@picked/svelte/plugins/devtools'
|
|
39
|
-
import MyTool from './MyTool'
|
|
40
|
-
|
|
41
|
-
const picked = createPicked({
|
|
42
|
-
projectId: 'your-project-id',
|
|
43
|
-
plugins: [
|
|
44
|
-
svelteDevtoolsPlugin({
|
|
45
|
-
customTools: [{ id: 'my-tool', label: 'My Tool', component: adaptReactComponent(MyTool) }],
|
|
46
|
-
}),
|
|
47
|
-
],
|
|
48
|
-
})
|
|
49
|
-
```
|
|
50
|
-
|
|
51
|
-
The Developer Tools shell is rendered with Svelte, so a tool's framework must also be registered on the client. A React app needs `reactFrameworkPlugin` (for the tool) alongside the Svelte framework and `svelteDevtoolsPlugin` (for the shell). If a tool's framework isn't registered, its tab shows a warning instead of rendering.
|
package/dist/docs/conditions.mdx
DELETED
|
@@ -1,59 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
layout: docs
|
|
3
|
-
---
|
|
4
|
-
|
|
5
|
-
import { Screenshot } from '../../components/Screenshot'
|
|
6
|
-
|
|
7
|
-
# Conditions
|
|
8
|
-
|
|
9
|
-
A condition evaluates logic and branches the flow into two paths — one for when the condition is true, another for when it's false.
|
|
10
|
-
|
|
11
|
-
<Screenshot
|
|
12
|
-
route="/{orgSlug}/{projectId}/workspaces/{workspaceId}/conditions"
|
|
13
|
-
alt="The conditions list for a workspace on the Picked dashboard"
|
|
14
|
-
/>
|
|
15
|
-
|
|
16
|
-
## Create a condition
|
|
17
|
-
|
|
18
|
-
1. Open your project.
|
|
19
|
-
2. Click **Conditions** in the sidebar.
|
|
20
|
-
3. Click **New Condition**.
|
|
21
|
-
4. Enter a name and key.
|
|
22
|
-
5. Click **Create**.
|
|
23
|
-
|
|
24
|
-
## Configure a condition
|
|
25
|
-
|
|
26
|
-
**Name**: The display name shown in the dashboard. Not visible to visitors.
|
|
27
|
-
|
|
28
|
-
**Key**: The programmatic identifier. Set once, can't change. Not visible to visitors.
|
|
29
|
-
|
|
30
|
-
## Define logic
|
|
31
|
-
|
|
32
|
-
Select a condition node in the flow builder to open its inspector. The **Logic** section contains a visual [condition builder](/flow-builder/condition-builder).
|
|
33
|
-
|
|
34
|
-
The condition builder lets you create rules using AND/OR groups. Each rule compares a data source against an operator and a target value.
|
|
35
|
-
|
|
36
|
-
### Available data sources
|
|
37
|
-
|
|
38
|
-
**Responses** — values visitors have submitted through form fields. For example, check if a visitor entered a specific email domain or selected a particular option.
|
|
39
|
-
|
|
40
|
-
**Actions** — references to actions that have been triggered during the flow.
|
|
41
|
-
|
|
42
|
-
**Features** — the state of feature flags in your project. Branch based on which variant a visitor is assigned to.
|
|
43
|
-
|
|
44
|
-
**Location** — properties of the visitor's current page URL, including pathname, search parameters, hostname, and hash. For example, show different content based on which page the visitor is on.
|
|
45
|
-
|
|
46
|
-
### Example
|
|
47
|
-
|
|
48
|
-
To branch based on a visitor's country selection:
|
|
49
|
-
|
|
50
|
-
1. Add a rule: **Responses → country** equals `US`.
|
|
51
|
-
2. The green (true) path handles US visitors. The red (false) path handles everyone else.
|
|
52
|
-
|
|
53
|
-
To combine multiple conditions, create an AND or OR group and add rules within it.
|
|
54
|
-
|
|
55
|
-
## Branching
|
|
56
|
-
|
|
57
|
-
In the flow builder, condition nodes have two output handles. The green handle (true) leads to the path taken when the condition matches. The red handle (false) leads to the alternative path.
|
|
58
|
-
|
|
59
|
-
You can chain conditions. Connect the output of one condition to the input of another to create complex decision trees.
|
|
@@ -1,93 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
layout: docs
|
|
3
|
-
---
|
|
4
|
-
|
|
5
|
-
import { Screenshot } from '../../../components/Screenshot'
|
|
6
|
-
|
|
7
|
-
# Asset Library
|
|
8
|
-
|
|
9
|
-
The Asset Library stores the files your content references: images, video, documents, and HTML.
|
|
10
|
-
|
|
11
|
-
<Screenshot
|
|
12
|
-
route="/{orgSlug}/{projectId}/assets"
|
|
13
|
-
alt="The asset library on the Picked dashboard"
|
|
14
|
-
/>
|
|
15
|
-
|
|
16
|
-
## Upload and manage assets
|
|
17
|
-
|
|
18
|
-
The Asset Library is a project-level store. Upload a file, then reference it from any Content Entry in the project.
|
|
19
|
-
|
|
20
|
-
- **Size limit:** 50 MB per file.
|
|
21
|
-
- **Allowed types:** images (PNG, JPEG, WebP, AVIF, GIF, SVG), video (MP4, WebM), common document formats, and HTML (`text/html`).
|
|
22
|
-
|
|
23
|
-
Uploads outside the allowed types or over the size limit are rejected at upload time.
|
|
24
|
-
|
|
25
|
-
## Reference an asset from a field
|
|
26
|
-
|
|
27
|
-
Two field types point at library items:
|
|
28
|
-
|
|
29
|
-
- An **Asset** field references an image, video, or document.
|
|
30
|
-
- An **HTML asset** field references an uploaded `.html` file.
|
|
31
|
-
|
|
32
|
-
Add the field to a [layout](/content/layouts), then pick a library item when filling in the [Content Entry](/content/content-entries).
|
|
33
|
-
|
|
34
|
-
## Pick an asset
|
|
35
|
-
|
|
36
|
-
Every Asset field opens the same picker: click **Choose file** (or **Replace** on a field that already has a value) to open a modal with two tabs, **Library** (browse existing assets) and **Upload** (add a new file).
|
|
37
|
-
|
|
38
|
-
<Screenshot
|
|
39
|
-
route="/{orgSlug}/{projectId}/design-systems/new"
|
|
40
|
-
wait='button:has-text("Upload file")'
|
|
41
|
-
click='button:has-text("Upload file")'
|
|
42
|
-
selector="[role=dialog]"
|
|
43
|
-
alt="The asset picker modal on the Picked dashboard, showing the Library tab with its search box, type filter, and Sort by menu"
|
|
44
|
-
renderWidth={1072}
|
|
45
|
-
renderHeight={790}
|
|
46
|
-
/>
|
|
47
|
-
|
|
48
|
-
### Search, filter, and sort
|
|
49
|
-
|
|
50
|
-
The Library tab has three controls for narrowing a large asset list, all applied on the server across the whole library, not just the assets already loaded:
|
|
51
|
-
|
|
52
|
-
- **Search:** filters by file name as you type.
|
|
53
|
-
- **Type filter:** narrows to a media-type bucket (All types, Images, Video, Audio, Documents, or Archives).
|
|
54
|
-
- **Sort by:** orders by Name or Date uploaded, each ascending or descending.
|
|
55
|
-
|
|
56
|
-
:::note
|
|
57
|
-
Results are paginated. Use **Load more** at the bottom of the list to fetch the next page.
|
|
58
|
-
:::
|
|
59
|
-
|
|
60
|
-
### Select one or several assets
|
|
61
|
-
|
|
62
|
-
The picker adapts to how many assets the field accepts:
|
|
63
|
-
|
|
64
|
-
- A field that holds a single asset (a layout's Asset field, or a design system's guidance file) shows a **radio** indicator next to each row. Picking a new asset replaces the current one.
|
|
65
|
-
- A surface that accepts several assets at once (for example, a workbench's Files tab) shows a **checkbox** indicator and a running selection count in the detail panel.
|
|
66
|
-
|
|
67
|
-
The detail panel on the right shows the selected asset's kind, dimensions, size, and upload date.
|
|
68
|
-
|
|
69
|
-
### Open an asset in a new tab
|
|
70
|
-
|
|
71
|
-
Each row, and the detail panel for the currently selected asset, has an **Open in new tab** control. It links to the asset's full detail page without losing your current selection in the picker.
|
|
72
|
-
|
|
73
|
-
:::tip
|
|
74
|
-
Use this to double-check an asset (its full-size preview, every uploaded version) before committing to it.
|
|
75
|
-
:::
|
|
76
|
-
|
|
77
|
-
## HTML assets
|
|
78
|
-
|
|
79
|
-
Upload a `.html` file and reference it from an **HTML asset** field. On upload, Picked runs an advisory scan that guides you but never blocks the upload. It surfaces performance, SEO, and accessibility findings so you can improve the file before publishing:
|
|
80
|
-
|
|
81
|
-
- **File size:** a warning at 100 KB and a stronger one at 250 KB.
|
|
82
|
-
- **Inline images:** a note when inline base64 image data adds roughly 50 KB or more.
|
|
83
|
-
- **Image dimensions:** images missing an explicit width or height, which risk layout shift.
|
|
84
|
-
- **Lazy loading:** images without `loading="lazy"`.
|
|
85
|
-
- **Link safety:** external links with `target="_blank"` but no `rel="noopener"`.
|
|
86
|
-
- **Link SEO:** external links without `rel="nofollow"`.
|
|
87
|
-
- **Accessibility:** an axe-core pass covering alt text, heading order, contrast, and more.
|
|
88
|
-
|
|
89
|
-
Every finding is advisory. You can always upload the file as is.
|
|
90
|
-
|
|
91
|
-
## How assets are served
|
|
92
|
-
|
|
93
|
-
Assets are served from a sandboxed storage origin, separate from your app's trusted origin. Serving HTML from its own origin means an uploaded document executes in isolation and cannot reach the page that embeds it. When an [Experience Content](/delivery-api/experience-content) response includes an HTML asset, its content is inlined into the response, so the SDK renders it without a second storage fetch.
|
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
layout: docs
|
|
3
|
-
---
|
|
4
|
-
|
|
5
|
-
import { Screenshot } from '../../../components/Screenshot'
|
|
6
|
-
|
|
7
|
-
# Content Entries
|
|
8
|
-
|
|
9
|
-
A Content Entry is an instance of a layout filled with real data. A Page renders one entry; a Flow Step can render one too.
|
|
10
|
-
|
|
11
|
-
<Screenshot
|
|
12
|
-
route="/{orgSlug}/{projectId}/workspaces/{workspaceId}/content"
|
|
13
|
-
alt="The content entries list on the Picked dashboard"
|
|
14
|
-
/>
|
|
15
|
-
|
|
16
|
-
## What a content entry is
|
|
17
|
-
|
|
18
|
-
A Content Entry is an instance of a layout's schema. The [layout](/content/layouts) defines the fields; the entry holds the actual values. One layout can back many entries, each with its own data.
|
|
19
|
-
|
|
20
|
-
## How entries bind to pages and steps
|
|
21
|
-
|
|
22
|
-
A [Page](/content/pages) has a single Step, and that Step links to its entry through the layout content link. A Flow [Step](/steps) backed by a Step Layout binds an entry the same way. When the SDK renders the Page or Step, it resolves the linked entry and hands its data to your component.
|
|
23
|
-
|
|
24
|
-
## Edit entry data
|
|
25
|
-
|
|
26
|
-
The entry editor renders a form driven by the layout schema: one input per field, in the order the schema defines. Repeatable fields appear as sortable lists you can add to and reorder. Group fields nest their inputs under a single heading.
|
|
27
|
-
|
|
28
|
-
## Validation
|
|
29
|
-
|
|
30
|
-
Invalid data surfaces as per-field errors using a JSON-path style that points at the exact location in the entry, for example `sections[0].data.title`. Fix every error before publishing: the published surface only serves valid content.
|