@epilot/sdk 2.20.33 → 2.20.35

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 (153) hide show
  1. package/definitions/event-catalog-runtime.json +1 -1
  2. package/definitions/event-catalog.json +310 -1
  3. package/definitions/integration-toolkit-runtime.json +1 -1
  4. package/definitions/integration-toolkit.json +530 -13
  5. package/definitions/metering.json +19 -8
  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 +6 -6
  19. package/dist/apis/automation.js +1 -1
  20. package/dist/apis/billing.cjs +6 -6
  21. package/dist/apis/billing.js +1 -1
  22. package/dist/apis/blueprint-manifest.cjs +6 -6
  23. package/dist/apis/blueprint-manifest.js +1 -1
  24. package/dist/apis/calendar.cjs +6 -6
  25. package/dist/apis/calendar.js +1 -1
  26. package/dist/apis/chat.cjs +6 -6
  27. package/dist/apis/chat.js +1 -1
  28. package/dist/apis/configuration-hub.cjs +6 -6
  29. package/dist/apis/configuration-hub.js +1 -1
  30. package/dist/apis/consent.cjs +6 -6
  31. package/dist/apis/consent.js +1 -1
  32. package/dist/apis/customer-portal.cjs +6 -6
  33. package/dist/apis/customer-portal.js +1 -1
  34. package/dist/apis/dashboard.cjs +6 -6
  35. package/dist/apis/dashboard.js +1 -1
  36. package/dist/apis/data-governance.cjs +6 -6
  37. package/dist/apis/data-governance.js +1 -1
  38. package/dist/apis/deduplication.cjs +6 -6
  39. package/dist/apis/deduplication.js +1 -1
  40. package/dist/apis/design.cjs +6 -6
  41. package/dist/apis/design.js +1 -1
  42. package/dist/apis/document.cjs +6 -6
  43. package/dist/apis/document.js +1 -1
  44. package/dist/apis/email-settings.cjs +6 -6
  45. package/dist/apis/email-settings.js +1 -1
  46. package/dist/apis/email-template.cjs +6 -6
  47. package/dist/apis/email-template.js +1 -1
  48. package/dist/apis/entity-mapping.cjs +6 -6
  49. package/dist/apis/entity-mapping.js +1 -1
  50. package/dist/apis/entity.cjs +6 -6
  51. package/dist/apis/entity.js +1 -1
  52. package/dist/apis/environments.cjs +6 -6
  53. package/dist/apis/environments.js +1 -1
  54. package/dist/apis/event-catalog.cjs +8 -8
  55. package/dist/apis/event-catalog.d.cts +2 -2
  56. package/dist/apis/event-catalog.d.ts +2 -2
  57. package/dist/apis/event-catalog.js +2 -2
  58. package/dist/apis/file.cjs +6 -6
  59. package/dist/apis/file.js +1 -1
  60. package/dist/apis/iban.cjs +6 -6
  61. package/dist/apis/iban.js +1 -1
  62. package/dist/apis/integration-toolkit.cjs +19 -15
  63. package/dist/apis/integration-toolkit.d.cts +2 -2
  64. package/dist/apis/integration-toolkit.d.ts +2 -2
  65. package/dist/apis/integration-toolkit.js +13 -9
  66. package/dist/apis/journey.cjs +6 -6
  67. package/dist/apis/journey.js +1 -1
  68. package/dist/apis/kanban.cjs +6 -6
  69. package/dist/apis/kanban.js +1 -1
  70. package/dist/apis/message.cjs +6 -6
  71. package/dist/apis/message.js +1 -1
  72. package/dist/apis/metering.cjs +6 -6
  73. package/dist/apis/metering.d.cts +2 -2
  74. package/dist/apis/metering.d.ts +2 -2
  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/pricing-tier.cjs +6 -6
  87. package/dist/apis/pricing-tier.js +1 -1
  88. package/dist/apis/pricing.cjs +6 -6
  89. package/dist/apis/pricing.js +1 -1
  90. package/dist/apis/purpose.cjs +6 -6
  91. package/dist/apis/purpose.js +1 -1
  92. package/dist/apis/query.cjs +6 -6
  93. package/dist/apis/query.js +1 -1
  94. package/dist/apis/sandbox.cjs +6 -6
  95. package/dist/apis/sandbox.js +1 -1
  96. package/dist/apis/sharing.cjs +6 -6
  97. package/dist/apis/sharing.js +1 -1
  98. package/dist/apis/snapshot.cjs +6 -6
  99. package/dist/apis/snapshot.js +1 -1
  100. package/dist/apis/submission.cjs +6 -6
  101. package/dist/apis/submission.js +1 -1
  102. package/dist/apis/target.cjs +6 -6
  103. package/dist/apis/target.js +1 -1
  104. package/dist/apis/targeting.cjs +6 -6
  105. package/dist/apis/targeting.js +1 -1
  106. package/dist/apis/template-variables.cjs +6 -6
  107. package/dist/apis/template-variables.js +1 -1
  108. package/dist/apis/user.cjs +6 -6
  109. package/dist/apis/user.js +1 -1
  110. package/dist/apis/validation-rules.cjs +6 -6
  111. package/dist/apis/validation-rules.js +1 -1
  112. package/dist/apis/webhooks.cjs +6 -6
  113. package/dist/apis/webhooks.js +1 -1
  114. package/dist/apis/workflow-definition.cjs +6 -6
  115. package/dist/apis/workflow-definition.js +1 -1
  116. package/dist/apis/workflow.cjs +6 -6
  117. package/dist/apis/workflow.js +1 -1
  118. package/dist/{chunk-4DTTVPUM.cjs → chunk-4M4Z7BKK.cjs} +1 -1
  119. package/dist/{chunk-WE4C7GER.js → chunk-4OBXBYLK.js} +1 -1
  120. package/dist/chunk-M6G3GHCU.js +14 -0
  121. package/dist/{chunk-YEFQY72W.js → chunk-OXXS3O7X.js} +5 -5
  122. package/dist/{chunk-ZBFAP6AO.cjs → chunk-RE2KDGKQ.cjs} +5 -5
  123. package/dist/chunk-ULV6ZQQR.cjs +14 -0
  124. package/dist/event-catalog-5HHAS7NI.js +7 -0
  125. package/dist/event-catalog-SAH4ZEOO.cjs +7 -0
  126. package/dist/{event-catalog-runtime-XWSYNUGQ.cjs → event-catalog-runtime-2ACQMB22.cjs} +2 -2
  127. package/dist/{event-catalog-runtime-Z6OMHQBD.js → event-catalog-runtime-5IXAZVIB.js} +1 -1
  128. package/dist/{event-catalog.d-CCE1qmBN.d.cts → event-catalog.d-BQqG_LGF.d.cts} +248 -1
  129. package/dist/{event-catalog.d-CCE1qmBN.d.ts → event-catalog.d-BQqG_LGF.d.ts} +248 -1
  130. package/dist/index.cjs +12 -12
  131. package/dist/index.d.cts +3 -3
  132. package/dist/index.d.ts +3 -3
  133. package/dist/index.js +3 -3
  134. package/dist/integration-toolkit-4ADZMNTB.cjs +7 -0
  135. package/dist/integration-toolkit-BCRYMKLW.js +7 -0
  136. package/dist/{integration-toolkit-runtime-TNDJH6HK.js → integration-toolkit-runtime-ABL4FFLI.js} +1 -1
  137. package/dist/{integration-toolkit-runtime-57I2O6DI.cjs → integration-toolkit-runtime-SU7VKZJB.cjs} +2 -2
  138. package/dist/{integration-toolkit.d-CEY26qJu.d.cts → integration-toolkit.d-BQ0Fj-48.d.cts} +274 -25
  139. package/dist/{integration-toolkit.d-CEY26qJu.d.ts → integration-toolkit.d-BQ0Fj-48.d.ts} +274 -25
  140. package/dist/{metering-COO4BTOC.js → metering-SHNCUA4O.js} +1 -1
  141. package/dist/{metering-FJI2AU7Q.cjs → metering-WAVFLJZD.cjs} +1 -1
  142. package/dist/{metering.d-DomHYl06.d.cts → metering.d-BP04w-gR.d.cts} +24 -15
  143. package/dist/{metering.d-DomHYl06.d.ts → metering.d-BP04w-gR.d.ts} +24 -15
  144. package/docs/event-catalog.md +439 -0
  145. package/docs/integration-toolkit.md +113 -8
  146. package/docs/metering.md +4 -4
  147. package/package.json +1 -1
  148. package/dist/chunk-2Q6CNXJ2.cjs +0 -14
  149. package/dist/chunk-LTCN52JS.js +0 -14
  150. package/dist/event-catalog-S4OYTDIB.js +0 -7
  151. package/dist/event-catalog-Z6BO4L2G.cjs +0 -7
  152. package/dist/integration-toolkit-FM53LFD7.cjs +0 -7
  153. package/dist/integration-toolkit-PUA7B6YT.js +0 -7
@@ -2,7 +2,7 @@
2
2
  "openapi": "3.0.3",
3
3
  "info": {
4
4
  "title": "Integration Toolkit API",
5
- "version": "1.33.0",
5
+ "version": "1.35.0",
6
6
  "description": "API for integrating with external systems in a standardised way."
7
7
  },
8
8
  "tags": [
@@ -49,6 +49,7 @@
49
49
  "/v1/erp/tracking/acknowledgement": {
50
50
  "post": {
51
51
  "operationId": "acknowledgeTracking",
52
+ "x-epilot-permissions": [],
52
53
  "summary": "acknowledgeTracking",
53
54
  "description": "Acknowledges an ERP tracking record by removing it from the tracking table, requires public authentication",
54
55
  "tags": [
@@ -106,6 +107,11 @@
106
107
  "/v1/erp/trigger": {
107
108
  "post": {
108
109
  "operationId": "triggerErp",
110
+ "x-epilot-permissions": [
111
+ {
112
+ "action": "entity:view"
113
+ }
114
+ ],
109
115
  "summary": "triggerErp",
110
116
  "description": "Triggers the ERP integration process",
111
117
  "tags": [
@@ -142,6 +148,7 @@
142
148
  "post": {
143
149
  "deprecated": true,
144
150
  "operationId": "processErpUpdatesEvents",
151
+ "x-epilot-permissions": [],
145
152
  "summary": "processErpUpdatesEvents",
146
153
  "description": "Handles updates from ERP systems and tracks them appropriately",
147
154
  "tags": [
@@ -227,6 +234,9 @@
227
234
  "401": {
228
235
  "$ref": "#/components/responses/Unauthorized"
229
236
  },
237
+ "429": {
238
+ "$ref": "#/components/responses/ERPUpdatesRetryableResponse"
239
+ },
230
240
  "500": {
231
241
  "$ref": "#/components/responses/InternalServerError"
232
242
  }
@@ -237,6 +247,7 @@
237
247
  "post": {
238
248
  "deprecated": true,
239
249
  "operationId": "processErpUpdatesEventsV2",
250
+ "x-epilot-permissions": [],
240
251
  "summary": "processErpUpdatesEventsV2",
241
252
  "description": "Handles updates from ERP systems using integration_id directly.\nThis is the v2 version that simplifies the API by accepting integration_id\ninstead of app_id and component_id.\n",
242
253
  "tags": [
@@ -286,6 +297,9 @@
286
297
  "404": {
287
298
  "$ref": "#/components/responses/NotFound"
288
299
  },
300
+ "429": {
301
+ "$ref": "#/components/responses/ERPUpdatesRetryableResponse"
302
+ },
289
303
  "500": {
290
304
  "$ref": "#/components/responses/InternalServerError"
291
305
  }
@@ -295,6 +309,7 @@
295
309
  "/v3/erp/updates/events": {
296
310
  "post": {
297
311
  "operationId": "processErpUpdatesEventsV3",
312
+ "x-epilot-permissions": [],
298
313
  "summary": "processErpUpdatesEventsV3",
299
314
  "description": "Handles updates from ERP systems using integration_id directly.\nThis is the v3 version that removes the unused event_type field and renames object_type to event_name\nto align with the integration UI naming.\n",
300
315
  "tags": [
@@ -342,6 +357,9 @@
342
357
  "404": {
343
358
  "$ref": "#/components/responses/NotFound"
344
359
  },
360
+ "429": {
361
+ "$ref": "#/components/responses/ERPUpdatesRetryableResponse"
362
+ },
345
363
  "500": {
346
364
  "$ref": "#/components/responses/InternalServerError"
347
365
  }
@@ -351,6 +369,7 @@
351
369
  "/v2/erp/updates/mapping_simulation": {
352
370
  "post": {
353
371
  "operationId": "simulateMappingV2",
372
+ "x-epilot-permissions": [],
354
373
  "summary": "simulateMappingV2",
355
374
  "description": "Test v2.0 mapping configuration by transforming a payload using the provided mapping rules without persisting data.\n\nThis endpoint accepts the same configuration format that is stored in the integration use case resource,\nmaking it easier to test configurations before saving them to a use case.\n\nSee documentation at /docs/MAPPING_V2.md for detailed v2.0 format specification.\n",
356
375
  "tags": [
@@ -622,6 +641,7 @@
622
641
  "/v1/erp/updates/direct_simulation": {
623
642
  "post": {
624
643
  "operationId": "simulateDirect",
644
+ "x-epilot-permissions": [],
625
645
  "summary": "simulateDirect",
626
646
  "description": "Dry run for direct-mode payloads: validates a `DirectPayload` against a `direct: true`\nuse case configuration and previews the internal entity and meter reading updates the\npipeline would apply — without persisting anything.\n\nUnlike the ingest endpoint, validation does not stop at the first problem: ALL issues\nacross all operations are collected into `errors`, each carrying the index of the\noperation it refers to. When the payload is valid, the response additionally contains\nthe translated update previews plus non-blocking `warnings` (for example unique-id\nfields that are not defined in the target entity schema, or a failed server-side\nunique-id type derivation).\n\nUse this endpoint while designing a direct integration, before sending events to\n`POST /v3/erp/updates/events`. See documentation at /docs/DIRECT_MODE.md.\n",
627
647
  "tags": [
@@ -783,6 +803,7 @@
783
803
  "/v1/erp/updates/mapping_simulation": {
784
804
  "post": {
785
805
  "operationId": "simulateMapping",
806
+ "x-epilot-permissions": [],
786
807
  "summary": "simulateMapping",
787
808
  "description": "Test mapping configuration by transforming a payload using the provided mapping rules without persisting data.\n\nSupports both v1.0 (object-based) and v2.0 (event-based) mapping formats.\nSee documentation at /docs/MAPPING_V2.md for detailed v2.0 format specification.\n",
788
809
  "tags": [
@@ -1116,6 +1137,11 @@
1116
1137
  "/v1/integrations": {
1117
1138
  "get": {
1118
1139
  "operationId": "listIntegrations",
1140
+ "x-epilot-permissions": [
1141
+ {
1142
+ "action": "integration:view"
1143
+ }
1144
+ ],
1119
1145
  "summary": "listIntegrations",
1120
1146
  "description": "Retrieve all integrations for the authenticated organization",
1121
1147
  "tags": [
@@ -1153,6 +1179,11 @@
1153
1179
  },
1154
1180
  "post": {
1155
1181
  "operationId": "createIntegration",
1182
+ "x-epilot-permissions": [
1183
+ {
1184
+ "action": "integration:manage"
1185
+ }
1186
+ ],
1156
1187
  "summary": "createIntegration",
1157
1188
  "description": "Create a new integration configuration",
1158
1189
  "tags": [
@@ -1194,6 +1225,11 @@
1194
1225
  "/v1/integrations/{integrationId}": {
1195
1226
  "get": {
1196
1227
  "operationId": "getIntegration",
1228
+ "x-epilot-permissions": [
1229
+ {
1230
+ "action": "integration:view"
1231
+ }
1232
+ ],
1197
1233
  "summary": "getIntegration",
1198
1234
  "description": "Retrieve a specific integration by its ID",
1199
1235
  "tags": [
@@ -1235,6 +1271,11 @@
1235
1271
  },
1236
1272
  "put": {
1237
1273
  "operationId": "updateIntegration",
1274
+ "x-epilot-permissions": [
1275
+ {
1276
+ "action": "integration:manage"
1277
+ }
1278
+ ],
1238
1279
  "summary": "updateIntegration",
1239
1280
  "description": "Update an existing integration configuration",
1240
1281
  "tags": [
@@ -1289,6 +1330,11 @@
1289
1330
  },
1290
1331
  "delete": {
1291
1332
  "operationId": "deleteIntegration",
1333
+ "x-epilot-permissions": [
1334
+ {
1335
+ "action": "integration:manage"
1336
+ }
1337
+ ],
1292
1338
  "summary": "deleteIntegration",
1293
1339
  "description": "Delete an integration and all its use cases",
1294
1340
  "tags": [
@@ -1337,6 +1383,11 @@
1337
1383
  "/v1/integrations/{integrationId}/events": {
1338
1384
  "post": {
1339
1385
  "operationId": "queryEvents",
1386
+ "x-epilot-permissions": [
1387
+ {
1388
+ "action": "integration:view"
1389
+ }
1390
+ ],
1340
1391
  "summary": "queryEvents",
1341
1392
  "description": "Query events for a specific integration",
1342
1393
  "tags": [
@@ -1386,6 +1437,11 @@
1386
1437
  "/v1/integrations/{integrationId}/events/replay": {
1387
1438
  "post": {
1388
1439
  "operationId": "replayEvents",
1440
+ "x-epilot-permissions": [
1441
+ {
1442
+ "action": "integration:manage"
1443
+ }
1444
+ ],
1389
1445
  "summary": "replayEvents",
1390
1446
  "description": "Replay one or more events for a specific integration. Events will be re-processed with their original payloads but with a new correlation ID for traceability.",
1391
1447
  "tags": [
@@ -1435,6 +1491,11 @@
1435
1491
  "/v1/integrations/{integrationId}/use-cases": {
1436
1492
  "get": {
1437
1493
  "operationId": "listUseCases",
1494
+ "x-epilot-permissions": [
1495
+ {
1496
+ "action": "integration:view"
1497
+ }
1498
+ ],
1438
1499
  "summary": "listUseCases",
1439
1500
  "description": "Retrieve all use cases for a specific integration",
1440
1501
  "tags": [
@@ -1484,6 +1545,11 @@
1484
1545
  },
1485
1546
  "post": {
1486
1547
  "operationId": "createUseCase",
1548
+ "x-epilot-permissions": [
1549
+ {
1550
+ "action": "integration:manage"
1551
+ }
1552
+ ],
1487
1553
  "summary": "createUseCase",
1488
1554
  "description": "Create a new use case for an integration",
1489
1555
  "tags": [
@@ -1540,6 +1606,11 @@
1540
1606
  "/v1/integrations/{integrationId}/use-cases/{useCaseId}": {
1541
1607
  "get": {
1542
1608
  "operationId": "getUseCase",
1609
+ "x-epilot-permissions": [
1610
+ {
1611
+ "action": "integration:view"
1612
+ }
1613
+ ],
1543
1614
  "summary": "getUseCase",
1544
1615
  "description": "Retrieve a specific use case by its ID",
1545
1616
  "tags": [
@@ -1591,6 +1662,11 @@
1591
1662
  },
1592
1663
  "put": {
1593
1664
  "operationId": "updateUseCase",
1665
+ "x-epilot-permissions": [
1666
+ {
1667
+ "action": "integration:manage"
1668
+ }
1669
+ ],
1594
1670
  "summary": "updateUseCase",
1595
1671
  "description": "Update an existing use case configuration",
1596
1672
  "tags": [
@@ -1655,6 +1731,11 @@
1655
1731
  },
1656
1732
  "delete": {
1657
1733
  "operationId": "deleteUseCase",
1734
+ "x-epilot-permissions": [
1735
+ {
1736
+ "action": "integration:manage"
1737
+ }
1738
+ ],
1658
1739
  "summary": "deleteUseCase",
1659
1740
  "description": "Delete a use case from an integration",
1660
1741
  "tags": [
@@ -1713,6 +1794,11 @@
1713
1794
  "/v1/integrations/{integrationId}/use-cases/{useCaseId}/history": {
1714
1795
  "get": {
1715
1796
  "operationId": "listUseCaseHistory",
1797
+ "x-epilot-permissions": [
1798
+ {
1799
+ "action": "integration:view"
1800
+ }
1801
+ ],
1716
1802
  "summary": "listUseCaseHistory",
1717
1803
  "description": "Retrieve historical versions of a use case's configuration.\nHistory entries are returned in reverse chronological order (newest first).\nUse the 'cursor' parameter for pagination to fetch additional entries.\n",
1718
1804
  "tags": [
@@ -1792,6 +1878,11 @@
1792
1878
  "/v1/integrations/{integrationId}/documentation": {
1793
1879
  "get": {
1794
1880
  "operationId": "listDocumentationPages",
1881
+ "x-epilot-permissions": [
1882
+ {
1883
+ "action": "integration:view"
1884
+ }
1885
+ ],
1795
1886
  "summary": "listDocumentationPages",
1796
1887
  "description": "Retrieve all documentation pages of an integration, without their markdown content.\nAn integration has at most one general page plus at most one page per use case.\nThe page id is 'general' for the integration-wide page, otherwise the use case ID.\n",
1797
1888
  "tags": [
@@ -1846,6 +1937,11 @@
1846
1937
  "/v1/integrations/{integrationId}/documentation/{docId}": {
1847
1938
  "get": {
1848
1939
  "operationId": "getDocumentationPage",
1940
+ "x-epilot-permissions": [
1941
+ {
1942
+ "action": "integration:view"
1943
+ }
1944
+ ],
1849
1945
  "summary": "getDocumentationPage",
1850
1946
  "description": "Retrieve a single documentation page including its markdown content",
1851
1947
  "tags": [
@@ -1897,6 +1993,11 @@
1897
1993
  },
1898
1994
  "put": {
1899
1995
  "operationId": "upsertDocumentationPage",
1996
+ "x-epilot-permissions": [
1997
+ {
1998
+ "action": "integration:manage"
1999
+ }
2000
+ ],
1900
2001
  "summary": "upsertDocumentationPage",
1901
2002
  "description": "Create or update the documentation page identified by docId.\nUpsert semantics enforce the invariant of one general page per\nintegration and one page per use case. For use case pages the\nuse case must exist.\n",
1902
2003
  "tags": [
@@ -1964,6 +2065,11 @@
1964
2065
  },
1965
2066
  "delete": {
1966
2067
  "operationId": "deleteDocumentationPage",
2068
+ "x-epilot-permissions": [
2069
+ {
2070
+ "action": "integration:manage"
2071
+ }
2072
+ ],
1967
2073
  "summary": "deleteDocumentationPage",
1968
2074
  "description": "Delete a documentation page",
1969
2075
  "tags": [
@@ -2025,6 +2131,11 @@
2025
2131
  "/v2/integrations": {
2026
2132
  "get": {
2027
2133
  "operationId": "listIntegrationsV2",
2134
+ "x-epilot-permissions": [
2135
+ {
2136
+ "action": "integration:view"
2137
+ }
2138
+ ],
2028
2139
  "summary": "listIntegrationsV2",
2029
2140
  "description": "Retrieve all integrations with embedded use cases for the authenticated organization",
2030
2141
  "tags": [
@@ -2062,6 +2173,11 @@
2062
2173
  },
2063
2174
  "post": {
2064
2175
  "operationId": "createIntegrationV2",
2176
+ "x-epilot-permissions": [
2177
+ {
2178
+ "action": "integration:manage"
2179
+ }
2180
+ ],
2065
2181
  "summary": "createIntegrationV2",
2066
2182
  "description": "Create a new integration with embedded use cases.\n",
2067
2183
  "tags": [
@@ -2103,6 +2219,11 @@
2103
2219
  "/v2/integrations/{integrationId}": {
2104
2220
  "get": {
2105
2221
  "operationId": "getIntegrationV2",
2222
+ "x-epilot-permissions": [
2223
+ {
2224
+ "action": "integration:view"
2225
+ }
2226
+ ],
2106
2227
  "summary": "getIntegrationV2",
2107
2228
  "description": "Retrieve a specific integration with all its embedded use cases",
2108
2229
  "tags": [
@@ -2144,6 +2265,11 @@
2144
2265
  },
2145
2266
  "put": {
2146
2267
  "operationId": "updateIntegrationV2",
2268
+ "x-epilot-permissions": [
2269
+ {
2270
+ "action": "integration:manage"
2271
+ }
2272
+ ],
2147
2273
  "summary": "updateIntegrationV2",
2148
2274
  "description": "Update an existing integration with embedded use cases.\nThe integration must already exist.\nUse cases are updated declaratively:\n- Use cases in the request with matching IDs are updated\n- Use cases in the request without matching IDs are created\n- Existing use cases not in the request are deleted\n",
2149
2275
  "tags": [
@@ -2198,6 +2324,11 @@
2198
2324
  },
2199
2325
  "delete": {
2200
2326
  "operationId": "deleteIntegrationV2",
2327
+ "x-epilot-permissions": [
2328
+ {
2329
+ "action": "integration:manage"
2330
+ }
2331
+ ],
2201
2332
  "summary": "deleteIntegrationV2",
2202
2333
  "description": "Delete an integration and all its use cases",
2203
2334
  "tags": [
@@ -2246,6 +2377,11 @@
2246
2377
  "/v2/integrations/{integrationId}/notifications/history": {
2247
2378
  "get": {
2248
2379
  "operationId": "listNotificationHistory",
2380
+ "x-epilot-permissions": [
2381
+ {
2382
+ "action": "integration:view"
2383
+ }
2384
+ ],
2249
2385
  "summary": "listNotificationHistory",
2250
2386
  "description": "Returns the cursor-paginated, newest-first notification history for an\nintegration (every real notification decision — both fired and suppressed).\nRequires the `integration:view` permission on the integration's organization.\n",
2251
2387
  "tags": [
@@ -2329,6 +2465,11 @@
2329
2465
  "/v2/integrations/{integrationId}/notifications/test": {
2330
2466
  "post": {
2331
2467
  "operationId": "testSendNotification",
2468
+ "x-epilot-permissions": [
2469
+ {
2470
+ "action": "integration:manage"
2471
+ }
2472
+ ],
2332
2473
  "summary": "testSendNotification",
2333
2474
  "description": "Renders and sends ONE representative notification of the requested kind/type to\nthe CALLING USER ONLY (never any other recipient), so an operator can preview how\na notification looks. A test send does NOT write to the notification history.\nRequires the `integration:manage` permission on the integration's organization.\n",
2334
2475
  "tags": [
@@ -2403,6 +2544,11 @@
2403
2544
  "/v2/integrations/{integrationId}/notifications/status": {
2404
2545
  "get": {
2405
2546
  "operationId": "getNotificationStatus",
2547
+ "x-epilot-permissions": [
2548
+ {
2549
+ "action": "integration:view"
2550
+ }
2551
+ ],
2406
2552
  "summary": "getNotificationStatus",
2407
2553
  "description": "Returns the live per-rule alert state and (for 'auto' rules) the current\nhour-of-week baseline band for an integration's notification monitoring.\nReflects the latest 5-minute sweep — near-real-time, not live.\nRequires the `integration:view` permission on the integration's organization.\n",
2408
2554
  "tags": [
@@ -2469,6 +2615,7 @@
2469
2615
  "/v2/integrations/{integrationId}/use-cases/{useCaseId}/secure-proxy-whitelist": {
2470
2616
  "get": {
2471
2617
  "operationId": "getSecureProxyWhitelist",
2618
+ "x-epilot-permissions": [],
2472
2619
  "summary": "getSecureProxyWhitelist",
2473
2620
  "description": "Returns the current allowed_domains, allowed_ips, and vpc_mode for a secure_proxy use case.\nStaff-only — gated by internal-auth issuer AND admin-portal Cognito user pool membership.\nRejects Login-As tokens.\n",
2474
2621
  "tags": [
@@ -2529,6 +2676,7 @@
2529
2676
  },
2530
2677
  "put": {
2531
2678
  "operationId": "updateSecureProxyWhitelist",
2679
+ "x-epilot-permissions": [],
2532
2680
  "summary": "updateSecureProxyWhitelist",
2533
2681
  "description": "Replaces allowed_domains and/or allowed_ips on a secure_proxy use case.\nAt least one of the two fields is required. Validation mirrors the CLI's\n`validateDomainPatterns` / `validateCidrs`. Writes a USECASE_HISTORY row\nwith the admin user's email as `changed_by`.\n\nUpdate semantics per field:\n - **omitted** — field is not modified; the stored value is preserved.\n - **non-empty array** — the stored value is replaced with the supplied list.\n - **empty array (`[]`)** — the list is cleared (stored as `[]`). This is\n the canonical way to remove all entries. `null` is not accepted.\n\nStaff-only — same auth gates as GET.\n",
2534
2682
  "tags": [
@@ -2601,6 +2749,7 @@
2601
2749
  "/v2/integrations/{integrationId}/use-cases/{useCaseId}/secure-proxy-whitelist/history": {
2602
2750
  "get": {
2603
2751
  "operationId": "listSecureProxyWhitelistHistory",
2752
+ "x-epilot-permissions": [],
2604
2753
  "summary": "listSecureProxyWhitelistHistory",
2605
2754
  "description": "Returns the most recent USECASE_HISTORY entries for a secure_proxy use case,\nin reverse chronological order (newest first). Each entry includes the\nactor email (`changed_by`), the ISO-8601 timestamp (`history_created_at`),\nthe `change_description` (free-text action), and the full `configuration`\nsnapshot — from which UI-08 computes a before/after diff between consecutive\nentries.\n\nStaff-only — gated by internal-auth issuer AND admin-portal Cognito user pool\nmembership. Rejects Login-As tokens (same auth gate as the GET / PUT\nsecure-proxy-whitelist operations).\n\nThin wrapper over the service-layer `listUseCaseHistory` that powers\n`GET /v1/integrations/{integrationId}/use-cases/{useCaseId}/history` — the\nseparate path exists because the /v1 variant is tenant-gated and admin-portal\ninternal-auth tokens do not carry tenant permissions.\n",
2606
2755
  "tags": [
@@ -2690,6 +2839,11 @@
2690
2839
  "/v1/integrations/{integrationId}/app-mapping": {
2691
2840
  "put": {
2692
2841
  "operationId": "setIntegrationAppMapping",
2842
+ "x-epilot-permissions": [
2843
+ {
2844
+ "action": "integration:manage"
2845
+ }
2846
+ ],
2693
2847
  "summary": "setIntegrationAppMapping",
2694
2848
  "description": "Creates or updates a mapping from an app/component to an integration.\nThis allows ERP updates sent via app_id and component_id to be associated\nwith a specific integration configuration.\n",
2695
2849
  "tags": [
@@ -2754,6 +2908,11 @@
2754
2908
  },
2755
2909
  "delete": {
2756
2910
  "operationId": "deleteIntegrationAppMapping",
2911
+ "x-epilot-permissions": [
2912
+ {
2913
+ "action": "integration:manage"
2914
+ }
2915
+ ],
2757
2916
  "summary": "deleteIntegrationAppMapping",
2758
2917
  "description": "Removes a mapping from an app/component to an integration.\n",
2759
2918
  "tags": [
@@ -2815,6 +2974,7 @@
2815
2974
  "/v1/integrations/{integrationId}/monitoring/inbound-events": {
2816
2975
  "post": {
2817
2976
  "operationId": "queryInboundMonitoringEvents",
2977
+ "x-epilot-permissions": [],
2818
2978
  "summary": "queryInboundMonitoringEvents",
2819
2979
  "description": "Query inbound monitoring events for a specific integration.\nReturns detailed information about inbound sync events from ERP systems,\nincluding success rates, error breakdowns, and processing metrics.\n",
2820
2980
  "tags": [
@@ -2865,6 +3025,7 @@
2865
3025
  "/v1/integrations/{integrationId}/monitoring/stats": {
2866
3026
  "post": {
2867
3027
  "operationId": "getMonitoringStats",
3028
+ "x-epilot-permissions": [],
2868
3029
  "summary": "getMonitoringStats",
2869
3030
  "description": "Get aggregated statistics for both inbound and outbound monitoring events for a specific integration.\nReturns summary metrics for inbound (ERP sync) and outbound (webhook delivery) events,\nincluding success/error counts and optional breakdowns.\n",
2870
3031
  "tags": [
@@ -2915,6 +3076,7 @@
2915
3076
  "/v1/integrations/{integrationId}/monitoring/timeseries": {
2916
3077
  "post": {
2917
3078
  "operationId": "getMonitoringTimeSeries",
3079
+ "x-epilot-permissions": [],
2918
3080
  "summary": "getMonitoringTimeSeries",
2919
3081
  "description": "Get time-series aggregated event counts for monitoring charts.\nReturns pre-bucketed counts at configurable intervals for both inbound and outbound events.\nMaximum of 200 buckets per request. Returns 400 if the time range and interval would exceed this limit.\n",
2920
3082
  "tags": [
@@ -2965,6 +3127,7 @@
2965
3127
  "/v1/integrations/{integrationId}/outbound-status": {
2966
3128
  "get": {
2967
3129
  "operationId": "getOutboundStatus",
3130
+ "x-epilot-permissions": [],
2968
3131
  "summary": "getOutboundStatus",
2969
3132
  "description": "Get the status of all outbound use cases for a specific integration.\nReturns conflict information when events or webhooks are disabled but the use case is enabled.\n",
2970
3133
  "tags": [
@@ -3008,6 +3171,7 @@
3008
3171
  "/v1/integrations/entities/{entityId}/sync-status": {
3009
3172
  "get": {
3010
3173
  "operationId": "getEntitySyncStatus",
3174
+ "x-epilot-permissions": [],
3011
3175
  "summary": "getEntitySyncStatus",
3012
3176
  "description": "Get the inbound ERP sync status of an entity: when each integration last\nsynchronized (checked) the entity against the ERP, and when it last\nactually changed it. `last_synced_at` also advances on no-op checks —\nevents that were received and evaluated but changed nothing — which by\ndesign leave no trace on the entity itself (no activity feed entry, no\n`_updated_at` bump). Use it to tell whether an entity is up to date with\nthe ERP. Returns an empty list for entities no inbound use case has\nprocessed. Org-scoped via the caller's token.\n\nDeprecated alias: `GET /v1/entities/{entityId}/sync-status` is still\nserved (rewritten to this path in the API handler) but will be removed —\nmigrate callers to this path.\n",
3013
3177
  "tags": [
@@ -3061,8 +3225,14 @@
3061
3225
  "/v1/integrations/{integrationId}/outbound/messages/poll": {
3062
3226
  "post": {
3063
3227
  "operationId": "pollOutboundMessages",
3228
+ "x-epilot-permissions": [
3229
+ {
3230
+ "action": "integration:consume",
3231
+ "resource": "integration:{integrationId}"
3232
+ }
3233
+ ],
3064
3234
  "summary": "pollOutboundMessages",
3065
- "description": "Poll outbound messages for an integration's poll-mode use cases.\nTakes a lease on the head-of-line batch of the integration's FIFO stream:\nthe returned messages stay invisible to subsequent polls until they are\nacknowledged or the visibility timeout elapses. POST because taking a\nlease mutates server state — auto-retrying middleware must not burn\nleases. One in-flight batch per stream: while a lease is active (or\nanother poll wins the race), the response is an empty batch\n(`messages: []`), not an error. Requires the `integration:consume` grant.\n",
3235
+ "description": "Poll outbound messages for an integration's poll-mode use cases.\nTakes a lease on the head-of-line batch of the integration's FIFO stream:\nthe returned messages stay invisible to subsequent polls until they are\nacknowledged or the visibility timeout elapses. POST because taking a\nlease mutates server state — auto-retrying middleware must not burn\nleases. One in-flight batch per stream: while a lease is active (or\nanother poll wins the race), the response is an empty batch\n(`messages: []`), not an error. Each message's `payload` is the\nuse case's JSONata transformation of the event when it has one\n(`mapping_version` identifies the transform), otherwise the raw\nevent. Requires the `integration:consume` grant.\n\nOrdering: messages are delivered in stream order, which follows the\nevent time. An event that arrives after the consumer was already handed\nevents with a later event time is not inserted behind them (it would\nnever be delivered); it is appended at the end of the stream and a\n`MSG_LATE_ARRIVAL` warning is recorded. Delivery is at-least-once: a\nmessage whose lease expires is delivered again, and in rare races the\nsame event can be delivered twice under different message ids, so\nconsumers should deduplicate by `event_id`.\n",
3066
3236
  "tags": [
3067
3237
  "integrations"
3068
3238
  ],
@@ -3125,6 +3295,12 @@
3125
3295
  "/v1/integrations/{integrationId}/outbound/messages/ack": {
3126
3296
  "post": {
3127
3297
  "operationId": "ackOutboundMessages",
3298
+ "x-epilot-permissions": [
3299
+ {
3300
+ "action": "integration:consume",
3301
+ "resource": "integration:{integrationId}"
3302
+ }
3303
+ ],
3128
3304
  "summary": "ackOutboundMessages",
3129
3305
  "description": "Acknowledge polled outbound messages. Acks are validated against the\nactive lease and committed as a prefix-contiguous cursor advance:\nmessages must be acknowledged in stream order. Out-of-order acks past\nthe first gap are rejected per id (`out_of_order`), acks with an\noutdated lease token are rejected (`stale_lease`), and unknown ids are\nrejected (`not_found`). Acknowledged messages are never delivered\nagain. Requires the `integration:consume` grant.\n",
3130
3306
  "tags": [
@@ -3189,6 +3365,12 @@
3189
3365
  "/v1/integrations/{integrationId}/outbound/messages/dlq": {
3190
3366
  "get": {
3191
3367
  "operationId": "listOutboundDlqMessages",
3368
+ "x-epilot-permissions": [
3369
+ {
3370
+ "action": "integration:manage",
3371
+ "resource": "integration:{integrationId}"
3372
+ }
3373
+ ],
3192
3374
  "summary": "listOutboundDlqMessages",
3193
3375
  "description": "List an integration's dead-lettered outbound queue messages\n(poison_policy enforcement and operator skips move messages here).\nOperator endpoint — requires the `integration:manage` grant. Message\npayloads are NOT included in listings: entries are keyed by the\nopaque message id and carry delivery metadata only. Paginated via an\nopaque `next_token`.\n",
3194
3376
  "tags": [
@@ -3264,8 +3446,14 @@
3264
3446
  "/v1/integrations/{integrationId}/outbound/messages/dlq/redrive": {
3265
3447
  "post": {
3266
3448
  "operationId": "redriveOutboundDlqMessages",
3449
+ "x-epilot-permissions": [
3450
+ {
3451
+ "action": "integration:manage",
3452
+ "resource": "integration:{integrationId}"
3453
+ }
3454
+ ],
3267
3455
  "summary": "redriveOutboundDlqMessages",
3268
- "description": "Redrive selected dead-lettered messages back into the live stream.\nOperator endpoint — requires the `integration:manage` grant.\nA redriven message is re-enqueued at the tail with a new id and\nsequence — it is delivered out of its original per-entity order (the\nstream has moved on); this is inherent to redrive and matches SQS DLQ\nsemantics. The redriven copy starts with zero delivery attempts and a\nfresh retention window; the original DLQ entry is removed. Per-id\nresults report `redriven` or `not_found` (unknown ids, or entries\nconcurrently redriven/expired).\n",
3456
+ "description": "Redrive selected dead-lettered messages back into the live stream.\nOperator endpoint — requires the `integration:manage` grant.\nA redriven message is re-enqueued at the tail with a new id and\nsequence — it is delivered out of its original per-entity order (the\nstream has moved on); this is inherent to redrive and matches SQS DLQ\nsemantics. The redriven copy starts with zero delivery attempts and a\nfresh retention window; the original DLQ entry is removed.\nWith `reapply_mapping`, the raw event is re-mapped with the use case's\ncurrent `jsonata_expression`; entries whose mapping failed are always\nre-mapped. Per-id results report `redriven`, `not_found` (unknown ids,\nor entries concurrently redriven/expired) or `mapping_failed` (the\nre-mapping failed again and the entry stays in the DLQ).\n",
3269
3457
  "tags": [
3270
3458
  "integrations"
3271
3459
  ],
@@ -3328,8 +3516,14 @@
3328
3516
  "/v1/integrations/{integrationId}/outbound/messages/unblock": {
3329
3517
  "post": {
3330
3518
  "operationId": "unblockOutboundStream",
3519
+ "x-epilot-permissions": [
3520
+ {
3521
+ "action": "integration:manage",
3522
+ "resource": "integration:{integrationId}"
3523
+ }
3524
+ ],
3331
3525
  "summary": "unblockOutboundStream",
3332
- "description": "Unblock an integration's outbound stream halted by the `block`\npoison policy: skips (dead-letters) the current blocked head message,\nemitting MSG_DEAD_LETTERED and letting the next message become the\nhead. Operator endpoint — requires the `integration:manage` grant.\nReturns `unblocked: false` as a no-op when the stream is not\ncurrently blocked (or the state moved concurrently) — safe to retry.\n",
3526
+ "description": "Unblock an integration's outbound stream halted by the `block`\npoison policy: skips (dead-letters) the current blocked head message,\nemitting MSG_DEAD_LETTERED and letting the next message become the\nhead. A head blocked because its `jsonata_expression` failed at\nenqueue is skipped the same way (its DLQ reason defaults to\n`mapping_failed`); fix the expression, then redrive the entry to\nre-map it. Operator endpoint — requires the `integration:manage` grant.\nReturns `unblocked: false` as a no-op when the stream is not\ncurrently blocked (or the state moved concurrently) — safe to retry.\n",
3333
3527
  "tags": [
3334
3528
  "integrations"
3335
3529
  ],
@@ -3389,9 +3583,80 @@
3389
3583
  }
3390
3584
  }
3391
3585
  },
3586
+ "/v1/integrations/{integrationId}/outbound/mapping-simulation": {
3587
+ "post": {
3588
+ "operationId": "simulateOutboundMapping",
3589
+ "x-epilot-permissions": [
3590
+ {
3591
+ "action": "integration:view",
3592
+ "resource": "integration:{integrationId}"
3593
+ }
3594
+ ],
3595
+ "summary": "simulateOutboundMapping",
3596
+ "description": "Preview a poll delivery's `jsonata_expression` without saving or\nenqueueing anything. The expression is checked and evaluated exactly\nas at enqueue time: the same length, syntax and binding checks, the\nsame `$env`/`$mapValue`/`$mapKey` bindings resolved server-side from\nthe org's non-secret environment variables and key/value maps, the\nsame evaluation limits, and the same rule that the output must be a\nJSON object.\n\nProvide exactly one input: `payload` (an event to map as-is), or\n`event_id` (with `event_catalog_event`) to load a historical\nevent-catalog event and hydrate it exactly as enqueue does — the\npreview is then exact, and the hydrated event is echoed as `input`.\n\nMapping failures are a `200` with `valid: false` and an `error`;\n`4xx` is reserved for malformed requests. Requires the\n`integration:view` grant.\n",
3597
+ "tags": [
3598
+ "integrations"
3599
+ ],
3600
+ "security": [
3601
+ {
3602
+ "EpilotAuth": []
3603
+ }
3604
+ ],
3605
+ "parameters": [
3606
+ {
3607
+ "name": "integrationId",
3608
+ "in": "path",
3609
+ "required": true,
3610
+ "description": "The integration ID",
3611
+ "schema": {
3612
+ "type": "string",
3613
+ "format": "uuid"
3614
+ }
3615
+ }
3616
+ ],
3617
+ "requestBody": {
3618
+ "required": true,
3619
+ "content": {
3620
+ "application/json": {
3621
+ "schema": {
3622
+ "$ref": "#/components/schemas/SimulateOutboundMappingRequest"
3623
+ }
3624
+ }
3625
+ }
3626
+ },
3627
+ "responses": {
3628
+ "200": {
3629
+ "description": "Simulation outcome (mapping failures included)",
3630
+ "content": {
3631
+ "application/json": {
3632
+ "schema": {
3633
+ "$ref": "#/components/schemas/SimulateOutboundMappingResponse"
3634
+ }
3635
+ }
3636
+ }
3637
+ },
3638
+ "400": {
3639
+ "$ref": "#/components/responses/BadRequest"
3640
+ },
3641
+ "401": {
3642
+ "$ref": "#/components/responses/Unauthorized"
3643
+ },
3644
+ "403": {
3645
+ "$ref": "#/components/responses/Forbidden"
3646
+ },
3647
+ "404": {
3648
+ "$ref": "#/components/responses/NotFound"
3649
+ },
3650
+ "500": {
3651
+ "$ref": "#/components/responses/InternalServerError"
3652
+ }
3653
+ }
3654
+ }
3655
+ },
3392
3656
  "/v1/integrations/{integrationId}/monitoring/access-logs": {
3393
3657
  "post": {
3394
3658
  "operationId": "queryAccessLogs",
3659
+ "x-epilot-permissions": [],
3395
3660
  "summary": "queryAccessLogs",
3396
3661
  "description": "Query API access logs for a specific integration's organization.\nReturns access token usage analytics filtered by user_id (access token).\nSupports infinite scroll pagination with cursor-based navigation.\n",
3397
3662
  "tags": [
@@ -3442,6 +3707,7 @@
3442
3707
  "/v1/integrations/{integrationId}/monitoring/outbound-events": {
3443
3708
  "post": {
3444
3709
  "operationId": "queryOutboundMonitoringEvents",
3710
+ "x-epilot-permissions": [],
3445
3711
  "summary": "queryOutboundMonitoringEvents",
3446
3712
  "description": "Query outbound monitoring events for a specific integration.\nReturns detailed information about outbound event deliveries,\nfiltered by event_name (event_catalog_event) linked to the integration's outbound use cases.\n",
3447
3713
  "tags": [
@@ -3492,6 +3758,7 @@
3492
3758
  "/v2/integrations/{integrationId}/monitoring/events": {
3493
3759
  "post": {
3494
3760
  "operationId": "queryMonitoringEventsV2",
3761
+ "x-epilot-permissions": [],
3495
3762
  "summary": "queryMonitoringEventsV2",
3496
3763
  "description": "Query monitoring events from the unified erp_monitoring_v2 table.\nReturns all event types (inbound, outbound, file_proxy, etc.) in a single list.\nReplaces the separate v1 inbound-events and outbound-events endpoints.\n",
3497
3764
  "tags": [
@@ -3542,6 +3809,7 @@
3542
3809
  "/v2/integrations/{integrationId}/monitoring/stats": {
3543
3810
  "post": {
3544
3811
  "operationId": "getMonitoringStatsV2",
3812
+ "x-epilot-permissions": [],
3545
3813
  "summary": "getMonitoringStatsV2",
3546
3814
  "description": "Get aggregated statistics from the unified erp_monitoring_v2 table.\nReturns combined metrics for all event types with optional breakdowns.\n",
3547
3815
  "tags": [
@@ -3592,6 +3860,7 @@
3592
3860
  "/v2/integrations/{integrationId}/monitoring/time-series": {
3593
3861
  "post": {
3594
3862
  "operationId": "getMonitoringTimeSeriesV2",
3863
+ "x-epilot-permissions": [],
3595
3864
  "summary": "getMonitoringTimeSeriesV2",
3596
3865
  "description": "Get time-series aggregated event counts from the unified erp_monitoring_v2 table.\nReturns bucketed counts for chart rendering.\n",
3597
3866
  "tags": [
@@ -3642,6 +3911,7 @@
3642
3911
  "/v2/integrations/{integrationId}/monitoring/events/{eventId}/associated": {
3643
3912
  "get": {
3644
3913
  "operationId": "getAssociatedMonitoringEvents",
3914
+ "x-epilot-permissions": [],
3645
3915
  "summary": "getAssociatedMonitoringEvents",
3646
3916
  "description": "Returns all monitoring events sharing the same event_id, ordered chronologically.\nAlso includes the original inbound event payload from erp_incoming_events if available.\nUsed to display a full event trace/timeline.\n",
3647
3917
  "tags": [
@@ -3688,6 +3958,11 @@
3688
3958
  "/v2/integrations/{integrationId}/monitoring/external-events": {
3689
3959
  "post": {
3690
3960
  "operationId": "ingestExternalMonitoringEvents",
3961
+ "x-epilot-permissions": [
3962
+ {
3963
+ "action": "integration:manage"
3964
+ }
3965
+ ],
3691
3966
  "summary": "ingestExternalMonitoringEvents",
3692
3967
  "description": "Ingest monitoring spans produced by an EXTERNAL system (e.g. an integration\nmiddleware), so the Integration Hub is the central monitoring point and the\ncross-system event trace spans both the external system and epilot's own\nprocessing.\n\nEach span is validated, assigned a server-controlled `EXTERNAL_*` taxonomy code\nderived from its `level` (the client never supplies a code — this marks\nprovenance and prevents spoofing an epilot code), has its `use_case_slug`\nresolved against the integration's configured use cases, and is republished onto\nthe same monitoring event bus as epilot's own spans — so external spans are\nfirst-class to the trace view, stats, alerting and digests.\n\nSpans link to the epilot trace via `correlation_id` (the trace id): the middleware\nmust stamp the same `correlation_id` here and on the event it forwards to the\ninbound endpoint. Invalid spans in a batch are reported per-item and do not fail\nthe whole batch.\n",
3693
3968
  "tags": [
@@ -3748,6 +4023,11 @@
3748
4023
  "/v2/integrations/{integrationId}/monitoring/traces/{correlationId}": {
3749
4024
  "get": {
3750
4025
  "operationId": "getMonitoringTraceByCorrelation",
4026
+ "x-epilot-permissions": [
4027
+ {
4028
+ "action": "integration:view"
4029
+ }
4030
+ ],
3751
4031
  "summary": "getMonitoringTraceByCorrelation",
3752
4032
  "description": "Returns the cross-system event trace for a `correlation_id`: every monitoring\nspan sharing it — external spans (middleware) plus epilot's own processing spans\n— ordered chronologically, with a rolled-up status and the epilot inbound event\n\"head\" attached. This is the correlation-grouped counterpart to\n`…/events/{eventId}/associated` (which groups a single epilot event's fan-out by\nevent_id). Origin is distinguished by the `EXTERNAL_*` code prefix on external\nspans. Freshness is near-real-time (spans land as they are produced/ingested).\n",
3753
4033
  "tags": [
@@ -3804,6 +4084,11 @@
3804
4084
  "/v1/integrations/secure-proxies": {
3805
4085
  "get": {
3806
4086
  "operationId": "listSecureProxies",
4087
+ "x-epilot-permissions": [
4088
+ {
4089
+ "action": "integration:view"
4090
+ }
4091
+ ],
3807
4092
  "summary": "listSecureProxies",
3808
4093
  "description": "Lists all secure_proxy use cases across all integrations for the authenticated organization.\nReturns minimal data suitable for dropdowns and selection UIs.\n",
3809
4094
  "tags": [
@@ -3848,6 +4133,11 @@
3848
4133
  "/v1/secure-proxy": {
3849
4134
  "post": {
3850
4135
  "operationId": "secureProxy",
4136
+ "x-epilot-permissions": [
4137
+ {
4138
+ "action": "integration:manage"
4139
+ }
4140
+ ],
3851
4141
  "summary": "secureProxy",
3852
4142
  "description": "Routes an HTTP request through a VPC with either static IP egress or VPN secure link access.\nThe VPC mode is determined by the referenced secure_proxy use case configuration.\nFor secure_link mode, the target URL must match the use case's allowed_domains whitelist.\n",
3853
4143
  "tags": [
@@ -3931,6 +4221,11 @@
3931
4221
  "/v1/managed-call/{slug}/execute": {
3932
4222
  "post": {
3933
4223
  "operationId": "managedCallExecute",
4224
+ "x-epilot-permissions": [
4225
+ {
4226
+ "action": "integration:manage"
4227
+ }
4228
+ ],
3934
4229
  "summary": "managedCallExecute",
3935
4230
  "description": "Execute a managed call operation synchronously. The slug in the path acts as the RPC method name.\nCalls an external partner API with JSONata mapping on both request and response.\n",
3936
4231
  "tags": [
@@ -4020,6 +4315,11 @@
4020
4315
  "/v1/integrations/{integrationId}/generate-types-preview": {
4021
4316
  "post": {
4022
4317
  "operationId": "generateTypesPreview",
4318
+ "x-epilot-permissions": [
4319
+ {
4320
+ "action": "integration:manage"
4321
+ }
4322
+ ],
4023
4323
  "summary": "generateTypesPreview",
4024
4324
  "description": "Analyses the JSONata mappings of all managed-call use cases in the integration and returns scaffolded type descriptors. The frontend uses these to show the type editor modal where developers fill in leaf types.\n",
4025
4325
  "tags": [
@@ -4070,6 +4370,11 @@
4070
4370
  "/v1/integrations/{integrationId}/generate-types": {
4071
4371
  "post": {
4072
4372
  "operationId": "generateTypes",
4373
+ "x-epilot-permissions": [
4374
+ {
4375
+ "action": "integration:manage"
4376
+ }
4377
+ ],
4073
4378
  "summary": "generateTypes",
4074
4379
  "description": "Generates a complete TypeScript npm package with typed interfaces for all managed-call use cases. This is a stateless operation that does not persist any changes. Use the commit-types endpoint to lock configurations after review.\n",
4075
4380
  "tags": [
@@ -4130,6 +4435,11 @@
4130
4435
  "/v1/integrations/{integrationId}/commit-types": {
4131
4436
  "post": {
4132
4437
  "operationId": "commitTypes",
4438
+ "x-epilot-permissions": [
4439
+ {
4440
+ "action": "integration:manage"
4441
+ }
4442
+ ],
4133
4443
  "summary": "commitTypes",
4134
4444
  "description": "Commits the generated types by locking use case configurations and updating version tracking. Should be called after the user reviews and downloads the generated package.\n",
4135
4445
  "tags": [
@@ -4190,6 +4500,11 @@
4190
4500
  "/v2/erp/imports": {
4191
4501
  "post": {
4192
4502
  "operationId": "createErpImport",
4503
+ "x-epilot-permissions": [
4504
+ {
4505
+ "action": "integration:manage"
4506
+ }
4507
+ ],
4193
4508
  "summary": "createErpImport",
4194
4509
  "description": "Register an already-uploaded file (S3 ref) as a pricing-file import job. Returns the job and a file preview. Nothing runs yet: no use case is chosen and no validation starts here. Optionally rank candidates with POST /v2/erp/imports/{importId}:suggest-use-cases, then start validation with POST /v2/erp/imports/{importId}:validate.\nPass `import_id` to repoint an existing import at a different file instead, keeping its id and its place in the history — allowed while the import has written nothing.",
4195
4510
  "tags": [
@@ -4253,6 +4568,11 @@
4253
4568
  },
4254
4569
  "get": {
4255
4570
  "operationId": "listErpImports",
4571
+ "x-epilot-permissions": [
4572
+ {
4573
+ "action": "integration:manage"
4574
+ }
4575
+ ],
4256
4576
  "summary": "listErpImports",
4257
4577
  "description": "List recent pricing-file import jobs for the org, newest first.\n\nPass `next_cursor` back as `cursor` for the next page. A page can be\nshorter than `limit` and still have more behind it, so stop on\n`next_cursor: null`.\n",
4258
4578
  "tags": [
@@ -4306,6 +4626,11 @@
4306
4626
  "/v2/erp/imports/{importId}": {
4307
4627
  "get": {
4308
4628
  "operationId": "getErpImport",
4629
+ "x-epilot-permissions": [
4630
+ {
4631
+ "action": "integration:manage"
4632
+ }
4633
+ ],
4309
4634
  "summary": "getErpImport",
4310
4635
  "description": "Get a pricing-file import job (status, counts, result links).",
4311
4636
  "tags": [
@@ -4345,6 +4670,11 @@
4345
4670
  },
4346
4671
  "delete": {
4347
4672
  "operationId": "deleteErpImport",
4673
+ "x-epilot-permissions": [
4674
+ {
4675
+ "action": "integration:manage"
4676
+ }
4677
+ ],
4348
4678
  "summary": "deleteErpImport",
4349
4679
  "description": "Remove an import and the file it owns. Allowed from any status: an import whose run is still in flight is stopped by the deletion, and rows it already wrote stay written.",
4350
4680
  "tags": [
@@ -4379,6 +4709,11 @@
4379
4709
  "/v2/erp/imports/{importId}:validate": {
4380
4710
  "post": {
4381
4711
  "operationId": "validateErpImport",
4712
+ "x-epilot-permissions": [
4713
+ {
4714
+ "action": "integration:manage"
4715
+ }
4716
+ ],
4382
4717
  "summary": "validateErpImport",
4383
4718
  "description": "Choose the use case to read this file with, and start the validate phase.\nCallable from PENDING, READY and FAILED — so a wrong choice is corrected by calling this again with a different use case, rather than re-uploading. Each call replaces any previous verdict. Any other status returns 409.",
4384
4719
  "tags": [
@@ -4443,6 +4778,11 @@
4443
4778
  "/v2/erp/imports/{importId}:suggest-use-cases": {
4444
4779
  "post": {
4445
4780
  "operationId": "suggestErpImportUseCases",
4781
+ "x-epilot-permissions": [
4782
+ {
4783
+ "action": "integration:manage"
4784
+ }
4785
+ ],
4446
4786
  "summary": "suggestErpImportUseCases",
4447
4787
  "description": "Rank the org's inbound use cases against this file's columns — the input to the ranked picker (\"matches 6 of your 7 columns\"). Optional: skip this and call `:validate` directly when the use case is already known. Reads only the file's first row, not its data.\nEvery eligible use case is returned, including ones matching nothing: the \"nothing fits, pick anyway\" view needs the full list. Highest match first.\nCSV only — an xlsx import fails with 400 rather than silently returning zero matches, which would look identical to \"we checked and nothing matches\".",
4448
4788
  "tags": [
@@ -4487,6 +4827,11 @@
4487
4827
  "/v2/erp/imports/{importId}:execute": {
4488
4828
  "post": {
4489
4829
  "operationId": "executeErpImport",
4830
+ "x-epilot-permissions": [
4831
+ {
4832
+ "action": "integration:manage"
4833
+ }
4834
+ ],
4490
4835
  "summary": "executeErpImport",
4491
4836
  "description": "Confirm and run the write phase of a validated import. Only a READY job may be executed; any other status returns 409.\nThe verdict is re-checked against live inputs first: if the mapping or an entity schema changed since the check, this returns 409 `VALIDATION_STALE` and leaves the verdict untouched for `:validate` to re-form.",
4492
4837
  "tags": [
@@ -4558,6 +4903,11 @@
4558
4903
  "/v2/erp/imports/{importId}:abort": {
4559
4904
  "post": {
4560
4905
  "operationId": "abortErpImport",
4906
+ "x-epilot-permissions": [
4907
+ {
4908
+ "action": "integration:manage"
4909
+ }
4910
+ ],
4561
4911
  "summary": "abortErpImport",
4562
4912
  "description": "Ask a running import to stop. Valid while the job is VALIDATING or PROCESSING; any other status returns 409.\nThe stop is cooperative: the job passes through CANCELLING and typically reaches CANCELLED within seconds.\nRows already published to the platform are **kept**: this is a stop, not a rollback. Aborting during VALIDATING has published nothing, so it is always clean; aborting during PROCESSING leaves a partial import, and the rows that landed are visible in monitoring under the job's correlation_id.",
4563
4913
  "tags": [
@@ -10057,7 +10407,7 @@
10057
10407
  "enabled",
10058
10408
  "delivery"
10059
10409
  ],
10060
- "description": "A mapping that delivers an event to an external system by one of three mechanisms — pushed to a webhook (with a JSONata payload transformation), made available on the pull-based poll queue (raw event payload, no transformation), or handed to a file_proxy use case that uploads files to an external document system (a pointer only; the referenced use case owns the payload and the fan-out)",
10410
+ "description": "A mapping that delivers an event to an external system by one of three mechanisms — pushed to a webhook (with a JSONata payload transformation), made available on the pull-based poll queue (the raw event payload, or its JSONata transformation when the mapping carries one), or handed to a file_proxy use case that uploads files to an external document system (a pointer only; the referenced use case owns the payload and the fan-out)",
10061
10411
  "properties": {
10062
10412
  "id": {
10063
10413
  "type": "string",
@@ -10071,7 +10421,7 @@
10071
10421
  },
10072
10422
  "jsonata_expression": {
10073
10423
  "type": "string",
10074
- "description": "JSONata expression to transform the event payload. Required for webhook delivery, ignored for poll delivery, and rejected for file_proxy delivery — a file_proxy payload is built by the referenced use case's steps, so accepting an expression here would silently do nothing.",
10424
+ "description": "JSONata expression transforming the event payload. Required for webhook delivery (evaluated by the webhook service). Optional for poll delivery: evaluated at enqueue time against the standardized event-catalog event with `$env`/`$mapValue`/`$mapKey` bindings; must return a JSON object; empty = raw event payload is delivered. Rejected for file_proxy delivery.",
10075
10425
  "example": "{ \"id\": entity._id, \"customer\": entity.customer_name }"
10076
10426
  },
10077
10427
  "enabled": {
@@ -10095,7 +10445,7 @@
10095
10445
  }
10096
10446
  },
10097
10447
  "DeliveryConfig": {
10098
- "description": "Configuration for how the event should be delivered. webhook = push delivery via svc-webhooks (JSONata-transformed payload); poll = pull-based queue delivery where the consumer fetches items via the poll API (raw event payload); file_proxy = one push per event attachment to an external document system, through a file_proxy use case (JSONata-transformed payload carrying the file bytes)",
10448
+ "description": "Configuration for how the event should be delivered. webhook = push delivery via svc-webhooks (JSONata-transformed payload); poll = pull-based queue delivery where the consumer fetches items via the poll API (raw event payload, or its JSONata transformation when the mapping carries a jsonata_expression); file_proxy = one push per event attachment to an external document system, through a file_proxy use case (JSONata-transformed payload carrying the file bytes)",
10099
10449
  "oneOf": [
10100
10450
  {
10101
10451
  "$ref": "#/components/schemas/WebhookDeliveryConfig"
@@ -10150,7 +10500,7 @@
10150
10500
  "required": [
10151
10501
  "type"
10152
10502
  ],
10153
- "description": "Pull-based queue delivery. Items carry the raw standardized event-catalog payload; no JSONata mapping is applied in poll mode. Consumers fetch and acknowledge items via the poll API.",
10503
+ "description": "Pull-based queue delivery. Consumers fetch and acknowledge items via the poll API. When the mapping carries a `jsonata_expression`, it is evaluated once at enqueue time against the standardized event-catalog event (with `$env`/`$mapValue`/`$mapKey` bindings) and its output — a JSON object — is the delivered payload; without one, items carry the raw standardized event-catalog payload. An item whose expression fails at enqueue is never delivered: when it reaches the head of the stream the poison_policy applies to it at once, without waiting for max_delivery_attempts.",
10154
10504
  "properties": {
10155
10505
  "type": {
10156
10506
  "type": "string",
@@ -10173,7 +10523,7 @@
10173
10523
  "block"
10174
10524
  ],
10175
10525
  "default": "dead_letter",
10176
- "description": "What happens when an item exhausts max_delivery_attempts: dead_letter routes the exhausted item to the dead-letter queue and advances past it so the stream keeps flowing; block halts the queue at that item until operator/consumer action removes it."
10526
+ "description": "What happens when an item exhausts max_delivery_attempts, or its jsonata_expression failed at enqueue: dead_letter routes the item to the dead-letter queue and advances past it so the stream keeps flowing; block halts the queue at that item until operator/consumer action removes it."
10177
10527
  },
10178
10528
  "max_delivery_attempts": {
10179
10529
  "type": "integer",
@@ -10568,10 +10918,19 @@
10568
10918
  "type": "string",
10569
10919
  "description": "Ordering group — messages sharing a group are strictly ordered,\ndistinct groups are independent. Constant \"0\" in v1.\n"
10570
10920
  },
10921
+ "org_id": {
10922
+ "type": "string",
10923
+ "description": "The epilot org the message belongs to. Always populated — lets one\nconsumer that polls many orgs attribute every message.\n"
10924
+ },
10571
10925
  "payload": {
10572
10926
  "type": "object",
10573
10927
  "additionalProperties": true,
10574
- "description": "The raw standardized event-catalog event, always inlined as-is"
10928
+ "description": "The mapped output when the use case has a `jsonata_expression`,\notherwise the raw standardized event-catalog event. Always inlined.\n"
10929
+ },
10930
+ "mapping_version": {
10931
+ "type": "string",
10932
+ "description": "Version of the transform that produced the payload — the first 16\nhex characters of sha256 over the trimmed expression. Absent for\nraw payloads.\n",
10933
+ "example": "3f2a9c1b7d4e8f60"
10575
10934
  },
10576
10935
  "enqueued_at": {
10577
10936
  "type": "string",
@@ -10723,7 +11082,15 @@
10723
11082
  },
10724
11083
  "reason": {
10725
11084
  "type": "string",
10726
- "description": "Why the message was dead-lettered (policy or operator reason)"
11085
+ "description": "Why the message was dead-lettered (policy or operator reason) —\n`max_delivery_attempts_exhausted`, `mapping_failed`, or the\noperator's own reason\n"
11086
+ },
11087
+ "mapping_error": {
11088
+ "type": "string",
11089
+ "description": "Why the message's transform failed, prefixed with the error code\n(e.g. `invalid_output: ...`). Present on entries whose mapping\nfailed — at enqueue, or again on a re-mapping redrive.\n"
11090
+ },
11091
+ "mapping_version": {
11092
+ "type": "string",
11093
+ "description": "Version of the transform that produced (or failed to produce) the payload"
10727
11094
  },
10728
11095
  "expires_at": {
10729
11096
  "type": "string",
@@ -10766,6 +11133,11 @@
10766
11133
  "type": "string"
10767
11134
  },
10768
11135
  "description": "Message ids (msg_…) of the DLQ entries to redrive"
11136
+ },
11137
+ "reapply_mapping": {
11138
+ "type": "boolean",
11139
+ "default": false,
11140
+ "description": "Re-apply the use case's CURRENT `jsonata_expression` to the raw\nevent instead of re-sending the stored payload. Entries whose\nmapping failed are always re-mapped, whatever this says. When the\nuse case no longer has an expression, the raw event is redriven.\n"
10769
11141
  }
10770
11142
  }
10771
11143
  },
@@ -10784,9 +11156,14 @@
10784
11156
  "type": "string",
10785
11157
  "enum": [
10786
11158
  "redriven",
10787
- "not_found"
11159
+ "not_found",
11160
+ "mapping_failed"
10788
11161
  ],
10789
- "description": "Outcome — `redriven` re-enqueued at the tail; `not_found` for\nunknown ids or entries concurrently redriven/expired\n"
11162
+ "description": "Outcome — `redriven` re-enqueued at the tail; `not_found` for\nunknown ids or entries concurrently redriven/expired;\n`mapping_failed` when re-mapping failed again (the entry stays in\nthe DLQ with the updated mapping_error and mapping_version)\n"
11163
+ },
11164
+ "mapping_error": {
11165
+ "type": "string",
11166
+ "description": "Why re-mapping failed — present only when status is mapping_failed"
10790
11167
  }
10791
11168
  }
10792
11169
  },
@@ -10832,6 +11209,96 @@
10832
11209
  }
10833
11210
  }
10834
11211
  },
11212
+ "SimulateOutboundMappingRequest": {
11213
+ "type": "object",
11214
+ "additionalProperties": false,
11215
+ "required": [
11216
+ "jsonata_expression"
11217
+ ],
11218
+ "description": "Exactly one of `payload` or `event_id` is required. `event_id` needs\n`event_catalog_event` to name the event it belongs to.\n",
11219
+ "properties": {
11220
+ "jsonata_expression": {
11221
+ "type": "string",
11222
+ "minLength": 1,
11223
+ "description": "The poll mapping expression to preview",
11224
+ "example": "{ \"contract_number\": contract.contract_number, \"status\": $mapValue($env.erp.statuses, contract.status) }"
11225
+ },
11226
+ "payload": {
11227
+ "type": "object",
11228
+ "additionalProperties": true,
11229
+ "description": "A standardized event-catalog event to map as-is"
11230
+ },
11231
+ "event_id": {
11232
+ "type": "string",
11233
+ "description": "Id of a historical event-catalog event to load, hydrate and map"
11234
+ },
11235
+ "event_catalog_event": {
11236
+ "type": "string",
11237
+ "description": "Event-catalog event name of `event_id` (required with `event_id`)",
11238
+ "example": "contract.updated"
11239
+ }
11240
+ }
11241
+ },
11242
+ "OutboundMappingSimulationError": {
11243
+ "type": "object",
11244
+ "required": [
11245
+ "code",
11246
+ "message"
11247
+ ],
11248
+ "properties": {
11249
+ "code": {
11250
+ "type": "string",
11251
+ "enum": [
11252
+ "syntax_error",
11253
+ "unknown_binding",
11254
+ "evaluation_error",
11255
+ "timeout",
11256
+ "invalid_output",
11257
+ "expression_too_long"
11258
+ ],
11259
+ "description": "`syntax_error` — the expression does not parse; `unknown_binding` —\nit reads a `$` name that is never bound; `evaluation_error` — it\nfailed while evaluating; `timeout` — it exceeded the evaluation\ntime or depth limit; `invalid_output` — it did not return a JSON\nobject; `expression_too_long` — it exceeds 10,000 characters\n"
11260
+ },
11261
+ "message": {
11262
+ "type": "string",
11263
+ "description": "Human-readable explanation"
11264
+ },
11265
+ "position": {
11266
+ "type": "integer",
11267
+ "description": "Character position of the failure in the expression, when known"
11268
+ }
11269
+ }
11270
+ },
11271
+ "SimulateOutboundMappingResponse": {
11272
+ "type": "object",
11273
+ "required": [
11274
+ "valid",
11275
+ "mapping_version"
11276
+ ],
11277
+ "properties": {
11278
+ "valid": {
11279
+ "type": "boolean",
11280
+ "description": "Whether the expression produced a deliverable payload"
11281
+ },
11282
+ "output": {
11283
+ "type": "object",
11284
+ "additionalProperties": true,
11285
+ "description": "The payload a consumer would receive — present when valid"
11286
+ },
11287
+ "error": {
11288
+ "$ref": "#/components/schemas/OutboundMappingSimulationError"
11289
+ },
11290
+ "mapping_version": {
11291
+ "type": "string",
11292
+ "description": "The `mapping_version` messages mapped by this expression carry",
11293
+ "example": "3f2a9c1b7d4e8f60"
11294
+ },
11295
+ "input": {
11296
+ "type": "object",
11297
+ "additionalProperties": true,
11298
+ "description": "The hydrated event the expression ran against — present when `event_id` was used"
11299
+ }
11300
+ }
11301
+ },
10835
11302
  "RelationConfig": {
10836
11303
  "type": "object",
10837
11304
  "required": [
@@ -12113,6 +12580,7 @@
12113
12580
  "MSG_ENQUEUED",
12114
12581
  "MSG_EXPIRED_UNPOLLED",
12115
12582
  "MSG_HEAD_BLOCKED",
12583
+ "MSG_LATE_ARRIVAL",
12116
12584
  "OAUTH2_TOKEN_FAILURE",
12117
12585
  "PAYLOAD_TOO_LARGE",
12118
12586
  "PRUNE_SCOPE_COMPLETED",
@@ -12941,6 +13409,55 @@
12941
13409
  }
12942
13410
  }
12943
13411
  },
13412
+ "ERPUpdatesRetryableResponse": {
13413
+ "description": "Some events could not be processed right now but will succeed on a retry: their\ndeduplication check was throttled, or another request carrying the same\ndeduplication_id is still being processed. Those events have status `error`.\nRetry the whole request after the `Retry-After` interval: events that were\naccepted by this request are recorded and come back as `skipped` on the retry.\n",
13414
+ "headers": {
13415
+ "Retry-After": {
13416
+ "description": "Seconds to wait before retrying the request",
13417
+ "schema": {
13418
+ "type": "integer"
13419
+ }
13420
+ }
13421
+ },
13422
+ "content": {
13423
+ "application/json": {
13424
+ "schema": {
13425
+ "type": "object",
13426
+ "properties": {
13427
+ "results": {
13428
+ "type": "array",
13429
+ "items": {
13430
+ "type": "object",
13431
+ "required": [
13432
+ "event_id",
13433
+ "status"
13434
+ ],
13435
+ "properties": {
13436
+ "event_id": {
13437
+ "type": "string",
13438
+ "description": "ID of the processed event"
13439
+ },
13440
+ "status": {
13441
+ "type": "string",
13442
+ "enum": [
13443
+ "success",
13444
+ "error",
13445
+ "skipped",
13446
+ "ignored"
13447
+ ],
13448
+ "description": "Processing status for the event (skipped indicates duplicate deduplication_id, ignored indicates unconfigured event)"
13449
+ },
13450
+ "message": {
13451
+ "type": "string"
13452
+ }
13453
+ }
13454
+ }
13455
+ }
13456
+ }
13457
+ }
13458
+ }
13459
+ }
13460
+ },
12944
13461
  "TriggerWebhookResponse": {
12945
13462
  "description": "Result of triggering an ERP synchronization event",
12946
13463
  "content": {