@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,14 +1,18 @@
|
|
|
1
1
|
---
|
|
2
|
+
type: reference
|
|
2
3
|
layout: docs
|
|
3
4
|
---
|
|
4
5
|
|
|
5
6
|
# Authorization and scopes
|
|
6
7
|
|
|
7
|
-
The Picked API
|
|
8
|
+
The Picked API controls access with scopes. Every authenticated caller carries a set
|
|
9
|
+
of scopes, and those scopes decide which operations the caller can do. A caller is
|
|
10
|
+
either a user with a session or an API key. This guide covers the scopes, the roles,
|
|
11
|
+
and how the API resolves a permission.
|
|
8
12
|
|
|
9
|
-
##
|
|
13
|
+
## The format of a scope name
|
|
10
14
|
|
|
11
|
-
|
|
15
|
+
A scope has the form `resource/action`:
|
|
12
16
|
|
|
13
17
|
```
|
|
14
18
|
organization/read
|
|
@@ -16,83 +20,87 @@ organization_members/create
|
|
|
16
20
|
organization_projects/delete
|
|
17
21
|
```
|
|
18
22
|
|
|
19
|
-
- **
|
|
20
|
-
|
|
23
|
+
- **resource** — a lowercase name. It uses an underscore between words, as in
|
|
24
|
+
`organization_members` and `organization_api_keys`.
|
|
25
|
+
- **action** — one of `create`, `read`, `update`, or `delete`.
|
|
21
26
|
|
|
22
|
-
|
|
27
|
+
The GraphQL schema holds the scopes in the `Scope` enum. There they are uppercase
|
|
28
|
+
with an underscore between words, as in `ORGANIZATION_READ` and
|
|
29
|
+
`ORGANIZATION_MEMBERS_CREATE`. The two forms name the same scope.
|
|
23
30
|
|
|
24
31
|
## Full scope list
|
|
25
32
|
|
|
26
|
-
|
|
33
|
+
These are the scopes:
|
|
27
34
|
|
|
28
35
|
### Organization
|
|
29
36
|
|
|
30
37
|
| Scope | GraphQL Enum | Description |
|
|
31
38
|
|-------|-------------|-------------|
|
|
32
|
-
| `organization/create` | `ORGANIZATION_CREATE` | Create
|
|
33
|
-
| `organization/read` | `ORGANIZATION_READ` |
|
|
34
|
-
| `organization/update` | `ORGANIZATION_UPDATE` | Update
|
|
39
|
+
| `organization/create` | `ORGANIZATION_CREATE` | Create an organization |
|
|
40
|
+
| `organization/read` | `ORGANIZATION_READ` | Read the detail of an organization |
|
|
41
|
+
| `organization/update` | `ORGANIZATION_UPDATE` | Update the name, the slug, and the settings of an organization |
|
|
35
42
|
| `organization/delete` | `ORGANIZATION_DELETE` | Delete an organization |
|
|
36
43
|
|
|
37
44
|
### Organization members
|
|
38
45
|
|
|
39
46
|
| Scope | GraphQL Enum | Description |
|
|
40
47
|
|-------|-------------|-------------|
|
|
41
|
-
| `organization_members/create` | `ORGANIZATION_MEMBERS_CREATE` | Add
|
|
42
|
-
| `organization_members/read` | `ORGANIZATION_MEMBERS_READ` |
|
|
43
|
-
| `organization_members/update` | `ORGANIZATION_MEMBERS_UPDATE` | Update member
|
|
44
|
-
| `organization_members/delete` | `ORGANIZATION_MEMBERS_DELETE` | Remove
|
|
48
|
+
| `organization_members/create` | `ORGANIZATION_MEMBERS_CREATE` | Add a member to an organization |
|
|
49
|
+
| `organization_members/read` | `ORGANIZATION_MEMBERS_READ` | Read the member list of an organization |
|
|
50
|
+
| `organization_members/update` | `ORGANIZATION_MEMBERS_UPDATE` | Update the role of a member |
|
|
51
|
+
| `organization_members/delete` | `ORGANIZATION_MEMBERS_DELETE` | Remove a member from an organization |
|
|
45
52
|
|
|
46
53
|
### Organization invitations
|
|
47
54
|
|
|
48
55
|
| Scope | GraphQL Enum | Description |
|
|
49
56
|
|-------|-------------|-------------|
|
|
50
|
-
| `organization_invitations/create` | `ORGANIZATION_INVITATIONS_CREATE` | Send
|
|
51
|
-
| `organization_invitations/read` | `ORGANIZATION_INVITATIONS_READ` |
|
|
52
|
-
| `organization_invitations/delete` | `ORGANIZATION_INVITATIONS_DELETE` | Revoke
|
|
57
|
+
| `organization_invitations/create` | `ORGANIZATION_INVITATIONS_CREATE` | Send an invitation to join an organization |
|
|
58
|
+
| `organization_invitations/read` | `ORGANIZATION_INVITATIONS_READ` | Read the invitations that wait for an answer |
|
|
59
|
+
| `organization_invitations/delete` | `ORGANIZATION_INVITATIONS_DELETE` | Revoke an invitation that waits for an answer |
|
|
53
60
|
|
|
54
61
|
### Organization projects
|
|
55
62
|
|
|
56
63
|
| Scope | GraphQL Enum | Description |
|
|
57
64
|
|-------|-------------|-------------|
|
|
58
|
-
| `organization_projects/create` | `ORGANIZATION_PROJECTS_CREATE` | Create
|
|
59
|
-
| `organization_projects/read` | `ORGANIZATION_PROJECTS_READ` |
|
|
60
|
-
| `organization_projects/update` | `ORGANIZATION_PROJECTS_UPDATE` | Update
|
|
61
|
-
| `organization_projects/delete` | `ORGANIZATION_PROJECTS_DELETE` | Delete
|
|
65
|
+
| `organization_projects/create` | `ORGANIZATION_PROJECTS_CREATE` | Create a project |
|
|
66
|
+
| `organization_projects/read` | `ORGANIZATION_PROJECTS_READ` | Read the detail of a project |
|
|
67
|
+
| `organization_projects/update` | `ORGANIZATION_PROJECTS_UPDATE` | Update the settings of a project |
|
|
68
|
+
| `organization_projects/delete` | `ORGANIZATION_PROJECTS_DELETE` | Delete a project |
|
|
62
69
|
|
|
63
70
|
### Organization API keys
|
|
64
71
|
|
|
65
72
|
| Scope | GraphQL Enum | Description |
|
|
66
73
|
|-------|-------------|-------------|
|
|
67
|
-
| `organization_api_keys/create` | `ORGANIZATION_API_KEYS_CREATE` | Create
|
|
68
|
-
| `organization_api_keys/read` | `ORGANIZATION_API_KEYS_READ` |
|
|
69
|
-
| `organization_api_keys/delete` | `ORGANIZATION_API_KEYS_DELETE` | Revoke API
|
|
74
|
+
| `organization_api_keys/create` | `ORGANIZATION_API_KEYS_CREATE` | Create an API key |
|
|
75
|
+
| `organization_api_keys/read` | `ORGANIZATION_API_KEYS_READ` | Read the API keys. This gives the prefix only, and not the full key. |
|
|
76
|
+
| `organization_api_keys/delete` | `ORGANIZATION_API_KEYS_DELETE` | Revoke an API key |
|
|
70
77
|
|
|
71
78
|
### Organization integrations
|
|
72
79
|
|
|
73
80
|
| Scope | GraphQL Enum | Description |
|
|
74
81
|
|-------|-------------|-------------|
|
|
75
|
-
| `organization_integrations/create` | `ORGANIZATION_INTEGRATIONS_CREATE` | Set up
|
|
76
|
-
| `organization_integrations/read` | `ORGANIZATION_INTEGRATIONS_READ` |
|
|
77
|
-
| `organization_integrations/update` | `ORGANIZATION_INTEGRATIONS_UPDATE` |
|
|
78
|
-
| `organization_integrations/delete` | `ORGANIZATION_INTEGRATIONS_DELETE` | Remove
|
|
82
|
+
| `organization_integrations/create` | `ORGANIZATION_INTEGRATIONS_CREATE` | Set up an integration |
|
|
83
|
+
| `organization_integrations/read` | `ORGANIZATION_INTEGRATIONS_READ` | Read the options of an integration |
|
|
84
|
+
| `organization_integrations/update` | `ORGANIZATION_INTEGRATIONS_UPDATE` | Change the settings of an integration |
|
|
85
|
+
| `organization_integrations/delete` | `ORGANIZATION_INTEGRATIONS_DELETE` | Remove an integration |
|
|
79
86
|
|
|
80
87
|
### Organization reports
|
|
81
88
|
|
|
82
89
|
| Scope | GraphQL Enum | Description |
|
|
83
90
|
|-------|-------------|-------------|
|
|
84
|
-
| `organization_reports/create` | `ORGANIZATION_REPORTS_CREATE` | Create
|
|
85
|
-
| `organization_reports/read` | `ORGANIZATION_REPORTS_READ` |
|
|
86
|
-
| `organization_reports/update` | `ORGANIZATION_REPORTS_UPDATE` | Update
|
|
87
|
-
| `organization_reports/delete` | `ORGANIZATION_REPORTS_DELETE` | Delete
|
|
91
|
+
| `organization_reports/create` | `ORGANIZATION_REPORTS_CREATE` | Create a report |
|
|
92
|
+
| `organization_reports/read` | `ORGANIZATION_REPORTS_READ` | Read a report |
|
|
93
|
+
| `organization_reports/update` | `ORGANIZATION_REPORTS_UPDATE` | Update the settings of a report |
|
|
94
|
+
| `organization_reports/delete` | `ORGANIZATION_REPORTS_DELETE` | Delete a report |
|
|
88
95
|
|
|
89
96
|
## Roles
|
|
90
97
|
|
|
91
|
-
|
|
98
|
+
Each member of an organization holds one of two roles:
|
|
92
99
|
|
|
93
100
|
### Owner
|
|
94
101
|
|
|
95
|
-
|
|
102
|
+
An owner has full control inside the organization. These are the default scopes of an
|
|
103
|
+
owner:
|
|
96
104
|
|
|
97
105
|
- All `organization/*` scopes (`read`, `update`, `delete`)
|
|
98
106
|
- All `organization_members/*` scopes
|
|
@@ -104,7 +112,8 @@ Owners have full control within their organization. Their default scopes include
|
|
|
104
112
|
|
|
105
113
|
### Member
|
|
106
114
|
|
|
107
|
-
|
|
115
|
+
A member can reach most things, but cannot delete the organization and cannot control
|
|
116
|
+
another member. These are the default scopes of a member:
|
|
108
117
|
|
|
109
118
|
- `organization/read`, `organization/update`
|
|
110
119
|
- `organization_members/read`
|
|
@@ -114,7 +123,7 @@ Members have broad access but cannot delete the organization or manage other mem
|
|
|
114
123
|
- All `organization_integrations/*` scopes
|
|
115
124
|
- `organization_reports/read`
|
|
116
125
|
|
|
117
|
-
|
|
126
|
+
These are the differences between an owner and a member:
|
|
118
127
|
|
|
119
128
|
| Capability | Owner | Member |
|
|
120
129
|
|-----------|-------|--------|
|
|
@@ -123,24 +132,30 @@ The key differences between owner and member:
|
|
|
123
132
|
| Remove members | Yes | No |
|
|
124
133
|
| Update member roles | Yes | No |
|
|
125
134
|
| Revoke invitations | Yes | No |
|
|
126
|
-
|
|
|
127
|
-
|
|
|
128
|
-
|
|
|
135
|
+
| Control projects and integrations | Yes | Yes |
|
|
136
|
+
| Control API keys | Yes | Yes |
|
|
137
|
+
| Read reports | Yes | Yes |
|
|
129
138
|
|
|
130
139
|
## How scopes are resolved
|
|
131
140
|
|
|
132
|
-
When an authenticated request reaches the API, the
|
|
141
|
+
When an authenticated request reaches the API, the API resolves the scopes like this:
|
|
133
142
|
|
|
134
|
-
1. **
|
|
135
|
-
|
|
143
|
+
1. **A user with a session** — the API finds the role of that caller in the target
|
|
144
|
+
organization. It then gives the caller the default scopes of that role.
|
|
145
|
+
2. **A request with an API key** — the API uses the scopes that the key received when
|
|
146
|
+
somebody created it. Those scopes are always scopes of the user who created the
|
|
147
|
+
key.
|
|
136
148
|
|
|
137
|
-
|
|
149
|
+
Most queries and mutations point at one organization. For those, the caller must hold
|
|
150
|
+
the scope inside that organization. For a root-level operation such as
|
|
151
|
+
`organizationCreate`, the API resolves the scope at the account level.
|
|
138
152
|
|
|
139
|
-
|
|
153
|
+
When the caller does not hold the scope that an operation needs, the API returns an
|
|
154
|
+
authorization error with the code `FORBIDDEN`. See [Errors](/reference/management-api/error-handling).
|
|
140
155
|
|
|
141
156
|
## Operations and required scopes
|
|
142
157
|
|
|
143
|
-
|
|
158
|
+
This table gives the scope that each common operation needs:
|
|
144
159
|
|
|
145
160
|
### Queries
|
|
146
161
|
|
|
@@ -192,7 +207,7 @@ Some mutations do not require organization-level scopes because they operate on
|
|
|
192
207
|
| `organizationInvitationAccept` / `organizationInvitationDecline` | Authenticated session (no specific scope) |
|
|
193
208
|
| `mfaFactorEnroll` / `mfaChallengeSend` / `mfaChallengeVerify` / `mfaFactorUnenroll` | Authenticated session (no specific scope) |
|
|
194
209
|
|
|
195
|
-
##
|
|
210
|
+
## Read your scopes
|
|
196
211
|
|
|
197
212
|
### Root-level scopes
|
|
198
213
|
|
|
@@ -259,4 +274,12 @@ Response:
|
|
|
259
274
|
}
|
|
260
275
|
```
|
|
261
276
|
|
|
262
|
-
|
|
277
|
+
Use this to build a UI that changes with the permissions of the caller. An example is
|
|
278
|
+
a **Delete Organization** button that the UI hides when the caller does not hold
|
|
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.
|
|
@@ -0,0 +1,233 @@
|
|
|
1
|
+
---
|
|
2
|
+
type: reference
|
|
3
|
+
layout: docs
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Errors
|
|
7
|
+
|
|
8
|
+
The Picked API returns an error in the standard GraphQL format. This guide covers the
|
|
9
|
+
shape of an error response, every error code, and what your code must do with each
|
|
10
|
+
one.
|
|
11
|
+
|
|
12
|
+
## Error response shape
|
|
13
|
+
|
|
14
|
+
When an operation fails, the API returns an `errors` array in the response body. Each
|
|
15
|
+
error object holds these fields:
|
|
16
|
+
|
|
17
|
+
```json
|
|
18
|
+
{
|
|
19
|
+
"data": null,
|
|
20
|
+
"errors": [
|
|
21
|
+
{
|
|
22
|
+
"message": "A human-readable description of the error",
|
|
23
|
+
"path": ["mutationName"],
|
|
24
|
+
"extensions": {
|
|
25
|
+
"code": "ERROR_CODE"
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
]
|
|
29
|
+
}
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
| Field | Description |
|
|
33
|
+
|-------|-------------|
|
|
34
|
+
| `message` | A description of the error that a person can read. Put it in your log. Do not write code against it. |
|
|
35
|
+
| `path` | The path to the field in the query that made the error. |
|
|
36
|
+
| `extensions.code` | An error code that a machine can read. Write your code against this field. |
|
|
37
|
+
|
|
38
|
+
One response can hold more than one error. The `data` field is `null` when the whole
|
|
39
|
+
operation failed. It holds part of the data when only some fields failed.
|
|
40
|
+
|
|
41
|
+
## Authentication error codes
|
|
42
|
+
|
|
43
|
+
These errors come from a session, an account, OAuth, a magic link, a password
|
|
44
|
+
operation, or MFA. They match the `AuthErrorCode` enum in the schema.
|
|
45
|
+
|
|
46
|
+
| Code | Description |
|
|
47
|
+
|------|-------------|
|
|
48
|
+
| `INVALID_CREDENTIALS` | The email address and the password do not match. |
|
|
49
|
+
| `EMAIL_NOT_CONFIRMED` | The account is there, but nobody verified the email address. See [Authentication](/reference/management-api/authentication#verify-an-email-address). |
|
|
50
|
+
| `USER_NOT_FOUND` | There is no account with that email address. |
|
|
51
|
+
| `USER_ALREADY_EXISTS` | An account with that email address is there already. The API returns this when you create an account. |
|
|
52
|
+
| `WEAK_PASSWORD` | The password is not strong enough. |
|
|
53
|
+
| `INVALID_TOKEN` | The token is invalid or malformed. This covers a verification token, a reset token, and a magic link token. |
|
|
54
|
+
| `TOKEN_EXPIRED` | The token expired. Ask for a new one. |
|
|
55
|
+
| `MFA_CHALLENGE_FAILED` | The MFA verification code is not correct. |
|
|
56
|
+
| `MFA_FACTOR_NOT_FOUND` | That MFA factor is not there, or it belongs to another caller. |
|
|
57
|
+
| `OAUTH_PROVIDER_ERROR` | The exchange with the OAuth provider, such as Google, failed. |
|
|
58
|
+
| `RATE_LIMITED` | Too many requests in a short period. Wait, then try again. |
|
|
59
|
+
|
|
60
|
+
### Example: invalid credentials
|
|
61
|
+
|
|
62
|
+
```json
|
|
63
|
+
{
|
|
64
|
+
"data": {
|
|
65
|
+
"sessionCreate": {
|
|
66
|
+
"session": null,
|
|
67
|
+
"requiresMfa": false,
|
|
68
|
+
"mfaFactors": null
|
|
69
|
+
}
|
|
70
|
+
},
|
|
71
|
+
"errors": [
|
|
72
|
+
{
|
|
73
|
+
"message": "Invalid credentials",
|
|
74
|
+
"path": ["sessionCreate"],
|
|
75
|
+
"extensions": {
|
|
76
|
+
"code": "INVALID_CREDENTIALS"
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
]
|
|
80
|
+
}
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
## Authorization error codes
|
|
84
|
+
|
|
85
|
+
An authorization error happens when the caller does not hold the
|
|
86
|
+
[scope](/reference/management-api/authorization-and-scopes) that an operation needs.
|
|
87
|
+
|
|
88
|
+
| Code | Description |
|
|
89
|
+
|------|-------------|
|
|
90
|
+
| `UNAUTHORIZED` | The request carries no valid authentication. It has no `Authorization` header and no `x-api-key` header, or the token is invalid. |
|
|
91
|
+
| `FORBIDDEN` | The caller is authenticated, but it does not hold the scope that the operation needs. |
|
|
92
|
+
|
|
93
|
+
### Example: the scope is not enough
|
|
94
|
+
|
|
95
|
+
A caller that holds `organization/read` only tries to delete an organization. It
|
|
96
|
+
receives this:
|
|
97
|
+
|
|
98
|
+
```json
|
|
99
|
+
{
|
|
100
|
+
"data": {
|
|
101
|
+
"organizationDelete": null
|
|
102
|
+
},
|
|
103
|
+
"errors": [
|
|
104
|
+
{
|
|
105
|
+
"message": "Insufficient permissions",
|
|
106
|
+
"path": ["organizationDelete"],
|
|
107
|
+
"extensions": {
|
|
108
|
+
"code": "FORBIDDEN"
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
]
|
|
112
|
+
}
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
## Organization, member, and invitation error codes
|
|
116
|
+
|
|
117
|
+
These errors come from an organization, a member operation, or an invitation. They
|
|
118
|
+
match the `ErrorCode` enum in the schema.
|
|
119
|
+
|
|
120
|
+
### Organization errors
|
|
121
|
+
|
|
122
|
+
| Code | Description |
|
|
123
|
+
|------|-------------|
|
|
124
|
+
| `ORGANIZATION_NOT_FOUND` | That organization is not there, or the caller cannot reach it. |
|
|
125
|
+
| `ORGANIZATION_ALREADY_EXISTS` | An organization with that name is there already. |
|
|
126
|
+
| `SLUG_ALREADY_EXISTS` | Another organization uses that slug already. |
|
|
127
|
+
| `INVALID_SLUG` | The slug holds an invalid character. A slug takes lowercase letters, digits, and hyphens only. |
|
|
128
|
+
|
|
129
|
+
### Member errors
|
|
130
|
+
|
|
131
|
+
| Code | Description |
|
|
132
|
+
|------|-------------|
|
|
133
|
+
| `MEMBER_NOT_FOUND` | That user is not a member of the organization. |
|
|
134
|
+
| `MEMBER_ALREADY_EXISTS` | The user is a member of the organization already. |
|
|
135
|
+
| `CANNOT_REMOVE_PRIMARY_OWNER` | You cannot remove the primary owner of an organization. |
|
|
136
|
+
| `CANNOT_CHANGE_OWN_ROLE` | A member cannot change the role of that same member. Another owner must do it. |
|
|
137
|
+
|
|
138
|
+
### Invitation errors
|
|
139
|
+
|
|
140
|
+
| Code | Description |
|
|
141
|
+
|------|-------------|
|
|
142
|
+
| `INVITATION_NOT_FOUND` | That invitation is not there. |
|
|
143
|
+
| `INVITATION_EXPIRED` | The invitation expired. Nobody can accept it now. |
|
|
144
|
+
| `INVITATION_ALREADY_ACCEPTED` | Somebody accepted the invitation already. |
|
|
145
|
+
|
|
146
|
+
### Project errors
|
|
147
|
+
|
|
148
|
+
| Code | Description |
|
|
149
|
+
|------|-------------|
|
|
150
|
+
| `PROJECT_NOT_FOUND` | That project is not there, or the caller cannot reach it. |
|
|
151
|
+
|
|
152
|
+
### General errors
|
|
153
|
+
|
|
154
|
+
| Code | Description |
|
|
155
|
+
|------|-------------|
|
|
156
|
+
| `VALIDATION_ERROR` | The input failed a validation rule. Read the `message` field to learn which field is invalid. |
|
|
157
|
+
| `INTERNAL_ERROR` | The server met an unexpected error. Try the request again. Contact support when the error continues. |
|
|
158
|
+
|
|
159
|
+
## What your code must do
|
|
160
|
+
|
|
161
|
+
### Look for an error first
|
|
162
|
+
|
|
163
|
+
Check every response for an `errors` array before you read `data`:
|
|
164
|
+
|
|
165
|
+
```javascript
|
|
166
|
+
const response = await fetch('/graphql', {
|
|
167
|
+
method: 'POST',
|
|
168
|
+
headers: {
|
|
169
|
+
'Content-Type': 'application/json',
|
|
170
|
+
'Authorization': `Bearer ${accessToken}`,
|
|
171
|
+
},
|
|
172
|
+
body: JSON.stringify({ query, variables }),
|
|
173
|
+
});
|
|
174
|
+
|
|
175
|
+
const result = await response.json();
|
|
176
|
+
|
|
177
|
+
if (result.errors) {
|
|
178
|
+
for (const error of result.errors) {
|
|
179
|
+
const code = error.extensions?.code;
|
|
180
|
+
|
|
181
|
+
switch (code) {
|
|
182
|
+
case 'UNAUTHORIZED':
|
|
183
|
+
// Send the user to the sign-in page.
|
|
184
|
+
break;
|
|
185
|
+
case 'FORBIDDEN':
|
|
186
|
+
// Show a permissions error.
|
|
187
|
+
break;
|
|
188
|
+
case 'RATE_LIMITED':
|
|
189
|
+
// Wait, then try again.
|
|
190
|
+
break;
|
|
191
|
+
default:
|
|
192
|
+
// Put the message in the log, or show it.
|
|
193
|
+
console.error(error.message);
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
```
|
|
198
|
+
|
|
199
|
+
### Refresh a token that expired
|
|
200
|
+
|
|
201
|
+
A request can return `UNAUTHORIZED` while the caller holds a refresh token. Try a
|
|
202
|
+
[session refresh](/reference/management-api/authentication#refresh-a-session) first. Do not treat it as a
|
|
203
|
+
failure to sign in:
|
|
204
|
+
|
|
205
|
+
```javascript
|
|
206
|
+
if (code === 'UNAUTHORIZED' && refreshToken) {
|
|
207
|
+
const refreshResult = await sessionRefresh(refreshToken);
|
|
208
|
+
if (refreshResult.session) {
|
|
209
|
+
// Try the first request again with the new access token.
|
|
210
|
+
} else {
|
|
211
|
+
// Send the user to the sign-in page.
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
```
|
|
215
|
+
|
|
216
|
+
### Read data that is only part complete
|
|
217
|
+
|
|
218
|
+
GraphQL can return part of the data together with an error. Take a query that reads
|
|
219
|
+
an organization and its members. It can succeed for the organization and fail for the
|
|
220
|
+
members, when the caller does not hold `organization_members/read`. The response then
|
|
221
|
+
holds `data` with the organization, and `errors` for the members field. Always read
|
|
222
|
+
both.
|
|
223
|
+
|
|
224
|
+
### Try again after a transient failure
|
|
225
|
+
|
|
226
|
+
`INTERNAL_ERROR` and `RATE_LIMITED` are both transient. For `RATE_LIMITED`, use an
|
|
227
|
+
exponential backoff before you try again. For `INTERNAL_ERROR`, one more try is
|
|
228
|
+
usually enough.
|
|
229
|
+
|
|
230
|
+
## Related
|
|
231
|
+
|
|
232
|
+
- [Authentication](/reference/management-api/authentication)
|
|
233
|
+
- [Your first API call](/tutorials/first-api-call)
|
|
@@ -1,14 +1,17 @@
|
|
|
1
1
|
---
|
|
2
|
+
type: reference
|
|
2
3
|
layout: docs
|
|
3
4
|
---
|
|
4
5
|
|
|
5
6
|
# Pagination
|
|
6
7
|
|
|
7
|
-
The Picked API
|
|
8
|
+
The Picked API paginates every list field that can return a large result. It uses a
|
|
9
|
+
cursor, in the Relay-style pattern. This guide covers the connection pattern and
|
|
10
|
+
shows how to move through a result.
|
|
8
11
|
|
|
9
12
|
## Connection pattern
|
|
10
13
|
|
|
11
|
-
|
|
14
|
+
A paginated field returns a **connection** object with this shape:
|
|
12
15
|
|
|
13
16
|
```graphql
|
|
14
17
|
type ExampleConnection {
|
|
@@ -32,20 +35,21 @@ type PageInfo {
|
|
|
32
35
|
|
|
33
36
|
| Field | Description |
|
|
34
37
|
|-------|-------------|
|
|
35
|
-
| `edges` | An ordered list of edges
|
|
36
|
-
| `pageInfo.hasNextPage` | `true`
|
|
37
|
-
| `pageInfo.hasPreviousPage` | `true`
|
|
38
|
-
| `pageInfo.startCursor` |
|
|
39
|
-
| `pageInfo.endCursor` |
|
|
40
|
-
| `totalCount` |
|
|
38
|
+
| `edges` | An ordered list of edges. Each edge holds a `cursor` and a `node`, and the `node` holds the data. |
|
|
39
|
+
| `pageInfo.hasNextPage` | `true` when more results come after the last edge |
|
|
40
|
+
| `pageInfo.hasPreviousPage` | `true` when results come before the first edge |
|
|
41
|
+
| `pageInfo.startCursor` | The cursor of the first edge on the current page |
|
|
42
|
+
| `pageInfo.endCursor` | The cursor of the last edge on the current page |
|
|
43
|
+
| `totalCount` | The number of items on every page together |
|
|
41
44
|
|
|
42
45
|
## Forward pagination with `first` and `after`
|
|
43
46
|
|
|
44
|
-
To
|
|
47
|
+
To move forward through the results, use two arguments. The `first` argument gives
|
|
48
|
+
the page size. The `after` argument gives the cursor to start after.
|
|
45
49
|
|
|
46
50
|
### First page
|
|
47
51
|
|
|
48
|
-
|
|
52
|
+
Leave the `after` argument out to read the first page:
|
|
49
53
|
|
|
50
54
|
```graphql
|
|
51
55
|
query {
|
|
@@ -89,16 +93,17 @@ query {
|
|
|
89
93
|
}
|
|
90
94
|
```
|
|
91
95
|
|
|
92
|
-
##
|
|
96
|
+
## Check for more pages
|
|
93
97
|
|
|
94
|
-
|
|
98
|
+
Read the `hasNextPage` field before you ask for the next page:
|
|
95
99
|
|
|
96
|
-
- `hasNextPage: true` — more results are available
|
|
97
|
-
|
|
100
|
+
- `hasNextPage: true` — more results are available. Pass `endCursor` as the `after`
|
|
101
|
+
argument of the next request.
|
|
102
|
+
- `hasNextPage: false` — you read every result. Stop here.
|
|
98
103
|
|
|
99
104
|
## Full paginated query example
|
|
100
105
|
|
|
101
|
-
|
|
106
|
+
This example reads every member of an organization, one page at a time:
|
|
102
107
|
|
|
103
108
|
```graphql
|
|
104
109
|
# Page 1
|
|
@@ -154,7 +159,8 @@ Continue until `hasNextPage` returns `false`.
|
|
|
154
159
|
|
|
155
160
|
## Paginated fields
|
|
156
161
|
|
|
157
|
-
|
|
162
|
+
These fields in the schema return a connection type. They all take the `first` and
|
|
163
|
+
`after` arguments:
|
|
158
164
|
|
|
159
165
|
| Parent Type | Field | Connection Type |
|
|
160
166
|
|------------|-------|----------------|
|
|
@@ -170,7 +176,17 @@ All of these fields accept the same `first` and `after` arguments and return the
|
|
|
170
176
|
|
|
171
177
|
## Tips
|
|
172
178
|
|
|
173
|
-
- **
|
|
174
|
-
|
|
175
|
-
- **
|
|
176
|
-
|
|
179
|
+
- **The default page size** — the API applies a default limit when you leave `first`
|
|
180
|
+
out. Set `first` yourself to make sure that each page has the size you expect.
|
|
181
|
+
- **A cursor is opaque** — treat a cursor string as an opaque token. Do not parse it,
|
|
182
|
+
build it, or change it. Pass it back exactly as the API gave it.
|
|
183
|
+
- **The order is stable** — a connection returns its results in a stable order. The
|
|
184
|
+
same cursor always points at the same position in the result.
|
|
185
|
+
- **Use them with other fields** — you can use the pagination arguments together with
|
|
186
|
+
other query fields. One request that reads an organization and the first page of
|
|
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)
|