@wildo-ai/saas-technical-doc 1.1.2 → 1.1.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 (96) hide show
  1. package/dist/esm/companion/application-documentation/application-connection-documentation.d.ts +25 -1
  2. package/dist/esm/companion/application-documentation/application-connection-documentation.d.ts.map +1 -1
  3. package/dist/esm/companion/application-documentation/application-connection-documentation.js +28 -1
  4. package/dist/esm/companion/application-documentation/application-connection-documentation.js.map +1 -1
  5. package/dist/esm/companion/application-documentation/application-domain-documentation.d.ts +133 -0
  6. package/dist/esm/companion/application-documentation/application-domain-documentation.d.ts.map +1 -0
  7. package/dist/esm/companion/application-documentation/application-domain-documentation.js +243 -0
  8. package/dist/esm/companion/application-documentation/application-domain-documentation.js.map +1 -0
  9. package/dist/esm/companion/application-documentation/application-integration-documentation.d.ts.map +1 -1
  10. package/dist/esm/companion/application-documentation/application-integration-documentation.js +23 -0
  11. package/dist/esm/companion/application-documentation/application-integration-documentation.js.map +1 -1
  12. package/dist/esm/companion/application-documentation/application-organization-role-documentation.d.ts +30 -0
  13. package/dist/esm/companion/application-documentation/application-organization-role-documentation.d.ts.map +1 -1
  14. package/dist/esm/companion/application-documentation/application-organization-role-documentation.js +38 -0
  15. package/dist/esm/companion/application-documentation/application-organization-role-documentation.js.map +1 -1
  16. package/dist/esm/companion/application-documentation/technical-documentation-engine-content-bundle.d.ts +61 -1
  17. package/dist/esm/companion/application-documentation/technical-documentation-engine-content-bundle.d.ts.map +1 -1
  18. package/dist/esm/companion/application-documentation/technical-documentation-engine-content-bundle.js +255 -218
  19. package/dist/esm/companion/application-documentation/technical-documentation-engine-content-bundle.js.map +1 -1
  20. package/dist/esm/companion/application-documentation/technical-documentation-private-derivation.d.ts +2 -0
  21. package/dist/esm/companion/application-documentation/technical-documentation-private-derivation.d.ts.map +1 -1
  22. package/dist/esm/companion/application-documentation/technical-documentation-private-derivation.js +1 -0
  23. package/dist/esm/companion/application-documentation/technical-documentation-private-derivation.js.map +1 -1
  24. package/dist/esm/companion/application-documentation/technical-documentation-publication-policy.js +1 -1
  25. package/dist/esm/companion/application-documentation/technical-documentation-publication-policy.js.map +1 -1
  26. package/dist/esm/companion/index.d.ts +2 -1
  27. package/dist/esm/companion/index.d.ts.map +1 -1
  28. package/dist/esm/companion/index.js +2 -1
  29. package/dist/esm/companion/index.js.map +1 -1
  30. package/dist/esm/companion/manual-controller-route-projection.d.ts +112 -0
  31. package/dist/esm/companion/manual-controller-route-projection.d.ts.map +1 -0
  32. package/dist/esm/companion/manual-controller-route-projection.js +249 -0
  33. package/dist/esm/companion/manual-controller-route-projection.js.map +1 -0
  34. package/dist/esm/companion/openapi-generator.d.ts +16 -0
  35. package/dist/esm/companion/openapi-generator.d.ts.map +1 -1
  36. package/dist/esm/companion/openapi-generator.js +489 -26
  37. package/dist/esm/companion/openapi-generator.js.map +1 -1
  38. package/dist/esm/companion/operation-projection.schemas.d.ts +44 -0
  39. package/dist/esm/companion/operation-projection.schemas.d.ts.map +1 -1
  40. package/dist/esm/companion/operation-projection.schemas.js +37 -0
  41. package/dist/esm/companion/operation-projection.schemas.js.map +1 -1
  42. package/dist/esm/companion/rendering/technical-documentation-docusaurus-renderer.d.ts +7 -1
  43. package/dist/esm/companion/rendering/technical-documentation-docusaurus-renderer.d.ts.map +1 -1
  44. package/dist/esm/companion/rendering/technical-documentation-docusaurus-renderer.js +34 -18
  45. package/dist/esm/companion/rendering/technical-documentation-docusaurus-renderer.js.map +1 -1
  46. package/dist/esm/companion/rendering/technical-documentation-managed-tree-validator.d.ts.map +1 -1
  47. package/dist/esm/companion/rendering/technical-documentation-managed-tree-validator.js +8 -1
  48. package/dist/esm/companion/rendering/technical-documentation-managed-tree-validator.js.map +1 -1
  49. package/dist/esm/companion/rendering/technical-documentation-markdown-renderer.d.ts +0 -9
  50. package/dist/esm/companion/rendering/technical-documentation-markdown-renderer.d.ts.map +0 -1
  51. package/dist/esm/companion/rendering/technical-documentation-markdown-renderer.js +0 -111
  52. package/dist/esm/companion/rendering/technical-documentation-markdown-renderer.js.map +0 -1
  53. package/dist/esm/companion/rendering/technical-documentation-render-model.d.ts.map +1 -1
  54. package/dist/esm/companion/rendering/technical-documentation-render-model.js +30 -13
  55. package/dist/esm/companion/rendering/technical-documentation-render-model.js.map +1 -1
  56. package/dist/esm/companion/rendering/technical-documentation-search-index-renderer.d.ts +10 -0
  57. package/dist/esm/companion/rendering/technical-documentation-search-index-renderer.d.ts.map +1 -1
  58. package/dist/esm/companion/rendering/technical-documentation-search-index-renderer.js +10 -15
  59. package/dist/esm/companion/rendering/technical-documentation-search-index-renderer.js.map +1 -1
  60. package/dist/esm/companion/technical-documentation-capture-execution-port.d.ts +27 -1
  61. package/dist/esm/companion/technical-documentation-capture-execution-port.d.ts.map +1 -1
  62. package/dist/esm/companion/technical-documentation-capture-execution-port.js.map +1 -1
  63. package/dist/esm/companion/technical-documentation-diagram-definitions.d.ts +33 -0
  64. package/dist/esm/companion/technical-documentation-diagram-definitions.d.ts.map +1 -0
  65. package/dist/esm/companion/technical-documentation-diagram-definitions.js +54 -0
  66. package/dist/esm/companion/technical-documentation-diagram-definitions.js.map +1 -0
  67. package/dist/esm/companion/technical-documentation-diagram-materializer.d.ts +10 -18
  68. package/dist/esm/companion/technical-documentation-diagram-materializer.d.ts.map +1 -1
  69. package/dist/esm/companion/technical-documentation-diagram-materializer.js +9 -39
  70. package/dist/esm/companion/technical-documentation-diagram-materializer.js.map +1 -1
  71. package/dist/esm/config/wildo-tech-doc-config.schemas.d.ts +8 -4
  72. package/dist/esm/config/wildo-tech-doc-config.schemas.d.ts.map +1 -1
  73. package/dist/esm/config/wildo-tech-doc-config.schemas.js +8 -4
  74. package/dist/esm/config/wildo-tech-doc-config.schemas.js.map +1 -1
  75. package/dist/esm/content/application-consumer-documentation-content.techdoc.d.ts +42 -64
  76. package/dist/esm/content/application-consumer-documentation-content.techdoc.d.ts.map +1 -1
  77. package/dist/esm/content/application-consumer-documentation-content.techdoc.js +164 -925
  78. package/dist/esm/content/application-consumer-documentation-content.techdoc.js.map +1 -1
  79. package/dist/esm/runtime/DocsAuthContext.d.ts +16 -1
  80. package/dist/esm/runtime/DocsAuthContext.d.ts.map +1 -1
  81. package/dist/esm/runtime/DocsAuthContext.js +18 -2
  82. package/dist/esm/runtime/DocsAuthContext.js.map +1 -1
  83. package/dist/esm/runtime/frontend-provider-registry.techdoc.d.ts +35 -13
  84. package/dist/esm/runtime/frontend-provider-registry.techdoc.d.ts.map +1 -1
  85. package/dist/esm/runtime/frontend-provider-registry.techdoc.js +28 -19
  86. package/dist/esm/runtime/frontend-provider-registry.techdoc.js.map +1 -1
  87. package/dist/esm/runtime/index.d.ts +1 -0
  88. package/dist/esm/runtime/index.d.ts.map +1 -1
  89. package/dist/esm/runtime/index.js +1 -0
  90. package/dist/esm/runtime/index.js.map +1 -1
  91. package/dist/esm/runtime/use-docs-provider-sdks.d.ts +21 -0
  92. package/dist/esm/runtime/use-docs-provider-sdks.d.ts.map +1 -0
  93. package/dist/esm/runtime/use-docs-provider-sdks.js +49 -0
  94. package/dist/esm/runtime/use-docs-provider-sdks.js.map +1 -0
  95. package/dist/tsconfig.build.tsbuildinfo +1 -1
  96. package/package.json +6 -5
@@ -7,15 +7,33 @@
7
7
  * generated application may consume them.
8
8
  *
9
9
  * The fragments describe customer-facing product domains and integration
10
- * journeys, not a generic “technical guides” catalogue. Application-domain
11
- * use cases are deliberately absent until the app-creator flow owns their
12
- * authoring and acceptance.
10
+ * journeys, not a generic “technical guides” catalogue.
11
+ *
12
+ * This header used to say application-domain use cases were "deliberately absent until the
13
+ * app-creator flow owns their authoring and acceptance". That sentence is retired, and it is worth
14
+ * keeping the reason: stated as policy, the largest gap in the whole site read as a decision
15
+ * rather than a defect, and survived every review for exactly that long. A customer could learn
16
+ * how to verify a webhook signature before learning what the product manages.
17
+ *
18
+ * `what-this-application-manages.md` closes it WITHOUT anyone authoring per-application prose,
19
+ * which is what the original reservation was protecting: the page is engine-authored and every
20
+ * fact in it is projected from sources the application already accepted — its own resource
21
+ * registry, its declared API-reference categories, and each specification's purpose and lifecycle.
22
+ *
23
+ * What remains genuinely deferred is a page PER resource. Those need a variable unit set, and the
24
+ * renderer's route table is deliberately fixed (see `pathForUnit`), so an application-owned unit
25
+ * still fails closed rather than acquiring an implicit route.
13
26
  */
14
27
  export declare const APPLICATION_CONSUMER_DOCUMENTATION_AUTHORED_CONTENT_V1: readonly [{
15
28
  readonly managedPath: "get-started.md";
16
29
  readonly unitRef: "technical-documentation:unit/application-orientation";
17
30
  readonly sourceRefs: readonly ["saas-technical-doc:engine-content/application-orientation", "source:companion-projection:application-connection"];
18
- readonly markdown: "# Get started\n\nThis documentation is for the people who use, administer, integrate with or operate {{APPLICATION_NAME}}. Pick the row that matches what you need to do; each leads to a page you can act on.\n\n## What do you need to do?\n\n| You need to | Start here | You will find |\n| --- | --- | --- |\n| Sign in, set up a second factor, or get back into your account | [Access and identity](/access-and-identity/overview) | The sign-in methods, multifactor enrollment and recovery, and what a refusal means |\n| Invite someone, change what they may do, or remove them | [User administration](/user-administration) | Memberships, the roles available in this application, organization units, single sign-on and directory provisioning |\n| Call the API from your own code | [Send your first API request](/integrations/rest/send-request) | A working request in ten minutes, then the [conventions](/integrations/rest/conventions) every operation follows |\n| Be notified when something changes | [Webhooks](/integrations/webhooks) | Signed deliveries, a receiver you can run, retries and operations |\n| Build in n8n, Zapier or Make | [Automation platforms](/integrations/automation-platforms) | The exact settings for each tool |\n| Connect an AI assistant such as Cursor, Codex or Claude Code | [AI coding tools](/integrations/ai-coding-tools) | The MCP connection and what the assistant may do |\n| Investigate who did what, or export security evidence | [Security and audit](/security-and-audit) | The audit trail, exports and delivery to your SIEM |\n| Understand a plan, an invoice or why access changed | [Billing and subscriptions](/billing-and-subscriptions) | How billing state turns into access, and how to reconcile a change |\n| Look up one operation, field or role | [API reference](/api) | The exact contract of every operation, generated from the application itself |\n\nSections appear in the navigation only when this application offers the capability. If a section named above is missing, the application does not expose that capability, and no setting on your side adds it.\n\n## Three things to know before you change anything\n\n1. **Organization.** Almost everything belongs to one organization. Check which organization you are working in before you invite, change or export; the same person can be a member of several.\n2. **Identity.** Use your own account for work you do yourself and a dedicated API key or OAuth client for software. Never lend an administrator's credential to an integration to make a request succeed; give the integration the smallest role that works.\n3. **Verification.** The application is the source of truth. After an administrative change, a payment or an API write, confirm the result in the application rather than trusting a green status alone.\n\n## How the documentation is organised\n\n- **Guides** explain a task from start to finish: what you need, what to click or send, what you should see, and what to do when it fails.\n- **Reference** pages hold exact values you look up rather than read: statuses, error codes, limits, field meanings. The [API reference](/api) is generated from the running application, so it is always the current contract.\n- Every guide links to the reference it relies on, and no guide repeats a value the reference owns.\n\n## When you ask for help\n\nGive the organization, the page or operation you were using, the time, what you expected and what you saw. For an API call, add the HTTP status and the `error.correlationId` from the response; for a webhook, the delivery identifier and `jti`. Never include a password, an API key, a bearer token or another person's data.";
31
+ readonly markdown: "# Get started\n\nThis documentation is for the people who use, administer, integrate with or operate {{APPLICATION_NAME}}. Pick the row that matches what you need to do; each leads to a page you can act on.\n\n## What do you need to do?\n\n| You need to | Start here | You will find |\n| --- | --- | --- |\n| Understand what this application is for | [What {{APPLICATION_NAME}} manages](/what-this-application-manages) | The things it manages, in its own words, and who may act on each |\n| Sign in, set up a second factor, or get back into your account | [Access and identity](/access-and-identity/overview) | The sign-in methods, multifactor enrollment and recovery, and what a refusal means |\n| Invite someone, change what they may do, or remove them | [User administration](/user-administration) | Memberships, the roles available in this application, organization units, single sign-on and directory provisioning |\n| Call the API from your own code | [Send your first API request](/integrations/rest/send-request) | A working request in ten minutes, then the [conventions](/integrations/rest/conventions) every operation follows |\n| Be notified when something changes | [Webhooks](/integrations/webhooks) | Signed deliveries, a receiver you can run, retries and operations |\n| Build in n8n, Zapier or Make | [Automation platforms](/integrations/automation-platforms) | The exact settings for each tool |\n| Connect an AI assistant such as Cursor, Codex or Claude Code | [AI coding tools](/integrations/ai-coding-tools) | The MCP connection and what the assistant may do |\n| Investigate who did what, or export security evidence | [Security and audit](/security-and-audit) | The audit trail, exports and delivery to your SIEM |\n| Look up one operation, field or role | [API reference](/api) | The exact contract of every operation, generated from the application itself |\n\nSections appear in the navigation only when this application offers the capability. If a section named above is missing, the application does not expose that capability, and no setting on your side adds it.\n\n## Three things to know before you change anything\n\n1. **Organization.** Almost everything belongs to one organization. Check which organization you are working in before you invite, change or export; the same person can be a member of several.\n2. **Identity.** Use your own account for work you do yourself and a dedicated API key or OAuth client for software. Never lend an administrator's credential to an integration to make a request succeed; give the integration the smallest role that works.\n3. **Verification.** The application is the source of truth. After an administrative change, a payment or an API write, confirm the result in the application rather than trusting a green status alone.\n\n## How the documentation is organised\n\n- **Guides** explain a task from start to finish: what you need, what to click or send, what you should see, and what to do when it fails.\n- **Reference** pages hold exact values you look up rather than read: statuses, error codes, limits, field meanings. The [API reference](/api) is generated from the running application, so it is always the current contract.\n- Every guide links to the reference it relies on, and no guide repeats a value the reference owns.\n\n## When you ask for help\n\nGive the organization, the page or operation you were using, the time, what you expected and what you saw. For an API call, add the HTTP status and the `error.correlationId` from the response; for a webhook, the delivery identifier and `jti`. Never include a password, an API key, a bearer token or another person's data.";
32
+ }, {
33
+ readonly managedPath: "what-this-application-manages.md";
34
+ readonly unitRef: "technical-documentation:unit/what-this-application-manages";
35
+ readonly sourceRefs: readonly ["saas-technical-doc:engine-content/what-this-application-manages", "source:companion-projection:application-connection", "source:companion-projection:application-domain"];
36
+ readonly markdown: "# What {{APPLICATION_NAME}} manages\n\nEvery other page here explains how to reach this application, administer it, integrate with it or\npay for it. This one says what it is FOR.\n\nEverything below is the application's own: the things it stores, the words it uses for them, and\nwho may act on each. None of it is written by the framework — it is read from the application's own\nresource definitions, so it says what this deployment actually publishes rather than what a product\nof this kind usually does.\n\n## What it manages\n\n{{APPLICATION_DOMAIN:domainOverview}}\n\n## Each one in detail\n\n{{APPLICATION_DOMAIN:domainResourceDetails}}\n\n## Where to go next\n\n| You need to | Go to |\n| --- | --- |\n| Read or change any of this from your own code | [Send your first API request](/integrations/rest/send-request) |\n| Look up the exact fields, arguments and responses | [API reference](/api) |\n| Be notified when one of these changes | [Webhooks](/integrations/webhooks) |\n| Let an AI assistant work with them | [AI coding tools](/integrations/ai-coding-tools) |\n| Change who may act on them | [Roles in this application](/user-administration/roles-and-permissions) |\n\nThe names above are the API's own, so a name you read here is the one you will send, the one an\nerror message will quote back, and the one a webhook payload will carry.";
19
37
  }, {
20
38
  readonly managedPath: "access-and-identity/overview.md";
21
39
  readonly unitRef: "technical-documentation:unit/authentication";
@@ -84,8 +102,8 @@ export declare const APPLICATION_CONSUMER_DOCUMENTATION_AUTHORED_CONTENT_V1: rea
84
102
  }, {
85
103
  readonly managedPath: "access-and-identity/oauth-provider.md";
86
104
  readonly unitRef: "technical-documentation:unit/oauth-provider";
87
- readonly sourceRefs: readonly ["saas-technical-doc:engine-content/oauth-provider", "source:consumer-fact:access-oauth-clients"];
88
- readonly markdown: "# OAuth provider and delegated access\n\nUse OAuth when software needs its own client identity or needs to act after a\nperson authorizes it. The integration does not receive the person's password or\ncopy their browser session.\n\nThis journey applies only when the application publishes an OAuth authorization\nserver. Its discovery metadata is authoritative for issuer identity, endpoints,\nsupported grants and onboarding. Do not construct those values from examples.\n\n| Before you begin | Successful result |\n| --- | --- |\n| Know who owns the integration, which environment it runs in, whether it acts as itself or for a person, and which application operations it needs | One independently registered client uses the published flow, carries only the intended roles and can be reviewed or revoked without affecting another integration |\n\n## Choose whose authority the client uses\n\n~~~mermaid\nflowchart TD\n accTitle: Choose an OAuth client journey by who authorizes the work\n accDescr: A backend workload that acts as itself uses an advertised machine grant and its own client roles. A client that acts for a person uses the advertised authorization journey, exact registered redirects and user consent when required; the final operation remains bounded by the client and person.\n need{\"Whose authority should the integration use?\"}\n need -->|Its own machine identity| machine[\"Register a workload client\"]\n machine --> machineGrant[\"Use an advertised machine grant\"]\n machineGrant --> machineRoles[\"Authorize operations with client roles\"]\n need -->|A person authorizes the client| delegated[\"Register a delegated client\"]\n delegated --> redirect[\"Use exact redirects and the published browser flow\"]\n redirect --> consent[\"Person approves or denies when consent is required\"]\n consent --> combined[\"Operation is bounded by client roles and the person's context\"]\n~~~\n\n- Choose a **machine client** for a backend process whose work should be\n attributable to the integration itself. Do not use an administrator's\n personal browser session for unattended work.\n- Choose **delegated access** when the operation should remain connected to the\n person who approved it. The client must send the person through the published\n authorization journey; collecting their password is never an alternative.\n- Use an **API key** instead when the exact API operation supports that simpler\n machine credential and no OAuth delegation or client lifecycle is needed.\n\n## Understand the four independent decisions\n\n| Decision | What it controls | What it does not do |\n| --- | --- | --- |\n| Grant | Whether the client acts as itself or uses a person's authorization journey | It does not grant an application role |\n| Client class and token method | Whether the runtime can protect a secret and how it authenticates to the token endpoint | A public client does not become confidential by embedding a secret in shipped code |\n| Identity scopes | Which supported identity claims the client may request | They do not authorize business operations |\n| Roles | Which application operations the client may perform | They do not replace the person's membership in a delegated journey |\n\n{{CONSUMER_FACT:source:consumer-fact:access-oauth-clients#markdown}}\n\nThe client can belong to an organization or to the application. That scope\nchooses the machine identity and administrative boundary; it does not make a\nclient more trusted merely because it is application-scoped.\n\n{{CONSUMER_FACT:source:consumer-fact:access-oauth-clients#scopeComparisonMarkdown}}\n\nRegister a separate client for each integration and environment. Redirects,\nissuer identity and credentials are environment-specific security boundaries,\nnot values to normalize or copy between deployments.\n\n## Start from discovery, not guessed endpoint paths\n\nThe authorization server publishes two equivalent metadata entry points:\n\n- OAuth authorization-server metadata at\n `/.well-known/oauth-authorization-server`;\n- OpenID Connect discovery at `/.well-known/openid-configuration`.\n\nFetch one from the **API issuer origin** and use the absolute endpoint values it\nreturns. The authorization endpoint is a browser-facing application page; the\ntoken, key, user-information, revocation and logout endpoints belong to the API\nissuer. They are deliberately not all under one hand-constructed path.\n\n~~~bash\nAPPLICATION_OAUTH_ISSUER=\"https://api.example.invalid\"\n\ncurl --fail --silent --show-error \"$APPLICATION_OAUTH_ISSUER/.well-known/oauth-authorization-server\"\n~~~\n\nCheck the returned `issuer` exactly. Then read the advertised grants,\n`code_challenge_methods_supported`, token authentication methods, registration\nendpoint and resource-indicator support before configuring the client. A\nmissing optional field means that capability is not advertised in this\nenvironment.\n\n~~~mermaid\nsequenceDiagram\n accTitle: Discover the authorization server before choosing a client flow\n accDescr: The integration starts from a resource or issuer, loads maintained metadata, selects only advertised registration and grant capabilities, and then uses the absolute endpoints returned by that metadata.\n participant Client as Integration client\n participant Resource as Protected resource\n participant AS as Authorization server\n Client->>Resource: Request protected operation\n Resource-->>Client: 401 plus protected-resource metadata when applicable\n Client->>Resource: Load protected-resource metadata\n Resource-->>Client: Authorization-server issuer and resource identifier\n Client->>AS: Load OAuth or OIDC metadata\n AS-->>Client: Issuer, endpoints, grants, PKCE and registration capabilities\n Client->>Client: Select supported registration and grant\n~~~\n\n## Use the protocol vocabulary consistently\n\n| Published element | Why the client needs it | Validation to retain |\n| --- | --- | --- |\n| `issuer` | Identifies the authorization server that produced the response and tokens | Exact string match; do not normalize hosts, paths or trailing slashes |\n| `authorization_endpoint` | Sends the person's browser through sign-in and consent | Use only the absolute discovered URL and preserve transaction state |\n| `token_endpoint` | Exchanges a machine credential, authorization code or refresh token | Use the registered client method and never log request credentials or returned tokens |\n| `jwks_uri` | Publishes public verification keys for signed tokens | Validate signature, algorithm, issuer, audience and time claims at the consuming service |\n| `resource` | Names the protected API, MCP server or A2A endpoint the token is meant for | Use the canonical advertised resource URI in both authorization and token requests when required |\n| `revocation_endpoint` | Ends a token authorization through the authenticated client lifecycle | Treat a successful no-oracle response as request acceptance, then verify the protected operation is refused |\n\nThe main standards behind those fields are [OAuth authorization-server metadata\n(RFC 8414)](https://www.rfc-editor.org/rfc/rfc8414), [PKCE (RFC\n7636)](https://www.rfc-editor.org/rfc/rfc7636), [OAuth resource indicators (RFC\n8707)](https://www.rfc-editor.org/rfc/rfc8707), [authorization-response issuer\nidentification (RFC 9207)](https://www.rfc-editor.org/rfc/rfc9207), [token\nrevocation (RFC 7009)](https://www.rfc-editor.org/rfc/rfc7009) and [OpenID\nConnect Discovery](https://openid.net/specs/openid-connect-discovery-1_0.html).\nThe environment's metadata is still the authority for which optional\ncapabilities are enabled here.\n\n## When the protected resource is an MCP server\n\nDo not register an MCP client by guessing an OAuth endpoint. The [MCP\nauthorization specification](https://modelcontextprotocol.io/specification/2026-07-28/basic/authorization)\nstarts from the protected resource, follows its RFC 9728 metadata to the\nauthorization server, and then chooses a registration mechanism in advertised\norder. In this application:\n\n1. use pre-registered client information when an administrator supplied it;\n2. use a Client ID Metadata Document only when metadata advertises support;\n3. use dynamic client registration only when a `registration_endpoint` is\n advertised; otherwise the route is intentionally unavailable;\n4. send the exact MCP endpoint as the RFC 8707 `resource` in the authorization\n and token requests.\n\nA dynamically registered client is deliberately **public, PKCE-only,\nauthorization-code-only, consent-required, role-free and identity-scope\nlimited**. That is an onboarding mechanism for a person-delegated MCP client,\nnot a way to mint an unattended privileged machine identity. Continue with the\n**MCP integration guide** — published under Integrations when the application\nexposes an MCP tool surface — for resource discovery and client setup.\n\n## Follow the OAuth client journey\n\n| Your next task | Start here | Successful result |\n| --- | --- | --- |\n| Define a new integration client | [Register an OAuth client](/access-and-identity/oauth-register-client) | One environment-specific client has the correct grant, class, roles and redirects |\n| Let a person authorize a client | [Authorize delegated access](/access-and-identity/oauth-authorize-delegated-access) | The person consents when required and the client receives no more authority than intended |\n| Review, rotate or revoke an active client | [Operate and revoke OAuth clients](/access-and-identity/oauth-operate-and-revoke) | Credential and authorization changes take effect without silently switching identities |\n\nBegin with the smallest safe proof: load the environment's discovery metadata,\ncomplete the selected flow with a controlled identity or workload, call one\nread-only operation and verify both the intended success and an expected\nrefusal. Do not add production writes until token storage, revocation,\nambiguous-outcome recovery and support ownership are defined.";
105
+ readonly sourceRefs: readonly ["saas-technical-doc:engine-content/oauth-provider", "source:companion-projection:application-connection", "source:consumer-fact:access-oauth-clients"];
106
+ readonly markdown: "# OAuth provider and delegated access\n\nUse OAuth when software needs its own client identity or needs to act after a\nperson authorizes it. The integration does not receive the person's password or\ncopy their browser session.\n\nThis journey applies only when the application publishes an OAuth authorization\nserver. Its discovery metadata is authoritative for issuer identity, endpoints,\nsupported grants and onboarding. Do not construct those values from examples.\n\n| Before you begin | Successful result |\n| --- | --- |\n| Know who owns the integration, which environment it runs in, whether it acts as itself or for a person, and which application operations it needs | One independently registered client uses the published flow, carries only the intended roles and can be reviewed or revoked without affecting another integration |\n\n## Choose whose authority the client uses\n\n~~~mermaid\nflowchart TD\n accTitle: Choose an OAuth client journey by who authorizes the work\n accDescr: A backend workload that acts as itself uses an advertised machine grant and its own client roles. A client that acts for a person uses the advertised authorization journey, exact registered redirects and user consent when required; the final operation remains bounded by the client and person.\n need{\"Whose authority should the integration use?\"}\n need -->|Its own machine identity| machine[\"Register a workload client\"]\n machine --> machineGrant[\"Use an advertised machine grant\"]\n machineGrant --> machineRoles[\"Authorize operations with client roles\"]\n need -->|A person authorizes the client| delegated[\"Register a delegated client\"]\n delegated --> redirect[\"Use exact redirects and the published browser flow\"]\n redirect --> consent[\"Person approves or denies when consent is required\"]\n consent --> combined[\"Operation is bounded by client roles and the person's context\"]\n~~~\n\n- Choose a **machine client** for a backend process whose work should be\n attributable to the integration itself. Do not use an administrator's\n personal browser session for unattended work.\n- Choose **delegated access** when the operation should remain connected to the\n person who approved it. The client must send the person through the published\n authorization journey; collecting their password is never an alternative.\n- Use an **API key** instead when the exact API operation supports that simpler\n machine credential and no OAuth delegation or client lifecycle is needed.\n\n## Understand the four independent decisions\n\n| Decision | What it controls | What it does not do |\n| --- | --- | --- |\n| Grant | Whether the client acts as itself or uses a person's authorization journey | It does not grant an application role |\n| Client class and token method | Whether the runtime can protect a secret and how it authenticates to the token endpoint | A public client does not become confidential by embedding a secret in shipped code |\n| Identity scopes | Which supported identity claims the client may request | They do not authorize business operations |\n| Roles | Which application operations the client may perform | They do not replace the person's membership in a delegated journey |\n\n{{CONSUMER_FACT:source:consumer-fact:access-oauth-clients#markdown}}\n\nThe client can belong to an organization or to the application. That scope\nchooses the machine identity and administrative boundary; it does not make a\nclient more trusted merely because it is application-scoped.\n\n{{CONSUMER_FACT:source:consumer-fact:access-oauth-clients#scopeComparisonMarkdown}}\n\nRegister a separate client for each integration and environment. Redirects,\nissuer identity and credentials are environment-specific security boundaries,\nnot values to normalize or copy between deployments.\n\n## Start from discovery, not guessed endpoint paths\n\nThe authorization server publishes two equivalent metadata entry points:\n\n- OAuth authorization-server metadata at\n `/.well-known/oauth-authorization-server`;\n- OpenID Connect discovery at `/.well-known/openid-configuration`.\n\nFetch one from the **API issuer origin** and use the absolute endpoint values it\nreturns. The authorization endpoint is a browser-facing application page; the\ntoken, key, user-information, revocation and logout endpoints belong to the API\nissuer. They are deliberately not all under one hand-constructed path.\n\n~~~bash\ncurl --fail --silent --show-error \"{{APPLICATION_CONNECTION_VALUE:oauthMetadataUrl}}\"\n~~~\n\nThat URL is not the issuer with the well-known segment appended, and the difference matters. RFC\n8414 inserts `/.well-known/oauth-authorization-server` **between the host and the issuer's path**,\nwhile OpenID Connect discovery appends its suffix to the issuer — the opposite construction. This\napplication's issuer is `{{APPLICATION_CONNECTION_VALUE:oauthIssuer}}`, and it serves the same\nmetadata document at both locations, so a client that derives either way finds it.\n\nCheck the returned `issuer` exactly. Then read the advertised grants,\n`code_challenge_methods_supported`, token authentication methods, registration\nendpoint and resource-indicator support before configuring the client. A\nmissing optional field means that capability is not advertised in this\nenvironment.\n\n~~~mermaid\nsequenceDiagram\n accTitle: Discover the authorization server before choosing a client flow\n accDescr: The integration starts from a resource or issuer, loads maintained metadata, selects only advertised registration and grant capabilities, and then uses the absolute endpoints returned by that metadata.\n participant Client as Integration client\n participant Resource as Protected resource\n participant AS as Authorization server\n Client->>Resource: Request protected operation\n Resource-->>Client: 401 plus protected-resource metadata when applicable\n Client->>Resource: Load protected-resource metadata\n Resource-->>Client: Authorization-server issuer and resource identifier\n Client->>AS: Load OAuth or OIDC metadata\n AS-->>Client: Issuer, endpoints, grants, PKCE and registration capabilities\n Client->>Client: Select supported registration and grant\n~~~\n\n## Use the protocol vocabulary consistently\n\n| Published element | Why the client needs it | Validation to retain |\n| --- | --- | --- |\n| `issuer` | Identifies the authorization server that produced the response and tokens | Exact string match; do not normalize hosts, paths or trailing slashes |\n| `authorization_endpoint` | Sends the person's browser through sign-in and consent | Use only the absolute discovered URL and preserve transaction state |\n| `token_endpoint` | Exchanges a machine credential, authorization code or refresh token | Use the registered client method and never log request credentials or returned tokens |\n| `jwks_uri` | Publishes public verification keys for signed tokens | Validate signature, algorithm, issuer, audience and time claims at the consuming service |\n| `resource` | Names the protected API, MCP server or A2A endpoint the token is meant for | Use the canonical advertised resource URI in both authorization and token requests when required |\n| `revocation_endpoint` | Ends a token authorization through the authenticated client lifecycle | Treat a successful no-oracle response as request acceptance, then verify the protected operation is refused |\n\nThe main standards behind those fields are [OAuth authorization-server metadata\n(RFC 8414)](https://www.rfc-editor.org/rfc/rfc8414), [PKCE (RFC\n7636)](https://www.rfc-editor.org/rfc/rfc7636), [OAuth resource indicators (RFC\n8707)](https://www.rfc-editor.org/rfc/rfc8707), [authorization-response issuer\nidentification (RFC 9207)](https://www.rfc-editor.org/rfc/rfc9207), [token\nrevocation (RFC 7009)](https://www.rfc-editor.org/rfc/rfc7009) and [OpenID\nConnect Discovery](https://openid.net/specs/openid-connect-discovery-1_0.html).\nThe environment's metadata is still the authority for which optional\ncapabilities are enabled here.\n\n## When the protected resource is an MCP server\n\nDo not register an MCP client by guessing an OAuth endpoint. The [MCP\nauthorization specification](https://modelcontextprotocol.io/specification/2026-07-28/basic/authorization)\nstarts from the protected resource, follows its RFC 9728 metadata to the\nauthorization server, and then chooses a registration mechanism in advertised\norder. In this application:\n\n1. use pre-registered client information when an administrator supplied it;\n2. use a Client ID Metadata Document only when metadata advertises support;\n3. use dynamic client registration only when a `registration_endpoint` is\n advertised; otherwise the route is intentionally unavailable;\n4. send the exact MCP endpoint as the RFC 8707 `resource` in the authorization\n and token requests.\n\nA dynamically registered client is deliberately **public, PKCE-only,\nauthorization-code-only, consent-required, role-free and identity-scope\nlimited**. That is an onboarding mechanism for a person-delegated MCP client,\nnot a way to mint an unattended privileged machine identity. Continue with the\n**MCP integration guide** — published under Integrations when the application\nexposes an MCP tool surface — for resource discovery and client setup.\n\n## Follow the OAuth client journey\n\n| Your next task | Start here | Successful result |\n| --- | --- | --- |\n| Define a new integration client | [Register an OAuth client](/access-and-identity/oauth-register-client) | One environment-specific client has the correct grant, class, roles and redirects |\n| Let a person authorize a client | [Authorize delegated access](/access-and-identity/oauth-authorize-delegated-access) | The person consents when required and the client receives no more authority than intended |\n| Review, rotate or revoke an active client | [Operate and revoke OAuth clients](/access-and-identity/oauth-operate-and-revoke) | Credential and authorization changes take effect without silently switching identities |\n\nBegin with the smallest safe proof: load the environment's discovery metadata,\ncomplete the selected flow with a controlled identity or workload, call one\nread-only operation and verify both the intended success and an expected\nrefusal. Do not add production writes until token storage, revocation,\nambiguous-outcome recovery and support ownership are defined.";
89
107
  }, {
90
108
  readonly managedPath: "access-and-identity/oauth-register-client.md";
91
109
  readonly unitRef: "technical-documentation:unit/oauth-register-client";
@@ -169,12 +187,12 @@ export declare const APPLICATION_CONSUMER_DOCUMENTATION_AUTHORED_CONTENT_V1: rea
169
187
  }, {
170
188
  readonly managedPath: "user-administration/scim-protocol-and-payloads.md";
171
189
  readonly unitRef: "technical-documentation:unit/scim-protocol-and-payloads";
172
- readonly sourceRefs: readonly ["saas-technical-doc:engine-content/scim-protocol-and-payloads", "source:consumer-fact:organization-scim-provisioning"];
173
- readonly markdown: "# SCIM protocol and payload reference\n\nUse this page to decide whether a directory or provisioning bridge is compatible\nwith this application **before** configuring production users. The application\nimplements a focused SCIM 2.0 User service. It is not a generic LDAP endpoint and\nit does not implement SCIM Groups.\n\n## Supported profile at a glance\n\n| Contract | This application supports | Important boundary |\n| --- | --- | --- |\n| Protocol | SCIM 2.0 over HTTPS with `application/scim+json` | SCIM 1.1 and direct LDAP binds are not accepted |\n| Authentication | A dedicated organization SCIM bearer token | The token selects one organization; it is not a user session or ordinary API key |\n| Resources | `Users` plus SCIM discovery documents | `Groups` is not implemented; group assignment can scope which users the provider sends but must not call `/Groups` |\n| User operations | Create, list, read, full replace, partial update and deactivate; Bulk accepts up to 100 operations | Organization-unit reconciliation differs by operation, as shown below |\n| Filtering | User lookup filters with a published maximum result size of 200 | Test the provider’s exact matching query before broad rollout |\n| Password changes | Not supported | Use the configured human sign-in or SSO journey; do not synchronize directory passwords |\n| Sorting and ETags | Not supported | A provider must not require sorting or conditional ETag writes |\n| Request budget | 300 requests per minute for each SCIM token | A 429 response includes retry information; reduce concurrency rather than rotating addresses |\n\nThe public discovery documents are available beneath the SCIM base URL:\n\n~~~text\nGET /ServiceProviderConfig\nGET /Schemas\nGET /ResourceTypes\n~~~\n\nRead `ServiceProviderConfig` during compatibility testing instead of assuming\nthat every feature mentioned by the SCIM standards is implemented.\n\n## Follow one SCIM request through the application\n\n~~~mermaid\nsequenceDiagram\n accTitle: How the application processes one SCIM User request\n accDescr: The provider sends an authenticated User operation. The SCIM service uses the bearer token to select an organization, validates the operation and profile, matches or creates the identity, maintains the organization membership, performs organization-unit reconciliation only when configured and supported for that operation, and returns a SCIM response.\n participant Provider as Provisioning provider\n participant Endpoint as SCIM endpoint\n participant Scope as Organization boundary\n participant Identity as User and membership\n participant Unit as Organization-unit mapping\n Provider->>Endpoint: User request plus bearer token\n Endpoint->>Scope: Resolve token to one organization\n Scope-->>Endpoint: Authorized organization context\n Endpoint->>Endpoint: Validate operation and SCIM profile\n Endpoint->>Identity: Match, create or update\n opt Mapping enabled and operation supported\n Endpoint->>Unit: Reconcile exact department mapping\n end\n Endpoint-->>Provider: SCIM resource, list or error response\n~~~\n\nThe token establishes the organization boundary **before** the profile is\napplied. The service then validates the request, resolves the person, maintains\nthe organization membership and, for the operations shown below, may reconcile\norganization-unit assignments. The response does not create a browser session\nand does not prove that the person can complete SSO.\n\n### Compatibility questions to answer before configuration\n\n| Provider requirement | Compatible expectation |\n| --- | --- |\n| Discovery | The provider can read `ServiceProviderConfig`, `Schemas` and `ResourceTypes` and respect the advertised feature set |\n| Resource types | User provisioning works without calling `/Groups` |\n| Update behavior | The provider can operate with the documented PUT/PATCH consequences, especially when department controls unit access |\n| Authentication | The provider can send the dedicated bearer token in the HTTPS `Authorization` header |\n| Matching and pagination | Its exact user filter and result-window behavior work within the published limit |\n| Unsupported features | It does not require password synchronization, sorting or conditional ETag writes |\n| Request volume | It respects rate-limit responses and does not depend on Bulk for organization-unit reconciliation |\n\n## Understand the base URL\n\nThe configuration resource supplies the API-relative path\n`/api/v1/scim/v2`. A provider needs the complete public URL:\n\n~~~text\nhttps://api.example.com/api/v1/scim/v2\n~~~\n\nThe organization is not encoded in that URL. The bearer token identifies the\norganization and must therefore be unique to one provider connection and one\nenvironment.\n\n## Example User document\n\nThe following payload shows the fields used by the maintained profile mapping\nand optional organization-unit mapping. Replace every value with a controlled\ntest identity; never copy a real person into documentation or a support ticket.\n\n~~~json\n{\n \"schemas\": [\n \"urn:ietf:params:scim:schemas:core:2.0:User\",\n \"urn:ietf:params:scim:schemas:extension:enterprise:2.0:User\"\n ],\n \"externalId\": \"directory-user-001\",\n \"userName\": \"alex.morgan@example.com\",\n \"active\": true,\n \"name\": {\n \"givenName\": \"Alex\",\n \"familyName\": \"Morgan\"\n },\n \"displayName\": \"Alex Morgan\",\n \"emails\": [{\n \"value\": \"alex.morgan@example.com\",\n \"type\": \"work\",\n \"primary\": true\n }],\n \"urn:ietf:params:scim:schemas:extension:enterprise:2.0:User\": {\n \"department\": \"Engineering\"\n }\n}\n~~~\n\nThe email mapping may use `userName`, the primary email or another configured\nemail path. Department is read from the standard Enterprise User extension; a\ntop-level `department` is accepted as a compatibility fallback. Its value is\nmatched exactly, after trimming, against the organization-unit mapping.\n\n{{CONSUMER_FACT:source:consumer-fact:organization-scim-provisioning#attributeMappingMarkdown}}\n\n## Choose operations with their consequences visible\n\n| Provider operation | User/profile effect | Organization-unit effect |\n| --- | --- | --- |\n| `POST /Users` | Creates or links the person according to the lifecycle configuration | Reconciles an exact mapped department when unit mapping and a default unit role are configured |\n| `PUT /Users/{id}` | Replaces the maintained profile and active state | Performs authoritative unit reconciliation from the full department value |\n| `PATCH /Users/{id}` | Applies supported partial profile or active-state changes | **Does not currently reconcile organization units** |\n| `DELETE /Users/{id}` | Runs the configured deactivation behavior; it does not physically erase the person | Does not perform a department-to-unit reconciliation |\n| `POST /Bulk` | Executes supported user operations individually | **Does not currently reconcile organization units**, including Bulk PUT operations |\n\nThis difference matters with providers that normally send PATCH. Do not enable\nauthoritative department-to-unit mapping merely because user creation worked.\nCapture the operation used for a department move and confirm that the former\nunit assignment is actually removed.\n\n## Recognize a valid list and error response\n\nA successful lookup with no match is a 200 response containing an empty SCIM\nlist—not a 404:\n\n~~~json\n{\n \"schemas\": [\"urn:ietf:params:scim:api:messages:2.0:ListResponse\"],\n \"totalResults\": 0,\n \"startIndex\": 1,\n \"itemsPerPage\": 0,\n \"Resources\": []\n}\n~~~\n\nErrors use the SCIM error media type and may include a `scimType` of\n`invalidSyntax`, `invalidValue`, `uniqueness` or `tooMany`. Preserve the HTTP status, SCIM type, redacted detail, operation,\nprovider job identifier and time. Never preserve the bearer token.\n\n## Standards used by this profile\n\n- [RFC 7643 §4.1](https://www.rfc-editor.org/rfc/rfc7643.html#section-4.1)\n defines the SCIM User resource; [§4.3](https://www.rfc-editor.org/rfc/rfc7643.html#section-4.3)\n defines the Enterprise User extension used for `department`.\n- [RFC 7644 §3.4.2](https://www.rfc-editor.org/rfc/rfc7644.html#section-3.4.2)\n defines filtering; [§3.5.1](https://www.rfc-editor.org/rfc/rfc7644.html#section-3.5.1)\n and [§3.5.2](https://www.rfc-editor.org/rfc/rfc7644.html#section-3.5.2)\n distinguish full replacement from PATCH; [§3.7](https://www.rfc-editor.org/rfc/rfc7644.html#section-3.7)\n defines Bulk; and [§3.12](https://www.rfc-editor.org/rfc/rfc7644.html#section-3.12)\n defines SCIM error responses.\n- [RFC 6750 §2.1](https://www.rfc-editor.org/rfc/rfc6750.html#section-2.1)\n defines bearer-token transport in the `Authorization` header. The\n application’s SCIM token lifecycle and authorization policy remain\n application behavior, not a promise made by that RFC.\n\nUse these standards to understand the wire contract. Use this page and the\napplication’s discovery response to understand the implemented profile.";
190
+ readonly sourceRefs: readonly ["saas-technical-doc:engine-content/scim-protocol-and-payloads", "source:companion-projection:application-connection", "source:consumer-fact:organization-scim-provisioning"];
191
+ readonly markdown: "# SCIM protocol and payload reference\n\nUse this page to decide whether a directory or provisioning bridge is compatible\nwith this application **before** configuring production users. The application\nimplements a focused SCIM 2.0 User service. It is not a generic LDAP endpoint and\nit does not implement SCIM Groups.\n\n## Supported profile at a glance\n\n| Contract | This application supports | Important boundary |\n| --- | --- | --- |\n| Protocol | SCIM 2.0 over HTTPS with `application/scim+json` | SCIM 1.1 and direct LDAP binds are not accepted |\n| Authentication | A dedicated organization SCIM bearer token | The token selects one organization; it is not a user session or ordinary API key |\n| Resources | `Users` plus SCIM discovery documents | `Groups` is not implemented; group assignment can scope which users the provider sends but must not call `/Groups` |\n| User operations | Create, list, read, full replace, partial update and deactivate; Bulk accepts up to 100 operations | Organization-unit reconciliation differs by operation, as shown below |\n| Filtering | User lookup filters with a published maximum result size of 200 | Test the provider’s exact matching query before broad rollout |\n| Password changes | Not supported | Use the configured human sign-in or SSO journey; do not synchronize directory passwords |\n| Sorting and ETags | Not supported | A provider must not require sorting or conditional ETag writes |\n| Request budget | 300 requests per minute for each SCIM token | A 429 response includes retry information; reduce concurrency rather than rotating addresses |\n\nThe public discovery documents are available beneath the SCIM base URL:\n\n~~~text\nGET /ServiceProviderConfig\nGET /Schemas\nGET /ResourceTypes\n~~~\n\nRead `ServiceProviderConfig` during compatibility testing instead of assuming\nthat every feature mentioned by the SCIM standards is implemented.\n\n## Follow one SCIM request through the application\n\n~~~mermaid\nsequenceDiagram\n accTitle: How the application processes one SCIM User request\n accDescr: The provider sends an authenticated User operation. The SCIM service uses the bearer token to select an organization, validates the operation and profile, matches or creates the identity, maintains the organization membership, performs organization-unit reconciliation only when configured and supported for that operation, and returns a SCIM response.\n participant Provider as Provisioning provider\n participant Endpoint as SCIM endpoint\n participant Scope as Organization boundary\n participant Identity as User and membership\n participant Unit as Organization-unit mapping\n Provider->>Endpoint: User request plus bearer token\n Endpoint->>Scope: Resolve token to one organization\n Scope-->>Endpoint: Authorized organization context\n Endpoint->>Endpoint: Validate operation and SCIM profile\n Endpoint->>Identity: Match, create or update\n opt Mapping enabled and operation supported\n Endpoint->>Unit: Reconcile exact department mapping\n end\n Endpoint-->>Provider: SCIM resource, list or error response\n~~~\n\nThe token establishes the organization boundary **before** the profile is\napplied. The service then validates the request, resolves the person, maintains\nthe organization membership and, for the operations shown below, may reconcile\norganization-unit assignments. The response does not create a browser session\nand does not prove that the person can complete SSO.\n\n### Compatibility questions to answer before configuration\n\n| Provider requirement | Compatible expectation |\n| --- | --- |\n| Discovery | The provider can read `ServiceProviderConfig`, `Schemas` and `ResourceTypes` and respect the advertised feature set |\n| Resource types | User provisioning works without calling `/Groups` |\n| Update behavior | The provider can operate with the documented PUT/PATCH consequences, especially when department controls unit access |\n| Authentication | The provider can send the dedicated bearer token in the HTTPS `Authorization` header |\n| Matching and pagination | Its exact user filter and result-window behavior work within the published limit |\n| Unsupported features | It does not require password synchronization, sorting or conditional ETag writes |\n| Request volume | It respects rate-limit responses and does not depend on Bulk for organization-unit reconciliation |\n\n## Understand the base URL\n\nThis is the complete base URL a provider needs. Everything below hangs off it:\n\n~~~text\n{{APPLICATION_CONNECTION_VALUE:scimBaseUrl}}\n~~~\n\nThe organization is not encoded in that URL. The bearer token identifies the\norganization and must therefore be unique to one provider connection and one\nenvironment.\n\n## Example User document\n\nThe following payload shows the fields used by the maintained profile mapping\nand optional organization-unit mapping. Replace every value with a controlled\ntest identity; never copy a real person into documentation or a support ticket.\n\n~~~json\n{\n \"schemas\": [\n \"urn:ietf:params:scim:schemas:core:2.0:User\",\n \"urn:ietf:params:scim:schemas:extension:enterprise:2.0:User\"\n ],\n \"externalId\": \"directory-user-001\",\n \"userName\": \"alex.morgan@example.com\",\n \"active\": true,\n \"name\": {\n \"givenName\": \"Alex\",\n \"familyName\": \"Morgan\"\n },\n \"displayName\": \"Alex Morgan\",\n \"emails\": [{\n \"value\": \"alex.morgan@example.com\",\n \"type\": \"work\",\n \"primary\": true\n }],\n \"urn:ietf:params:scim:schemas:extension:enterprise:2.0:User\": {\n \"department\": \"Engineering\"\n }\n}\n~~~\n\nThe email mapping may use `userName`, the primary email or another configured\nemail path. Department is read from the standard Enterprise User extension; a\ntop-level `department` is accepted as a compatibility fallback. Its value is\nmatched exactly, after trimming, against the organization-unit mapping.\n\n{{CONSUMER_FACT:source:consumer-fact:organization-scim-provisioning#attributeMappingMarkdown}}\n\n## Choose operations with their consequences visible\n\n| Provider operation | User/profile effect | Organization-unit effect |\n| --- | --- | --- |\n| `POST /Users` | Creates or links the person according to the lifecycle configuration | Reconciles an exact mapped department when unit mapping and a default unit role are configured |\n| `PUT /Users/{id}` | Replaces the maintained profile and active state | Performs authoritative unit reconciliation from the full department value |\n| `PATCH /Users/{id}` | Applies supported partial profile or active-state changes | **Does not currently reconcile organization units** |\n| `DELETE /Users/{id}` | Runs the configured deactivation behavior; it does not physically erase the person | Does not perform a department-to-unit reconciliation |\n| `POST /Bulk` | Executes supported user operations individually | **Does not currently reconcile organization units**, including Bulk PUT operations |\n\nThis difference matters with providers that normally send PATCH. Do not enable\nauthoritative department-to-unit mapping merely because user creation worked.\nCapture the operation used for a department move and confirm that the former\nunit assignment is actually removed.\n\n## Recognize a valid list and error response\n\nA successful lookup with no match is a 200 response containing an empty SCIM\nlist—not a 404:\n\n~~~json\n{\n \"schemas\": [\"urn:ietf:params:scim:api:messages:2.0:ListResponse\"],\n \"totalResults\": 0,\n \"startIndex\": 1,\n \"itemsPerPage\": 0,\n \"Resources\": []\n}\n~~~\n\nErrors use the SCIM error media type and may include a `scimType` of\n`invalidSyntax`, `invalidValue`, `uniqueness` or `tooMany`. Preserve the HTTP status, SCIM type, redacted detail, operation,\nprovider job identifier and time. Never preserve the bearer token.\n\n## Standards used by this profile\n\n- [RFC 7643 §4.1](https://www.rfc-editor.org/rfc/rfc7643.html#section-4.1)\n defines the SCIM User resource; [§4.3](https://www.rfc-editor.org/rfc/rfc7643.html#section-4.3)\n defines the Enterprise User extension used for `department`.\n- [RFC 7644 §3.4.2](https://www.rfc-editor.org/rfc/rfc7644.html#section-3.4.2)\n defines filtering; [§3.5.1](https://www.rfc-editor.org/rfc/rfc7644.html#section-3.5.1)\n and [§3.5.2](https://www.rfc-editor.org/rfc/rfc7644.html#section-3.5.2)\n distinguish full replacement from PATCH; [§3.7](https://www.rfc-editor.org/rfc/rfc7644.html#section-3.7)\n defines Bulk; and [§3.12](https://www.rfc-editor.org/rfc/rfc7644.html#section-3.12)\n defines SCIM error responses.\n- [RFC 6750 §2.1](https://www.rfc-editor.org/rfc/rfc6750.html#section-2.1)\n defines bearer-token transport in the `Authorization` header. The\n application’s SCIM token lifecycle and authorization policy remain\n application behavior, not a promise made by that RFC.\n\nUse these standards to understand the wire contract. Use this page and the\napplication’s discovery response to understand the implemented profile.";
174
192
  }, {
175
193
  readonly managedPath: "user-administration/scim-configure.md";
176
194
  readonly unitRef: "technical-documentation:unit/scim-configure";
177
- readonly sourceRefs: readonly ["saas-technical-doc:engine-content/scim-configure", "source:consumer-fact:organization-scim-provisioning"];
195
+ readonly sourceRefs: readonly ["saas-technical-doc:engine-content/scim-configure", "source:companion-projection:application-connection", "source:consumer-fact:organization-scim-provisioning"];
178
196
  readonly markdown: "# Configure SCIM provisioning\n\nConfigure the lifecycle rules and a dedicated credential before you send any\nproduction user. This page is for an organization administrator working with\nthe identity team that owns the directory connection.\n\n## What you need and what success looks like\n\n| | |\n| --- | --- |\n| **Who performs this task** | An organization owner or administrator together with the identity-directory owner |\n| **Where the configuration applies** | One selected organization and one directory environment |\n| **Before you begin** | Prove enterprise sign-in, choose lifecycle defaults, create any mapped units and prepare a protected secret store |\n| **Successful result** | The provisioning configuration and a dedicated active token exist, and a controlled SCIM user operation produces the expected application state |\n\n## Open SCIM administration\n\n1. Select the organization the directory will manage.\n2. Open **Settings**, then the organization’s **User provisioning** area.\n3. Use **Provisioning** for lifecycle defaults, attribute mappings and unit\n mappings.\n4. Use **Tokens** to create and manage the directory credential.\n\nIf **User provisioning** is absent, do not infer that SCIM is enabled. Confirm\nthe organization entitlement and application capability with the application\nowner. For automation, use the SCIM configuration and token API references\nlinked from this section.\n\n## Confirm the prerequisites\n\n- The organization type allows SCIM. The provisioning record has no separate\n `scimEnabled` switch.\n- Enterprise sign-in works for a representative directory-managed person.\n- You have selected a least-privileged default organization role.\n- Any organization units referenced by the directory already exist.\n- You know whether trusted directory assertions verify email and whether\n directory deactivation should change application access.\n\n## Configure the lifecycle decisions\n\nThe configuration below is projected from the maintained SCIM resource\nspecification and schema. The API reference remains authoritative for its exact\nrequest shape; this table explains what each value changes operationally.\n\n{{CONSUMER_FACT:source:consumer-fact:organization-scim-provisioning#configurationMarkdown}}\n\nThe standard **Organization owner** and **Organization administrator** roles\ncannot be SCIM defaults. Review every custom role’s effective inheritance before\nusing it for automatic provisioning.\n\n### Example: cautious first configuration\n\n~~~json\n{\n \"autoCreateUsers\": true,\n \"autoVerifyEmail\": true,\n \"autoDeactivateUsers\": false,\n \"defaultRole\": \"ORG_MEMBER\",\n \"attributeMapping\": {\n \"email\": \"emails[primary eq true].value\",\n \"firstName\": \"name.givenName\",\n \"lastName\": \"name.familyName\",\n \"displayName\": \"displayName\"\n }\n}\n~~~\n\nThis example deliberately leaves automatic deactivation off for the first\ncontrolled tests. It is not a recommended permanent policy: before production,\ndecide who owns leaver access and prove the multi-organization consequence\ndescribed below. Replace the example role with one from this application’s\n[Roles and permissions](/user-administration/roles-and-permissions) page.\n\n## Create the directory credential\n\nUse the application’s public API origin with the SCIM base path:\n\n~~~text\n/api/v1/scim/v2\n~~~\n\nSend a dedicated bearer token:\n\n~~~http\nAuthorization: Bearer SCIM_TOKEN\n~~~\n\nCreate a separate token for each directory connection and environment. The\nplaintext secret is returned once; store it immediately in the identity\nprovider’s secret store. Keep it out of source control, screenshots, logs,\ntickets and reusable examples.\n\nThe current request budget is **300 requests per minute per token**. When the\nservice returns a rate limit, follow its retry information and reduce\nconcurrency instead of starting parallel retries.\n\n## Treat deactivation as a high-impact choice\n\nThe current deactivation path marks both the global user and the addressed\norganization membership inactive. For a person who belongs to several\norganizations, this can affect more than the directory-owned membership. Test\nthat case before production rollout. A later `active:true` does not prove that\nthe organization membership was restored; verify both layers before announcing\nrecovery.";
179
197
  }, {
180
198
  readonly managedPath: "user-administration/scim-microsoft-entra.md";
@@ -210,7 +228,7 @@ export declare const APPLICATION_CONSUMER_DOCUMENTATION_AUTHORED_CONTENT_V1: rea
210
228
  readonly managedPath: "security-and-audit/audit-trail-and-siem.md";
211
229
  readonly unitRef: "technical-documentation:unit/audit-and-siem";
212
230
  readonly sourceRefs: readonly ["saas-technical-doc:engine-content/audit-and-siem"];
213
- readonly markdown: "# Security and audit\n\nThe audit trail answers **who or what acted, what changed, where it happened,\nwhen it happened and whether it succeeded**. Use it to investigate access and\nadministrative activity. Use SIEM export when a security team needs selected\norganization events delivered to its own monitoring system.\n\nThese are two related but separate paths. The application writes the\nauthoritative audit record first. SIEM delivery is a filtered outbound copy. A\nSIEM outage therefore does not erase the application's stored event, and a\nsuccessful SIEM delivery does not replace the source record.\n\n| Before you begin | Successful result |\n| --- | --- |\n| Know the organization and environment, the question being investigated, the authorized reviewer and the smallest useful time range | A stored event or bounded absence is reconciled with current application state, any SIEM delivery issue is treated separately, and controlled evidence has an owner and retention rule |\n\n~~~mermaid\nflowchart LR\n accTitle: Separate authoritative audit creation from SIEM delivery\n accDescr: A protected action creates an immutable application audit record. The organization filter may select that event for formatting and delivery to the SIEM. Failed delivery moves to the dead-letter queue while the original record remains available for investigation.\n action[\"Protected action or access decision\"] --> record[\"Immutable application audit record\"]\n record --> investigate[\"In-product investigation and bounded JSON export\"]\n record --> filter{\"Organization SIEM filter selects event?\"}\n filter -->|No| retained[\"Record remains in audit trail\"]\n filter -->|Yes| deliver[\"Format and deliver to SIEM\"]\n deliver -->|Success| siem[\"Organization SIEM\"]\n deliver -->|Failure| dlq[\"SIEM delivery queue for recovery\"]\n~~~\n\n## Understand what the trail proves\n\nAn audit row records that the application observed a particular action or\ndecision at a time. Its event identifier follows that event across retained and\nexported copies; its correlation identifier links activity from the same\nrequest or job. Actor, source, organization, outcome and event-specific data\nexplain the recorded context.\n\nThe trail does **not** automatically prove that:\n\n- the resource still has the same state now;\n- a declared event name is actually emitted by every operation;\n- the SIEM received its copy;\n- a broad export contains every matching row; or\n- a successful administrative action was low risk.\n\nReconcile material findings with the current authoritative resource. Treat a\nmissing expected row as a question about scope, filters, time and producer\ncoverage—not immediate proof that no action happened.\n\n## Keep actor and authority visible\n\n| Actor description | Meaning for investigation |\n| --- | --- |\n| Named person | The action is attributed to that person; verify the membership and role that applied at the time |\n| Machine | An API key or OAuth client acted; identify the credential record and owning workload |\n| System | A scheduled, internal or lifecycle process acted by design |\n| Unattributed | A principal was expected but could not be resolved; treat this as an anomaly to investigate |\n\nThe actor can differ from the person or resource affected by the action. Keep\nboth in the investigation so an administrator changing another person's access\nis not misread as self-service.\n\n## Choose the task you need\n\n- [Investigate an audit event](/security-and-audit/investigate-event) from a\n bounded symptom, time and organization scope.\n- [Review access and privileged changes](/security-and-audit/review-access-changes)\n without relying on declared-but-unemitted event names.\n- [Export a bounded audit window](/security-and-audit/export-audit-records) as\n JSON for an approved investigation.\n- [Configure organization SIEM export](/security-and-audit/configure-siem) with\n the appropriate format, authentication and event filter.\n- [Operate and troubleshoot SIEM delivery](/security-and-audit/operate-siem)\n from retries and dead-letter state.\n- [Protect and retain audit evidence](/security-and-audit/protect-evidence)\n without turning a diagnostic copy into an uncontrolled data store.\n\nClose each task with the question, organization/environment, filters and time\nboundary, event and correlation identifiers, current-state comparison, reviewer\ndecision and owned follow-up. Never place credentials, complete tokens or an\nunrestricted evidence export in an ordinary support ticket.";
231
+ readonly markdown: "# Security and audit\n\nThe audit trail answers **who or what acted, what changed, where it happened,\nwhen it happened and whether it succeeded**. Use it to investigate access and\nadministrative activity. Use SIEM export when a security team needs selected\norganization events delivered to its own monitoring system.\n\nThese are two related but separate paths. The application writes the\nauthoritative audit record first. SIEM delivery is a filtered outbound copy. A\nSIEM outage therefore does not erase the application's stored event, and a\nsuccessful SIEM delivery does not replace the source record.\n\n| Before you begin | Successful result |\n| --- | --- |\n| Know the organization and environment, the question being investigated, the authorized reviewer and the smallest useful time range | A stored event or bounded absence is reconciled with current application state, any SIEM delivery issue is treated separately, and controlled evidence has an owner and retention rule |\n\n~~~mermaid\nflowchart LR\n accTitle: Separate authoritative audit creation from SIEM delivery\n accDescr: A protected action creates an immutable application audit record. The organization filter may select that event for formatting and delivery to the SIEM. Failed delivery moves to the dead-letter queue while the original record remains available for investigation.\n action[\"Protected action or access decision\"] --> record[\"Immutable application audit record\"]\n record --> investigate[\"In-product investigation and bounded JSON export\"]\n record --> filter{\"Organization SIEM filter selects event?\"}\n filter -->|No| retained[\"Record remains in audit trail\"]\n filter -->|Yes| deliver[\"Format and deliver to SIEM\"]\n deliver -->|Success| siem[\"Organization SIEM\"]\n deliver -->|Failure| dlq[\"SIEM delivery queue for recovery\"]\n~~~\n\n## Understand what the trail proves\n\nAn audit row records that the application observed a particular action or\ndecision at a time. Its event identifier follows that event across retained and\nexported copies; its correlation identifier links activity from the same\nrequest or job. Actor, source, organization, outcome and event-specific data\nexplain the recorded context.\n\nThe trail does **not** automatically prove that:\n\n- the resource still has the same state now;\n- a declared event name is actually emitted by every operation;\n- the SIEM received its copy;\n- a broad export contains every matching row; or\n- a successful administrative action was low risk.\n\nReconcile material findings with the current authoritative resource. Treat a\nmissing expected row as a question about scope, filters, time and producer\ncoverage—not immediate proof that no action happened.\n\n## Keep actor and authority visible\n\n| Actor description | Meaning for investigation |\n| --- | --- |\n| Named person | The action is attributed to that person; verify the membership and role that applied at the time |\n| Machine | An API key or OAuth client acted; identify the credential record and owning workload |\n| System | A scheduled, internal or lifecycle process acted by design |\n| Unattributed | A principal was expected but could not be resolved; treat this as an anomaly to investigate |\n\nThe actor can differ from the person or resource affected by the action. Keep\nboth in the investigation so an administrator changing another person's access\nis not misread as self-service.\n\n## Choose the task you need\n\n- [Investigate an audit event](/security-and-audit/investigate-event) from a\n bounded symptom, time and organization scope.\n- [Review access and privileged changes](/security-and-audit/review-access-changes)\n without relying on declared-but-unemitted event names.\n- [Export a bounded audit window](/security-and-audit/export-audit-records) as\n JSON for an approved investigation.\n- [Configure organization SIEM export](/security-and-audit/configure-siem) with\n the appropriate format, authentication and event filter.\n- [Operate and troubleshoot SIEM delivery](/security-and-audit/operate-siem)\n from retries and dead-letter state.\n- [Protect and retain audit evidence](/security-and-audit/protect-evidence)\n without turning a diagnostic copy into an uncontrolled data store.\n- [Respond to a leaked credential](/security-and-audit/respond-to-leaked-credential)\n in the order an incident requires: contain, then assess, then recover.\n\nClose each task with the question, organization/environment, filters and time\nboundary, event and correlation identifiers, current-state comparison, reviewer\ndecision and owned follow-up. Never place credentials, complete tokens or an\nunrestricted evidence export in an ordinary support ticket.";
214
232
  }, {
215
233
  readonly managedPath: "security-and-audit/investigate-event.md";
216
234
  readonly unitRef: "technical-documentation:unit/investigate-audit-event";
@@ -251,56 +269,16 @@ export declare const APPLICATION_CONSUMER_DOCUMENTATION_AUTHORED_CONTENT_V1: rea
251
269
  readonly unitRef: "technical-documentation:unit/operate-and-troubleshoot-siem-delivery";
252
270
  readonly sourceRefs: readonly ["saas-technical-doc:engine-content/operate-and-troubleshoot-siem-delivery", "source:consumer-fact:organization-siem-export"];
253
271
  readonly markdown: "# Operate and troubleshoot SIEM delivery\n\nThe organization audit record and the SIEM copy have different health signals.\nWhen delivery fails, investigate the delivery queue without treating the source\nevent as missing.\n\n| Before you begin | Successful result |\n| --- | --- |\n| Have the organization/environment, source event ID, destination identity, approximate failure time, current configuration owner and permission to inspect recovery rows | The source event is confirmed, the receiver/configuration fault is corrected, eligible events are re-enqueued or intentionally purged with approval, and delivery is verified without exposing credentials |\n\n~~~mermaid\nflowchart TD\n accTitle: Recover a failed SIEM delivery\n accDescr: A selected audit event is delivered to the configured receiver. Normal retries happen before a failure capture is stored in the dead-letter queue. An authorized retry re-enqueues the stored envelope and removes that recovery row; a later failure creates a new row. Purge removes only recovery rows.\n selected[\"Selected audit event\"] --> attempt[\"Delivery attempt\"]\n attempt -->|Receiver accepts| delivered[\"SIEM copy delivered\"]\n attempt -->|Retry budget remains| attempt\n attempt -->|Delivery cannot continue| captured[\"Failure captured in dead-letter queue\"]\n captured --> inspect[\"Correct receiver, credentials, format or filtering\"]\n inspect -->|Authorized retry| requeue[\"Re-enqueue stored event\"]\n requeue -->|Queue accepts event| remove[\"Remove this recovery row\"]\n remove --> attempt\n captured -->|Authorized purge| purge[\"Remove recovery row without retry\"]\n~~~\n\n## When a destination keeps failing\n\n{{CONSUMER_FACT:source:consumer-fact:organization-siem-export#deliveryReliabilityMarkdown}}\n\n## Start from the failure boundary\n\n| Symptom | First checks |\n| --- | --- |\n| No events after enabling | Five-minute configuration cache, organization routing and event filter |\n| Receiver rejects every request | URL, selected format, content type and configured authentication |\n| HMAC verification fails | Exact received bytes and current shared secret; never parse and reserialize first |\n| Repeated timeouts | Receiver availability and configured timeout; reduce work before acknowledgement |\n| Events enter the dead-letter queue | Failure reason, failure count, last attempt and next retry time |\n| Only some event types arrive | Category, minimum severity and specific-event allowlist |\n\nThe delivery service retries with exponential backoff according to the configured\nbudget. Repeated failures can open a scope-specific circuit breaker; affected\nevents go to the dead-letter queue instead of being silently discarded.\n\n## Diagnose in source-to-receiver order\n\n1. Find the authoritative audit row by event ID or the narrowest available\n organization/time filter. If no source row exists, this is not yet a SIEM\n delivery problem.\n2. Confirm that the organization route and current category, severity and event-\n type filters select the event.\n3. Account for the configuration cache after enabling, changing or moving the\n destination.\n4. Inspect the delivery/recovery row for attempt count, last failure and next\n retry state.\n5. Check DNS/TLS reachability, timeout and receiver acknowledgement before\n changing credentials or format.\n6. Verify authentication at the receiver without logging the bearer/API-key/HMAC\n secret. For HMAC, verify the exact received bytes before parsing.\n7. Confirm the receiver parses the selected format into the intended event ID,\n actor, organization, outcome and severity.\n\nChange one boundary at a time and send a new controlled event. Replaying many\nrows before the receiver is corrected creates noise and can reopen the circuit.\n\nRetry a single row or all eligible rows only after correcting the receiver. A\nsuccessful retry action means **the event was accepted back onto the delivery\nqueue**, not that the SIEM has already accepted it. The recovery row is removed\nafter re-enqueue; if delivery fails again, a new dead-letter row records that\nlater failure.\n\n| Recovery action | What it proves | What it does not prove |\n| --- | --- | --- |\n| Retry one/all eligible rows | The stored envelope was accepted back onto the delivery queue | The receiver accepted or indexed it |\n| Receiver acknowledgement | The destination accepted the HTTP delivery | The event was parsed into the intended fields or detection rule |\n| Purge recovery row | The failed-delivery work item was intentionally removed | The source audit event was deleted |\n\nAfter re-enqueue, follow the new delivery outcome and find the event in the SIEM\nby its event ID. Compare critical fields with the source row; do not close on an\nHTTP success alone.\n\nPurging removes delivery-recovery rows, not the authoritative audit events.\nPreserve event ID and failure evidence long enough to prove the recovery result.\nUse purge only when retry is no longer appropriate—for example the receiver or\nevent route was intentionally retired—and retain who approved that loss of the\ndelivery copy.\n\nClose the incident with source event ID, organization/environment, destination,\nfilter decision, failure class, attempts, configuration correction, retry/purge\ndecision, receiver lookup and correlation evidence. Exclude authentication\nsecrets, raw Authorization headers and unnecessary event personal data.";
272
+ }, {
273
+ readonly managedPath: "security-and-audit/respond-to-leaked-credential.md";
274
+ readonly unitRef: "technical-documentation:unit/respond-to-leaked-credential";
275
+ readonly sourceRefs: readonly ["saas-technical-doc:engine-content/respond-to-leaked-credential"];
276
+ readonly markdown: "# Respond to a leaked credential\n\nA credential of this application has been exposed — an API key in a public repository, a token in a\nsupport ticket or a log, an OAuth client secret in a screenshot, or a person's password reused on a\nservice that was breached.\n\nEvery other page in this section explains ONE capability well. This one exists because an incident\nis not one capability: it is an ORDER. The costly mistakes here are not doing the wrong thing, they\nare doing the right things in the wrong sequence — investigating before containing, or revoking\nbefore you know what the credential reached.\n\n**Contain first. Assess second. Recover third.** Work down the page.\n\n## Before you start\n\nWrite down the exposure time you will use as the window's lower bound — when the credential first\nbecame readable by someone who should not have it, NOT when you found out. If you cannot establish\nit, use the credential's creation time. Every step below is bounded by that instant, and widening it\nlater means redoing the assessment.\n\n## 1 · Contain\n\nDo this before anything else, including before you finish reading the rest of this page. A credential\nyou are still investigating is a credential still being used.\n\n| What leaked | Do this |\n| --- | --- |\n| An API key | Revoke it — see [API key lifecycle](/access-and-identity/api-keys-lifecycle). Revocation takes effect for new requests; it does not retract a request already in flight |\n| An OAuth client secret, or a token issued to a client | [Operate and revoke delegated access](/access-and-identity/oauth-operate-and-revoke), and revoke the client's outstanding grants, not only the secret |\n| A person's password | Suspend the account — see [Suspend or remove a user](/user-administration/suspend-or-remove-user). Suspending ends their sessions; a password reset alone does not tell you whether someone else is already signed in |\n| A SCIM or directory token | Rotate at the identity provider, then in [SCIM configuration](/user-administration/scim-configure). Until both sides carry the new value, provisioning is stopped — that is the correct trade during containment |\n\n**Do not delete anything yet.** Deleting the API key, the client or the user removes rows the next\nstep reads. Revoke and suspend, which stop use while keeping the record.\n\nIf you do not yet know which credential leaked, suspend the narrowest thing that certainly covers it\nand widen only if the assessment says so. An over-broad containment is recoverable in minutes; a\nmissed one runs for as long as you are investigating.\n\n## 2 · Assess\n\nOnly now, and only inside the window you wrote down.\n\n1. **What did it reach?** [Investigate an audit event](/security-and-audit/investigate-event),\n filtered to the credential's own identifier rather than to a person — a leaked key acts under its\n own identity, and filtering by the human who created it will not show you its requests.\n2. **Did it change access?** [Review access and privileged changes](/security-and-audit/review-access-changes).\n This is the question that decides whether containment is finished: a credential that granted a\n role, added a member or registered a client has left something behind that revoking it does not\n remove.\n3. **Take the evidence out.** [Export a bounded audit window](/security-and-audit/export-audit-records)\n for the window, before retention or an investigation of your own moves it. Handle the export as\n the sensitive artefact it is — [Protect and retain audit evidence](/security-and-audit/protect-evidence).\n\nIf step 2 found a change, treat every artefact it created as also compromised and return to\n**Contain** for each one. That loop is the point of the ordering: a leaked key that minted a second\nkey is only half-contained when the first is revoked.\n\n## 3 · Recover\n\n- Issue the replacement credential and store it where the leaked one was not —\n [Create and store an API key](/access-and-identity/api-keys-create-and-store) states where a\n secret may and may not live.\n- Give the replacement the SMALLEST role that works. An incident is the cheapest moment to correct\n an over-broad credential, because whatever breaks is being watched.\n- Lift the containment you widened, narrowest first, confirming after each one.\n- If the account is a person's, require a second factor before returning it to service —\n [Multifactor enrollment and recovery](/access-and-identity/mfa-enrollment-and-recovery).\n\n## What this application cannot tell you\n\nThe audit trail records what reached THIS application. A credential leaked in one place is usually\nleaked for others: if the same secret, or a password reused from it, opens anything else you run,\nthis page's window is a lower bound on the incident, not its boundary.\n\nNor can the trail prove absence. A window with no suspicious request means nothing suspicious\n**reached this application** during it — not that the credential was unused, and not that your lower\nbound was early enough.";
254
277
  }, {
255
278
  readonly managedPath: "security-and-audit/protect-evidence.md";
256
279
  readonly unitRef: "technical-documentation:unit/protect-and-retain-audit-evidence";
257
280
  readonly sourceRefs: readonly ["saas-technical-doc:engine-content/protect-and-retain-audit-evidence"];
258
281
  readonly markdown: "# Protect and retain audit evidence\n\nAudit evidence can contain identities, IP addresses, device context, role\nchanges and event-specific business identifiers. Its security value does not\nmake every copy safe or every reader appropriate.\n\n| Before you disclose or retain a copy | Successful result |\n| --- | --- |\n| Know the investigation purpose, evidence owner, authorized readers, retention rule and deletion date | The smallest useful evidence remains traceable and protected without creating an indefinite uncontrolled copy |\n\n~~~mermaid\nflowchart LR\n accTitle: Keep the authoritative audit trail separate from controlled copies\n accDescr: The application retains the immutable source audit row. An investigator may create a bounded JSON copy, SIEM delivery may create an operational monitoring copy, and archival may create a durable retention copy. Each downstream copy needs its own access, integrity, retention and deletion controls.\n source[\"Authoritative application audit row\"] --> review[\"In-product investigation\"]\n source --> bounded[\"Bounded JSON export\"]\n source --> siem[\"Organization SIEM copy\"]\n source --> archive[\"Durable archive copy\"]\n bounded --> controls[\"Named owner, access and deletion rule\"]\n siem --> controls\n archive --> controls\n~~~\n\nThe application audit row remains the source record. An exported file, SIEM\nevent or archive object is a separate copy with a separate custody lifecycle;\none copy's retention or deletion setting does not silently govern the others.\n\n## Know which copy you are handling\n\n| Evidence location | Primary purpose | Control to record |\n| --- | --- | --- |\n| Application audit trail | Authoritative investigation and access-review record | Who may search or export the organization scope |\n| Bounded JSON export | Small approved investigation or compliance review | Purpose, filters, recipient, protected location and deletion date |\n| SIEM destination | Continuous detection, correlation and operational response | Receiver access, delivery health, downstream retention and incident ownership |\n| Durable archive | Long-term governed retention | Retention basis, integrity checks, restoration procedure and legal-hold handling |\n\n## Preserve integrity and minimize disclosure\n\n- Keep event ID, timestamp, actor classification, organization, outcome and\n correlation fields unchanged.\n- Never add a credential or secret to event data, a support ticket or a SIEM rule.\n- Share the smallest time range and field set needed for the investigation.\n- Separate security evidence from operational logs and business history; each\n has a different purpose and access policy.\n- Record who exported or disclosed evidence and the approved reason.\n\nWhen a ticket or report needs only a few events, attach a redacted subset and\nretain a reference to the protected source copy. Do not edit the source evidence\nto make it easier to read. Explain redactions separately so another authorized\nreviewer can reproduce the selection.\n\n## Apply retention to every copy\n\nAudit rows are immutable: the resource exposes no update or delete operation.\nWhen archival is configured, records older than the archival horizon are copied\nto durable file storage; the primary audit rows are not deleted. When no\narchival horizon is configured, the primary store retains them indefinitely.\nProduction archival cannot be configured below one year.\n\nBefore retaining evidence, answer:\n\n1. Which policy, investigation, legal hold or regulatory purpose requires it?\n2. Which copy is authoritative for this use?\n3. Who owns access approval and periodic review?\n4. When may the copy be deleted, and who verifies deletion?\n5. How will an authorized reviewer verify that identifiers and timestamps were\n not changed?\n\n> **Archival is not deletion from the primary audit trail.** It creates another\n> durable copy after the configured horizon. Plan access, restoration and final\n> disposition for that copy explicitly.\n\n## Treat optional context carefully\n\nCorrelation ID connects events from one request to application logs and errors.\nClient-instance ID may connect activity across sessions only when the application\nhas explicitly enabled that context. Its absence is not a collection failure.\nFrontend service name may be absent for jobs, scheduled work and internal\noperations.\n\nApply the organization's retention, legal-hold, privacy and incident-response\npolicy to every exported or downstream copy. A SIEM retention rule does not\nchange the application's authoritative audit retention.\n\n## Before closing the evidence task\n\n- confirm the organization, environment, time range and event count;\n- preserve event and correlation identifiers unchanged;\n- record the evidence owner, approved recipients and purpose;\n- confirm the protected storage location and deletion or legal-hold rule;\n- remove temporary local copies and ticket attachments that are no longer\n required;\n- keep credentials and unrelated personal data out of the evidence package.";
259
- }, {
260
- readonly managedPath: "billing-and-subscriptions/billing.md";
261
- readonly unitRef: "technical-documentation:unit/billing";
262
- readonly sourceRefs: readonly ["saas-technical-doc:engine-content/billing", "source:consumer-fact:billing-lifecycle"];
263
- readonly markdown: "# Billing and subscriptions\n\nUse this section when you are responsible for an organization's plan, invoices,\nusage or access after a billing change. You do not need to know which billing\nprovider the application uses. You do need to distinguish three records:\n\n- the **product and price** describe what can be bought and on which terms;\n- the **subscription** records the current recurring relationship;\n- the application's **billing-derived access** records which features and limits\n the current subscription actually grants.\n\n| Before you begin | Successful result |\n| --- | --- |\n| Know the organization being billed, who approved the commercial decision, the current product and the application access expected afterwards | The intended billing record reaches a known state, the resulting access is verified in the same organization, and payment evidence remains protected |\n\n{{CONSUMER_FACT:source:consumer-fact:billing-lifecycle#markdown}}\n\n## Keep the four billing views separate\n\n| View | Question it answers | Do not use it as proof of |\n| --- | --- | --- |\n| Product and price | What is offered, at what amount and interval, with which intended grants? | A purchase or active access |\n| Checkout or billing portal | Where are payment details, tax information and provider documents handled? | The final application subscription state |\n| Subscription and invoice summary | What recurring relationship and payment evidence did the application record? | Every feature currently available to the organization |\n| Resolved application access | Which features and limits can the organization actually use now? | Why that access exists without checking billing and other allowed sources |\n\nFor organization billing, the standard management operations accept\n**Organization Owner** and **Organization Admin** authority. A custom role may\ninherit effective authority in an application-specific role graph; review\n[Roles and permissions](/user-administration/roles-and-permissions) and the\nexact operation contract rather than granting a broad role merely to expose the\nBilling area.\n\n~~~mermaid\nflowchart LR\n accTitle: From a billing decision to usable application access\n accDescr: An authorized administrator selects a product and price, completes hosted checkout, waits for verified billing state, then confirms the subscription and billing-derived access in the application. Invoice and usage records remain separate evidence.\n choice[\"Choose product, price and billed scope\"] --> checkout[\"Complete hosted checkout\"]\n checkout --> verify[\"Application verifies billing result\"]\n verify --> subscription[\"Subscription state is updated\"]\n subscription --> access[\"Features and limits are recomputed\"]\n verify --> invoice[\"Invoice and payment state is recorded\"]\n usage[\"Metered application usage\"] --> invoice\n~~~\n\nThe important boundary is after checkout: **returning to the application is not\nproof that access changed**. Read the current subscription and verify the feature\nor limit you expected before telling people the change is complete.\n\nThe diagram has two evidence branches for a reason. Invoice/payment state\nexplains the commercial event, while subscription state drives the billing\naccess recomputation. A paid invoice and an unavailable feature can therefore\nboth be true during a mismatch that still needs reconciliation.\n\n## Choose the task you need\n\n| Your task | Start here | You are finished when |\n| --- | --- | --- |\n| Decide what to buy | [Understand plans, prices and access](/billing-and-subscriptions/plans-and-access) | The billed scope, price terms and expected access are explicit before approval |\n| Create the recurring relationship | [Start a subscription](/billing-and-subscriptions/start-subscription) | The application records Active or Trialing state and the intended access works |\n| Upgrade, downgrade, add capacity or end access | [Change, resume or end a subscription](/billing-and-subscriptions/change-or-end-subscription) | Effective timing, charge/credit and access consequences match the approved decision |\n| Review a charge, payment state, document or measured quantity | [Billing records and usage](/billing-and-subscriptions/billing-records) | The question is routed to its owning record and matched to the correct scope and period |\n| Resolve a mismatch | [Reconcile billing and application access](/billing-and-subscriptions/reconcile-access) | Provider evidence, application records and the original application action agree |\n| Recover from an unclear result | [Troubleshoot a billing change](/billing-and-subscriptions/troubleshoot) | The failing layer is identified without a duplicate purchase or hidden access grant |\n\n## Close every billing task with evidence\n\nRetain the billed organization, product/price identity, subscription or invoice\nidentifier, observed state, effective period, approval reference and correlation\ninformation needed for support. Do not retain card details, payment-method data,\nprovider secrets, complete invoice documents or capability-style invoice URLs in\nordinary logs and tickets.";
264
- }, {
265
- readonly managedPath: "billing-and-subscriptions/plans-and-access.md";
266
- readonly unitRef: "technical-documentation:unit/understand-billing-plans-and-access";
267
- readonly sourceRefs: readonly ["saas-technical-doc:engine-content/understand-billing-plans-and-access", "source:consumer-fact:billing-lifecycle"];
268
- readonly markdown: "# Understand plans, prices and access\n\nBefore approving a purchase, identify **what is being bought, who will be\nbilled, when the charge repeats and which application access should change**.\nThe current Billing area is authoritative for the products and prices offered by\nthis application. The supported product-kind inventory is not proof that every\nkind is offered here.\n\n| Before you begin | Successful result |\n| --- | --- |\n| Have the intended organization, business owner, expected users or workload, required features/capacity and approved spending boundary | One current product and price satisfy the outcome without unnecessary capacity, and the expected access can be verified after purchase |\n\n## Start from the work, not the plan name\n\nWrite down the outcome before comparing offers—for example, “the Support\norganization needs ten additional automated runs this month.” Then ask:\n\n- Is the requirement a continuing base capability, optional recurring capacity,\n measured use, a one-time item or prepaid credits?\n- Does the purchase belong to this organization, and will everybody who needs\n it operate in that same scope?\n- Which exact feature or limit should change, and what current application\n action will prove it?\n- When should the commercial and access change take effect?\n- Who owns renewal, usage review and cancellation?\n\n{{CONSUMER_FACT:source:consumer-fact:billing-lifecycle#productTypesMarkdown}}\n\nThe table lists product kinds the application can support. Only products and\nprices shown in this application's current Billing area are purchasable offers.\nDo not ask support to create a missing kind from this list.\n\n## Understand how quantity changes the amount\n\nThe product kind explains **what you are buying**. The pricing model explains\n**how the selected quantity becomes a charge**. Do not use the words “tiered”\nand “graduated” interchangeably: they produce different totals.\n\n{{CONSUMER_FACT:source:consumer-fact:billing-lifecycle#pricingModelsMarkdown}}\n\n### Worked example: 240 units\n\nThe following numbers are illustrative, not an offer from this application.\nThey show why the pricing model must be recorded with the amount:\n\n| Model | Illustrative terms | Result for 240 units |\n| --- | --- | --- |\n| Flat | €100 for the line item | €100 |\n| Per unit | €0.50 per unit | 240 × €0.50 = €120 |\n| Volume tiered | Up to 100 at €0.50; above 100 at €0.40 for all units | 240 × €0.40 = €96 |\n| Graduated | First 100 at €0.50; remaining units at €0.40 | (100 × €0.50) + (140 × €0.40) = €106 |\n| Package | €10 per block of 25, rounded up | 10 packages × €10 = €100 |\n\nFor a tiered or package offer, keep the tier boundaries, flat additions and\npackage size with the approval. A headline unit price is not enough to\nreconstruct the expected invoice.\n\n## Read a price as a complete offer\n\nCheck the product name and description together with:\n\n- the billed scope—usually an organization, or a person only when the\n application explicitly offers personal billing;\n- currency and amount;\n- monthly or yearly interval for recurring prices;\n- whether tax is included in the displayed amount or added at checkout;\n- trial duration and whether a payment method is required;\n- included features, capacity limits and any metered usage;\n- promotion eligibility and the date on which the offer expires.\n\nFor a recurring price, read both the interval and its count. “Month” with an\ninterval count of 3 means every three months, not monthly:\n\n{{CONSUMER_FACT:source:consumer-fact:billing-lifecycle#billingIntervalsMarkdown}}\n\nCurrency codes should be interpreted using the maintained\n[ISO 4217 currency list](https://www.iso.org/iso-4217-currency-codes.html).\nThe displayed currency does not determine whether tax is included:\n\n{{CONSUMER_FACT:source:consumer-fact:billing-lifecycle#taxDisplayModesMarkdown}}\n\nIf the hosted billing screen is Stripe, its maintained\n[tax-behaviour guide](https://docs.stripe.com/tax/products-prices-tax-codes-tax-behavior)\nexplains the provider-side inclusive/exclusive distinction. The application\noffer and checkout total remain the evidence for this purchase.\n\nAn **add-on** changes the same subscription without replacing its primary plan.\nA **credit pack** adds a consumable balance. Neither should be described as a\nplan upgrade unless that is what the product screen actually presents.\n\n## Trace an offer to application access\n\n~~~mermaid\nflowchart TD\n accTitle: Evaluate a billing offer from commercial terms to application access\n accDescr: The administrator starts with a required business outcome, chooses an offered product and price for one billed scope, reviews trial, timing and usage terms, identifies the promised feature or limit, then records how that access will be verified after purchase.\n outcome[\"Name the required business outcome\"] --> scope[\"Confirm billed organization or person\"]\n scope --> offer[\"Choose one currently offered product and price\"]\n offer --> terms[\"Review interval, tax, trial, quantity and promotion\"]\n terms --> grants[\"Identify expected features, limits or credits\"]\n grants --> proof[\"Define one application action that proves access\"]\n proof --> approval[\"Record approval and lifecycle owner\"]\n~~~\n\nThe important handoff is from **grants** to **proof**. A product description can\nstate what should be included; the original application action verifies what is\nactually usable after the billing state is processed.\n\n## Understand how access is assembled\n\nOne active plan supplies the base features and limits. Active add-ons can add\nfeatures or capacity. The application recomputes that billing-derived access\nfrom subscriptions in **Active** or **Trialing** state. Other subscription states\ndo not contribute billing-derived access.\n\nManual or broader-scope access can also exist. A feature remaining available\nafter a downgrade therefore does not, by itself, prove that billing\nreconciliation failed. Compare the expected product grants with the resolved\napplication access for the billed scope.\n\nBase-plan and add-on limits can combine according to the offered product policy:\nan add-on may add capacity or establish a higher limit. “Unlimited” capacity\nremains unlimited when combined. Do not calculate the final limit from marketing\nlabels alone; read the resolved limit in the billed scope.\n\n{{CONSUMER_FACT:source:consumer-fact:billing-lifecycle#limitGrantModesMarkdown}}\n\nFor example, a plan can establish 50 scheduled runs, while an add-on adds 20.\nThe expected result is 70. If instead the add-on establishes a limit of 100,\nthe expected result is 100—not 150. Verify the resolved value after purchase,\nbecause access can also come from a broader scope or an approved manual source.\n\n## Treat a promotion as conditional until checkout accepts it\n\n{{CONSUMER_FACT:source:consumer-fact:billing-lifecycle#promotionVocabularyMarkdown}}\n\nA promotion shown in Billing can still be refused for the selected purchase.\nBefore relying on it, verify its validity dates, remaining redemptions, eligible\nproducts, discount currency when fixed, and duration. The checkout result is the\npositive proof; visibility in a list is only a reason to evaluate it.\n\n## Approve with a reviewable record\n\nRecord the selected product and price, currency, interval, quantity, tax/trial\nterms, expected effective date, billed scope, expected grants and the person who\napproved them. Keep payment instruments and provider credentials out of that\nrecord. Continue to [Start a subscription](/billing-and-subscriptions/start-subscription)\nonly after the expected application proof is clear.";
269
- }, {
270
- readonly managedPath: "billing-and-subscriptions/start-subscription.md";
271
- readonly unitRef: "technical-documentation:unit/start-billing-subscription";
272
- readonly sourceRefs: readonly ["saas-technical-doc:engine-content/start-billing-subscription"];
273
- readonly markdown: "# Start a subscription\n\nStart a subscription only when you can approve billing for the selected scope.\nFor organization billing, organization owners and administrators are the\nstandard authorized roles. Confirm your application exposes Billing and the\nintended product before beginning.\n\n| Before you begin | Successful result |\n| --- | --- |\n| Have the approved organization, current product and price, expected access, spending approval, protected payment owner and a way to reconcile an unclear result | One checkout creates the intended subscription, the application records its current state and the expected feature or limit works in the billed scope |\n\n> **One checkout attempt can complete even when the browser never returns.**\n> Keep its identifiers and reconcile the application state before opening a\n> replacement checkout.\n\n## Before checkout\n\n1. Select the intended organization before opening Billing. Do not rely on the\n organization that happened to be active in a previous browser session.\n2. Confirm the product, price, currency, interval, quantity, tax display, trial\n terms and expected access against the approval.\n3. Check whether the displayed promotion applies to this exact product and\n price. Visibility of a promotion does not guarantee that every item accepts it.\n4. Record the approver, expected effective date and application action that will\n prove the resulting access.\n5. Continue once to the hosted checkout presented by the application.\n\nPayment details, billing address and tax identifiers belong on that hosted\nbilling surface. Do not send them through application support, an API metadata\nfield or a screenshot.\n\nWhen you enter a promotion code, stop if checkout refuses it. Do not compensate\nby changing quantity, selecting another organization or asking support to copy\nthe discount manually. Recheck the product, validity period, redemption limit\nand discount currency against the approved offer.\n\n~~~mermaid\nsequenceDiagram\n accTitle: Start and verify a subscription\n accDescr: The administrator opens checkout from the application, completes provider-hosted payment, returns to the application, then verifies the application subscription and resulting access instead of trusting the redirect alone.\n participant A as Administrator\n participant App as Application\n participant B as Hosted billing\n A->>App: Select product and price for the intended scope\n App-->>A: Open authorized checkout\n A->>B: Confirm payment and billing details\n B-->>A: Return to application\n App->>App: Verify billing result and update subscription\n A->>App: Read subscription state and expected access\n~~~\n\nThe browser return is only navigation. The application updates its billing\nrecords from the verified provider result, then recomputes access. Closing the\nbrowser, losing the redirect or receiving a timeout does not establish whether\nthe provider completed the checkout.\n\nIf the hosted screen identifies itself as Stripe, see Stripe's maintained\n[subscription Checkout journey](https://docs.stripe.com/billing/subscriptions/build-subscriptions)\nfor the provider-side steps. That reference explains the hosted screen; the\napplication subscription and resulting access remain the completion evidence.\n\n## Confirm success\n\nDo not use the success URL as the success criterion. In the application, verify:\n\n- a subscription exists for the intended billing account;\n- its product, price and period are correct;\n- its state is **Active** or **Trialing**;\n- the expected feature or limit is available in the intended organization;\n- any first invoice has the expected total and state.\n\nUse the maintained subscription meanings when reading the result:\n\nThe subscription states and what each one means for access are listed under\n[Reconcile access after a billing change](/billing-and-subscriptions/reconcile-access).\n\nIf the state remains incomplete, past due, unpaid or absent, do not create a\nsecond checkout immediately. Use the troubleshooting and reconciliation pages\nto determine whether the first attempt is still being processed.\n\n### Example: the browser closes after payment\n\nSuppose an administrator approves a paid plan, completes the hosted\npayment, and the browser closes before returning. Reopen Billing in the same\norganization and read the current subscription. If the approved plan is Active\nand the expected limit works, record that result and close the task. If the\nsubscription is absent or Incomplete, preserve the first checkout identifier and\nreconcile it; **do not start another purchase merely to obtain a success page**.\n\n## Verify access, not only billing\n\nRepeat the application action identified before checkout. Confirm it in the\nsame organization and with an ordinary intended user—not only with the billing\nadministrator. Also verify one limit or unavailable action that should remain\nunchanged, so the proof does not hide an unexpectedly broad grant.\n\n## Retain safe completion evidence\n\nKeep the organization, product/price identity, checkout or subscription\nidentifier, visible status, period dates, first-invoice summary, approver,\ncorrelation data and access-verification result. Do not retain card details,\npayment-method data, complete invoice documents, provider secrets or the full\ncheckout URL.";
274
- }, {
275
- readonly managedPath: "billing-and-subscriptions/change-or-end-subscription.md";
276
- readonly unitRef: "technical-documentation:unit/change-or-end-billing-subscription";
277
- readonly sourceRefs: readonly ["saas-technical-doc:engine-content/change-or-end-billing-subscription", "source:consumer-fact:billing-lifecycle"];
278
- readonly markdown: "# Change, resume or end a subscription\n\nA plan change is both a commercial decision and an access decision. Before\nconfirming it, review the new price, effective date, prorated charge or credit,\nand the features or limits that will be added or removed.\n\n| Before you begin | Successful result |\n| --- | --- |\n| Have the current subscription, approved target product/add-on, desired effective timing, expected charge or credit, and named access consequences | The application subscription reflects the approved change, access changes at the intended time, and no scheduled cancellation or stale item remains unexplained |\n\n{{CONSUMER_FACT:source:consumer-fact:billing-lifecycle#changeTimingMarkdown}}\n\n> **A requested policy is not proof of the applied charge or date.** Some billing\n> providers cannot schedule every change. Review any preview the application\n> presents, then verify the returned subscription, invoice or credit and the\n> resulting access. If those disagree with the approval, stop and reconcile the\n> change instead of applying another one.\n\n## Choose the lifecycle action\n\n~~~mermaid\nflowchart TD\n accTitle: Choose how a subscription should change\n accDescr: An administrator decides whether the organization needs a different base plan, an add-on change, end-of-period cancellation, immediate cancellation or reversal of a still-pending cancellation, then verifies the returned subscription and access consequence.\n need{\"What business decision was approved?\"}\n need -->|Replace base offer| plan[\"Change plan with product policy timing\"]\n need -->|Add or remove capacity| addon[\"Change subscription add-on\"]\n need -->|Stop at renewal| period[\"Schedule cancellation at period end\"]\n need -->|Stop now| immediate[\"Cancel immediately if policy permits\"]\n need -->|Undo pending cancellation| resume[\"Resume before the subscription ends\"]\n plan --> verify[\"Re-read subscription, charge evidence and access\"]\n addon --> verify\n period --> verify\n immediate --> verify\n resume --> verify\n~~~\n\nDo not choose from the wording “upgrade” or “downgrade” alone. Determine which\nbase product and add-ons will remain, when the provider applies the commercial\nchange, and when users should gain or lose the corresponding application access.\n\n## Change the plan or its add-ons\n\n1. Read the current subscription, including its items, state and period end.\n2. Choose the new plan or add-on from the current application catalogue.\n3. Confirm that the selected price belongs to that product and applies to the\n billed scope.\n4. Review the presented timing and proration before approving the change.\n5. After confirmation, re-read the subscription and verify the expected access.\n\nFor an add-on change, verify the base plan remains present and the intended\nadd-on appears or disappears exactly once. For a plan replacement, verify that\nthe returned base item is the approved product and price. Do not infer the\nresult from a checkout or portal confirmation message.\n\nDo not assume every billing connector can defer a downgrade. The **returned\napplication subscription** is the source of truth for what was applied.\n\nIf the hosted billing provider is Stripe, use its maintained\n[proration explanation](https://docs.stripe.com/billing/subscriptions/prorations)\nto interpret provider invoice lines. In particular, a credit line is not by\nitself proof that money was refunded, and a positive proration is not by itself\nproof that it was collected immediately. Match the application change, invoice\nstate and payment evidence.\n\n### Worked example: increase capacity mid-period\n\nThe figures below are illustrative; your own limits are shown in Billing.\nSuppose an organization's plan allows 50 automated runs and it needs 20 more\nimmediately. Before confirming an add-on, record:\n\n- the current 50-run limit and current billing-period end;\n- the add-on price and whether the presented adjustment is immediate;\n- the expected resolved limit of 70;\n- the application operation that will prove the extra capacity.\n\nAfter confirmation, verify that the base plan is still present, the add-on\nappears once, any provider adjustment matches the presented currency and period,\nand the resolved limit is 70. If the request times out, re-read those records\nbefore trying to add the same item again.\n\n## End at period end or cancel immediately\n\n- **End at period end** keeps the subscription active through its current\n period and marks it for cancellation. Access normally continues while the\n subscription remains Active or Trialing.\n- **Cancel immediately** marks the subscription Cancelled now and removes its\n contribution to billing-derived access when access is recomputed.\n\nImmediate cancellation is not always allowed by the product policy. Use it only\nwhen the business decision includes the immediate access consequence.\n\nBefore immediate cancellation, identify workflows, exports or administrative\nactions that depend on billing-derived access. Do not use a temporary manual\nrole or feature override to disguise the resulting loss; if continuity is\nrequired, approve the alternative access source explicitly.\n\n## Resume a scheduled cancellation\n\nA subscription can be resumed only while it is pending end-of-period\ncancellation. Resume clears that pending cancellation and returns the local\nsubscription to Active. Verify both the next period date and the resulting\naccess; a subscription that already ended needs a new approved purchase rather\nthan resume.\n\n## Verify by action and by time\n\n1. Confirm the returned subscription items, state, period end and cancellation\n flag in the billed scope.\n2. Match any immediate invoice or credit to the selected currency, quantity,\n proration and period.\n3. Repeat the application action affected by the change.\n4. For a deferred change, record what stays active now and schedule a check at\n the effective boundary.\n5. Verify an expected unaffected capability so the change did not alter a\n broader scope.\n\nRetain the approval, old and new product/price identities, selected timing,\nvisible proration evidence, subscription state and access proof. If the request\ntimes out, read the subscription before repeating it; an absent response is not\nevidence that the change failed.";
279
- }, {
280
- readonly managedPath: "billing-and-subscriptions/billing-records.md";
281
- readonly unitRef: "technical-documentation:unit/billing-records-and-usage";
282
- readonly sourceRefs: readonly ["saas-technical-doc:engine-content/billing-records-and-usage"];
283
- readonly markdown: "# Billing records and usage\n\nUse this journey when you need to explain **what was bought, what was charged,\nwhat was measured, or why application access differs from the commercial\nrecord**. Those questions use related records, but they do not have the same\nauthority.\n\n| Before you begin | Successful result |\n| --- | --- |\n| Know the environment, organization, product, billing period and the exact question being investigated | The question is answered from the record that owns it, then checked against the adjacent records without exposing payment data or duplicating a charge |\n\n## Choose the record that owns the answer\n\n| Question | Start with | Then compare |\n| --- | --- | --- |\n| Which recurring product is current? | Subscription items, status and period | Product/price offer and resolved access |\n| Was a charge created or paid? | Application invoice summary | Complete document in the authenticated provider portal |\n| Why is the invoice quantity different? | Local usage rows for the same period | Reported state and provider meter result |\n| Why is a feature unavailable after payment? | Current subscription and resolved access | Invoice/payment evidence only if the subscription state requires it |\n\n~~~mermaid\nflowchart LR\n accTitle: Use each billing record for the question it owns\n accDescr: The product and price describe the offer. The subscription records the recurring relationship and drives billing-derived access. Metered activity becomes local usage records and is reported to the provider. The provider creates the invoice; the application stores a safe summary while the complete document and payment methods remain in the authenticated provider portal.\n offer[\"Product and price\"] --> subscription[\"Subscription\"]\n subscription --> access[\"Billing-derived access\"]\n activity[\"Metered activity\"] --> usage[\"Local usage records\"]\n usage --> provider[\"Provider meter\"]\n subscription --> invoice[\"Provider invoice\"]\n provider --> invoice\n invoice --> summary[\"Application invoice summary\"]\n invoice --> portal[\"Authenticated provider portal\"]\n~~~\n\nThe useful boundary is between **operational summary** and **protected source\ndocument**. The application exposes enough invoice state and total information\nfor reconciliation, but complete tax documents and payment methods stay behind\nthe provider's authenticated portal. Usage remains separately traceable so a\nquantity can be explained before it becomes an invoice line.\n\n## Choose your task\n\n- [Manage invoices and payment details](/billing-and-subscriptions/invoices-and-payments)\n when the question concerns payment state, currency, tax or the complete invoice.\n- [Understand metered usage](/billing-and-subscriptions/metered-usage) when the\n question concerns measured quantity, reporting delay or a provider meter.\n- [Reconcile billing and application access](/billing-and-subscriptions/reconcile-access)\n when the commercial record is correct but the application outcome is not.\n- [Troubleshoot a billing change](/billing-and-subscriptions/troubleshoot) when\n the first durable record or failing boundary is still unclear.\n\nRetain identifiers, totals, states, periods and correlation evidence. Do not\ncopy card data, payment-method details, complete invoice documents, temporary\nportal URLs or personal data from usage metadata into ordinary tickets.";
284
- }, {
285
- readonly managedPath: "billing-and-subscriptions/invoices-and-payments.md";
286
- readonly unitRef: "technical-documentation:unit/manage-invoices-and-payments";
287
- readonly sourceRefs: readonly ["saas-technical-doc:engine-content/manage-invoices-and-payments", "source:consumer-fact:billing-lifecycle"];
288
- readonly markdown: "# Manage invoices and payment details\n\nAn invoice is evidence of a charge, not the subscription itself. The application\nstores a small invoice summary—state, total and timestamps—while the billing\nprovider keeps the complete tax document and payment methods behind its\nauthenticated portal.\n\n| Before you begin | Successful result |\n| --- | --- |\n| Know the billed organization, product, billing period and question being investigated; use an authorized billing administrator for provider documents | The application summary and provider document refer to the same charge, payment state and period without exposing payment data |\n\n## Know which record answers which question\n\n~~~mermaid\nflowchart LR\n accTitle: Separate the application invoice summary from the protected provider document\n accDescr: A subscription defines the recurring product and billing period. The provider creates an invoice and owns payment methods and the complete tax document. The application retains a safe status and total summary for operational review, while an authorized administrator opens the authenticated portal for the full document or payment change.\n subscription[\"Subscription and billing period\"] --> invoice[\"Provider invoice\"]\n invoice --> summary[\"Application invoice summary\"]\n invoice --> portal[\"Authenticated billing portal\"]\n portal --> document[\"Complete invoice or receipt\"]\n portal --> payment[\"Payment methods and billing details\"]\n~~~\n\nThe application summary is designed for status checks and reconciliation. It is\nnot a replacement for the provider's full tax document.\n\n{{CONSUMER_FACT:source:consumer-fact:billing-lifecycle#invoiceStatusesMarkdown}}\n\nOpen complete invoice documents through the authenticated billing portal. Direct\nprovider document URLs are deliberately not exposed in the application API:\nthey can act like bearer links to documents containing names and billing\naddresses.\n\nUse the provider portal only from the application's Billing area and return to\nthe intended environment afterwards. Do not copy a complete invoice into an\nordinary ticket when its identifier, total, currency, period and state are\nsufficient to investigate.\n\nIf the portal identifies itself as Stripe, use Stripe's maintained\n[customer-portal guide](https://docs.stripe.com/customer-management/integrate-customer-portal)\nto understand the provider handoff and its\n[Hosted Invoice Page guide](https://docs.stripe.com/invoicing/hosted-invoice-page)\nto understand the complete document surface. Always open a fresh portal session\nfrom the application; do not preserve or redistribute its temporary URL.\n\n## Read payment and subscription state together\n\n- An **Open** or **Uncollectible** invoice explains a payment problem, but the\n current subscription state determines whether billing-derived access remains.\n- A **Paid** invoice proves settlement of that invoice; still verify that the\n corresponding subscription and access update reached the intended scope.\n- A **Void** invoice should not be treated as a successful payment or as a new\n entitlement.\n\nAn invoice can change after it is first created—for example from Draft to Open\nor Paid. Record the state and observation time when using it as evidence. The\nlatest application summary is appropriate for operational review; the provider\nportal owns the complete document.\n\n## Interpret currency, tax and payment state separately\n\n{{CONSUMER_FACT:source:consumer-fact:billing-lifecycle#taxDisplayModesMarkdown}}\n\nInclusive or exclusive describes the **displayed price**. It does not prove the\ntax rate, jurisdiction, payment success or final amount. Compare the invoice\ncurrency, subtotal, tax, total and period with the approved offer and the\nprovider document. For an unfamiliar currency code, use the\n[ISO 4217 currency list](https://www.iso.org/iso-4217-currency-codes.html).\n\nWhen the invoice is Open or Uncollectible, an authorized administrator should\nopen Billing, enter the authenticated provider portal and review the available\npayment action. Do not ask the person to send card numbers, bank details or a\nscreenshot of the payment instrument to application support.\n\n### Example: a paid invoice but unchanged access\n\nA Paid invoice proves that **that invoice** was settled. It does not prove that\nthe application processed the corresponding subscription update or recomputed\naccess. Confirm the subscription is Active or Trialing, then repeat the\napplication action that should now be available. If that action still fails,\ncontinue with [Reconcile billing and application access](/billing-and-subscriptions/reconcile-access).\n\n## Protect financial evidence\n\nInvoice summaries remain financial history even when the billed scope is later\nretired. Limit access to administrators who need it, keep exports in protected\nstorage, and apply the organization's retention and legal-hold rules. Retain\nthe invoice identifier, currency, total, state, period and observation time in\nordinary support evidence—not the complete document or payment details.";
289
- }, {
290
- readonly managedPath: "billing-and-subscriptions/metered-usage.md";
291
- readonly unitRef: "technical-documentation:unit/understand-metered-usage";
292
- readonly sourceRefs: readonly ["saas-technical-doc:engine-content/understand-metered-usage", "source:consumer-fact:billing-lifecycle"];
293
- readonly markdown: "# Understand metered usage\n\nThis page applies only if a plan or add-on you hold charges for a measured\nquantity. If everything you subscribe to is a flat recurring price, no usage is\nrecorded and no usage line appears on an invoice — check\n[Understand plans, prices and access](/billing-and-subscriptions/plans-and-access)\nto see which of the two you have.\n\nA metered product charges for a measured quantity, such as processed documents,\nautomated runs or storage consumed. The application records the activity first;\nthe billing provider receives grouped usage later and uses its configured meter\nwhen preparing the invoice.\n\n| Before you begin | Successful result |\n| --- | --- |\n| Know the organization, metered product, billing period, unit being counted and application action that produces it | Local records, reported state, provider quantity and invoice use the same product, scope, period and unit without duplicating usage |\n\n## Follow one quantity through the system\n\n~~~mermaid\nsequenceDiagram\n accTitle: Follow metered usage from application activity to an invoice\n accDescr: A successful application action creates a local usage row. The Billing area can show the local total while the row is pending. A scheduled flush groups pending rows by billing account and product, reports the quantity to the provider, then marks the local rows as reported. Provider processing is asynchronous, so the invoice can lag behind the newest local activity.\n participant U as User or workload\n participant App as Application\n participant Store as Local usage records\n participant Job as Billing reporter\n participant P as Billing provider\n U->>App: Complete a metered action\n App->>Store: Record product, quantity and occurrence time\n Note over Store: reportedToProvider = false\n Job->>Store: Read pending rows by account + product\n Job->>P: Report grouped quantity\n P-->>Job: Accept report\n Job->>Store: Mark included rows as reported\n P->>P: Process meter and prepare invoice asynchronously\n~~~\n\nThe two delays in the diagram are different:\n\n- **Pending locally** means the application has recorded the activity but has\n not yet marked it as reported to the provider.\n- **Accepted by the provider** still does not mean an invoice or provider usage\n summary has updated immediately. Provider meter processing is asynchronous.\n\nThe application does not promise a universal flush interval. Record the last\nlocal occurrence time and the reported state instead of saying “billing updates\nevery hour”.\n\n## Understand what created the record\n\n{{CONSUMER_FACT:source:consumer-fact:billing-lifecycle#usageSourceTypesMarkdown}}\n\nThe source helps an administrator locate the business action that produced the\nquantity. It is not a reason to store a person's name, email or free-text notes\nin usage metadata. These records are retained as financial history.\n\n## Worked example: local usage is temporarily ahead\n\nThree application actions create quantities of 40, 25 and 10 for the same\nproduct and billing period. The local total is **75**. The first two rows have\nalready been reported, while the last row remains pending, so the provider can\ntemporarily show **65**.\n\nDo not manually send the missing 10 or recreate the application action. First\nwait for the normal reporting boundary and verify that the original row becomes\nreported. Re-sending a quantity that the normal flush later sends can create a\nduplicate charge.\n\n## Reconcile a usage difference\n\n| Check | What to compare | What it rules out |\n| --- | --- | --- |\n| Scope | Environment, organization and billing account | Usage from another tenant or test environment |\n| Product | Product key and the unit described by the offer | Comparing requests with storage, seats or another meter |\n| Period | Local occurrence timestamps and provider invoice period | Correct usage assigned to a different billing cycle |\n| Local total | Every row in the period, including pending rows | A dashboard total that omitted recent activity |\n| Reporting state | **Reported to provider** and **reported at** values | Treating pending activity as already invoiced |\n| Provider result | Meter quantity and invoice state after processing | A provider-side delay or rejected meter event |\n\nClose the investigation only when the same records explain both totals, or when\na named correction owner has accepted the difference. Preserve the product,\nperiod, local total, reported total, pending row identifiers and correlation\nevidence. Do not retain provider credentials or personal data.\n\nIf the hosted provider is Stripe, its maintained\n[usage-based billing overview](https://docs.stripe.com/billing/subscriptions/usage-based/how-it-works),\n[meter-event recording guide](https://docs.stripe.com/billing/subscriptions/usage-based/recording-usage-api)\nand [meter configuration guide](https://docs.stripe.com/billing/subscriptions/usage-based/meters/configure)\nexplain the provider side. Use those references to interpret provider processing;\nuse the application's local records to identify what was actually measured.";
294
- }, {
295
- readonly managedPath: "billing-and-subscriptions/reconcile-access.md";
296
- readonly unitRef: "technical-documentation:unit/reconcile-billing-and-access";
297
- readonly sourceRefs: readonly ["saas-technical-doc:engine-content/reconcile-billing-and-access", "source:consumer-fact:billing-lifecycle"];
298
- readonly markdown: "# Reconcile billing and application access\n\nUse reconciliation when the provider, the application subscription and the\nperson's visible access do not tell the same story. Keep those layers separate;\nchanging a role to conceal a billing problem creates a second access problem.\n\n| Before you begin | Successful result |\n| --- | --- |\n| Have the environment, billed organization, subscription and invoice identities, expected product grants, original application action and approximate change time | The first inconsistent layer is identified, repaired through its normal workflow and verified against current application state without a duplicate charge or unrelated access grant |\n\n{{CONSUMER_FACT:source:consumer-fact:billing-lifecycle#subscriptionStatusesMarkdown}}\n\n## Name the layer that disagrees\n\n| Layer | Evidence to read | Typical question |\n| --- | --- | --- |\n| Commercial offer | Current product, price, quantity and behavior policy shown by the application | Was the approved item actually offered for this scope? |\n| Provider transaction | Authenticated checkout/portal and invoice evidence | Did the provider complete, refuse or leave payment incomplete? |\n| Application billing state | Subscription items, status, period dates, invoice summary and usage reporting state | Did the verified result reach the intended billing account? |\n| Billing-derived access | Product grants and resolved feature/limit in the billed scope | Did the application recompute the access that this state should contribute? |\n| Original user action | The operation the person or workload tried to perform | Is the intended outcome now genuinely usable? |\n\nMove down the table in order. A role change at the final layer cannot repair an\nincomplete provider transaction, and a paid invoice does not by itself prove\nthat the application's subscription or feature state was updated.\n\n~~~mermaid\nflowchart TD\n accTitle: Reconcile a billing change from scope to entitlement\n accDescr: The reviewer confirms the billed scope, reads the application subscription and invoice, checks whether the subscription state contributes billing access, compares product grants with resolved access, and then repairs the failing layer.\n symptom[\"Expected access differs from visible access\"] --> scope[\"Confirm billed organization or person\"]\n scope --> subscription[\"Read current application subscription\"]\n subscription --> state{\"Active or Trialing?\"}\n state -->|No| payment[\"Inspect invoice and payment state\"]\n state -->|Yes| grants[\"Compare plan and add-on grants\"]\n grants --> resolved[\"Check resolved feature and limit\"]\n payment --> repair[\"Repair billing or wait for verified update\"]\n resolved --> repair\n repair --> verify[\"Repeat the original application action\"]\n~~~\n\nNotice that the flow checks **Active or Trialing** before comparing grants.\nThose are the only maintained subscription states that contribute billing-\nderived access. Payment repair belongs before feature repair when the\nsubscription is in another state.\n\n## Reconciliation checklist\n\n1. Confirm the environment and billed scope.\n2. Read the current application subscription; do not rely on a provider email\n or redirect.\n3. Verify its product items, status, period dates and cancellation flag.\n4. If payment is involved, match the invoice total, currency and state.\n5. Compare the plan and add-on grants with the resolved feature or limit.\n6. Repeat the original application operation to prove access, not merely the\n Billing screen.\n7. Record the final subscription state and the evidence used to close the case.\n\nWhere a change may still be processing, preserve the first attempt and allow a\nbounded observation window instead of opening a replacement checkout. Where a\nwrite returned no response, re-read current subscription state before deciding\nwhether a retry is safe.\n\nOnly Active and Trialing subscriptions contribute billing-derived access. A\nfeature can still come from another allowed source, and a finite application\nlimit can combine with plan and add-on limits. Explain the actual resolved\nresult instead of assuming one plan label owns all access.\n\n## Choose the repair by the failing layer\n\n- **Wrong scope or offer:** return to the intended organization and select a\n current product/price through the normal Billing journey.\n- **Incomplete or failed payment:** use the authenticated billing portal; do not\n send payment details to application support.\n- **Stale application subscription:** preserve transaction and correlation\n evidence for support rather than patching the subscription record.\n- **Correct subscription but wrong grants:** compare the product and add-on\n definitions with the resolved feature/limit; do not add a broad role as a\n substitute.\n- **Correct resolved access but failed action:** troubleshoot the operation's\n organization, role, resource visibility and request separately from billing.\n\nClose with the organization, original symptom, responsible layer, correction,\nfinal subscription/invoice state and the repeated application action. Exclude\ncard details, provider secrets and complete invoice documents.";
299
- }, {
300
- readonly managedPath: "billing-and-subscriptions/troubleshoot.md";
301
- readonly unitRef: "technical-documentation:unit/troubleshoot-billing-change";
302
- readonly sourceRefs: readonly ["saas-technical-doc:engine-content/troubleshoot-billing-change"];
303
- readonly markdown: "# Troubleshoot a billing change\n\nBegin with what the administrator or user can observe. Repeating checkout,\ngranting a broader role or manually changing access before identifying the\nfailed layer can create duplicate charges or hide the original problem.\n\n| Before you begin | Successful result |\n| --- | --- |\n| Preserve the environment, organization, first attempt, product/price, subscription or invoice identifier, approximate time, visible status and original application symptom | One failing boundary is identified and repaired without duplicating a purchase, exposing payment data or leaving unrelated access in place |\n\n## Diagnose from the first durable record\n\n~~~mermaid\nflowchart TD\n accTitle: Troubleshoot a billing change without repeating it blindly\n accDescr: The administrator starts from the first checkout or subscription evidence, confirms the billed scope, reads current subscription and invoice state, compares product grants with resolved access, then repeats the original application action after repairing only the failing layer.\n symptom[\"Billing or access result is unexpected\"] --> scope[\"Confirm environment and billed scope\"]\n scope --> attempt[\"Preserve first checkout or change evidence\"]\n attempt --> subscription{\"Application subscription present?\"}\n subscription -->|No or incomplete| payment[\"Check invoice/provider evidence and processing state\"]\n subscription -->|Yes| status{\"State contributes billing access?\"}\n status -->|No| payment\n status -->|Yes| grants[\"Compare product/add-on grants with resolved access\"]\n grants --> action[\"Repeat original application action\"]\n payment --> repair[\"Repair payment or reconcile verified provider result\"]\n repair --> subscription\n~~~\n\nDo not begin from a success redirect, provider email or plan label. Begin from\nthe application billing account and current subscription for the intended\nscope, then correlate provider evidence only where the state requires it.\n\nUse these maintained state meanings while diagnosing:\n\nThe full list of subscription states, and what each one means for access, is under\n[Reconcile access after a billing change](/billing-and-subscriptions/reconcile-access).\n\n## Start from the symptom\n\n| Symptom | First checks | Safe next step |\n| --- | --- | --- |\n| Returned from checkout but no subscription appears | Intended scope, existing incomplete subscription, processing delay and the first attempt's billing evidence | Reconcile the first attempt before opening checkout again |\n| Subscription is Active but feature is unavailable | Product and price, expected grants, current organization, resolved feature/limit and the original operation | Repair grant/access reconciliation; do not broaden the person's role |\n| Subscription is Past due, Unpaid or Paused | Current invoice state and the authenticated billing portal; these states do not contribute billing-derived access | Resolve payment in the portal, then wait for verified application state |\n| Downgrade or cancellation appears immediate | Returned subscription items, status, period end and cancellation flag; do not rely only on the requested timing | Compare the applied product policy and access consequence with the approval |\n| Cancellation was requested but access remains | End-of-period cancellation may intentionally keep an Active subscription until period end | Record the effective boundary and verify again when the period ends |\n| Invoice total differs from expectation | Currency, tax display, quantity, proration, promotion and billing period | Compare the selected offer and applied adjustment before disputing the charge |\n| Metered usage differs from provider | Local period total, last recorded time, reported state and aggregation delay | Wait for the bounded reporting window, then compare the same product and period |\n| Resume is refused | The subscription must still be pending end-of-period cancellation | If it already ended, use a newly approved purchase instead of resume |\n| Billing screen is correct but the application action fails | Resolved feature/limit, organization, role and exact operation | Troubleshoot authorization or resource scope separately from billing |\n\n## Recover without making the record harder to understand\n\n- Keep the first checkout or change identifiers and do not create a replacement\n until its state is known.\n- Use the authenticated billing portal for payment methods and invoice documents.\n- Correct the product, price or scope through the normal billing operation; do\n not patch subscription status directly.\n- After recovery, verify both the billing record and the application action that\n depends on it.\n- Share invoice identifiers, status, timestamps and correlation evidence with\n support—not card details, full invoice documents or provider secrets.\n\nIf the application record and provider evidence still disagree, preserve both\nviews and escalate the reconciliation. The application retains subscriptions,\ninvoice references and usage records as financial history rather than deleting\nthem when a scope is retired.\n\n## Escalate a reproducible case\n\nProvide the environment, billed organization, product/price identity, first\nattempt or subscription identifier, invoice summary, timestamps, current state,\nexpected access, observed application action and correlation identifier. State\nwhether payment, subscription state or access changed between observations.\nNever attach card data, payment-method details, complete invoice documents,\nhosted invoice URLs, provider secrets or unrestricted personal data.";
304
282
  }, {
305
283
  readonly managedPath: "integrations.md";
306
284
  readonly unitRef: "technical-documentation:unit/integrations";
@@ -314,18 +292,18 @@ export declare const APPLICATION_CONSUMER_DOCUMENTATION_AUTHORED_CONTENT_V1: rea
314
292
  }, {
315
293
  readonly managedPath: "integrations/automation/n8n.md";
316
294
  readonly unitRef: "technical-documentation:unit/connect-n8n";
317
- readonly sourceRefs: readonly ["saas-technical-doc:engine-content/connect-n8n", "source:consumer-fact:access-api-keys"];
318
- readonly markdown: "# Connect n8n\n\nUse n8n when a visual workflow should read or change information in this\napplication. There is no application-specific n8n node to install: the workflow\nuses n8n's standard **HTTP Request** node and the REST API published in this\ndocumentation.\n\nThis guide first builds a manual, read-only workflow. By the end, one click in\nn8n will call one authenticated operation and show recognizable application\ndata in the node output. Only then will you connect a trigger or add a write.\n\n> **If the application should start the workflow when something happens,**\n> complete the read-only connection first, then follow **Start from an\n> application event** below. Do not poll repeatedly when a published webhook\n> already represents the event you need.\n\n## What do you need before starting?\n\nAsk the application administrator or integration owner for:\n\n- the server origin shown in this application's API reference;\n- one authenticated **GET** operation and its complete path;\n- the non-production organization and known data you may use for the test;\n- a dedicated API key with only the role accepted by that operation; and\n- an owner who can revoke the key if the workflow is abandoned or exposed.\n\nUse [Create and store an API key](/access-and-identity/api-keys-create-and-store)\nif the credential has not been prepared. Keep n8n and the application in the\nsame environment throughout the test.\n\n## Build the first read-only workflow\n\n### 1. Create an explicit test trigger\n\nCreate a new workflow and keep it inactive. Add a **Manual Trigger** so that the\napplication is contacted only when you choose **Execute workflow**. Name the\nworkflow after the business result and environment—for example, “Read approved\nrecords — test”—not after the credential.\n\n### 2. Add the application request\n\nAdd an **HTTP Request** node after the trigger, then complete these fields from\nthe same API-reference operation:\n\n| n8n field | Value to use | How to verify it |\n| --- | --- | --- |\n| **Method** | The operation's documented HTTP method, initially **GET** | It matches the operation heading in the API reference |\n| **URL** | Server origin followed by the complete documented operation path | The origin appears once and the API path appears once |\n| **Authentication** | **Generic Credential Type**, then **Header Auth** | The key is stored as an n8n credential, not in the URL or workflow data |\n| **Send Headers** | Add **Accept** with value **application/json** | The request asks for the documented JSON response |\n| Query/path values | Only values required by the selected operation | Organization and resource identifiers are in the locations defined by the reference |\n\nWhen creating the **Header Auth** credential, use the maintained application\nheader contract below. Enter the header name and secret value in the credential\ndialog; do not construct them with an expression inside the node.\n\n~~~text\n{{CONSUMER_FACT:source:consumer-fact:access-api-keys#requestHeader}}\n~~~\n\nn8n's [HTTP Request node documentation](https://docs.n8n.io/integrations/builtin/core-nodes/n8n-nodes-base.httprequest/)\nexplains the current node controls and generic credential options. If the\nlabels in your installed n8n version differ, use that documentation for the UI\nlocation while keeping the application request contract defined here.\n\n### 3. Execute and inspect the output\n\nSelect **Execute workflow**. The Manual Trigger and HTTP Request nodes should\ncomplete successfully, and the HTTP Request output panel should contain JSON\nmatching the response schema in the API reference.\n\nDo not treat a green node alone as proof. Confirm:\n\n- the output is from the intended application environment;\n- the data belongs to the intended organization;\n- the known record or collection result is present;\n- required fields have the types documented in the response schema; and\n- the API key is absent from the input, output and execution data panels.\n\n~~~mermaid\nsequenceDiagram\n accTitle: Build and prove the first n8n application workflow\n accDescr: An operator runs a manual trigger, n8n reads application data with a stored credential, the operator verifies the returned organization and schema, and only then replaces the trigger or adds a controlled business action.\n actor Operator\n participant n8n\n participant App as Application API\n Operator->>n8n: Execute inactive test workflow\n n8n->>App: Authenticated GET from HTTP Request node\n App-->>n8n: Documented JSON response\n n8n-->>Operator: Show node output\n Operator->>Operator: Verify environment, organization and known data\n Operator->>n8n: Add trigger or one controlled action\n~~~\n\nThe checkpoint in the diagram is the human verification after the first read.\nIt prevents an apparently successful workflow from being activated against the\nwrong organization or environment.\n\n## Prove the credential boundary\n\nCopy the HTTP Request node for this negative test. On the copy, temporarily set\nauthentication to **None** while leaving the URL and parameters unchanged. Run\nonly that node. The authenticated operation should return its documented\nauthentication refusal, normally **401**.\n\nDelete the unauthenticated copy after the test. If it returns the same protected\ndata as the authenticated node, stop: either the wrong operation was selected or\nthe access boundary needs investigation. Do not continue by adding a write.\n\n## Turn the read into a useful workflow\n\nConnect one decision or transformation step to the verified HTTP Request node.\nFor example, an **If** node can stop the workflow when the collection is empty,\nor a mapping step can select only the fields the next system is allowed to\nreceive.\n\nBefore adding a state-changing request, define all four items:\n\n1. the exact application state that should change;\n2. the condition that permits the change;\n3. the read operation that proves the final state; and\n4. what the workflow does when a write times out without a response.\n\nFor the first write, keep automatic retry disabled. Execute it once with known\ntest data, then read the target back. **A timeout is not proof that the write did\nnot happen**; use the read-back before deciding whether another request is\nneeded.\n\n## Start from an application event\n\nUse this path only when a Webhooks section is present in this documentation and\nthe application publishes the event you need.\n\n1. Add an n8n **Webhook** trigger and copy its **test URL**.\n2. Put n8n into test-listening mode.\n3. Configure a non-production application webhook endpoint for that URL.\n4. Send one controlled event and inspect the received request before mapping\n any fields.\n5. Verify the application's signature and deduplicate the delivery before a\n downstream action.\n6. Publish the n8n workflow, copy its **production URL**, and update the\n application endpoint. The temporary test URL is not the production address.\n\nFollow [Verify a webhook delivery](/integrations/webhooks/verify-delivery) for\nthe application trust boundary. n8n's\n[Webhook workflow guide](https://docs.n8n.io/integrations/builtin/core-nodes/n8n-nodes-base.webhook/workflow-development/)\nexplains its test and production URL lifecycle.\n\n## When the workflow does not work\n\n| What you see in n8n | Most likely boundary | What to check next |\n| --- | --- | --- |\n| Connection or TLS error | Server/network | Confirm the API-reference server origin is reachable from the n8n host |\n| **401** response | Credential transport or lifecycle | Confirm Header Auth is selected and the stored key is active; never expose the value while checking |\n| **403** response | Role, organization or operation authority | Compare the key's approved role with the operation requirement |\n| **404** response | Identifier, organization scope or visibility | Confirm the target exists in the application and the path values came from the same environment |\n| Green node, wrong records | Scope or mapping | Stop the workflow and correct organization, filters or response mapping before adding downstream nodes |\n| Timeout after a write | Ambiguous business result | Read the application state; do not repeatedly execute the write node |\n| Webhook works only in test mode | URL lifecycle | Publish the workflow and configure the production URL |\n\nUse [Troubleshoot an API request](/integrations/rest/troubleshoot) when the\nHTTP response needs deeper diagnosis.\n\n## Before activating the workflow\n\n- Replace the Manual Trigger only after the read and negative test pass.\n- Keep the application key in n8n's credential store and restrict who can edit\n or use that credential.\n- Pin the server, organization and workflow purpose; do not make them silently\n depend on whichever item ran previously.\n- Validate required fields before a write and reject unexpected values.\n- Define failed-execution alerts, an accountable operator and a revocation\n procedure.\n- Test a revoked key, insufficient permission, invalid input and an unavailable\n dependency.\n- Retain non-secret operation, status, time and correlation evidence so an\n operator can reconcile the business result.";
295
+ readonly sourceRefs: readonly ["saas-technical-doc:engine-content/connect-n8n", "source:companion-projection:application-connection", "source:consumer-fact:access-api-keys"];
296
+ readonly markdown: "# Connect n8n\n\nUse n8n when a visual workflow should read or change information in this\napplication. There is no application-specific n8n node to install: the workflow\nuses n8n's standard **HTTP Request** node and the REST API published in this\ndocumentation.\n\nThis guide first builds a manual, read-only workflow. By the end, one click in\nn8n will call one authenticated operation and show recognizable application\ndata in the node output. Only then will you connect a trigger or add a write.\n\n> **If the application should start the workflow when something happens,**\n> complete the read-only connection first, then follow **Start from an\n> application event** below. Do not poll repeatedly when a published webhook\n> already represents the event you need.\n\n## What do you need before starting?\n\nAsk the application administrator or integration owner for:\n\n- the server origin shown in this application's API reference;\n- one authenticated **GET** operation and its complete path;\n- the non-production organization and known data you may use for the test;\n- a dedicated API key with only the role accepted by that operation; and\n- an owner who can revoke the key if the workflow is abandoned or exposed.\n\nUse [Create and store an API key](/access-and-identity/api-keys-create-and-store)\nif the credential has not been prepared. Keep n8n and the application in the\nsame environment throughout the test.\n\n## Build the first read-only workflow\n\n### 1. Create an explicit test trigger\n\nCreate a new workflow and keep it inactive. Add a **Manual Trigger** so that the\napplication is contacted only when you choose **Execute workflow**. Name the\nworkflow after the business result and environment—for example, “Read approved\nrecords — test”—not after the credential.\n\n### 2. Add the application request\n\nAdd an **HTTP Request** node after the trigger, then complete these fields from\nthe same API-reference operation:\n\n| n8n field | Value to use | How to verify it |\n| --- | --- | --- |\n| **Method** | The operation's documented HTTP method, initially **GET** | It matches the operation heading in the API reference |\n| **URL** | `{{APPLICATION_CONNECTION_VALUE:baseUrl}}` followed by the operation's documented path | The origin appears once and the API path appears once |\n| **Authentication** | **Generic Credential Type**, then **Header Auth** | The key is stored as an n8n credential, not in the URL or workflow data |\n| **Send Headers** | Add **Accept** with value **application/json** | The request asks for the documented JSON response |\n| Query/path values | Only values required by the selected operation | Organization and resource identifiers are in the locations defined by the reference |\n\nWhen creating the **Header Auth** credential, use the maintained application\nheader contract below. Enter the header name and secret value in the credential\ndialog; do not construct them with an expression inside the node.\n\n~~~text\n{{CONSUMER_FACT:source:consumer-fact:access-api-keys#requestHeader}}\n~~~\n\nn8n's [HTTP Request node documentation](https://docs.n8n.io/integrations/builtin/core-nodes/n8n-nodes-base.httprequest/)\nexplains the current node controls and generic credential options. If the\nlabels in your installed n8n version differ, use that documentation for the UI\nlocation while keeping the application request contract defined here.\n\n### 3. Execute and inspect the output\n\nSelect **Execute workflow**. The Manual Trigger and HTTP Request nodes should\ncomplete successfully, and the HTTP Request output panel should contain JSON\nmatching the response schema in the API reference.\n\nDo not treat a green node alone as proof. Confirm:\n\n- the output is from the intended application environment;\n- the data belongs to the intended organization;\n- the known record or collection result is present;\n- required fields have the types documented in the response schema; and\n- the API key is absent from the input, output and execution data panels.\n\n~~~mermaid\nsequenceDiagram\n accTitle: Build and prove the first n8n application workflow\n accDescr: An operator runs a manual trigger, n8n reads application data with a stored credential, the operator verifies the returned organization and schema, and only then replaces the trigger or adds a controlled business action.\n actor Operator\n participant n8n\n participant App as Application API\n Operator->>n8n: Execute inactive test workflow\n n8n->>App: Authenticated GET from HTTP Request node\n App-->>n8n: Documented JSON response\n n8n-->>Operator: Show node output\n Operator->>Operator: Verify environment, organization and known data\n Operator->>n8n: Add trigger or one controlled action\n~~~\n\nThe checkpoint in the diagram is the human verification after the first read.\nIt prevents an apparently successful workflow from being activated against the\nwrong organization or environment.\n\n## Prove the credential boundary\n\nCopy the HTTP Request node for this negative test. On the copy, temporarily set\nauthentication to **None** while leaving the URL and parameters unchanged. Run\nonly that node. The authenticated operation should return its documented\nauthentication refusal, normally **401**.\n\nDelete the unauthenticated copy after the test. If it returns the same protected\ndata as the authenticated node, stop: either the wrong operation was selected or\nthe access boundary needs investigation. Do not continue by adding a write.\n\n## Turn the read into a useful workflow\n\nConnect one decision or transformation step to the verified HTTP Request node.\nFor example, an **If** node can stop the workflow when the collection is empty,\nor a mapping step can select only the fields the next system is allowed to\nreceive.\n\nBefore adding a state-changing request, define all four items:\n\n1. the exact application state that should change;\n2. the condition that permits the change;\n3. the read operation that proves the final state; and\n4. what the workflow does when a write times out without a response.\n\nFor the first write, keep automatic retry disabled. Execute it once with known\ntest data, then read the target back. **A timeout is not proof that the write did\nnot happen**; use the read-back before deciding whether another request is\nneeded.\n\n## Start from an application event\n\nUse this path only when a Webhooks section is present in this documentation and\nthe application publishes the event you need.\n\n1. Add an n8n **Webhook** trigger and copy its **test URL**.\n2. Put n8n into test-listening mode.\n3. Configure a non-production application webhook endpoint for that URL.\n4. Send one controlled event and inspect the received request before mapping\n any fields.\n5. Verify the application's signature and deduplicate the delivery before a\n downstream action.\n6. Publish the n8n workflow, copy its **production URL**, and update the\n application endpoint. The temporary test URL is not the production address.\n\nFollow [Verify a webhook delivery](/integrations/webhooks/verify-delivery) for\nthe application trust boundary. n8n's\n[Webhook workflow guide](https://docs.n8n.io/integrations/builtin/core-nodes/n8n-nodes-base.webhook/workflow-development/)\nexplains its test and production URL lifecycle.\n\n## When the workflow does not work\n\n| What you see in n8n | Most likely boundary | What to check next |\n| --- | --- | --- |\n| Connection or TLS error | Server/network | Confirm the API-reference server origin is reachable from the n8n host |\n| **401** response | Credential transport or lifecycle | Confirm Header Auth is selected and the stored key is active; never expose the value while checking |\n| **403** response | Role, organization or operation authority | Compare the key's approved role with the operation requirement |\n| **404** response | Identifier, organization scope or visibility | Confirm the target exists in the application and the path values came from the same environment |\n| Green node, wrong records | Scope or mapping | Stop the workflow and correct organization, filters or response mapping before adding downstream nodes |\n| Timeout after a write | Ambiguous business result | Read the application state; do not repeatedly execute the write node |\n| Webhook works only in test mode | URL lifecycle | Publish the workflow and configure the production URL |\n\nUse [Troubleshoot an API request](/integrations/rest/troubleshoot) when the\nHTTP response needs deeper diagnosis.\n\n## Before activating the workflow\n\n- Replace the Manual Trigger only after the read and negative test pass.\n- Keep the application key in n8n's credential store and restrict who can edit\n or use that credential.\n- Pin the server, organization and workflow purpose; do not make them silently\n depend on whichever item ran previously.\n- Validate required fields before a write and reject unexpected values.\n- Define failed-execution alerts, an accountable operator and a revocation\n procedure.\n- Test a revoked key, insufficient permission, invalid input and an unavailable\n dependency.\n- Retain non-secret operation, status, time and correlation evidence so an\n operator can reconcile the business result.";
319
297
  }, {
320
298
  readonly managedPath: "integrations/automation/zapier.md";
321
299
  readonly unitRef: "technical-documentation:unit/connect-zapier";
322
- readonly sourceRefs: readonly ["saas-technical-doc:engine-content/connect-zapier", "source:consumer-fact:access-api-keys"];
323
- readonly markdown: "# Connect Zapier\n\nUse Zapier when an existing Zap should read or change information in this\napplication. There is no application-specific Zapier connector to install. For\nan authenticated request, use **API by Zapier** so the API key lives in an app\nconnection instead of a visible Zap step.\n\nThis guide first creates one read-only action in an inactive Zap. You will test\nit with a known record, prove the authentication boundary, and only then connect\nthe action to a real trigger or add a write.\n\n> **Choose the other direction when the application starts the work.** If a\n> published application event should start the Zap, follow **Receive an\n> application event** below after the API connection proof.\n\n## Prepare one safe test\n\nBefore opening the Zap editor, collect:\n\n- the server origin and one authenticated **GET** operation from this\n application's API reference;\n- the non-production organization and one known record or collection result;\n- a dedicated API key with only the role accepted by that operation; and\n- an accountable owner for the Zap and credential.\n\nZapier's [current API-request comparison](https://help.zapier.com/hc/en-us/articles/44391646192397-Ways-to-make-API-requests-in-Zapier)\nexplains why **API by Zapier** is the appropriate choice for APIs that use an API\nkey: the credential is stored in an app connection. **Webhooks by Zapier** keeps\ncredentials in step fields and is not the preferred authenticated-request path.\n\n## Build the first read-only action\n\n### 1. Keep the Zap inactive\n\nCreate a Zap with the business outcome and environment in its name. Use a\ntrigger that can provide one controlled test item, but do not publish or turn on\nthe Zap yet.\n\n### 2. Add API by Zapier\n\nAdd **API by Zapier** as the action app and choose **API Request**. Create a new\napp connection for this application and environment. Configure the API key as a\nstatic header using the maintained application contract:\n\n~~~text\n{{CONSUMER_FACT:source:consumer-fact:access-api-keys#requestHeader}}\n~~~\n\nThe connection should own the secret. Do not copy the key into the request URL,\nZap name, mapped test data, notes or an ordinary step field.\n\n### 3. Enter the request from the API reference\n\nComplete the API Request action from one operation in the current reference:\n\n| Zapier field | Value to use | Verification |\n| --- | --- | --- |\n| Method | The documented method, initially **GET** | It matches the operation heading |\n| URL | Server origin plus the complete operation path | Origin and API prefix each appear once |\n| Headers | **Accept: application/json** plus connection-managed authentication | No API key is visible in the Zap step |\n| Parameters | Only required query/path values | Organization and record values are in the documented locations |\n| Body | Empty for the selected read unless the operation explicitly documents one | No response field was copied back as an invented request field |\n\n### 4. Test and inspect the action\n\nRun **Test step**. A useful connection proof has all of these results:\n\n- Zapier reports the operation's documented success status;\n- the output JSON matches the response schema;\n- the known record or collection result belongs to the intended organization;\n- the application key does not appear in the action input or output; and\n- later Zap steps can select the stable application identifier they need.\n\nDo not use a human-readable label as the reconciliation key when the response\nprovides a stable identifier.\n\n## Prove the request is protected\n\nAdd a temporary **Webhooks by Zapier — GET** action with the same read URL and\nparameters but **no authentication**. Test only that action. The protected\noperation should return its documented authentication refusal, normally\n**401**. Delete the temporary action after the proof.\n\nIf the unauthenticated action returns the protected data, stop. Confirm that you\nselected the intended authenticated operation before adding a write or enabling\nthe Zap.\n\n## Add one controlled business action\n\nPlace a **Filter** or equivalent decision step before any state-changing\nrequest. The filter should reject missing identifiers, the wrong organization\nand any business condition that does not justify the change.\n\nFor the first write:\n\n1. copy the exact method, schema and operation path from the API reference;\n2. test with one recognizable non-production record;\n3. keep automatic repetition disabled;\n4. read the record back from the application; and\n5. retain the returned application identifier for reconciliation.\n\n**A Zapier timeout is not proof that the application made no change.** Read the\nauthoritative record before replaying the action or the complete Zap.\n\n## Receive an application event\n\nUse this path only when a Webhooks section is published here and the application\npublishes the event you need.\n\n1. Add **Webhooks by Zapier — Catch Raw Hook** when the trigger must preserve\n the request needed for signature verification; otherwise use **Catch Hook**.\n2. Copy the unique hook URL and treat it as sensitive connection information.\n3. Configure one non-production application webhook endpoint for that URL.\n4. Send one controlled event and inspect the sample before mapping fields.\n5. Verify the application signature and deduplicate the delivery before any\n business effect.\n\nThe [official Catch Hook guide](https://help.zapier.com/hc/en-us/articles/8496288690317-Trigger-Zap-workflows-from-webhooks)\nexplains the trigger URL and sample lifecycle. If the selected Zapier trigger\ncannot preserve the raw signed request required by this application's\nverification contract, receive and verify the event in a controlled service,\nthen forward only the trusted fields the Zap needs.\n\n~~~mermaid\nflowchart TD\n accTitle: Choose a safe Zapier connection\n accDescr: A Zap either calls the application through a stored API connection or receives a verified application event. Both paths validate scope and input before mapping data into downstream actions.\n need{\"What starts the Zap?\"}\n need -->|Zap schedule or another app| request[\"Stored API connection\"]\n request --> api[\"Documented REST operation\"]\n need -->|Application event| hook[\"Catch Hook or verified receiver\"]\n hook --> verify[\"Verify and deduplicate event\"]\n api --> map[\"Validate and map result\"]\n verify --> map\n map --> downstream[\"One intended downstream effect\"]\n~~~\n\n## When a test or run fails\n\n| What Zapier shows | Check first | Safe next action |\n| --- | --- | --- |\n| Connection failure | Server origin, network and TLS | Repair reachability before changing the app connection |\n| **401** | API by Zapier connection and key lifecycle | Reconnect the correct active key without revealing it in the step |\n| **403** | Required role, organization and operation authority | Request only the approved missing authority; do not switch to an administrator credential |\n| **404** | Operation path, record identifier and organization visibility | Confirm the record in the application and the selected environment |\n| Test succeeds, later mapping is empty | Response schema and selected output path | Compare the test output with the current operation response before remapping |\n| Zap reports success, record is missing | Each step's input/output and authoritative application state | Locate the first divergent step; do not replay the entire Zap blindly |\n| Duplicate business effect | Trigger/delivery identity and reconciliation key | Stop the Zap and add deduplication before another event is accepted |\n\n## Before turning the Zap on\n\n- Pin the connection to one application environment and organization.\n- Confirm who can use the app connection and who owns revocation.\n- Test invalid input, a revoked key, insufficient permission and an unavailable\n dependency.\n- Define how a timeout after a write is reconciled before Zapier retries.\n- Prevent two trigger items or webhook deliveries from producing two business\n effects.\n- Send failure alerts with operation, time, status and correlation evidence—but\n no credential or unrestricted sensitive payload.";
300
+ readonly sourceRefs: readonly ["saas-technical-doc:engine-content/connect-zapier", "source:companion-projection:application-connection", "source:consumer-fact:access-api-keys"];
301
+ readonly markdown: "# Connect Zapier\n\nUse Zapier when an existing Zap should read or change information in this\napplication. There is no application-specific Zapier connector to install. For\nan authenticated request, use **API by Zapier** so the API key lives in an app\nconnection instead of a visible Zap step.\n\nThis guide first creates one read-only action in an inactive Zap. You will test\nit with a known record, prove the authentication boundary, and only then connect\nthe action to a real trigger or add a write.\n\n> **Choose the other direction when the application starts the work.** If a\n> published application event should start the Zap, follow **Receive an\n> application event** below after the API connection proof.\n\n## Prepare one safe test\n\nBefore opening the Zap editor, collect:\n\n- the server origin and one authenticated **GET** operation from this\n application's API reference;\n- the non-production organization and one known record or collection result;\n- a dedicated API key with only the role accepted by that operation; and\n- an accountable owner for the Zap and credential.\n\nZapier's [current API-request comparison](https://help.zapier.com/hc/en-us/articles/44391646192397-Ways-to-make-API-requests-in-Zapier)\nexplains why **API by Zapier** is the appropriate choice for APIs that use an API\nkey: the credential is stored in an app connection. **Webhooks by Zapier** keeps\ncredentials in step fields and is not the preferred authenticated-request path.\n\n## Build the first read-only action\n\n### 1. Keep the Zap inactive\n\nCreate a Zap with the business outcome and environment in its name. Use a\ntrigger that can provide one controlled test item, but do not publish or turn on\nthe Zap yet.\n\n### 2. Add API by Zapier\n\nAdd **API by Zapier** as the action app and choose **API Request**. Create a new\napp connection for this application and environment. Configure the API key as a\nstatic header using the maintained application contract:\n\n~~~text\n{{CONSUMER_FACT:source:consumer-fact:access-api-keys#requestHeader}}\n~~~\n\nThe connection should own the secret. Do not copy the key into the request URL,\nZap name, mapped test data, notes or an ordinary step field.\n\n### 3. Enter the request from the API reference\n\nComplete the API Request action from one operation in the current reference:\n\n| Zapier field | Value to use | Verification |\n| --- | --- | --- |\n| Method | The documented method, initially **GET** | It matches the operation heading |\n| URL | `{{APPLICATION_CONNECTION_VALUE:baseUrl}}` plus the operation's documented path | Origin and API prefix each appear once |\n| Headers | **Accept: application/json** plus connection-managed authentication | No API key is visible in the Zap step |\n| Parameters | Only required query/path values | Organization and record values are in the documented locations |\n| Body | Empty for the selected read unless the operation explicitly documents one | No response field was copied back as an invented request field |\n\n### 4. Test and inspect the action\n\nRun **Test step**. A useful connection proof has all of these results:\n\n- Zapier reports the operation's documented success status;\n- the output JSON matches the response schema;\n- the known record or collection result belongs to the intended organization;\n- the application key does not appear in the action input or output; and\n- later Zap steps can select the stable application identifier they need.\n\nDo not use a human-readable label as the reconciliation key when the response\nprovides a stable identifier.\n\n## Prove the request is protected\n\nAdd a temporary **Webhooks by Zapier — GET** action with the same read URL and\nparameters but **no authentication**. Test only that action. The protected\noperation should return its documented authentication refusal, normally\n**401**. Delete the temporary action after the proof.\n\nIf the unauthenticated action returns the protected data, stop. Confirm that you\nselected the intended authenticated operation before adding a write or enabling\nthe Zap.\n\n## Add one controlled business action\n\nPlace a **Filter** or equivalent decision step before any state-changing\nrequest. The filter should reject missing identifiers, the wrong organization\nand any business condition that does not justify the change.\n\nFor the first write:\n\n1. copy the exact method, schema and operation path from the API reference;\n2. test with one recognizable non-production record;\n3. keep automatic repetition disabled;\n4. read the record back from the application; and\n5. retain the returned application identifier for reconciliation.\n\n**A Zapier timeout is not proof that the application made no change.** Read the\nauthoritative record before replaying the action or the complete Zap.\n\n## Receive an application event\n\nUse this path only when a Webhooks section is published here and the application\npublishes the event you need.\n\n1. Add **Webhooks by Zapier — Catch Raw Hook** when the trigger must preserve\n the request needed for signature verification; otherwise use **Catch Hook**.\n2. Copy the unique hook URL and treat it as sensitive connection information.\n3. Configure one non-production application webhook endpoint for that URL.\n4. Send one controlled event and inspect the sample before mapping fields.\n5. Verify the application signature and deduplicate the delivery before any\n business effect.\n\nThe [official Catch Hook guide](https://help.zapier.com/hc/en-us/articles/8496288690317-Trigger-Zap-workflows-from-webhooks)\nexplains the trigger URL and sample lifecycle. If the selected Zapier trigger\ncannot preserve the raw signed request required by this application's\nverification contract, receive and verify the event in a controlled service,\nthen forward only the trusted fields the Zap needs.\n\n~~~mermaid\nflowchart TD\n accTitle: Choose a safe Zapier connection\n accDescr: A Zap either calls the application through a stored API connection or receives a verified application event. Both paths validate scope and input before mapping data into downstream actions.\n need{\"What starts the Zap?\"}\n need -->|Zap schedule or another app| request[\"Stored API connection\"]\n request --> api[\"Documented REST operation\"]\n need -->|Application event| hook[\"Catch Hook or verified receiver\"]\n hook --> verify[\"Verify and deduplicate event\"]\n api --> map[\"Validate and map result\"]\n verify --> map\n map --> downstream[\"One intended downstream effect\"]\n~~~\n\n## When a test or run fails\n\n| What Zapier shows | Check first | Safe next action |\n| --- | --- | --- |\n| Connection failure | Server origin, network and TLS | Repair reachability before changing the app connection |\n| **401** | API by Zapier connection and key lifecycle | Reconnect the correct active key without revealing it in the step |\n| **403** | Required role, organization and operation authority | Request only the approved missing authority; do not switch to an administrator credential |\n| **404** | Operation path, record identifier and organization visibility | Confirm the record in the application and the selected environment |\n| Test succeeds, later mapping is empty | Response schema and selected output path | Compare the test output with the current operation response before remapping |\n| Zap reports success, record is missing | Each step's input/output and authoritative application state | Locate the first divergent step; do not replay the entire Zap blindly |\n| Duplicate business effect | Trigger/delivery identity and reconciliation key | Stop the Zap and add deduplication before another event is accepted |\n\n## Before turning the Zap on\n\n- Pin the connection to one application environment and organization.\n- Confirm who can use the app connection and who owns revocation.\n- Test invalid input, a revoked key, insufficient permission and an unavailable\n dependency.\n- Define how a timeout after a write is reconciled before Zapier retries.\n- Prevent two trigger items or webhook deliveries from producing two business\n effects.\n- Send failure alerts with operation, time, status and correlation evidence—but\n no credential or unrestricted sensitive payload.";
324
302
  }, {
325
303
  readonly managedPath: "integrations/automation/make.md";
326
304
  readonly unitRef: "technical-documentation:unit/connect-make";
327
- readonly sourceRefs: readonly ["saas-technical-doc:engine-content/connect-make", "source:consumer-fact:access-api-keys"];
328
- readonly markdown: "# Connect Make\n\nUse Make when a visual scenario should read or change information in this\napplication. There is no application-specific Make app to install. The scenario\nuses **HTTP — Make a request** with a credential stored in a Make keychain.\n\nThis guide builds one read-only module in an inactive scenario, verifies its\noutput and access boundary, and only then adds a schedule, downstream module or\napplication webhook.\n\n## Prepare the connection proof\n\nCollect these values before opening the Scenario Builder:\n\n- the server origin and one authenticated **GET** operation from this\n application's API reference;\n- the intended non-production organization;\n- one record or collection result you can recognize;\n- a dedicated API key with only the role accepted by the operation; and\n- the person who owns the scenario and can revoke its credential.\n\n## Build the first read-only scenario\n\n### 1. Add the HTTP module\n\nCreate a scenario, keep scheduling **off**, and add **HTTP — Make a request**.\nName the scenario after its business result and environment rather than after\nthe credential.\n\n### 2. Store the credential\n\nIn the module's **Credentials** field, choose API-key authentication and create\na dedicated keychain. Put the complete application key in the key field, choose\nheader placement, and use **Authorization** as the parameter name. The resulting\nrequest must contain:\n\n~~~text\n{{CONSUMER_FACT:source:consumer-fact:access-api-keys#requestHeader}}\n~~~\n\nUse the dedicated credential field. Do not duplicate the key in ordinary\nheaders, query parameters, the scenario name, notes or mapped bundles.\n\n### 3. Configure the documented request\n\nComplete the remaining module fields from the same API-reference operation:\n\n| Make field | Value to use | Verification |\n| --- | --- | --- |\n| URL | Server origin plus the complete operation path | HTTPS, origin and API prefix each appear once |\n| Method | The documented method, initially **GET** | It matches the operation heading |\n| Headers | Add **Accept: application/json** | Authentication remains in **Credentials**, not duplicated here |\n| Query parameters | Only parameters accepted by the operation | Organization and record values are in documented locations |\n| Body content type | No body for the selected read unless documented | For later writes, choose the exact documented content type |\n| Parse response | **Yes** | Returned fields become available for mapping after a successful run |\n\nMake's [current HTTP app documentation](https://apps.make.com/http) defines the\nmodule fields, credential types, response parsing and pagination controls. Do\nnot select a pagination mode until the application's exact collection operation\ndocuments the matching contract.\n\n### 4. Run once and inspect the bundle\n\nSelect **Run once** and execute the module. A successful connection proof means:\n\n- the module returns the operation's documented success status;\n- the parsed output matches the documented response shape;\n- the known record or collection belongs to the intended organization;\n- the API key is absent from the module input/output bundles; and\n- the stable application identifier is available for later modules.\n\nDo not add mappings while the result belongs to the wrong environment or\norganization, even when the module is green.\n\n## Prove the authentication boundary\n\nClone the HTTP module for a temporary negative test. Remove **Credentials** from\nthe copy without adding an Authorization header, then run only that module. The\nprotected operation should return the documented authentication refusal,\nnormally **401**. Delete the unauthenticated copy after the test.\n\nIf it returns the protected data, stop and verify that the selected operation\nactually requires authentication before continuing.\n\n## Add one controlled change\n\nBefore adding a state-changing HTTP module, define the exact condition that\npermits it and add a Make filter that rejects missing identifiers, the wrong\norganization and incomplete source data.\n\nRun the first write once with a recognizable non-production record. Then read\nthe target back from the application. **A connection loss or timeout does not\nprove that the write failed**; reconcile current state before allowing Make to\nrepeat the module.\n\n## Receive an application event\n\nUse this path only when a Webhooks section is present here and the application\npublishes the event you need.\n\n1. Add **Webhooks — Custom webhook**, select **Add**, give the webhook a name,\n and copy the generated URL.\n2. In **Advanced settings**, enable **Get request headers** and **JSON\n pass-through** when required by the application's raw-body verification\n contract.\n3. Select **Run once** so Make listens for a controlled sample.\n4. Configure one non-production application webhook endpoint and send one known\n event.\n5. Verify the application signature and deduplicate the delivery before a\n downstream business action.\n\nMake's [current Webhooks documentation](https://apps.make.com/gateway) explains\nthe unique URL, **Run once**, data structures, request headers and JSON\npass-through controls. A generated Make data structure is an editing aid, not a\ntrust decision. If the module cannot preserve the exact signed request required\nby this application's verification contract, receive and verify it in a\ncontrolled service first, then forward only trusted fields to Make.\n\n~~~mermaid\nsequenceDiagram\n accTitle: Move a Make scenario from a controlled test to operation\n accDescr: The operator stores an API key in a Make keychain, proves one application read, optionally captures one verified webhook sample, maps only required values, then schedules or activates the scenario with failure handling.\n participant Operator\n participant Make\n participant App as Application\n Operator->>Make: Create API-key keychain\n Make->>App: Safe documented read\n App-->>Make: Parsed JSON response\n App->>Make: Optional controlled webhook event\n Operator->>Make: Validate mapping and error route\n Operator->>Make: Activate scenario\n~~~\n\n## When the scenario does not work\n\n| What Make shows | Check first | Safe next action |\n| --- | --- | --- |\n| Connection or TLS error | Server origin and reachability from Make | Repair the connection before changing the keychain |\n| **400** | Required values and mapped request body | Compare each submitted field with the current operation schema |\n| **401** | Keychain selection and key lifecycle | Attach the correct active keychain without exposing its value in headers |\n| **403** | Required role, organization and operation authority | Request only the approved missing authority; do not switch to an administrator key |\n| **404** | Operation path, identifier and organization visibility | Confirm the target and environment in the application |\n| Parsed field disappears | Raw response and current response schema | Correct the mapping after establishing whether the contract or selected path changed |\n| Timeout after a write | Authoritative application state | Read the target before repeating the module |\n| Webhook bundle lacks signed material | Request-header and JSON pass-through settings | Stop downstream actions until the verification boundary can be preserved |\n\n## Before scheduling or activating\n\n- Pin the scenario, keychain and webhook to one environment and organization.\n- Keep one credential per workload so it can be rotated or deactivated alone.\n- Add an error route that distinguishes invalid input, access refusal,\n throttling and unavailable dependencies.\n- Test a revoked key, insufficient permission, malformed input and a timeout\n after a controlled write.\n- Deduplicate triggers before producing a downstream business effect.\n- Retain application identifiers, status, time and correlation evidence—not\n credentials or unrestricted request/response bodies.";
305
+ readonly sourceRefs: readonly ["saas-technical-doc:engine-content/connect-make", "source:companion-projection:application-connection", "source:consumer-fact:access-api-keys"];
306
+ readonly markdown: "# Connect Make\n\nUse Make when a visual scenario should read or change information in this\napplication. There is no application-specific Make app to install. The scenario\nuses **HTTP — Make a request** with a credential stored in a Make keychain.\n\nThis guide builds one read-only module in an inactive scenario, verifies its\noutput and access boundary, and only then adds a schedule, downstream module or\napplication webhook.\n\n## Prepare the connection proof\n\nCollect these values before opening the Scenario Builder:\n\n- the server origin and one authenticated **GET** operation from this\n application's API reference;\n- the intended non-production organization;\n- one record or collection result you can recognize;\n- a dedicated API key with only the role accepted by the operation; and\n- the person who owns the scenario and can revoke its credential.\n\n## Build the first read-only scenario\n\n### 1. Add the HTTP module\n\nCreate a scenario, keep scheduling **off**, and add **HTTP — Make a request**.\nName the scenario after its business result and environment rather than after\nthe credential.\n\n### 2. Store the credential\n\nIn the module's **Credentials** field, choose API-key authentication and create\na dedicated keychain. Put the complete application key in the key field, choose\nheader placement, and use **Authorization** as the parameter name. The resulting\nrequest must contain:\n\n~~~text\n{{CONSUMER_FACT:source:consumer-fact:access-api-keys#requestHeader}}\n~~~\n\nUse the dedicated credential field. Do not duplicate the key in ordinary\nheaders, query parameters, the scenario name, notes or mapped bundles.\n\n### 3. Configure the documented request\n\nComplete the remaining module fields from the same API-reference operation:\n\n| Make field | Value to use | Verification |\n| --- | --- | --- |\n| URL | `{{APPLICATION_CONNECTION_VALUE:baseUrl}}` plus the operation's documented path | The scheme, origin and API prefix each appear once |\n| Method | The documented method, initially **GET** | It matches the operation heading |\n| Headers | Add **Accept: application/json** | Authentication remains in **Credentials**, not duplicated here |\n| Query parameters | Only parameters accepted by the operation | Organization and record values are in documented locations |\n| Body content type | No body for the selected read unless documented | For later writes, choose the exact documented content type |\n| Parse response | **Yes** | Returned fields become available for mapping after a successful run |\n\nMake's [current HTTP app documentation](https://apps.make.com/http) defines the\nmodule fields, credential types, response parsing and pagination controls. Do\nnot select a pagination mode until the application's exact collection operation\ndocuments the matching contract.\n\n### 4. Run once and inspect the bundle\n\nSelect **Run once** and execute the module. A successful connection proof means:\n\n- the module returns the operation's documented success status;\n- the parsed output matches the documented response shape;\n- the known record or collection belongs to the intended organization;\n- the API key is absent from the module input/output bundles; and\n- the stable application identifier is available for later modules.\n\nDo not add mappings while the result belongs to the wrong environment or\norganization, even when the module is green.\n\n## Prove the authentication boundary\n\nClone the HTTP module for a temporary negative test. Remove **Credentials** from\nthe copy without adding an Authorization header, then run only that module. The\nprotected operation should return the documented authentication refusal,\nnormally **401**. Delete the unauthenticated copy after the test.\n\nIf it returns the protected data, stop and verify that the selected operation\nactually requires authentication before continuing.\n\n## Add one controlled change\n\nBefore adding a state-changing HTTP module, define the exact condition that\npermits it and add a Make filter that rejects missing identifiers, the wrong\norganization and incomplete source data.\n\nRun the first write once with a recognizable non-production record. Then read\nthe target back from the application. **A connection loss or timeout does not\nprove that the write failed**; reconcile current state before allowing Make to\nrepeat the module.\n\n## Receive an application event\n\nUse this path only when a Webhooks section is present here and the application\npublishes the event you need.\n\n1. Add **Webhooks — Custom webhook**, select **Add**, give the webhook a name,\n and copy the generated URL.\n2. In **Advanced settings**, enable **Get request headers** and **JSON\n pass-through** when required by the application's raw-body verification\n contract.\n3. Select **Run once** so Make listens for a controlled sample.\n4. Configure one non-production application webhook endpoint and send one known\n event.\n5. Verify the application signature and deduplicate the delivery before a\n downstream business action.\n\nMake's [current Webhooks documentation](https://apps.make.com/gateway) explains\nthe unique URL, **Run once**, data structures, request headers and JSON\npass-through controls. A generated Make data structure is an editing aid, not a\ntrust decision. If the module cannot preserve the exact signed request required\nby this application's verification contract, receive and verify it in a\ncontrolled service first, then forward only trusted fields to Make.\n\n~~~mermaid\nsequenceDiagram\n accTitle: Move a Make scenario from a controlled test to operation\n accDescr: The operator stores an API key in a Make keychain, proves one application read, optionally captures one verified webhook sample, maps only required values, then schedules or activates the scenario with failure handling.\n participant Operator\n participant Make\n participant App as Application\n Operator->>Make: Create API-key keychain\n Make->>App: Safe documented read\n App-->>Make: Parsed JSON response\n App->>Make: Optional controlled webhook event\n Operator->>Make: Validate mapping and error route\n Operator->>Make: Activate scenario\n~~~\n\n## When the scenario does not work\n\n| What Make shows | Check first | Safe next action |\n| --- | --- | --- |\n| Connection or TLS error | Server origin and reachability from Make | Repair the connection before changing the keychain |\n| **400** | Required values and mapped request body | Compare each submitted field with the current operation schema |\n| **401** | Keychain selection and key lifecycle | Attach the correct active keychain without exposing its value in headers |\n| **403** | Required role, organization and operation authority | Request only the approved missing authority; do not switch to an administrator key |\n| **404** | Operation path, identifier and organization visibility | Confirm the target and environment in the application |\n| Parsed field disappears | Raw response and current response schema | Correct the mapping after establishing whether the contract or selected path changed |\n| Timeout after a write | Authoritative application state | Read the target before repeating the module |\n| Webhook bundle lacks signed material | Request-header and JSON pass-through settings | Stop downstream actions until the verification boundary can be preserved |\n\n## Before scheduling or activating\n\n- Pin the scenario, keychain and webhook to one environment and organization.\n- Keep one credential per workload so it can be rotated or deactivated alone.\n- Add an error route that distinguishes invalid input, access refusal,\n throttling and unavailable dependencies.\n- Test a revoked key, insufficient permission, malformed input and a timeout\n after a controlled write.\n- Deduplicate triggers before producing a downstream business effect.\n- Retain application identifiers, status, time and correlation evidence—not\n credentials or unrestricted request/response bodies.";
329
307
  }, {
330
308
  readonly managedPath: "integrations/ai-coding-tools.md";
331
309
  readonly unitRef: "technical-documentation:unit/ai-coding-tools";
@@ -355,7 +333,7 @@ export declare const APPLICATION_CONSUMER_DOCUMENTATION_AUTHORED_CONTENT_V1: rea
355
333
  readonly managedPath: "integrations/create-your-own-integration.md";
356
334
  readonly unitRef: "technical-documentation:unit/first-request";
357
335
  readonly sourceRefs: readonly ["saas-technical-doc:engine-content/first-request", "source:companion-projection:application-connection", "source:consumer-fact:access-api-keys"];
358
- readonly markdown: "# Create your own integration\n\nUse this guide when **your service must call this application's REST API** and\nnone of the ready-made automation guides fits the job. You will make one\nauthenticated read in a non-production organization, prove that the security\nboundary works, and then decide whether the integration is ready to make one\ncontrolled change.\n\n> **Looking for a different kind of connection?** If the application should\n> notify your system, start with [Webhooks](/integrations/webhooks). If n8n,\n> Zapier or Make will run the workflow, use\n> [Automation platforms](/integrations/automation-platforms). MCP and A2A have\n> separate [Agent integration](/integrations/agents) guides.\n\n## What will you have at the end?\n\nA successful first integration is deliberately small. It can:\n\n- authenticate with a credential created for **one workload**;\n- read one known piece of information from **one intended organization**;\n- show a response that matches the current API reference;\n- demonstrate that the same operation is refused without valid access; and\n- explain what to do if a later write times out before a response is received.\n\nThis is enough to prove the connection. Scheduling, high volume, automatic\nretries and a larger data mapping come later.\n\n~~~mermaid\nsequenceDiagram\n accTitle: Prove a custom integration before it changes application data\n accDescr: An integration owner selects an authenticated read from the API reference, creates a dedicated credential, proves the allowed request and an expected refusal, and only then adds one controlled write with a read-back recovery path.\n actor Owner as Integration owner\n participant Reference as API reference\n participant Service as Your service\n participant App as Application API\n Owner->>Reference: Choose one authenticated read\n Owner->>Service: Store server, path and dedicated credential\n Service->>App: Send the documented request\n App-->>Service: Return the documented success response\n Service->>App: Repeat without valid access\n App-->>Service: Refuse the request\n Owner->>Service: Permit one controlled write\n Service->>App: Write, then read back authoritative state\n~~~\n\nThe important sequence is **read, refusal, then write**. A successful read\nalone proves connectivity; the refusal proves that your test did not bypass the\naccess boundary.\n\n## Before you open your code editor\n\nCollect these values. Do not guess any of them from another environment or\nanother application.\n\n| What you need | Where to find it | What to record |\n| --- | --- | --- |\n| Server origin | The server selector at the top of the API reference | The complete scheme and host, without adding another API prefix |\n| Read operation | One **GET** operation in the API reference that permits the intended credential | Method, operation path, required parameters and documented success status |\n| Organization | The non-production organization approved for the test | Its identifier and where the selected operation expects it |\n| Credential | [Create and store an API key](/access-and-identity/api-keys-create-and-store) | A dedicated key with the smallest role accepted by the operation |\n| Expected record | The application itself | One record or collection whose visible result you can recognize |\n\n> **Do not use a personal administrator credential for a deployed service.** A\n> service needs its own credential so that its access can be reviewed, rotated\n> or revoked without affecting a person.\n\n## Step 1: choose a harmless read\n\nOpen the **API reference** from the top navigation and choose the normal\napplication API. Start with a GET operation that reads a collection or a known\nrecord; do not start with an administrative or state-changing operation.\n\nOn the operation page, confirm all of the following:\n\n1. the operation supports the credential type you intend to use;\n2. the documented role requirement matches the key you were given;\n3. you know where the organization and resource identifiers belong;\n4. you have copied the request path exactly; and\n5. you know which success response and body shape to expect.\n\nIf any of those items is unclear, stop here. A broader key does not repair an\nunclear operation contract.\n\n## Step 2: send the request once\n\nReplace the two angle-bracket placeholders with the server origin and operation\npath from the same API-reference environment. The generated authorization line\nis the application's maintained API-key transport contract.\n\n~~~bash\ncurl --fail-with-body --url \"{{APPLICATION_CONNECTION_VALUE:baseUrl}}<documented-operation-path>\" {{CONSUMER_FACT:source:consumer-fact:access-api-keys#curlRequestHeader}} --header \"accept: application/json\"\n~~~\n\nAdd only the parameters required by the selected operation. If the reference\nplaces the organization in the path, query or body, keep it there—do not invent\nan additional organization header.\n\n### What should you see?\n\nThe request is a valid connection proof only when:\n\n- the HTTP status is one of the operation's documented success responses;\n- the JSON shape matches that response, including its collection wrapper when\n one is documented;\n- the returned information belongs to the intended organization; and\n- the known record or collection result is recognizable in the application.\n\nRecord the operation identity, environment, organization, time, status and a\nnon-secret correlation identifier if the response supplies one. **Never copy\nthe API key into a log, ticket, screenshot or test fixture.**\n\n## Step 3: prove the request is protected\n\nRepeat the same authenticated operation in the same non-production environment\nwithout sending a valid credential. The operation should return the documented\nauthentication refusal, normally **401**. Restore the credential immediately\nafter the test.\n\nThen test the narrowest relevant authorization boundary: for example, a key\nwithout the required role or an organization the workload should not access.\nConfirm the documented refusal or absence behavior. Do not add authority merely\nto turn a refusal into a success; first establish whether the refusal is the\ncorrect result.\n\n## Step 4: add one business change\n\nOnly add a write when the business outcome requires one. Choose one documented\ncreate or update operation and use a target that a person can inspect safely.\n\nBefore sending it, write down:\n\n- the current state;\n- the exact state that should change;\n- the state that must remain unchanged; and\n- the read operation that will prove the final result.\n\nSend the write once, then read the target back from the application. A client\nsuccess message is useful, but the read-back is the authoritative verification.\n\n> **A timeout is not a safe retry signal.** It means your service did not\n> receive the response; the application may still have completed the change.\n> Read the target's current state before deciding whether another write is\n> necessary.\n\n## If the first request fails\n\n| What you observe | Check first | Safe next action |\n| --- | --- | --- |\n| No HTTP response | Server origin, DNS, TLS and network reachability | Correct the connection; do not rotate a credential that was never presented |\n| 400-series validation response | Required path/query values and the request schema | Compare the submitted values field by field with the operation reference |\n| **401** | Selected environment, authorization transport and key lifecycle | Restore the correct active key; never print the key while diagnosing |\n| **403** | Required role, organization membership and operation authority | Request only the missing approved authority; do not switch to an administrator key |\n| **404** | Resource identifier, organization scope and visibility rules | Confirm the target in the application before changing the request |\n| Conflict response | Current resource state or concurrency requirement | Read current state and reconcile; do not blindly repeat the write |\n| Timeout or server failure after a write | Authoritative application state | Read back the target before any retry |\n\nContinue with [Troubleshoot an API request](/integrations/rest/troubleshoot)\nwhen the response still does not identify the failing boundary.\n\n## Before the integration runs unattended\n\n- Move the credential into the deployment platform's secret store.\n- Give the workload, credential and alert an accountable human owner.\n- Validate response shapes and reject unexpected enum values before acting on\n them.\n- Bound concurrency and retries; use backoff for failures that are safe to\n repeat.\n- Reconcile timeouts, conflicts and duplicate work from authoritative state.\n- Prove how to revoke the credential and stop the workload during an incident.\n- Retain identifiers, statuses and correlation evidence—not secrets or\n unrestricted response bodies.\n\nNext, read [REST API](/integrations/rest-api) for the complete request journey,\nincluding collections, controlled writes and troubleshooting.";
336
+ readonly markdown: "# Create your own integration\n\nUse this guide when **your service must call this application's REST API** and\nnone of the ready-made automation guides fits the job. You will make one\nauthenticated read in a non-production organization, prove that the security\nboundary works, and then decide whether the integration is ready to make one\ncontrolled change.\n\n> **Looking for a different kind of connection?** If the application should\n> notify your system, start with [Webhooks](/integrations/webhooks). If n8n,\n> Zapier or Make will run the workflow, use\n> [Automation platforms](/integrations/automation-platforms). MCP and A2A have\n> separate [Agent integration](/integrations/agents) guides.\n\n## What will you have at the end?\n\nA successful first integration is deliberately small. It can:\n\n- authenticate with a credential created for **one workload**;\n- read one known piece of information from **one intended organization**;\n- show a response that matches the current API reference;\n- demonstrate that the same operation is refused without valid access; and\n- explain what to do if a later write times out before a response is received.\n\nThis is enough to prove the connection. Scheduling, high volume, automatic\nretries and a larger data mapping come later.\n\n~~~mermaid\nsequenceDiagram\n accTitle: Prove a custom integration before it changes application data\n accDescr: An integration owner selects an authenticated read from the API reference, creates a dedicated credential, proves the allowed request and an expected refusal, and only then adds one controlled write with a read-back recovery path.\n actor Owner as Integration owner\n participant Reference as API reference\n participant Service as Your service\n participant App as Application API\n Owner->>Reference: Choose one authenticated read\n Owner->>Service: Store server, path and dedicated credential\n Service->>App: Send the documented request\n App-->>Service: Return the documented success response\n Service->>App: Repeat without valid access\n App-->>Service: Refuse the request\n Owner->>Service: Permit one controlled write\n Service->>App: Write, then read back authoritative state\n~~~\n\nThe important sequence is **read, refusal, then write**. A successful read\nalone proves connectivity; the refusal proves that your test did not bypass the\naccess boundary.\n\n## Before you open your code editor\n\nCollect these values. Do not guess any of them from another environment or\nanother application.\n\n| What you need | Where to find it | What to record |\n| --- | --- | --- |\n| Server origin | The server selector at the top of the API reference | The complete scheme and host, without adding another API prefix |\n| Read operation | One **GET** operation in the API reference that permits the intended credential | Method, operation path, required parameters and documented success status |\n| Organization | The non-production organization approved for the test | Its identifier and where the selected operation expects it |\n| Credential | [Create and store an API key](/access-and-identity/api-keys-create-and-store) | A dedicated key with the smallest role accepted by the operation |\n| Expected record | The application itself | One record or collection whose visible result you can recognize |\n\n> **Do not use a personal administrator credential for a deployed service.** A\n> service needs its own credential so that its access can be reviewed, rotated\n> or revoked without affecting a person.\n\n## Step 1: choose a harmless read\n\nOpen the **API reference** from the top navigation and choose the normal\napplication API. Start with a GET operation that reads a collection or a known\nrecord; do not start with an administrative or state-changing operation.\n\nOn the operation page, confirm all of the following:\n\n1. the operation supports the credential type you intend to use;\n2. the documented role requirement matches the key you were given;\n3. you know where the organization and resource identifiers belong;\n4. you have copied the request path exactly; and\n5. you know which success response and body shape to expect.\n\nIf any of those items is unclear, stop here. A broader key does not repair an\nunclear operation contract.\n\n## Step 2: send the request once\n\nThe origin below is this application's own, so the only thing left to supply is\nthe operation path from the API reference and your key. The authorization line\nis the application's maintained API-key transport contract.\n\n~~~bash\ncurl --fail-with-body --url \"{{APPLICATION_CONNECTION_VALUE:baseUrl}}<documented-operation-path>\" {{CONSUMER_FACT:source:consumer-fact:access-api-keys#curlRequestHeader}} --header \"accept: application/json\"\n~~~\n\nAdd only the parameters required by the selected operation. If the reference\nplaces the organization in the path, query or body, keep it there—do not invent\nan additional organization header.\n\n### What should you see?\n\nThe request is a valid connection proof only when:\n\n- the HTTP status is one of the operation's documented success responses;\n- the JSON shape matches that response, including its collection wrapper when\n one is documented;\n- the returned information belongs to the intended organization; and\n- the known record or collection result is recognizable in the application.\n\nRecord the operation identity, environment, organization, time, status and a\nnon-secret correlation identifier if the response supplies one. **Never copy\nthe API key into a log, ticket, screenshot or test fixture.**\n\n## Step 3: prove the request is protected\n\nRepeat the same authenticated operation in the same non-production environment\nwithout sending a valid credential. The operation should return the documented\nauthentication refusal, normally **401**. Restore the credential immediately\nafter the test.\n\nThen test the narrowest relevant authorization boundary: for example, a key\nwithout the required role or an organization the workload should not access.\nConfirm the documented refusal or absence behavior. Do not add authority merely\nto turn a refusal into a success; first establish whether the refusal is the\ncorrect result.\n\n## Step 4: add one business change\n\nOnly add a write when the business outcome requires one. Choose one documented\ncreate or update operation and use a target that a person can inspect safely.\n\nBefore sending it, write down:\n\n- the current state;\n- the exact state that should change;\n- the state that must remain unchanged; and\n- the read operation that will prove the final result.\n\nSend the write once, then read the target back from the application. A client\nsuccess message is useful, but the read-back is the authoritative verification.\n\n> **A timeout is not a safe retry signal.** It means your service did not\n> receive the response; the application may still have completed the change.\n> Read the target's current state before deciding whether another write is\n> necessary.\n\n## If the first request fails\n\n| What you observe | Check first | Safe next action |\n| --- | --- | --- |\n| No HTTP response | Server origin, DNS, TLS and network reachability | Correct the connection; do not rotate a credential that was never presented |\n| 400-series validation response | Required path/query values and the request schema | Compare the submitted values field by field with the operation reference |\n| **401** | Selected environment, authorization transport and key lifecycle | Restore the correct active key; never print the key while diagnosing |\n| **403** | Required role, organization membership and operation authority | Request only the missing approved authority; do not switch to an administrator key |\n| **404** | Resource identifier, organization scope and visibility rules | Confirm the target in the application before changing the request |\n| Conflict response | Current resource state or concurrency requirement | Read current state and reconcile; do not blindly repeat the write |\n| Timeout or server failure after a write | Authoritative application state | Read back the target before any retry |\n\nContinue with [Troubleshoot an API request](/integrations/rest/troubleshoot)\nwhen the response still does not identify the failing boundary.\n\n## Before the integration runs unattended\n\n- Move the credential into the deployment platform's secret store.\n- Give the workload, credential and alert an accountable human owner.\n- Validate response shapes and reject unexpected enum values before acting on\n them.\n- Bound concurrency and retries; use backoff for failures that are safe to\n repeat.\n- Reconcile timeouts, conflicts and duplicate work from authoritative state.\n- Prove how to revoke the credential and stop the workload during an incident.\n- Retain identifiers, statuses and correlation evidence—not secrets or\n unrestricted response bodies.\n\nNext, read [REST API](/integrations/rest-api) for the complete request journey,\nincluding collections, controlled writes and troubleshooting.";
359
337
  }, {
360
338
  readonly managedPath: "integrations/rest-api.md";
361
339
  readonly unitRef: "technical-documentation:unit/common-rest-api";
@@ -370,7 +348,7 @@ export declare const APPLICATION_CONSUMER_DOCUMENTATION_AUTHORED_CONTENT_V1: rea
370
348
  readonly managedPath: "integrations/rest/send-request.md";
371
349
  readonly unitRef: "technical-documentation:unit/send-api-request";
372
350
  readonly sourceRefs: readonly ["saas-technical-doc:engine-content/send-api-request", "source:companion-projection:application-connection", "source:consumer-fact:access-api-keys"];
373
- readonly markdown: "# Send your first API request\n\nTen minutes from an API key to a verified connection. The first request proves four things and nothing else: you reached the right environment, the credential is accepted, it sees the organization you expect, and you can read the response. Use a read operation that changes nothing.\n\n## What you need\n\n- The **base URL** of the environment you are calling. {{APPLICATION_NAME}} publishes these:\n\n{{APPLICATION_CONNECTION:baseUrls}}\n\n- Your **organization identifier**, shown in the application's organization settings and present in the URL of most screens.\n- An **organization API key** created for this integration, following [Create and store an API key](/access-and-identity/api-keys-create-and-store). Keep it in a secret store or an environment variable, never in the request URL or a build log.\n\nGive the request a name in your notes before you send it. \"List the members of the Support organization, expect Alex Morgan\" is a result you can check; \"the call returned JSON\" is not.\n\n## Step 1: read your own organization\n\nThe safest first call reads the organization the key belongs to. It needs no other identifier and changes nothing.\n\n~~~bash\nBASE_URL=\"https://api.example.com\" # from the API reference's Servers list\nORGANIZATION_ID=\"7c1f6f0a-4b1e-4d8f-9a0c-2e5b3c9d1f42\" # from the application's organization settings\nORGANIZATION_API_KEY=\"sk_org_…\" # the key you created\n\ncurl --fail-with-body \\\n --url \"$BASE_URL/api/v1/organizations/$ORGANIZATION_ID\" \\\n {{CONSUMER_FACT:source:consumer-fact:access-api-keys#curlRequestHeader}} \\\n --header \"accept: application/json\"\n~~~\n\nReplace the three values with yours; leave the header exactly as shown. {{CONSUMER_FACT:source:consumer-fact:access-api-keys#markdown}}\n\nA successful answer is **200** with the organization record: its `_id` is the identifier you sent, and `name` is the organization you expected. Anything else, read the [failure table](#if-it-fails) below before changing more than one thing.\n\n## Step 2: read a collection\n\nNow list the organization's members. This exercises the collection envelope you will meet on every list and search operation:\n\n~~~bash\ncurl --fail-with-body \\\n --url \"$BASE_URL/api/v1/organizations/$ORGANIZATION_ID/organization-members?limit=5&sort=joinedAt:desc\" \\\n --header \"Authorization: $ORGANIZATION_API_KEY\" \\\n --header \"accept: application/json\"\n~~~\n\nThe response is `{ \"data\": [ … ], \"pagination\": { \"page\": 1, \"limit\": 5, \"total\": …, \"totalPages\": … } }`. Check that `total` matches the member count you see in the application. [Read collections](/integrations/rest/read-collections) covers paging, sorting and filters in full.\n\n## Step 3: prove the boundary holds\n\nA connection is only safe when a wrong credential is refused. Send the first request again with the key deliberately broken:\n\n~~~bash\ncurl --include \\\n --url \"$BASE_URL/api/v1/organizations/$ORGANIZATION_ID\" \\\n --header \"Authorization: sk_org_not_a_real_key\" \\\n --header \"accept: application/json\"\n~~~\n\nExpect **401** with `\"type\": \"AUTHENTICATION\"` in the error body. Then send the correct key against an organization it does not belong to and expect **404**: the application does not confirm that organizations outside your scope exist. Those two refusals are the negative proof; record them beside the successful read.\n\n## If it fails\n\n| You see | It means | Do this |\n| --- | --- | --- |\n| No response, or a TLS or DNS error | The base URL is wrong or unreachable from where you run | Compare the URL with the Servers list; test from the network the integration will run on |\n| **401** `AUTHENTICATION` | The key was not accepted | Check the header carries the full key with no `Bearer` prefix, that the key is `active`, and that it belongs to this environment |\n| **403** `AUTHORIZATION` | The key is valid but its roles do not allow this operation | Compare the roles on the key with the roles the operation lists in the reference |\n| **404** `NOT_FOUND` | The organization identifier is wrong, or this key cannot see it | Copy the identifier from the application again |\n| **429** `RATE_LIMIT` | Too many requests | Wait `Retry-After` seconds |\n\nEvery error an operation produces carries `error.correlationId`. Quote it when you ask for help. [Troubleshoot an API request](/integrations/rest/troubleshoot) goes deeper.\n\n## Before your first write\n\nRepeat Step 1 from the environment where the integration will actually run. Then rotate the key once ([API key lifecycle](/access-and-identity/api-keys-lifecycle)) to prove that the operating procedure works before you depend on it. Only then choose one small write and read [Write and reconcile changes](/integrations/rest/write-and-reconcile).";
351
+ readonly markdown: "# Send your first API request\n\nTen minutes from an API key to a verified connection. The first request proves four things and nothing else: you reached the right environment, the credential is accepted, it sees the organization you expect, and you can read the response. Use a read operation that changes nothing.\n\n## What you need\n\n- The **base URL** of the environment you are calling. {{APPLICATION_NAME}} publishes these:\n\n{{APPLICATION_CONNECTION:baseUrls}}\n\n- Your **organization identifier**, shown in the application's organization settings and present in the URL of most screens.\n- An **organization API key** created for this integration, following [Create and store an API key](/access-and-identity/api-keys-create-and-store). Keep it in a secret store or an environment variable, never in the request URL or a build log.\n\nGive the request a name in your notes before you send it. \"List the members of the Support organization, expect Alex Morgan\" is a result you can check; \"the call returned JSON\" is not.\n\n## Step 1: read your own organization\n\nThe safest first call reads the organization the key belongs to. It needs no other identifier and changes nothing.\n\n~~~bash\nBASE_URL=\"{{APPLICATION_CONNECTION_VALUE:baseUrl}}\" # this application's own origin\nORGANIZATION_ID=\"7c1f6f0a-4b1e-4d8f-9a0c-2e5b3c9d1f42\" # from the application's organization settings\nORGANIZATION_API_KEY=\"sk_org_…\" # the key you created\n\ncurl --fail-with-body \\\n --url \"$BASE_URL/api/v1/organizations/$ORGANIZATION_ID\" \\\n {{CONSUMER_FACT:source:consumer-fact:access-api-keys#curlRequestHeader}} \\\n --header \"accept: application/json\"\n~~~\n\nReplace the organization id and the key with yours; the base URL above is already this application's. Leave the header exactly as shown. {{CONSUMER_FACT:source:consumer-fact:access-api-keys#markdown}}\n\nA successful answer is **200** with the organization record: its `_id` is the identifier you sent, and `name` is the organization you expected. Anything else, read the [failure table](#if-it-fails) below before changing more than one thing.\n\n## Step 2: read a collection\n\nNow list the organization's members. This exercises the collection envelope you will meet on every list and search operation:\n\n~~~bash\ncurl --fail-with-body \\\n --url \"$BASE_URL/api/v1/organizations/$ORGANIZATION_ID/organization-members?limit=5&sort=joinedAt:desc\" \\\n --header \"Authorization: $ORGANIZATION_API_KEY\" \\\n --header \"accept: application/json\"\n~~~\n\nThe response is `{ \"data\": [ … ], \"pagination\": { \"page\": 1, \"limit\": 5, \"total\": …, \"totalPages\": … } }`. Check that `total` matches the member count you see in the application. [Read collections](/integrations/rest/read-collections) covers paging, sorting and filters in full.\n\n## Step 3: prove the boundary holds\n\nA connection is only safe when a wrong credential is refused. Send the first request again with the key deliberately broken:\n\n~~~bash\ncurl --include \\\n --url \"$BASE_URL/api/v1/organizations/$ORGANIZATION_ID\" \\\n --header \"Authorization: sk_org_not_a_real_key\" \\\n --header \"accept: application/json\"\n~~~\n\nExpect **401** with `\"type\": \"AUTHENTICATION\"` in the error body. Then send the correct key against an organization it does not belong to and expect **404**: the application does not confirm that organizations outside your scope exist. Those two refusals are the negative proof; record them beside the successful read.\n\n## If it fails\n\n| You see | It means | Do this |\n| --- | --- | --- |\n| No response, or a TLS or DNS error | The base URL is wrong or unreachable from where you run | Compare the URL with the Servers list; test from the network the integration will run on |\n| **401** `AUTHENTICATION` | The key was not accepted | Check the header carries the full key with no `Bearer` prefix, that the key is `active`, and that it belongs to this environment |\n| **403** `AUTHORIZATION` | The key is valid but its roles do not allow this operation | Compare the roles on the key with the roles the operation lists in the reference |\n| **404** `NOT_FOUND` | The organization identifier is wrong, or this key cannot see it | Copy the identifier from the application again |\n| **429** `RATE_LIMIT` | Too many requests | Wait `Retry-After` seconds |\n\nEvery error an operation produces carries `error.correlationId`. Quote it when you ask for help. [Troubleshoot an API request](/integrations/rest/troubleshoot) goes deeper.\n\n## Before your first write\n\nRepeat Step 1 from the environment where the integration will actually run. Then rotate the key once ([API key lifecycle](/access-and-identity/api-keys-lifecycle)) to prove that the operating procedure works before you depend on it. Only then choose one small write and read [Write and reconcile changes](/integrations/rest/write-and-reconcile).";
374
352
  }, {
375
353
  readonly managedPath: "integrations/rest/read-collections.md";
376
354
  readonly unitRef: "technical-documentation:unit/work-with-api-collections";
@@ -385,7 +363,7 @@ export declare const APPLICATION_CONSUMER_DOCUMENTATION_AUTHORED_CONTENT_V1: rea
385
363
  readonly managedPath: "integrations/rest/troubleshoot.md";
386
364
  readonly unitRef: "technical-documentation:unit/troubleshoot-api-request";
387
365
  readonly sourceRefs: readonly ["saas-technical-doc:engine-content/troubleshoot-api-request", "source:consumer-fact:access-api-keys", "source:consumer-fact:rest-conventions"];
388
- readonly markdown: "# Troubleshoot an API request\n\nStart from what the application returned: the HTTP status and the error body. Together they name the one boundary that failed. Change one thing, resend, and keep the first failure's evidence until the fix is proven.\n\n## Read the status and the error body\n\nEvery failed request answers with the same envelope. The two fields to read first are `error.type` and, when present, `error.code`:\n\n{{CONSUMER_FACT:source:consumer-fact:rest-conventions#errorEnvelopeMarkdown}}\n\n{{CONSUMER_FACT:source:consumer-fact:rest-conventions#errorStatusMarkdown}}\n\n## No HTTP response at all\n\nA connection refusal, a DNS failure, a TLS error and a client timeout are different problems, and none of them is an application answer.\n\n- Compare the base URL with the **Servers** list in the API reference; a URL copied from another environment is the usual cause.\n- Test from the network the integration runs on, not only from a laptop.\n- A timeout on a read can be repeated. A timeout on a write is an ambiguous outcome: follow [Recover from a lost response](/integrations/rest/write-and-reconcile#recover-from-a-lost-response) before resending.\n\n## 401: the credential was not accepted\n\n- The `Authorization` header must carry the whole key, with no `Bearer` prefix in front of an API key and no key inside a URL or a cookie. {{CONSUMER_FACT:source:consumer-fact:access-api-keys#markdown}}\n- Check the key's status in the application: an `inactive` or `expired` key is refused. [API key lifecycle](/access-and-identity/api-keys-lifecycle) explains each status.\n- Check the environment: a key minted in one environment does not work in another.\n\nDo not fix a 401 by borrowing an administrator's key. That hides the defect and widens what the integration can do.\n\n## 403: valid credential, refused operation\n\nThe application knows who is calling and refuses this operation in this scope.\n\n- Compare the roles on the key with the roles the operation lists in the API reference.\n- A collection under an organization the key is not a member of is refused with 403; confirm the organization identifier.\n- `FEATURE_NOT_AVAILABLE` and `FEATURE_LIMIT_EXCEEDED` are plan refusals, not role refusals; see [Plans and access](/billing-and-subscriptions/plans-and-access).\n\n## 404: the record is not visible here\n\nEither the identifier is wrong or the record belongs to an organization this key cannot see. The application does not distinguish the two on purpose. Copy the identifier from the application again and confirm the organization in the path.\n\n## 409 and 422: the current state refuses the change\n\nRead the record, then read `error.code` and `error.customMessageReference`. A stale `if-match` carries `error.details.versionConflict` with the current version. [Write and reconcile changes](/integrations/rest/write-and-reconcile) shows what to do for each case.\n\n## 429: too many requests\n\n{{CONSUMER_FACT:source:consumer-fact:rest-conventions#rateLimitMarkdown}}\n\nWait the full `Retry-After`, then resume where you stopped. If several workers share one key they share its counters; spread the load or use one key per worker.\n\n## 5xx: the application failed\n\nKeep `error.correlationId`, the operation path and the time. Reads can be retried with a short back-off. For a write, read the record before resending.\n\n## Prove the fix\n\nResend the smallest request with exactly one change. Then run the two negative checks from [Send your first API request](/integrations/rest/send-request#step-3-prove-the-boundary-holds) again: a wrong key is still refused, and another organization is still invisible. A fix that opened the boundary is not a fix.\n\n## Ask for help with the right evidence\n\nQuote the operation path, the HTTP status, `error.type`, `error.code`, `error.correlationId` and the timestamp. Say whether a write may already have applied. Never paste the key, a bearer token or a full response body.";
366
+ readonly markdown: "# Troubleshoot an API request\n\nStart from what the application returned: the HTTP status and the error body. Together they name the one boundary that failed. Change one thing, resend, and keep the first failure's evidence until the fix is proven.\n\n## Read the status and the error body\n\nEvery failed request answers with the same envelope. The two fields to read first are `error.type` and, when present, `error.code`:\n\n{{CONSUMER_FACT:source:consumer-fact:rest-conventions#errorEnvelopeMarkdown}}\n\n{{CONSUMER_FACT:source:consumer-fact:rest-conventions#errorStatusMarkdown}}\n\n## No HTTP response at all\n\nA connection refusal, a DNS failure, a TLS error and a client timeout are different problems, and none of them is an application answer.\n\n- Compare the base URL with the **Servers** list in the API reference; a URL copied from another environment is the usual cause.\n- Test from the network the integration runs on, not only from a laptop.\n- A timeout on a read can be repeated. A timeout on a write is an ambiguous outcome: follow [Recover from a lost response](/integrations/rest/write-and-reconcile#recover-from-a-lost-response) before resending.\n\n## 401: the credential was not accepted\n\n- The `Authorization` header must carry the whole key, with no `Bearer` prefix in front of an API key and no key inside a URL or a cookie. {{CONSUMER_FACT:source:consumer-fact:access-api-keys#markdown}}\n- Check the key's status in the application: an `inactive` or `expired` key is refused. [API key lifecycle](/access-and-identity/api-keys-lifecycle) explains each status.\n- Check the environment: a key minted in one environment does not work in another.\n\nDo not fix a 401 by borrowing an administrator's key. That hides the defect and widens what the integration can do.\n\n## 403: valid credential, refused operation\n\nThe application knows who is calling and refuses this operation in this scope.\n\n- Compare the roles on the key with the roles the operation lists in the API reference.\n- A collection under an organization the key is not a member of is refused with 403; confirm the organization identifier.\n- `FEATURE_NOT_AVAILABLE` and `FEATURE_LIMIT_EXCEEDED` are plan refusals, not role refusals: the organization's subscription does not include the capability, or has reached its limit for it. Changing a role will not clear either one.\n\n## 404: the record is not visible here\n\nEither the identifier is wrong or the record belongs to an organization this key cannot see. The application does not distinguish the two on purpose. Copy the identifier from the application again and confirm the organization in the path.\n\n## 409 and 422: the current state refuses the change\n\nRead the record, then read `error.code` and `error.customMessageReference`. A stale `if-match` carries `error.details.versionConflict` with the current version. [Write and reconcile changes](/integrations/rest/write-and-reconcile) shows what to do for each case.\n\n## 429: too many requests\n\n{{CONSUMER_FACT:source:consumer-fact:rest-conventions#rateLimitMarkdown}}\n\nWait the full `Retry-After`, then resume where you stopped. If several workers share one key they share its counters; spread the load or use one key per worker.\n\n## 5xx: the application failed\n\nKeep `error.correlationId`, the operation path and the time. Reads can be retried with a short back-off. For a write, read the record before resending.\n\n## Prove the fix\n\nResend the smallest request with exactly one change. Then run the two negative checks from [Send your first API request](/integrations/rest/send-request#step-3-prove-the-boundary-holds) again: a wrong key is still refused, and another organization is still invisible. A fix that opened the boundary is not a fix.\n\n## Ask for help with the right evidence\n\nQuote the operation path, the HTTP status, `error.type`, `error.code`, `error.correlationId` and the timestamp. Say whether a write may already have applied. Never paste the key, a bearer token or a full response body.";
389
367
  }, {
390
368
  readonly managedPath: "integrations/webhooks.md";
391
369
  readonly unitRef: "technical-documentation:unit/webhooks";