@epilot/sdk 2.20.85 → 2.20.87

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 (163) hide show
  1. package/definitions/automation-runtime.json +1 -1
  2. package/definitions/automation.json +294 -17
  3. package/definitions/workflow-definition.json +686 -12
  4. package/definitions/workflow-runtime.json +1 -1
  5. package/definitions/workflow.json +4072 -1386
  6. package/dist/apis/access-token.cjs +6 -6
  7. package/dist/apis/access-token.js +1 -1
  8. package/dist/apis/address-suggestions.cjs +6 -6
  9. package/dist/apis/address-suggestions.js +1 -1
  10. package/dist/apis/address.cjs +6 -6
  11. package/dist/apis/address.js +1 -1
  12. package/dist/apis/ai-agents.cjs +6 -6
  13. package/dist/apis/ai-agents.js +1 -1
  14. package/dist/apis/app.cjs +6 -6
  15. package/dist/apis/app.js +1 -1
  16. package/dist/apis/audit-logs.cjs +6 -6
  17. package/dist/apis/audit-logs.js +1 -1
  18. package/dist/apis/automation.cjs +8 -8
  19. package/dist/apis/automation.d.cts +2 -2
  20. package/dist/apis/automation.d.ts +2 -2
  21. package/dist/apis/automation.js +2 -2
  22. package/dist/apis/billing.cjs +6 -6
  23. package/dist/apis/billing.js +1 -1
  24. package/dist/apis/blueprint-manifest.cjs +6 -6
  25. package/dist/apis/blueprint-manifest.js +1 -1
  26. package/dist/apis/calendar.cjs +6 -6
  27. package/dist/apis/calendar.js +1 -1
  28. package/dist/apis/chat.cjs +6 -6
  29. package/dist/apis/chat.js +1 -1
  30. package/dist/apis/configuration-hub.cjs +6 -6
  31. package/dist/apis/configuration-hub.js +1 -1
  32. package/dist/apis/consent.cjs +6 -6
  33. package/dist/apis/consent.js +1 -1
  34. package/dist/apis/customer-portal.cjs +6 -6
  35. package/dist/apis/customer-portal.js +1 -1
  36. package/dist/apis/dashboard.cjs +6 -6
  37. package/dist/apis/dashboard.js +1 -1
  38. package/dist/apis/data-governance.cjs +6 -6
  39. package/dist/apis/data-governance.js +1 -1
  40. package/dist/apis/deduplication.cjs +6 -6
  41. package/dist/apis/deduplication.js +1 -1
  42. package/dist/apis/design.cjs +6 -6
  43. package/dist/apis/design.js +1 -1
  44. package/dist/apis/document.cjs +6 -6
  45. package/dist/apis/document.js +1 -1
  46. package/dist/apis/email-settings.cjs +6 -6
  47. package/dist/apis/email-settings.js +1 -1
  48. package/dist/apis/email-template.cjs +6 -6
  49. package/dist/apis/email-template.js +1 -1
  50. package/dist/apis/entity-mapping.cjs +6 -6
  51. package/dist/apis/entity-mapping.js +1 -1
  52. package/dist/apis/entity.cjs +6 -6
  53. package/dist/apis/entity.js +1 -1
  54. package/dist/apis/environments.cjs +6 -6
  55. package/dist/apis/environments.js +1 -1
  56. package/dist/apis/event-catalog.cjs +6 -6
  57. package/dist/apis/event-catalog.js +1 -1
  58. package/dist/apis/external-values.cjs +6 -6
  59. package/dist/apis/external-values.js +1 -1
  60. package/dist/apis/file.cjs +6 -6
  61. package/dist/apis/file.js +1 -1
  62. package/dist/apis/iban.cjs +6 -6
  63. package/dist/apis/iban.js +1 -1
  64. package/dist/apis/identity.cjs +6 -6
  65. package/dist/apis/identity.js +1 -1
  66. package/dist/apis/integration-toolkit.cjs +6 -6
  67. package/dist/apis/integration-toolkit.js +1 -1
  68. package/dist/apis/journey.cjs +6 -6
  69. package/dist/apis/journey.js +1 -1
  70. package/dist/apis/kanban.cjs +6 -6
  71. package/dist/apis/kanban.js +1 -1
  72. package/dist/apis/message.cjs +6 -6
  73. package/dist/apis/message.js +1 -1
  74. package/dist/apis/metering.cjs +6 -6
  75. package/dist/apis/metering.js +1 -1
  76. package/dist/apis/notes.cjs +6 -6
  77. package/dist/apis/notes.js +1 -1
  78. package/dist/apis/notification.cjs +6 -6
  79. package/dist/apis/notification.js +1 -1
  80. package/dist/apis/organization.cjs +6 -6
  81. package/dist/apis/organization.js +1 -1
  82. package/dist/apis/partner-directory.cjs +6 -6
  83. package/dist/apis/partner-directory.js +1 -1
  84. package/dist/apis/permissions.cjs +6 -6
  85. package/dist/apis/permissions.js +1 -1
  86. package/dist/apis/phone-integration.cjs +6 -6
  87. package/dist/apis/phone-integration.js +1 -1
  88. package/dist/apis/pricing-tier.cjs +6 -6
  89. package/dist/apis/pricing-tier.js +1 -1
  90. package/dist/apis/pricing.cjs +6 -6
  91. package/dist/apis/pricing.js +1 -1
  92. package/dist/apis/purpose.cjs +6 -6
  93. package/dist/apis/purpose.js +1 -1
  94. package/dist/apis/query.cjs +6 -6
  95. package/dist/apis/query.js +1 -1
  96. package/dist/apis/sandbox.cjs +6 -6
  97. package/dist/apis/sandbox.js +1 -1
  98. package/dist/apis/sharing.cjs +6 -6
  99. package/dist/apis/sharing.js +1 -1
  100. package/dist/apis/snapshot.cjs +6 -6
  101. package/dist/apis/snapshot.js +1 -1
  102. package/dist/apis/submission.cjs +6 -6
  103. package/dist/apis/submission.js +1 -1
  104. package/dist/apis/target.cjs +6 -6
  105. package/dist/apis/target.js +1 -1
  106. package/dist/apis/targeting.cjs +6 -6
  107. package/dist/apis/targeting.js +1 -1
  108. package/dist/apis/template-variables.cjs +6 -6
  109. package/dist/apis/template-variables.js +1 -1
  110. package/dist/apis/user.cjs +6 -6
  111. package/dist/apis/user.js +1 -1
  112. package/dist/apis/validation-rules.cjs +6 -6
  113. package/dist/apis/validation-rules.js +1 -1
  114. package/dist/apis/webhooks.cjs +6 -6
  115. package/dist/apis/webhooks.js +1 -1
  116. package/dist/apis/workflow-definition.cjs +6 -6
  117. package/dist/apis/workflow-definition.d.cts +2 -2
  118. package/dist/apis/workflow-definition.d.ts +2 -2
  119. package/dist/apis/workflow-definition.js +1 -1
  120. package/dist/apis/workflow.cjs +8 -8
  121. package/dist/apis/workflow.d.cts +2 -2
  122. package/dist/apis/workflow.d.ts +2 -2
  123. package/dist/apis/workflow.js +2 -2
  124. package/dist/automation-KNJZDJD7.cjs +7 -0
  125. package/dist/automation-RKVFGJTO.js +7 -0
  126. package/dist/{automation-runtime-KLCXZKEC.cjs → automation-runtime-7LXZ343U.cjs} +2 -2
  127. package/dist/{automation-runtime-Y52HM57N.js → automation-runtime-JZKABTGP.js} +1 -1
  128. package/dist/{automation.d-B8g3nYp-.d.cts → automation.d-cTvIBxDI.d.cts} +514 -26
  129. package/dist/{automation.d-B8g3nYp-.d.ts → automation.d-cTvIBxDI.d.ts} +514 -26
  130. package/dist/{chunk-7T4BNWMN.js → chunk-AMLTCPBT.js} +5 -5
  131. package/dist/{chunk-WOUASZJW.cjs → chunk-EIT2JFPB.cjs} +1 -1
  132. package/dist/{chunk-QW3ROE6H.js → chunk-JKCBMHOZ.js} +1 -1
  133. package/dist/{chunk-ZSZ4IWLQ.cjs → chunk-PQONAXAH.cjs} +5 -5
  134. package/dist/chunk-SWEH4LP3.cjs +14 -0
  135. package/dist/chunk-W5OQ3L53.js +14 -0
  136. package/dist/index.cjs +12 -12
  137. package/dist/index.d.cts +3 -3
  138. package/dist/index.d.ts +3 -3
  139. package/dist/index.js +3 -3
  140. package/dist/workflow-B5IJTSPX.js +7 -0
  141. package/dist/workflow-GOWWDU4Y.cjs +7 -0
  142. package/dist/workflow-definition-46NTR2N5.cjs +7 -0
  143. package/dist/workflow-definition-BSY2BNM2.js +7 -0
  144. package/dist/{workflow-definition.d-CweGhhBU.d.ts → workflow-definition.d-Be0CM3Py.d.cts} +574 -10
  145. package/dist/{workflow-definition.d-CweGhhBU.d.cts → workflow-definition.d-Be0CM3Py.d.ts} +574 -10
  146. package/dist/{workflow-runtime-L5HMFISV.js → workflow-runtime-GPXNF7WI.js} +1 -1
  147. package/dist/{workflow-runtime-LMGACZP4.cjs → workflow-runtime-HD6U5ZSL.cjs} +2 -2
  148. package/dist/workflow.d-B7utaxgb.d.cts +6868 -0
  149. package/dist/workflow.d-B7utaxgb.d.ts +6868 -0
  150. package/docs/automation.md +267 -26
  151. package/docs/workflow-definition.md +840 -138
  152. package/docs/workflow.md +4537 -1746
  153. package/package.json +1 -1
  154. package/dist/automation-G2CKAQNB.cjs +0 -7
  155. package/dist/automation-UPTNUOYO.js +0 -7
  156. package/dist/chunk-522LYPPW.js +0 -14
  157. package/dist/chunk-PM25LLET.cjs +0 -14
  158. package/dist/workflow-JQT3F5NJ.cjs +0 -7
  159. package/dist/workflow-Q6FAE5OL.js +0 -7
  160. package/dist/workflow-definition-MSO4JDA3.js +0 -7
  161. package/dist/workflow-definition-XTWO4RMY.cjs +0 -7
  162. package/dist/workflow.d-5cyNJgVQ.d.cts +0 -3843
  163. package/dist/workflow.d-5cyNJgVQ.d.ts +0 -3843
@@ -2,7 +2,7 @@
2
2
  "openapi": "3.0.0",
3
3
  "info": {
4
4
  "title": "Workflows Definitions",
5
- "version": "1.1.0",
5
+ "version": "1.3.0",
6
6
  "description": "The Workflows Definitions API enables you to create, manage, and configure reusable workflow templates\nwithin your organization. Workflow definitions serve as blueprints that define the structure and behavior\nof business processes, which can then be instantiated as workflow executions.\n\n## Core Concepts\n\n### Workflow Definition (V1)\nA workflow definition is a template that describes a business process. It consists of:\n- **Sections**: Logical groupings (phases) that organize related steps together\n- **Steps**: Individual tasks or actions that need to be completed within a section\n- **Closing Reasons**: Predefined reasons that can be selected when closing/completing a workflow\n\n### Flow Template (V2)\nThe modern workflow model that provides advanced capabilities:\n- **Phases**: Named stages that group related tasks and track progress through the workflow\n- **Tasks**: Individual units of work that can be manual, automated, AI-powered, or decision points\n- **Edges**: Connections between tasks that define the flow sequence and support conditional branching\n- **Triggers**: Define how a workflow is started (manual, automation, journey submission)\n\n### Task Types (V2)\n- **MANUAL**: Tasks assigned to users that require human action to complete\n- **AUTOMATION**: Tasks that execute automated actions when reached\n- **DECISION**: Conditional branching points that evaluate conditions to determine the next path\n- **AI_AGENT**: Tasks that invoke AI agents to perform intelligent actions\n\n## API Versions\n- **V1 endpoints** (`/v1/workflows/...`): Legacy linear workflow model with sections and steps\n- **V2 endpoints** (`/v2/flows/...`): Modern graph-based flow model with phases, tasks, and edges\n"
7
7
  },
8
8
  "servers": [
@@ -163,7 +163,7 @@
163
163
  "post": {
164
164
  "operationId": "createDefinition",
165
165
  "summary": "createDefinition",
166
- "description": "Create a new V1 workflow definition. The definition consists of sections and steps\nthat define the structure of the workflow. Once created, the definition can be used\nto start workflow executions.\n",
166
+ "description": "Create a new V1 workflow definition. The definition consists of sections and steps\nthat define the structure of the workflow. Once created, the definition can be used\nto start workflow executions.\n\nDeprecated: from 17 October 2026 00:00 Europe/Berlin this endpoint answers 409 —\ncreate a flow via `POST /v2/flows/templates` instead.\n",
167
167
  "tags": [
168
168
  "Workflows"
169
169
  ],
@@ -317,6 +317,19 @@
317
317
  }
318
318
  }
319
319
  },
320
+ "409": {
321
+ "description": "Workflow creation is closed — from 17 October 2026 00:00 Europe/Berlin\n(16 October being the last day) no new V1 workflow definitions are\naccepted. Create a flow via `POST /v2/flows/templates` instead;\nexisting workflow definitions stay readable, updatable and executable.\nBlueprint installs and other internal epilot services (which reach\nthis operation through a direct Lambda invocation) are exempt, so\nblueprints captured before the cutoff keep installing.\n",
322
+ "content": {
323
+ "application/json": {
324
+ "schema": {
325
+ "$ref": "#/components/schemas/ErrorResp"
326
+ },
327
+ "example": {
328
+ "message": "Workflows can no longer be created. Create a flow instead: POST /v2/flows/templates. Existing workflows stay editable."
329
+ }
330
+ }
331
+ }
332
+ },
320
333
  "500": {
321
334
  "description": "Other errors",
322
335
  "content": {
@@ -1764,6 +1777,20 @@
1764
1777
  "description": "Optional detailed description of the workflow's purpose and behavior.",
1765
1778
  "maxLength": 5000
1766
1779
  },
1780
+ "portal_titles": {
1781
+ "type": "object",
1782
+ "description": "Portal-facing overrides of the flow name. Portal surfaces (the End Customer and Installer portals, and the builder's portal views) show the matching override instead of `name`; an absent key falls back to `name`. Has no effect on execution behaviour.",
1783
+ "properties": {
1784
+ "ecp": {
1785
+ "type": "string",
1786
+ "description": "Flow title shown to end customers."
1787
+ },
1788
+ "installer": {
1789
+ "type": "string",
1790
+ "description": "Flow title shown to installers."
1791
+ }
1792
+ }
1793
+ },
1767
1794
  "trigger": {
1768
1795
  "$ref": "#/components/schemas/Trigger"
1769
1796
  },
@@ -1811,7 +1838,7 @@
1811
1838
  },
1812
1839
  "additional_triggers": {
1813
1840
  "type": "array",
1814
- "description": "Additional trigger configurations that can also start this flow. Useful for flows that should be startable via multiple methods (e.g., both automation AND manual).",
1841
+ "description": "Additional trigger configurations that can also start this flow.\nUseful for flows that should be startable via multiple methods\n(e.g., both automation AND manual). Each additional trigger may\ntarget its own entity and may carry its own entry edge (an edge\nwhose `from_id` is the trigger's `id`); without an entry edge of\nits own it starts the flow at the primary entry. Triggers must be\ncomplementary — no two triggers on a flow may cover the same\nentity and event.\n",
1815
1842
  "items": {
1816
1843
  "$ref": "#/components/schemas/Trigger"
1817
1844
  }
@@ -1822,6 +1849,13 @@
1822
1849
  "$ref": "#/components/schemas/Phase"
1823
1850
  }
1824
1851
  },
1852
+ "stages": {
1853
+ "type": "array",
1854
+ "description": "Customer-facing progress segments layered on top of the flow graph. Stages are strictly ordered boundaries: the first is anchored at the trigger, every later one is an edge cut (or a legacy entry-node anchor whose in-edges form the cut). The array order is the boundary order and must match the graph. Per-node stage membership is always computed from the graph, never stored, and a run may end in any stage.",
1855
+ "items": {
1856
+ "$ref": "#/components/schemas/Stage"
1857
+ }
1858
+ },
1825
1859
  "tasks": {
1826
1860
  "type": "array",
1827
1861
  "items": {
@@ -1868,12 +1902,19 @@
1868
1902
  "type": "boolean",
1869
1903
  "description": "When true, this is a linear flow: task enablement is computed at runtime from the graph — a task is enabled only when all of its direct predecessor tasks in its branch are done. This fully overrides any explicit per-task requirements."
1870
1904
  },
1905
+ "context_settings": {
1906
+ "$ref": "#/components/schemas/FlowContextSettings"
1907
+ },
1871
1908
  "limit_warnings": {
1872
1909
  "type": "array",
1873
1910
  "description": "Non-blocking warnings for configuration limits the flow exceeds. Returned on read (get-flow) and on create/update responses. Size/count limits are soft: a flow exceeding them is still accepted and stored, and the violations are reported here so the UI can surface an informational banner. The flow is still fully editable and usable.",
1874
1911
  "items": {
1875
1912
  "$ref": "#/components/schemas/FlowLimitWarning"
1876
1913
  }
1914
+ },
1915
+ "keep_task_automations_in_sync": {
1916
+ "type": "boolean",
1917
+ "description": "Persisted preference for how the flow's task automations relate to the flow's `enabled` state. When `true`, task automations always mirror the flow: their enabled state is re-synced on every update and new task automations are created with the flow's current enabled state. When `false`, task automations are managed independently: updates never change their enabled state and new task automations are always created enabled, so a flow that is built or edited while disabled does not accumulate automations that stay off after the flow is re-enabled. When unset, legacy behavior applies: new task automations inherit the flow's enabled state and updates leave existing ones untouched. Safety: on updates that do NOT change `enabled`, the in-sync mode never re-enables automations that were disabled by the system (e.g. infinite-loop protection) — only a deliberate `enabled` flip on the flow re-arms those."
1877
1918
  }
1878
1919
  }
1879
1920
  },
@@ -2150,7 +2191,10 @@
2150
2191
  "type": "string",
2151
2192
  "enum": [
2152
2193
  "created_at",
2153
- "updated_at"
2194
+ "updated_at",
2195
+ "name",
2196
+ "enabled",
2197
+ "id"
2154
2198
  ],
2155
2199
  "default": "updated_at"
2156
2200
  },
@@ -2220,8 +2264,17 @@
2220
2264
  "automation_config": {
2221
2265
  "$ref": "#/components/schemas/AutomationConfig"
2222
2266
  },
2267
+ "on_failure": {
2268
+ "$ref": "#/components/schemas/AutomationFailurePolicy"
2269
+ },
2223
2270
  "trigger_mode": {
2224
- "$ref": "#/components/schemas/TriggerMode"
2271
+ "$ref": "#/components/schemas/TriggerMode",
2272
+ "allOf": [
2273
+ {
2274
+ "$ref": "#/components/schemas/TriggerMode"
2275
+ }
2276
+ ],
2277
+ "description": "How the automation is started. `automatic` runs it as soon as the task becomes current; `manual` waits for a person to run it. An absent value is read as `manual` everywhere: the engine dispatches only an explicit `automatic`, the builder shows the task as manual, and the task may carry the skip gate and required subtasks."
2225
2278
  },
2226
2279
  "schedule": {
2227
2280
  "$ref": "#/components/schemas/ActionSchedule"
@@ -2235,6 +2288,15 @@
2235
2288
  }
2236
2289
  ]
2237
2290
  },
2291
+ "AutomationFailurePolicy": {
2292
+ "type": "string",
2293
+ "enum": [
2294
+ "stop",
2295
+ "continue"
2296
+ ],
2297
+ "default": "stop",
2298
+ "description": "What the flow does when this automation ends in a failed state. `stop` waits on the failed task until it is retried or skipped. `continue` proceeds to the next task. An absent value means `stop`."
2299
+ },
2238
2300
  "AutomationConfig": {
2239
2301
  "type": "object",
2240
2302
  "description": "Configuration for automation execution to run",
@@ -2268,12 +2330,46 @@
2268
2330
  },
2269
2331
  "input_context": {
2270
2332
  "$ref": "#/components/schemas/AutomationInputContext"
2333
+ },
2334
+ "output_context": {
2335
+ "$ref": "#/components/schemas/AutomationOutputContext"
2336
+ },
2337
+ "eligible_closing_reason_ids": {
2338
+ "type": "array",
2339
+ "description": "The closing reasons a person may choose from when running this task, making a `cancel-flow-execution` automation semi-automated: the step is configured here, the reason is picked at execution time. Every id must also appear in the flow template's `closing_reasons` — the step narrows the flow's vocabulary rather than introducing its own, which is what keeps the chosen reason a member of the execution's `configured_reasons` and what lets blueprints export the reasons a step depends on. Only a task whose `trigger_mode` is `manual` or absent can carry it; the template healer clears it from an `automatic` task, which has no assignee moment to choose in. Empty or absent means the automation runs with the reasons fixed in its own action config.",
2340
+ "items": {
2341
+ "type": "string"
2342
+ }
2343
+ },
2344
+ "email_review": {
2345
+ "$ref": "#/components/schemas/EmailReviewConfig"
2346
+ },
2347
+ "allow_execution_note": {
2348
+ "type": "boolean",
2349
+ "description": "Whether the person running a semi-automated cancel step may add a free-text note alongside the reason they choose. Only meaningful with `eligible_closing_reason_ids`, since the note is written in the same prompt; the template healer clears it from a step that asks nothing."
2350
+ }
2351
+ }
2352
+ },
2353
+ "EmailReviewConfig": {
2354
+ "type": "object",
2355
+ "description": "Whether the person running a semi-automated send-email step may adjust the email before it goes out, and what they may adjust. Meaningful only on a task a person triggers — the engine's own dispatch has nobody to review — so the template healer clears it from an `automatic` task. With `enabled` false the email is sent exactly as configured and the person only triggers it.",
2356
+ "properties": {
2357
+ "enabled": {
2358
+ "type": "boolean"
2359
+ },
2360
+ "allow_document_selection": {
2361
+ "type": "boolean",
2362
+ "description": "The assignee may attach documents from the task's entity at execution, in addition to whatever the configured rules match."
2363
+ },
2364
+ "allow_subject_and_body_edit": {
2365
+ "type": "boolean",
2366
+ "description": "The assignee may rewrite the rendered subject and body. They edit the rendered text, not the template, so the template is unchanged and other flows using it are unaffected."
2271
2367
  }
2272
2368
  }
2273
2369
  },
2274
2370
  "AutomationInputContext": {
2275
2371
  "type": "object",
2276
- "description": "Optional. Source of the entity fed into this automation task. If omitted, the workflow's primary entity is used.\n",
2372
+ "description": "Optional. Source of the entity fed into this automation task. If omitted, the entity of the trigger that started the run is used.\n",
2277
2373
  "required": [
2278
2374
  "source"
2279
2375
  ],
@@ -2284,11 +2380,152 @@
2284
2380
  "trigger",
2285
2381
  "task"
2286
2382
  ],
2287
- "description": "`trigger` = workflow's primary (trigger) entity. `task` = entity produced by an upstream task in the graph.\n"
2383
+ "description": "`trigger` = the entity of the trigger that started the run, or of the specific configured trigger named by `trigger_id`. `task` = entity produced by an upstream task in the graph.\n"
2288
2384
  },
2289
2385
  "task_id": {
2290
2386
  "type": "string",
2291
2387
  "description": "Required when source is `task`. The id of the upstream task whose output entity should feed this task."
2388
+ },
2389
+ "trigger_id": {
2390
+ "type": "string",
2391
+ "description": "Optional when source is `trigger`. Pins the input to one specific configured trigger (primary or additional) by its id. When absent, the trigger that started the run supplies the entity.\n"
2392
+ }
2393
+ }
2394
+ },
2395
+ "FlowContextSettings": {
2396
+ "type": "object",
2397
+ "description": "Where a flow runs, and where people see it.\nA run is ALWAYS visible on the entities it runs on — the entity its trigger supplied and every context it picks up. That is not configurable: it is what running there means, and hiding a run from its own entity is what `visibility: background` is for.\n`displays` lists ADDITIONAL entity kinds, reached by relation. It is written once and holds for every trigger: which entry point started a run says how it began, not who the process concerns. A flow that finance must see on the Account must be seen there whether it started from a web form or an inbound email.\n",
2398
+ "properties": {
2399
+ "visibility": {
2400
+ "type": "string",
2401
+ "enum": [
2402
+ "entity_views",
2403
+ "background"
2404
+ ],
2405
+ "default": "entity_views",
2406
+ "description": "`entity_views` — the flow appears on entity pages, table views and the portal, as decided by `displays`.\n`background` — the flow is hidden from every entity view. It runs and records exactly the same way; only the surfaces are suppressed.\n"
2407
+ },
2408
+ "main_context": {
2409
+ "$ref": "#/components/schemas/MainContextSetting"
2410
+ },
2411
+ "displays": {
2412
+ "type": "array",
2413
+ "items": {
2414
+ "$ref": "#/components/schemas/FlowDisplayRule"
2415
+ },
2416
+ "description": "Additional entity kinds this flow is visible on, beyond the entities it runs on. Empty or absent means it is seen only where it runs.\nORDERED. An entry may anchor (`from`) only on the main context or on an EARLIER entry. That ordering is what makes a cycle (contact anchored on account anchored on contact) unrepresentable rather than something to detect at runtime.\n"
2417
+ }
2418
+ }
2419
+ },
2420
+ "MainContextSetting": {
2421
+ "type": "object",
2422
+ "description": "Which of a flow's contexts owns the run: the entity conditions, automations and entity sync resolve against by default.\nABSENT means the historical behaviour — the primary trigger's entity. That default exists because it describes every flow built so far, not because the primary trigger is special: a flow with several complementary triggers has no natural primary, which is exactly when stating it explicitly earns its place.\nThis decides the STARTING main context only. A task with `output_context.set_as_primary` still moves it mid-run; the setting seeds the run and the graph moves it from there.\n",
2423
+ "required": [
2424
+ "schema"
2425
+ ],
2426
+ "properties": {
2427
+ "schema": {
2428
+ "type": "string",
2429
+ "description": "Entity schema of the main context. It need not be a schema any trigger provides: a run started on another context resolves it from that entity's relations."
2430
+ },
2431
+ "relation_labels": {
2432
+ "type": "array",
2433
+ "items": {
2434
+ "type": "string"
2435
+ },
2436
+ "description": "Optional narrowing for that resolution. A run started on a context of another schema looks through the starting entity's relations for one of `schema`; these `_tags` narrow which relations count, for when schema alone is ambiguous.\nSeveral matches: the FIRST is taken. Unlike an attaching display rule — which attaches nothing when several match, since binding an arbitrary entity as a surface has no justification — a run needs a primary to function at all, so a deterministic pick beats none.\nNo match: the run starts with the entity it was started on as primary, and records that the configured main context did not resolve. A manual start is never blocked because a relation happens to be missing.\n"
2437
+ }
2438
+ }
2439
+ },
2440
+ "FlowDisplayRule": {
2441
+ "type": "object",
2442
+ "description": "One additional entity kind the flow should be visible on, found by relation from the main context or from an earlier entry.\nAn entity reached this way has no context of its own: it shows the main context's run, and acting on it acts on the main context. Nothing is copied and no second run starts.\nThere is no `enabled` flag and no entry for an entity the flow already runs on. An entry exists because someone wants the flow seen there; remove it to stop. Whether an entity is a context at all is decided by the trigger, by a task's `output_context`, or by `attach_to_contexts` below — never by a display setting.\n",
2443
+ "required": [
2444
+ "id",
2445
+ "entity_schema"
2446
+ ],
2447
+ "properties": {
2448
+ "id": {
2449
+ "type": "string"
2450
+ },
2451
+ "entity_schema": {
2452
+ "type": "string",
2453
+ "description": "The schema of the entity this rule is about."
2454
+ },
2455
+ "from": {
2456
+ "$ref": "#/components/schemas/FlowRuleAnchor"
2457
+ },
2458
+ "relation_labels": {
2459
+ "type": "array",
2460
+ "items": {
2461
+ "type": "string"
2462
+ },
2463
+ "description": "Relation `_tags` to match (`family:label` form supported). Absent or empty matches every relation of `entity_schema`.\n"
2464
+ },
2465
+ "attach_to_contexts": {
2466
+ "type": "boolean",
2467
+ "default": false,
2468
+ "description": "Governs CONTEXT. When true the matched entity is added to the run's contexts, so later rules can anchor on it and conditions, entity sync and task automations can address it. Resolved by the ENGINE — at start and whenever the contexts change — never as a side effect of rendering, which would make a run's context set depend on who opened which page.\nA context must resolve to one entity: when several match, none is attached. Display is unaffected and still shows all of them.\n"
2469
+ }
2470
+ }
2471
+ },
2472
+ "FlowRuleAnchor": {
2473
+ "description": "Where an entry starts looking. Absent means `main_context`.\nA ROLE, not a schema: an entry anchored on `main_context` follows the primary when a task promotes another entity, where naming a schema would freeze it on the old one.\n",
2474
+ "oneOf": [
2475
+ {
2476
+ "$ref": "#/components/schemas/MainContextAnchor"
2477
+ },
2478
+ {
2479
+ "$ref": "#/components/schemas/RuleAnchor"
2480
+ }
2481
+ ]
2482
+ },
2483
+ "MainContextAnchor": {
2484
+ "type": "object",
2485
+ "description": "The run's primary context, whatever it currently is.",
2486
+ "required": [
2487
+ "role"
2488
+ ],
2489
+ "properties": {
2490
+ "role": {
2491
+ "type": "string",
2492
+ "enum": [
2493
+ "main_context"
2494
+ ]
2495
+ }
2496
+ }
2497
+ },
2498
+ "RuleAnchor": {
2499
+ "type": "object",
2500
+ "description": "An earlier entry in `displays`, by its id: this entry searches from whatever that one matched. Chaining ticket -> contact -> account this way keeps both hops DISPLAY-only; making the contact a real context first is a separate decision (`attach_to_contexts`), not a prerequisite for reaching the account.\n",
2501
+ "required": [
2502
+ "role",
2503
+ "rule_id"
2504
+ ],
2505
+ "properties": {
2506
+ "role": {
2507
+ "type": "string",
2508
+ "enum": [
2509
+ "rule"
2510
+ ]
2511
+ },
2512
+ "rule_id": {
2513
+ "type": "string",
2514
+ "description": "Id of an entry that appears earlier in `displays`."
2515
+ }
2516
+ }
2517
+ },
2518
+ "AutomationOutputContext": {
2519
+ "type": "object",
2520
+ "description": "Optional. What happens to the entity produced by this automation task (the last successful entity-producing action of its automation).\n",
2521
+ "properties": {
2522
+ "set_as_primary": {
2523
+ "type": "boolean",
2524
+ "description": "When true, the entity this task's automation produces becomes the run's primary context (\"main context\") when the task completes. Downstream tasks and decisions configured with the default input context then act on that entity. When the task is reverted or reset, the previous primary context is restored.\n"
2525
+ },
2526
+ "attach_to_contexts": {
2527
+ "type": "boolean",
2528
+ "description": "When true, the entity this task's automation produces is added to the run's contexts without becoming the main one. `set_as_primary` implies this: an entity cannot be the primary context without being a context. Contexts are unique by entity id, so a task that re-produces an entity already on the run adds nothing.\n"
2292
2529
  }
2293
2530
  }
2294
2531
  },
@@ -2302,6 +2539,14 @@
2302
2539
  "properties": {
2303
2540
  "agent_config": {
2304
2541
  "$ref": "#/components/schemas/AgentConfig"
2542
+ },
2543
+ "trigger_mode": {
2544
+ "allOf": [
2545
+ {
2546
+ "$ref": "#/components/schemas/TriggerMode"
2547
+ }
2548
+ ],
2549
+ "description": "How the agent run is started. `automatic` starts it as soon as the task becomes current; `manual` waits for a person to run it and to approve the result. An absent value is read as `manual` everywhere: the engine dispatches only an explicit `automatic`, the builder shows the task as manual, and the task may carry the skip gate and required subtasks."
2305
2550
  }
2306
2551
  }
2307
2552
  }
@@ -2453,8 +2698,7 @@
2453
2698
  },
2454
2699
  "allow_parallel_execution": {
2455
2700
  "type": "boolean",
2456
- "description": "When true, all branches with met conditions execute in parallel. When false, only the first branch with a met condition is executed. Defaults to true for backwards compatibility.",
2457
- "default": true
2701
+ "description": "When true, all branches with met conditions execute in parallel. When false, only the first branch with a met condition is executed. The default depends on the trigger mode: automatic decisions treat an absent field as true (backwards compatibility), while manual decisions require an explicit true before multiple branches can be selected at execution time (absent = single-select)."
2458
2702
  },
2459
2703
  "schedule": {
2460
2704
  "anyOf": [
@@ -2527,6 +2771,18 @@
2527
2771
  "$ref": "#/components/schemas/EnableRequirement"
2528
2772
  }
2529
2773
  },
2774
+ "required": {
2775
+ "type": "boolean",
2776
+ "default": false,
2777
+ "description": "When true, the task is required and users cannot skip it while the flow is running. Unrelated to `requirements`, which gate when a task becomes enabled. System-driven skips are unaffected — tasks on a not-taken decision branch, and automation tasks whose automation execution itself reports a skipped verdict (e.g. unmet trigger conditions). Only a manual task, or an automation or AI task whose `trigger_mode` is `manual` or absent, can carry it: on a decision or an automatic kind it is normalised to false on create, update and load."
2778
+ },
2779
+ "subtasks": {
2780
+ "type": "array",
2781
+ "description": "Checklist items from the task's party descriptions, derived by the server from the checklist markup (`ul[__lexicallisttype=\"check\"] > li[data-subtask-id]`, nearest list ancestor) on every create, update and load — a client-supplied array is replaced. Parties are read in the order description, ecp, installer, partner and the first occurrence of an id wins; an id occurring twice in one task is rejected. An item is required only when it is marked `data-subtask-required=\"true\"` in the markup, the task kind has a person action (a manual task, a decision with `trigger_mode: manual`, or an automation or AI task whose `trigger_mode` is `manual` or absent) and it lives in the co-worker or partner description. Required items gate task completion while the flow is running.",
2782
+ "items": {
2783
+ "$ref": "#/components/schemas/Subtask"
2784
+ }
2785
+ },
2530
2786
  "assigned_to": {
2531
2787
  "type": "array",
2532
2788
  "items": {
@@ -2612,6 +2868,71 @@
2612
2868
  "name"
2613
2869
  ]
2614
2870
  },
2871
+ "Stage": {
2872
+ "type": "object",
2873
+ "description": "A customer-facing progress segment layered on top of the flow graph. Unlike phases (internal task grouping), stages exist to communicate progress to outside users (e.g. end customers) with a title and description. Stages form a strict total order; the array order is the boundary order and must match the graph. The first stage's entry node is always the trigger node.",
2874
+ "properties": {
2875
+ "id": {
2876
+ "type": "string",
2877
+ "description": "Stable unique identifier for the stage."
2878
+ },
2879
+ "name": {
2880
+ "type": "string",
2881
+ "description": "User-facing stage title."
2882
+ },
2883
+ "description": {
2884
+ "type": "string",
2885
+ "description": "Customer-facing description of what happens in this stage."
2886
+ },
2887
+ "entry_node_id": {
2888
+ "type": "string",
2889
+ "description": "Id of the graph node (task, phase, or the trigger sentinel) at which this stage begins; its incoming edges form the stage boundary, so no path may reach the node's successors without passing it. The first stage's entry_node_id is the trigger sentinel. Exactly one of entry_node_id / cut_edge_ids per stage; when both are present, cut_edge_ids wins."
2890
+ },
2891
+ "cut_edge_ids": {
2892
+ "type": "array",
2893
+ "items": {
2894
+ "type": "string"
2895
+ },
2896
+ "description": "Edge-cut boundary, for stages that begin inside branching regions: the stage begins where these edges are crossed — one cut edge per branch that continues past the boundary, so that no path crosses it twice and none bypasses it. Branches that end before the boundary need no cut; a run may end in any stage. Cut edges may not be loop edges, end edges, or phase-internal edges. Node membership is derived by counting crossed boundaries, never stored."
2897
+ },
2898
+ "color": {
2899
+ "type": "string",
2900
+ "description": "Optional stage accent color, a key from a fixed palette."
2901
+ },
2902
+ "portal_names": {
2903
+ "type": "object",
2904
+ "description": "Portal-facing overrides of the stage name. Portal surfaces show the matching override instead of `name`; an absent key falls back to `name`.",
2905
+ "properties": {
2906
+ "ecp": {
2907
+ "type": "string",
2908
+ "description": "Stage name shown to end customers."
2909
+ },
2910
+ "installer": {
2911
+ "type": "string",
2912
+ "description": "Stage name shown to installers."
2913
+ }
2914
+ }
2915
+ },
2916
+ "portal_descriptions": {
2917
+ "type": "object",
2918
+ "description": "Portal-facing overrides of the stage description. Portal surfaces show the matching override instead of `description`; an absent key falls back to `description`.",
2919
+ "properties": {
2920
+ "ecp": {
2921
+ "type": "string",
2922
+ "description": "Stage description shown to end customers."
2923
+ },
2924
+ "installer": {
2925
+ "type": "string",
2926
+ "description": "Stage description shown to installers."
2927
+ }
2928
+ }
2929
+ }
2930
+ },
2931
+ "required": [
2932
+ "id",
2933
+ "name"
2934
+ ]
2935
+ },
2615
2936
  "VariableAssignment": {
2616
2937
  "type": "object",
2617
2938
  "description": "Represents a variable assignment with its expression and optional resolved value. Used for dynamic user assignments that get resolved during workflow execution.",
@@ -2652,7 +2973,8 @@
2652
2973
  "type": "string"
2653
2974
  },
2654
2975
  "from_id": {
2655
- "type": "string"
2976
+ "type": "string",
2977
+ "description": "Source node of the edge: a task id, a phase id, the literal `trigger`\n(the primary trigger's entry edge), or an additional trigger's `id`\n(that trigger's own entry edge — allowing the flow to start at a\ndifferent node depending on which trigger fired).\n"
2656
2978
  },
2657
2979
  "to_id": {
2658
2980
  "type": "string",
@@ -2757,8 +3079,11 @@
2757
3079
  "enum": [
2758
3080
  "entity",
2759
3081
  "workflow",
2760
- "journey_block"
2761
- ]
3082
+ "journey_block",
3083
+ "trigger_source",
3084
+ "main_context"
3085
+ ],
3086
+ "description": "`trigger_source` (with origin `trigger`) marks a \"started by\" statement: the run's fired trigger is compared against the configured trigger ids in `values` — no entity attribute is involved.\n`main_context` (with origin `trigger`, no `id`) marks a statement evaluated against the run's PRIMARY context: the fired trigger's entity, re-bound by any completed task that promotes its output to main context (`output_context.set_as_primary`). `schema` carries the subject's schema for attribute selection only — resolution is by the primary flag, never by schema.\n"
2762
3087
  },
2763
3088
  "schema": {
2764
3089
  "type": "string"
@@ -2931,6 +3256,39 @@
2931
3256
  "when"
2932
3257
  ]
2933
3258
  },
3259
+ "Subtask": {
3260
+ "description": "One checklist item of a task, derived from the checklist markup in the party descriptions. Identity is the stable data-subtask-id the editor mints into the markup.",
3261
+ "type": "object",
3262
+ "properties": {
3263
+ "id": {
3264
+ "type": "string",
3265
+ "description": "Stable id, mirrored as data-subtask-id in the description markup"
3266
+ },
3267
+ "name": {
3268
+ "type": "string",
3269
+ "description": "Plain-text snapshot of the checklist item label"
3270
+ },
3271
+ "party": {
3272
+ "type": "string",
3273
+ "description": "Which description field the item lives in",
3274
+ "enum": [
3275
+ "description",
3276
+ "ecp",
3277
+ "installer",
3278
+ "partner"
3279
+ ]
3280
+ },
3281
+ "required": {
3282
+ "type": "boolean",
3283
+ "default": false,
3284
+ "description": "When true, the task cannot be completed while the flow is running until this item is checked"
3285
+ }
3286
+ },
3287
+ "required": [
3288
+ "id",
3289
+ "party"
3290
+ ]
3291
+ },
2934
3292
  "WorkflowDefinition": {
2935
3293
  "type": "object",
2936
3294
  "description": "V1 workflow definition schema. Defines a linear workflow structure with sections\nand steps. Sections group related steps together, and steps represent individual\ntasks that need to be completed. This is the legacy workflow model; for new\nimplementations, consider using V2 flow templates instead.\n",
@@ -3208,13 +3566,169 @@
3208
3566
  "name": {
3209
3567
  "type": "string"
3210
3568
  },
3569
+ "portal_button_label": {
3570
+ "type": "string",
3571
+ "maxLength": 50,
3572
+ "description": "Portal-facing label that replaces the default \"Start now\" button shown for this task's linked journey in the End Customer Portal / Installer Portal. Blank or absent means the portal keeps its own translated default."
3573
+ },
3211
3574
  "complete_task_automatically": {
3212
3575
  "type": "boolean",
3213
3576
  "default": true,
3214
3577
  "description": "If true, the task be auto completed when the journey is completed. By default it is true."
3578
+ },
3579
+ "journey_submission_required": {
3580
+ "type": "boolean",
3581
+ "default": false,
3582
+ "description": "When true, the task cannot be completed while the flow is running until the linked journey was actually submitted. The execution service verifies the submission server-side via the correlation claims in the submission entity's journey_context. Manual tasks only: on any other task kind, or on a manual task with a delayed or relative schedule, the template is rejected (400); when no journey is linked the flag is dropped on create, update and load."
3583
+ },
3584
+ "context_parameters": {
3585
+ "type": "array",
3586
+ "description": "Values preset by the flow author for context parameters the journey declares in its contextSchema (String/Number parameters only, not entity-typed ones). Passed as journey context when the journey is launched from the task, overriding the default value of the parameter (e.g. `origin`).",
3587
+ "items": {
3588
+ "$ref": "#/components/schemas/JourneyContextParameter"
3589
+ }
3590
+ },
3591
+ "ai_prefill": {
3592
+ "$ref": "#/components/schemas/AiPrefillConfig"
3215
3593
  }
3216
3594
  }
3217
3595
  },
3596
+ "AiPrefillConfig": {
3597
+ "type": "object",
3598
+ "description": "AI extraction + prefill configuration for the attached journey (Flows v2 only)",
3599
+ "properties": {
3600
+ "enabled": {
3601
+ "type": "boolean",
3602
+ "default": false
3603
+ },
3604
+ "source": {
3605
+ "type": "object",
3606
+ "properties": {
3607
+ "type": {
3608
+ "type": "string",
3609
+ "enum": [
3610
+ "flow_context"
3611
+ ],
3612
+ "default": "flow_context"
3613
+ },
3614
+ "input_entity": {
3615
+ "type": "string",
3616
+ "enum": [
3617
+ "thread",
3618
+ "first_email",
3619
+ "last_email"
3620
+ ],
3621
+ "default": "last_email"
3622
+ }
3623
+ }
3624
+ },
3625
+ "extraction_fields": {
3626
+ "type": "array",
3627
+ "items": {
3628
+ "$ref": "#/components/schemas/AiPrefillExtractionField"
3629
+ }
3630
+ },
3631
+ "mappings": {
3632
+ "type": "array",
3633
+ "items": {
3634
+ "$ref": "#/components/schemas/AiPrefillMapping"
3635
+ }
3636
+ },
3637
+ "min_confidence": {
3638
+ "type": "number",
3639
+ "minimum": 0,
3640
+ "maximum": 1,
3641
+ "default": 0.8
3642
+ },
3643
+ "instructions": {
3644
+ "type": "string",
3645
+ "maxLength": 2000,
3646
+ "description": "Free-text, cross-field context for the extractor (e.g. \"amounts are always in euros\")"
3647
+ }
3648
+ }
3649
+ },
3650
+ "AiPrefillExtractionField": {
3651
+ "type": "object",
3652
+ "required": [
3653
+ "key",
3654
+ "type"
3655
+ ],
3656
+ "properties": {
3657
+ "key": {
3658
+ "type": "string"
3659
+ },
3660
+ "type": {
3661
+ "type": "string",
3662
+ "enum": [
3663
+ "string",
3664
+ "number",
3665
+ "boolean",
3666
+ "date",
3667
+ "enum"
3668
+ ]
3669
+ },
3670
+ "description": {
3671
+ "type": "string"
3672
+ },
3673
+ "description_overridden": {
3674
+ "type": "boolean",
3675
+ "description": "Set when the author replaced the derived description with their own; the builder preserves flagged descriptions across re-derivations"
3676
+ },
3677
+ "enum": {
3678
+ "type": "array",
3679
+ "items": {
3680
+ "type": "string"
3681
+ }
3682
+ }
3683
+ }
3684
+ },
3685
+ "AiPrefillMapping": {
3686
+ "type": "object",
3687
+ "required": [
3688
+ "source",
3689
+ "block_id",
3690
+ "block_type"
3691
+ ],
3692
+ "properties": {
3693
+ "source": {
3694
+ "type": "string"
3695
+ },
3696
+ "block_id": {
3697
+ "type": "string"
3698
+ },
3699
+ "block_type": {
3700
+ "type": "string",
3701
+ "enum": [
3702
+ "text-input",
3703
+ "number-input",
3704
+ "personal-information",
3705
+ "meter-reading"
3706
+ ]
3707
+ },
3708
+ "block_field": {
3709
+ "type": "string"
3710
+ }
3711
+ }
3712
+ },
3713
+ "JourneyContextParameter": {
3714
+ "type": "object",
3715
+ "properties": {
3716
+ "key": {
3717
+ "type": "string",
3718
+ "maxLength": 100,
3719
+ "description": "The journey context parameter key (paramKey in the journey's contextSchema)"
3720
+ },
3721
+ "value": {
3722
+ "type": "string",
3723
+ "maxLength": 500,
3724
+ "description": "The value to pass for the parameter when launching the journey"
3725
+ }
3726
+ },
3727
+ "required": [
3728
+ "key",
3729
+ "value"
3730
+ ]
3731
+ },
3218
3732
  "ECPDetails": {
3219
3733
  "type": "object",
3220
3734
  "description": "Details regarding ECP for the workflow step",
@@ -3586,6 +4100,166 @@
3586
4100
  "type",
3587
4101
  "condition"
3588
4102
  ]
4103
+ },
4104
+ "JourneyContextUsagesReq": {
4105
+ "type": "object",
4106
+ "description": "Request payload for getJourneyContextUsages.",
4107
+ "required": [
4108
+ "journey_id",
4109
+ "param_keys"
4110
+ ],
4111
+ "properties": {
4112
+ "journey_id": {
4113
+ "type": "string",
4114
+ "description": "Journey whose context parameters are being checked for usage."
4115
+ },
4116
+ "param_keys": {
4117
+ "type": "array",
4118
+ "items": {
4119
+ "type": "string"
4120
+ },
4121
+ "description": "Context parameter keys to look for, as plain strings."
4122
+ },
4123
+ "param_ids": {
4124
+ "type": "array",
4125
+ "items": {
4126
+ "type": "string"
4127
+ },
4128
+ "description": "Accepted and ignored. This service stores context references by name only; the field keeps one request shape across every adapter in this feature."
4129
+ }
4130
+ }
4131
+ },
4132
+ "JourneyContextUsage": {
4133
+ "type": "object",
4134
+ "description": "One place a flow template task presets one of the requested context parameters.",
4135
+ "required": [
4136
+ "kind",
4137
+ "resource",
4138
+ "matched_as"
4139
+ ],
4140
+ "properties": {
4141
+ "kind": {
4142
+ "type": "string",
4143
+ "enum": [
4144
+ "workflow-task"
4145
+ ]
4146
+ },
4147
+ "resource": {
4148
+ "type": "object",
4149
+ "required": [
4150
+ "type",
4151
+ "id"
4152
+ ],
4153
+ "properties": {
4154
+ "type": {
4155
+ "type": "string",
4156
+ "enum": [
4157
+ "workflow_template"
4158
+ ]
4159
+ },
4160
+ "id": {
4161
+ "type": "string",
4162
+ "description": "Flow template id."
4163
+ },
4164
+ "name": {
4165
+ "type": "string",
4166
+ "description": "Flow template name, when the template has one."
4167
+ }
4168
+ }
4169
+ },
4170
+ "location": {
4171
+ "type": "object",
4172
+ "description": "Present only when the matching task carries an id and/or a name.",
4173
+ "properties": {
4174
+ "task_id": {
4175
+ "type": "string"
4176
+ },
4177
+ "task_name": {
4178
+ "type": "string"
4179
+ }
4180
+ }
4181
+ },
4182
+ "matched_as": {
4183
+ "type": "object",
4184
+ "required": [
4185
+ "dialect",
4186
+ "token",
4187
+ "at"
4188
+ ],
4189
+ "properties": {
4190
+ "dialect": {
4191
+ "type": "string",
4192
+ "enum": [
4193
+ "name"
4194
+ ]
4195
+ },
4196
+ "token": {
4197
+ "type": "string",
4198
+ "description": "The bare parameter key, e.g. `origin` — never a `journey_context.origin`-style prefixed token. Unlike every sibling adapter, this service stores the reference structurally in a typed field (`tasks[].journey.context_parameters[].key`), so the prefixed path string never appears in the stored record; `dialect: name` already tells the caller how to interpret `token`."
4199
+ },
4200
+ "at": {
4201
+ "type": "string",
4202
+ "description": "Debugging path into the flow template where the match was found, e.g. `tasks[0].journey.context_parameters[1].key`. Not stable across edits to the template."
4203
+ }
4204
+ }
4205
+ },
4206
+ "link_hint": {
4207
+ "type": "object",
4208
+ "description": "Omitted when the underlying flow template has no id: a link built from an empty id could not resolve, so none is included. The usage row itself is still reported.",
4209
+ "required": [
4210
+ "route",
4211
+ "params"
4212
+ ],
4213
+ "properties": {
4214
+ "route": {
4215
+ "type": "string",
4216
+ "enum": [
4217
+ "workflows-hub-flow"
4218
+ ]
4219
+ },
4220
+ "params": {
4221
+ "type": "object",
4222
+ "required": [
4223
+ "template_id"
4224
+ ],
4225
+ "properties": {
4226
+ "template_id": {
4227
+ "type": "string"
4228
+ }
4229
+ }
4230
+ }
4231
+ }
4232
+ }
4233
+ }
4234
+ },
4235
+ "JourneyContextUsagesResp": {
4236
+ "type": "object",
4237
+ "description": "Response payload for getJourneyContextUsages.",
4238
+ "required": [
4239
+ "usages",
4240
+ "status",
4241
+ "scanned"
4242
+ ],
4243
+ "properties": {
4244
+ "usages": {
4245
+ "type": "array",
4246
+ "items": {
4247
+ "$ref": "#/components/schemas/JourneyContextUsage"
4248
+ }
4249
+ },
4250
+ "status": {
4251
+ "type": "string",
4252
+ "enum": [
4253
+ "ok",
4254
+ "partial"
4255
+ ],
4256
+ "description": "`partial` means the usages list hit its cap and the scan stopped there, before every scannable flow template in the org was examined. `ok` means the scan reached the end of the scannable population and returned every match found there — it does NOT mean every flow template in the org was examined: the underlying query only returns `version = v3` records, so legacy v1/v2 templates never enter the scan, and any record that fails to normalize is silently skipped and logged rather than failing the whole lookup."
4257
+ },
4258
+ "scanned": {
4259
+ "type": "integer",
4260
+ "description": "Count of flow templates examined. This is every scannable flow template in the org, not only templates bound to this journey: the underlying query has no server-side journey filter, so it counts the org's whole scannable flow-template population, up to wherever the scan stopped if `status` is `partial`. \"Scannable\" excludes legacy v1/v2 records (the query filters to `version = v3`) and any record that fails to normalize (skipped and logged rather than failing the lookup), so this can be lower than the org's true total flow-template count."
4261
+ }
4262
+ }
3589
4263
  }
3590
4264
  }
3591
4265
  }