@epilot/sdk 2.20.72 → 2.20.73

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 (137) hide show
  1. package/definitions/entity-runtime.json +1 -1
  2. package/definitions/entity.json +1491 -44
  3. package/dist/apis/access-token.cjs +6 -6
  4. package/dist/apis/access-token.js +1 -1
  5. package/dist/apis/address-suggestions.cjs +6 -6
  6. package/dist/apis/address-suggestions.js +1 -1
  7. package/dist/apis/address.cjs +6 -6
  8. package/dist/apis/address.js +1 -1
  9. package/dist/apis/ai-agents.cjs +6 -6
  10. package/dist/apis/ai-agents.js +1 -1
  11. package/dist/apis/app.cjs +6 -6
  12. package/dist/apis/app.js +1 -1
  13. package/dist/apis/audit-logs.cjs +6 -6
  14. package/dist/apis/audit-logs.js +1 -1
  15. package/dist/apis/automation.cjs +6 -6
  16. package/dist/apis/automation.js +1 -1
  17. package/dist/apis/billing.cjs +6 -6
  18. package/dist/apis/billing.js +1 -1
  19. package/dist/apis/blueprint-manifest.cjs +6 -6
  20. package/dist/apis/blueprint-manifest.js +1 -1
  21. package/dist/apis/calendar.cjs +6 -6
  22. package/dist/apis/calendar.js +1 -1
  23. package/dist/apis/chat.cjs +6 -6
  24. package/dist/apis/chat.js +1 -1
  25. package/dist/apis/configuration-hub.cjs +6 -6
  26. package/dist/apis/configuration-hub.js +1 -1
  27. package/dist/apis/consent.cjs +6 -6
  28. package/dist/apis/consent.js +1 -1
  29. package/dist/apis/customer-portal.cjs +6 -6
  30. package/dist/apis/customer-portal.js +1 -1
  31. package/dist/apis/dashboard.cjs +6 -6
  32. package/dist/apis/dashboard.js +1 -1
  33. package/dist/apis/data-governance.cjs +6 -6
  34. package/dist/apis/data-governance.js +1 -1
  35. package/dist/apis/deduplication.cjs +6 -6
  36. package/dist/apis/deduplication.js +1 -1
  37. package/dist/apis/design.cjs +6 -6
  38. package/dist/apis/design.js +1 -1
  39. package/dist/apis/document.cjs +6 -6
  40. package/dist/apis/document.js +1 -1
  41. package/dist/apis/email-settings.cjs +6 -6
  42. package/dist/apis/email-settings.js +1 -1
  43. package/dist/apis/email-template.cjs +6 -6
  44. package/dist/apis/email-template.js +1 -1
  45. package/dist/apis/entity-mapping.cjs +6 -6
  46. package/dist/apis/entity-mapping.js +1 -1
  47. package/dist/apis/entity.cjs +8 -8
  48. package/dist/apis/entity.d.cts +2 -2
  49. package/dist/apis/entity.d.ts +2 -2
  50. package/dist/apis/entity.js +2 -2
  51. package/dist/apis/environments.cjs +6 -6
  52. package/dist/apis/environments.js +1 -1
  53. package/dist/apis/event-catalog.cjs +6 -6
  54. package/dist/apis/event-catalog.js +1 -1
  55. package/dist/apis/external-values.cjs +6 -6
  56. package/dist/apis/external-values.js +1 -1
  57. package/dist/apis/file.cjs +6 -6
  58. package/dist/apis/file.js +1 -1
  59. package/dist/apis/iban.cjs +6 -6
  60. package/dist/apis/iban.js +1 -1
  61. package/dist/apis/identity.cjs +6 -6
  62. package/dist/apis/identity.js +1 -1
  63. package/dist/apis/integration-toolkit.cjs +6 -6
  64. package/dist/apis/integration-toolkit.js +1 -1
  65. package/dist/apis/journey.cjs +6 -6
  66. package/dist/apis/journey.js +1 -1
  67. package/dist/apis/kanban.cjs +6 -6
  68. package/dist/apis/kanban.js +1 -1
  69. package/dist/apis/message.cjs +6 -6
  70. package/dist/apis/message.js +1 -1
  71. package/dist/apis/metering.cjs +6 -6
  72. package/dist/apis/metering.js +1 -1
  73. package/dist/apis/notes.cjs +6 -6
  74. package/dist/apis/notes.js +1 -1
  75. package/dist/apis/notification.cjs +6 -6
  76. package/dist/apis/notification.js +1 -1
  77. package/dist/apis/organization.cjs +6 -6
  78. package/dist/apis/organization.js +1 -1
  79. package/dist/apis/partner-directory.cjs +6 -6
  80. package/dist/apis/partner-directory.js +1 -1
  81. package/dist/apis/permissions.cjs +6 -6
  82. package/dist/apis/permissions.js +1 -1
  83. package/dist/apis/phone-integration.cjs +6 -6
  84. package/dist/apis/phone-integration.js +1 -1
  85. package/dist/apis/pricing-tier.cjs +6 -6
  86. package/dist/apis/pricing-tier.js +1 -1
  87. package/dist/apis/pricing.cjs +6 -6
  88. package/dist/apis/pricing.js +1 -1
  89. package/dist/apis/purpose.cjs +6 -6
  90. package/dist/apis/purpose.js +1 -1
  91. package/dist/apis/query.cjs +6 -6
  92. package/dist/apis/query.js +1 -1
  93. package/dist/apis/sandbox.cjs +6 -6
  94. package/dist/apis/sandbox.js +1 -1
  95. package/dist/apis/sharing.cjs +6 -6
  96. package/dist/apis/sharing.js +1 -1
  97. package/dist/apis/snapshot.cjs +6 -6
  98. package/dist/apis/snapshot.js +1 -1
  99. package/dist/apis/submission.cjs +6 -6
  100. package/dist/apis/submission.js +1 -1
  101. package/dist/apis/target.cjs +6 -6
  102. package/dist/apis/target.js +1 -1
  103. package/dist/apis/targeting.cjs +6 -6
  104. package/dist/apis/targeting.js +1 -1
  105. package/dist/apis/template-variables.cjs +6 -6
  106. package/dist/apis/template-variables.js +1 -1
  107. package/dist/apis/user.cjs +6 -6
  108. package/dist/apis/user.js +1 -1
  109. package/dist/apis/validation-rules.cjs +6 -6
  110. package/dist/apis/validation-rules.js +1 -1
  111. package/dist/apis/webhooks.cjs +6 -6
  112. package/dist/apis/webhooks.js +1 -1
  113. package/dist/apis/workflow-definition.cjs +6 -6
  114. package/dist/apis/workflow-definition.js +1 -1
  115. package/dist/apis/workflow.cjs +6 -6
  116. package/dist/apis/workflow.js +1 -1
  117. package/dist/chunk-3JBENXET.cjs +14 -0
  118. package/dist/{chunk-5QSR7CYT.cjs → chunk-5PG5IEQ7.cjs} +2 -2
  119. package/dist/chunk-K77ESMSG.js +14 -0
  120. package/dist/{chunk-B42G3PU6.js → chunk-WG7OKIQ3.js} +2 -2
  121. package/dist/entity-GZC53ATN.cjs +7 -0
  122. package/dist/entity-T26ZCCI6.js +7 -0
  123. package/dist/entity-runtime-L3EGYXRI.cjs +5 -0
  124. package/dist/{entity-runtime-JRSXJKRV.js → entity-runtime-YZPCXKZW.js} +1 -1
  125. package/dist/{entity.d-BwsBk0Po.d.cts → entity.d-DlI8zhXF.d.cts} +1369 -75
  126. package/dist/{entity.d-BwsBk0Po.d.ts → entity.d-DlI8zhXF.d.ts} +1369 -75
  127. package/dist/index.cjs +10 -10
  128. package/dist/index.d.cts +1 -1
  129. package/dist/index.d.ts +1 -1
  130. package/dist/index.js +2 -2
  131. package/docs/entity.md +586 -3
  132. package/package.json +1 -1
  133. package/dist/chunk-KXNPNC4J.js +0 -14
  134. package/dist/chunk-XT2XPHUH.cjs +0 -14
  135. package/dist/entity-AQTIV5LR.js +0 -7
  136. package/dist/entity-TJAYHTIU.cjs +0 -7
  137. package/dist/entity-runtime-DYQQGB4F.cjs +0 -5
@@ -22,6 +22,10 @@
22
22
  "name": "Activity",
23
23
  "description": "Entity Events"
24
24
  },
25
+ {
26
+ "name": "AI",
27
+ "description": "AI generated content for entities"
28
+ },
25
29
  {
26
30
  "name": "Import-Export",
27
31
  "description": "Import and Export entities via portable files (CSV)"
@@ -59,6 +63,11 @@
59
63
  "/v1/entity/schemas": {
60
64
  "get": {
61
65
  "operationId": "listSchemas",
66
+ "x-epilot-permissions": [
67
+ {
68
+ "access": "org"
69
+ }
70
+ ],
62
71
  "summary": "listSchemas",
63
72
  "description": "Get the latest versions of all schemas",
64
73
  "parameters": [
@@ -137,6 +146,11 @@
137
146
  "/v2/entity/schemas": {
138
147
  "get": {
139
148
  "operationId": "listSchemasV2",
149
+ "x-epilot-permissions": [
150
+ {
151
+ "access": "org"
152
+ }
153
+ ],
140
154
  "summary": "listSchemasV2",
141
155
  "description": "Get the latest versions of all schemas.\nReturns summary schemas by default (only summary attributes, no capabilities).\nUse ?full=true for complete schemas.\n",
142
156
  "parameters": [
@@ -224,6 +238,11 @@
224
238
  "/v1/entity/schemas/{slug}": {
225
239
  "get": {
226
240
  "operationId": "getSchema",
241
+ "x-epilot-permissions": [
242
+ {
243
+ "access": "org"
244
+ }
245
+ ],
227
246
  "summary": "getSchema",
228
247
  "description": "Gets the latest version of the Schema.\nPass ?id= to get a specific version by ID.\n",
229
248
  "tags": [
@@ -269,6 +288,12 @@
269
288
  },
270
289
  "put": {
271
290
  "operationId": "putSchema",
291
+ "x-epilot-permissions": [
292
+ {
293
+ "action": "schema:update",
294
+ "resource": "{slug}"
295
+ }
296
+ ],
272
297
  "summary": "putSchema",
273
298
  "description": "Create or update a schema with a new version.\n",
274
299
  "tags": [
@@ -286,6 +311,24 @@
286
311
  "default": false,
287
312
  "type": "boolean"
288
313
  }
314
+ },
315
+ {
316
+ "in": "query",
317
+ "name": "base_version",
318
+ "description": "The schema version these edits were made on top of. When passed, the save is rejected\nwith `409` if another save has landed since, instead of silently overwriting it.\nIgnored for drafts.\n",
319
+ "schema": {
320
+ "type": "integer",
321
+ "minimum": 0
322
+ }
323
+ },
324
+ {
325
+ "in": "query",
326
+ "name": "base_updated_at",
327
+ "description": "The `updated_at` of the `base_version` the edits were made on top of. Narrows the check to\nthat exact write, since some schema writes replace the current version in place. Requires\n`base_version`.\n",
328
+ "schema": {
329
+ "type": "string",
330
+ "format": "date-time"
331
+ }
289
332
  }
290
333
  ],
291
334
  "requestBody": {
@@ -308,6 +351,16 @@
308
351
  }
309
352
  }
310
353
  },
354
+ "409": {
355
+ "description": "The schema was changed since `base_version`. Nothing was written.",
356
+ "content": {
357
+ "application/json": {
358
+ "schema": {
359
+ "$ref": "#/components/schemas/SchemaVersionConflictError"
360
+ }
361
+ }
362
+ }
363
+ },
311
364
  "429": {
312
365
  "$ref": "#/components/responses/TooManyRequestsError"
313
366
  }
@@ -315,6 +368,12 @@
315
368
  },
316
369
  "delete": {
317
370
  "operationId": "deleteSchema",
371
+ "x-epilot-permissions": [
372
+ {
373
+ "action": "schema:update",
374
+ "resource": "{slug}"
375
+ }
376
+ ],
318
377
  "summary": "deleteSchema",
319
378
  "description": "Delete a schema, or a specific version of a schema",
320
379
  "tags": [
@@ -335,9 +394,52 @@
335
394
  }
336
395
  }
337
396
  },
397
+ "/v1/entity/schemas/{slug}/head": {
398
+ "get": {
399
+ "operationId": "getSchemaHead",
400
+ "x-epilot-permissions": [
401
+ {
402
+ "access": "org"
403
+ }
404
+ ],
405
+ "summary": "getSchemaHead",
406
+ "description": "Lightweight lookup of the schema version saves currently land on top of. Meant for editors\nto detect that someone else saved while they were editing, without fetching the schema.\n",
407
+ "tags": [
408
+ "Schemas"
409
+ ],
410
+ "parameters": [
411
+ {
412
+ "$ref": "#/components/parameters/EntitySlugPathParam"
413
+ }
414
+ ],
415
+ "responses": {
416
+ "200": {
417
+ "description": "Success",
418
+ "content": {
419
+ "application/json": {
420
+ "schema": {
421
+ "$ref": "#/components/schemas/SchemaHead"
422
+ }
423
+ }
424
+ }
425
+ },
426
+ "404": {
427
+ "$ref": "#/components/responses/NotFoundError"
428
+ },
429
+ "429": {
430
+ "$ref": "#/components/responses/TooManyRequestsError"
431
+ }
432
+ }
433
+ }
434
+ },
338
435
  "/v1/entity/schemas/{slug}/json/schema": {
339
436
  "get": {
340
437
  "operationId": "getJsonSchema",
438
+ "x-epilot-permissions": [
439
+ {
440
+ "access": "org"
441
+ }
442
+ ],
341
443
  "summary": "getJsonSchema",
342
444
  "description": "Get formal JSON schema definition draft 2020-12 for the given epilot schema",
343
445
  "tags": [
@@ -669,6 +771,11 @@
669
771
  "/v1/entity/schemas/{slug}/json/example": {
670
772
  "get": {
671
773
  "operationId": "getSchemaExample",
774
+ "x-epilot-permissions": [
775
+ {
776
+ "access": "org"
777
+ }
778
+ ],
672
779
  "summary": "getSchemaExample",
673
780
  "description": "Get a full example entity for the given schema",
674
781
  "tags": [
@@ -704,6 +811,11 @@
704
811
  "/v1/entity/schemas/{slug}/versions": {
705
812
  "get": {
706
813
  "operationId": "getSchemaVersions",
814
+ "x-epilot-permissions": [
815
+ {
816
+ "access": "org"
817
+ }
818
+ ],
707
819
  "summary": "getSchemaVersions",
708
820
  "description": "Get all versions of this schema ordered by the latest versions including drafts.",
709
821
  "tags": [
@@ -818,6 +930,12 @@
818
930
  "/v1/entity/schemas/{slug}/freeze": {
819
931
  "post": {
820
932
  "operationId": "freezeSchema",
933
+ "x-epilot-permissions": [
934
+ {
935
+ "action": "schema:update",
936
+ "resource": "{slug}"
937
+ }
938
+ ],
821
939
  "summary": "freezeSchema",
822
940
  "deprecated": true,
823
941
  "description": "Deprecated no-op: schema freezing is retired and every read returns the latest version.\nReturns the latest version of the schema unchanged. This endpoint will be removed.\n",
@@ -868,6 +986,12 @@
868
986
  "/v1/entity/schemas/{slug}/unfreeze": {
869
987
  "post": {
870
988
  "operationId": "unfreezeSchema",
989
+ "x-epilot-permissions": [
990
+ {
991
+ "action": "schema:update",
992
+ "resource": "{slug}"
993
+ }
994
+ ],
871
995
  "summary": "unfreezeSchema",
872
996
  "deprecated": true,
873
997
  "description": "Deprecated: schema freezing is retired. Cleans up a leftover frozen pointer by promoting the\nlatest version to the current version, and succeeds when there is nothing to clean up.\nThis endpoint will be removed.\n",
@@ -899,6 +1023,11 @@
899
1023
  "/v1/entity/schemas/{slug}/capabilities/available": {
900
1024
  "get": {
901
1025
  "operationId": "listAvailableCapabilities",
1026
+ "x-epilot-permissions": [
1027
+ {
1028
+ "access": "org"
1029
+ }
1030
+ ],
902
1031
  "summary": "listAvailableCapabilities",
903
1032
  "description": "List available capabilities for schema",
904
1033
  "tags": [
@@ -934,6 +1063,11 @@
934
1063
  "/v1/entity/schemas/blueprints": {
935
1064
  "get": {
936
1065
  "operationId": "listSchemaBlueprints",
1066
+ "x-epilot-permissions": [
1067
+ {
1068
+ "access": "org"
1069
+ }
1070
+ ],
937
1071
  "summary": "listSchemaBlueprints",
938
1072
  "description": "List canonical versions of all available schemas",
939
1073
  "tags": [
@@ -964,6 +1098,12 @@
964
1098
  "/v1/entity:search": {
965
1099
  "post": {
966
1100
  "operationId": "searchEntities",
1101
+ "x-epilot-permissions": [
1102
+ {
1103
+ "action": "entity:view",
1104
+ "filter": true
1105
+ }
1106
+ ],
967
1107
  "summary": "searchEntities",
968
1108
  "x-rate-limit": {
969
1109
  "limit": 5000,
@@ -1008,6 +1148,12 @@
1008
1148
  "/v1/entity:list": {
1009
1149
  "post": {
1010
1150
  "operationId": "listEntities",
1151
+ "x-epilot-permissions": [
1152
+ {
1153
+ "action": "entity:view",
1154
+ "filter": true
1155
+ }
1156
+ ],
1011
1157
  "summary": "listEntities",
1012
1158
  "x-rate-limit": {
1013
1159
  "limit": 5000,
@@ -1052,6 +1198,12 @@
1052
1198
  "/v1/entity:graph": {
1053
1199
  "post": {
1054
1200
  "operationId": "queryEntityGraph",
1201
+ "x-epilot-permissions": [
1202
+ {
1203
+ "action": "entity:view",
1204
+ "filter": true
1205
+ }
1206
+ ],
1055
1207
  "summary": "queryEntityGraph",
1056
1208
  "description": "Traverse an entity relationship graph starting from a seed entity.\n\nDefine the shape of the graph using nodes (entity schemas) and edges (relationships with cardinality).\nThe API will traverse the graph bidirectionally and return all discovered entity IDs.\n\nExample: Find all entities connected to a contact through portal_user -> contact -> billing_account -> files\n",
1057
1209
  "tags": [
@@ -1090,6 +1242,12 @@
1090
1242
  "/v1/entity/{slug}": {
1091
1243
  "post": {
1092
1244
  "operationId": "createEntity",
1245
+ "x-epilot-permissions": [
1246
+ {
1247
+ "action": "entity:create",
1248
+ "resource": "{slug}"
1249
+ }
1250
+ ],
1093
1251
  "summary": "createEntity",
1094
1252
  "description": "Creates a new entity using a key.\n\n## Activity\n\nIf no `activity_id` query parameter is provided, implicitly creates Activity of type `EntityCreated`\n\n## Relations\n\nTo create a relation, store a property object that defines a `$relation` array.\n\nExample:\n\n```json\n{\n \"contacts\": {\n \"$relation\": [\n { \"entity_id\": \"3fa85f64-5717-4562-b3fc-2c963f66afa6\" }\n ]\n }\n}\n```\n\nThe items in `$relation` support two properties:\n- `entity_id` - The ID of the entity to link\n- `_tags` - Tags or labels for the relation (optional)\n",
1095
1253
  "tags": [
@@ -1186,6 +1344,11 @@
1186
1344
  "/v1/entity/{slug}:validate": {
1187
1345
  "post": {
1188
1346
  "operationId": "validateEntity",
1347
+ "x-epilot-permissions": [
1348
+ {
1349
+ "access": "org"
1350
+ }
1351
+ ],
1189
1352
  "summary": "validateEntity",
1190
1353
  "description": "Validates an entity against the schema.",
1191
1354
  "tags": [
@@ -1243,6 +1406,11 @@
1243
1406
  "/v2/entity/{slug}:validate": {
1244
1407
  "post": {
1245
1408
  "operationId": "validateEntityV2",
1409
+ "x-epilot-permissions": [
1410
+ {
1411
+ "access": "org"
1412
+ }
1413
+ ],
1246
1414
  "summary": "validateEntityV2",
1247
1415
  "description": "Validates an entity against the schema.",
1248
1416
  "tags": [
@@ -1300,6 +1468,20 @@
1300
1468
  "/v1/entity/{slug}:upsert": {
1301
1469
  "patch": {
1302
1470
  "operationId": "upsertEntity",
1471
+ "x-epilot-permissions": [
1472
+ {
1473
+ "anyOf": [
1474
+ {
1475
+ "action": "entity:create",
1476
+ "resource": "{slug}"
1477
+ },
1478
+ {
1479
+ "action": "entity:edit",
1480
+ "resource": "{slug}"
1481
+ }
1482
+ ]
1483
+ }
1484
+ ],
1303
1485
  "summary": "upsertEntity",
1304
1486
  "description": "Create or update an entity using `unique_key`\n\n- If no entities are matched, a new entity is created.\n- If exactly one entity is matched, a `PATCH`-style update is applied to the existing entity.\n\n## Activity\n\nIf no `activity_id` query parameter is provided, implicitly creates Activity of type `EntityCreated` or `EntityUpdated`\n",
1305
1487
  "tags": [
@@ -1410,6 +1592,12 @@
1410
1592
  "/v2/entity/{slug}/{id}": {
1411
1593
  "get": {
1412
1594
  "operationId": "getEntityV2",
1595
+ "x-epilot-permissions": [
1596
+ {
1597
+ "action": "entity:view",
1598
+ "resource": "{slug}:{id}"
1599
+ }
1600
+ ],
1413
1601
  "summary": "getEntityV2",
1414
1602
  "description": "Gets Entity by id.\n\nSupports `hydrate` and `fields` parameters to control the shape of the response.\n",
1415
1603
  "tags": [
@@ -1462,6 +1650,12 @@
1462
1650
  "/v1/entity/{slug}/{id}:restore": {
1463
1651
  "patch": {
1464
1652
  "operationId": "restoreEntity",
1653
+ "x-epilot-permissions": [
1654
+ {
1655
+ "action": "entity:edit",
1656
+ "resource": "{slug}:{id}"
1657
+ }
1658
+ ],
1465
1659
  "summary": "restoreEntity",
1466
1660
  "description": "Restores an entity by id\n\n## Activity\n\nIf no `activity_id` query parameter is provided, implicitly creates Activity of type `EntityRestore`\n",
1467
1661
  "tags": [
@@ -1514,6 +1708,12 @@
1514
1708
  "/v1/entity/{slug}/{id}:reindex": {
1515
1709
  "post": {
1516
1710
  "operationId": "reindexEntity",
1711
+ "x-epilot-permissions": [
1712
+ {
1713
+ "action": "entity:view",
1714
+ "resource": "{slug}:{id}"
1715
+ }
1716
+ ],
1517
1717
  "summary": "reindexEntity",
1518
1718
  "description": "Triggers a reindex for the Entity for search.\n",
1519
1719
  "tags": [
@@ -1563,6 +1763,12 @@
1563
1763
  "/v1/entity/{slug}/{id}": {
1564
1764
  "get": {
1565
1765
  "operationId": "getEntity",
1766
+ "x-epilot-permissions": [
1767
+ {
1768
+ "action": "entity:view",
1769
+ "resource": "{slug}:{id}"
1770
+ }
1771
+ ],
1566
1772
  "summary": "getEntity",
1567
1773
  "description": "Gets Entity and relations by id.\n\n## Relations\n\nWhen `hydrate=true`, relation attributes are replaced in-place with nested entity values.\n\nExample:\n```json\n{\n \"_id\": \"123\",\n \"name\": \"parent\",\n \"_tags\": [\"parent\"],\n \"contacts\": {\n \"$relation\": [\n { \"entity_id\": \"456\", \"_tags\": [\"primary\"] },\n { \"entity_id\": \"789\", \"_tags\": [\"secondary\"] },\n ]\n },\n \"addresses\": {\n \"$relation_ref\": [\n { \"entity_id\": \"123\", \"_tags\": [\"primary\"], \"path\": \"address.0\" },\n { \"entity_id\": \"234\", \"_tags\": [\"secondary\"], \"path\": \"address.0\" },\n ]\n }\n}\n```\n\nBecomes:\n```json\n{\n \"_id\": \"123\",\n \"name\": \"parent\",\n \"_tags\": [\"parent\"],\n \"contacts\": [\n {\n \"$relation\": { \"entity_id\": \"456\", \"_tags\": [\"primary\"] },\n \"_id\": \"456\",\n \"name\": \"child 1\",\n \"_tags\": [\"child\"]\n },\n {\n \"$relation\": { \"entity_id\": \"789\", \"_tags\": [\"secondary\"] },\n \"_id\": \"789\",\n \"name\": \"child 2\",\n \"_tags\": [\"child\"]\n }\n ],\n \"addresses\": [\n {\n \"$relation_ref\": { \"entity_id\": \"123\", \"_tags\": [\"primary\"], \"path\": \"address.0\" },\n \"_id\": \"123\",\n \"address\": \"address 1\",\n \"_tags\": [\"child\"]\n },\n {\n \"$relation_ref\": { \"entity_id\": \"234\", \"_tags\": [\"secondary\"], \"path\": \"address.0\" },\n \"_id\": \"234\",\n \"address\": \"address 2\",\n \"_tags\": [\"child\"]\n }\n ]\n}\n```\n",
1568
1774
  "tags": [
@@ -1611,6 +1817,12 @@
1611
1817
  },
1612
1818
  "put": {
1613
1819
  "operationId": "updateEntity",
1820
+ "x-epilot-permissions": [
1821
+ {
1822
+ "action": "entity:edit",
1823
+ "resource": "{slug}:{id}"
1824
+ }
1825
+ ],
1614
1826
  "summary": "updateEntity",
1615
1827
  "description": "Updates an Entity\n\n## Activity\n\nIf no `activity_id` query parameter is provided, implicitly creates Activity of type `EntityUpdated`\n\n## Relations\n\nTo create a relation, store a property that defines a `$relation` array.\n\nExample:\n\n```json\n{\n \"contacts\": {\n \"$relation\": [\n { \"entity_id\": \"3fa85f64-5717-4562-b3fc-2c963f66afa6\" }\n ]\n }\n}\n```\n\nThe items in `$relation` support two properties:\n- `entity_id` - The ID of the entity to link\n- `_tags` - Tags or labels for the relation (optional)\n",
1616
1828
  "tags": [
@@ -1674,6 +1886,12 @@
1674
1886
  },
1675
1887
  "patch": {
1676
1888
  "operationId": "patchEntity",
1889
+ "x-epilot-permissions": [
1890
+ {
1891
+ "action": "entity:edit",
1892
+ "resource": "{slug}:{id}"
1893
+ }
1894
+ ],
1677
1895
  "summary": "patchEntity",
1678
1896
  "description": "Partially updates an entity with the passed in entity data.\n\n- If an _updated_at is passed and the server contains a newer version of the entity a `409` Error is returned\n\n## Activity\n\nIf no `activity_id` query parameter is provided, implicitly creates Activity of type `EntityUpdated`\n\n## Relations\n\nTo create a relation, store a property that defines a `$relation` array.\n\nExample:\n\n```json\n{\n \"contacts\": {\n \"$relation\": [\n { \"entity_id\": \"3fa85f64-5717-4562-b3fc-2c963f66afa6\" }\n ]\n }\n}\n```\n\nThe items in `$relation` support two properties:\n- `entity_id` - The ID of the entity to link\n- `_tags` - Tags or labels for the relation (optional)\n",
1679
1897
  "tags": [
@@ -1744,6 +1962,12 @@
1744
1962
  },
1745
1963
  "delete": {
1746
1964
  "operationId": "deleteEntity",
1965
+ "x-epilot-permissions": [
1966
+ {
1967
+ "action": "entity:delete",
1968
+ "resource": "{slug}:{id}"
1969
+ }
1970
+ ],
1747
1971
  "summary": "deleteEntity",
1748
1972
  "description": "Deletes an Entity\n\n## Activity\n\nIf no `activity_id` query parameter is provided, implicitly creates Activity of type `EntityDeleted`\n\n## Deletion Mode\n\nAll entities are soft deleted by default. To force an actual deletion from the system, provide `purge:true` to delete the entity and all its activity history permanently.\n",
1749
1973
  "tags": [
@@ -1782,6 +2006,12 @@
1782
2006
  "/v1/entity:autocomplete": {
1783
2007
  "get": {
1784
2008
  "operationId": "autocomplete",
2009
+ "x-epilot-permissions": [
2010
+ {
2011
+ "action": "entity:view",
2012
+ "filter": true
2013
+ }
2014
+ ],
1785
2015
  "summary": "autocomplete",
1786
2016
  "description": "Autocomplete entity attributes.\n\nSuggestions are derived from the values **currently stored on entities** the caller is allowed to read.\nA value only shows up while at least one entity carries it, so this endpoint reflects usage, not\nconfiguration.\n\nTo enumerate the label catalogue managed in the Label Builder (including labels that are not\nassigned to any entity yet, and excluding archived ones), use the Taxonomy endpoints instead:\n`POST /v1/entity/taxonomies/classifications:search` (`taxonomiesClassificationsSearch`) or\n`GET /v1/entity/taxonomies/{taxonomySlug}:autocomplete` (`taxonomyAutocomplete`).\n\nFor `attribute=_tags` the distinct values are aggregated across all matching entities, `hits` is the exact\nnumber of distinct values (capped at 1000) and results are ordered by usage. For other attributes the\n1000 most recently updated entities are scanned and `hits` is the number of distinct values found so far.\n",
1787
2017
  "tags": [
@@ -1884,8 +2114,20 @@
1884
2114
  "/v1/entity:wipeAllEntities": {
1885
2115
  "post": {
1886
2116
  "operationId": "wipeAllEntities",
2117
+ "x-epilot-permissions": [
2118
+ {
2119
+ "anyOf": [
2120
+ {
2121
+ "access": "internal"
2122
+ },
2123
+ {
2124
+ "access": "owner"
2125
+ }
2126
+ ]
2127
+ }
2128
+ ],
1887
2129
  "summary": "wipeAllEntities",
1888
- "description": "Creates a request to queue the deletion of all entities in the system. This is a destructive operation and should only be used in sandbox environments.\n",
2130
+ "description": "Creates a request to queue the deletion of all entities in the system. This is a destructive operation and should only be used in sandbox environments.\n\nThe request is persisted as a wipe job whose progress can be followed with `listWipeJobs`.\nOmit `schemas` to wipe all schemas of the organization. An empty `schemas` array is rejected.\n\nOnly one wipe can run per schema at a time: a request that overlaps a running wipe\n(same schema, or any schema while a wipe of all schemas is running) is rejected with `409`.\nWipe executions are limited to 23 hours so they stop before their 24-hour locks expire.\n",
1889
2131
  "tags": [
1890
2132
  "Entities"
1891
2133
  ],
@@ -1897,6 +2139,8 @@
1897
2139
  "properties": {
1898
2140
  "schemas": {
1899
2141
  "type": "array",
2142
+ "description": "Schemas to wipe. Omit to wipe all schemas. An empty array is rejected with 400.",
2143
+ "maxItems": 90,
1900
2144
  "items": {
1901
2145
  "$ref": "#/components/schemas/EntitySlug"
1902
2146
  }
@@ -1908,7 +2152,85 @@
1908
2152
  },
1909
2153
  "responses": {
1910
2154
  "201": {
1911
- "description": "Wipe request was created"
2155
+ "description": "Wipe request was created",
2156
+ "content": {
2157
+ "application/json": {
2158
+ "schema": {
2159
+ "$ref": "#/components/schemas/WipeJob"
2160
+ }
2161
+ }
2162
+ }
2163
+ },
2164
+ "400": {
2165
+ "$ref": "#/components/responses/BadRequestError"
2166
+ },
2167
+ "409": {
2168
+ "description": "A wipe of one or more of the requested schemas is already running",
2169
+ "content": {
2170
+ "application/json": {
2171
+ "schema": {
2172
+ "$ref": "#/components/schemas/WipeJobConflictError"
2173
+ }
2174
+ }
2175
+ }
2176
+ }
2177
+ }
2178
+ }
2179
+ },
2180
+ "/v1/entity:wipeJobs": {
2181
+ "get": {
2182
+ "operationId": "listWipeJobs",
2183
+ "x-epilot-permissions": [
2184
+ {
2185
+ "anyOf": [
2186
+ {
2187
+ "access": "internal"
2188
+ },
2189
+ {
2190
+ "access": "owner"
2191
+ }
2192
+ ]
2193
+ }
2194
+ ],
2195
+ "summary": "listWipeJobs",
2196
+ "description": "Lists the most recent wipe jobs of the organization, newest first.\n",
2197
+ "tags": [
2198
+ "Entities"
2199
+ ],
2200
+ "parameters": [
2201
+ {
2202
+ "name": "limit",
2203
+ "in": "query",
2204
+ "description": "Maximum number of jobs to return",
2205
+ "schema": {
2206
+ "type": "integer",
2207
+ "default": 20,
2208
+ "minimum": 1,
2209
+ "maximum": 50
2210
+ }
2211
+ }
2212
+ ],
2213
+ "responses": {
2214
+ "200": {
2215
+ "description": "Success",
2216
+ "content": {
2217
+ "application/json": {
2218
+ "schema": {
2219
+ "type": "object",
2220
+ "required": [
2221
+ "results"
2222
+ ],
2223
+ "properties": {
2224
+ "results": {
2225
+ "type": "array",
2226
+ "items": {
2227
+ "$ref": "#/components/schemas/WipeJob"
2228
+ }
2229
+ }
2230
+ }
2231
+ }
2232
+ }
2233
+ }
1912
2234
  }
1913
2235
  }
1914
2236
  }
@@ -1916,6 +2238,11 @@
1916
2238
  "/v1/entity/activity": {
1917
2239
  "post": {
1918
2240
  "operationId": "createActivity",
2241
+ "x-epilot-permissions": [
2242
+ {
2243
+ "action": "entity:view"
2244
+ }
2245
+ ],
1919
2246
  "summary": "createActivity",
1920
2247
  "description": "Create an activity that can be displayed in activity feeds.\n\n- All activites are published as events on the event bus\n- Entity mutations are always part of an activity\n- When more than 10 entities are passed, the first 10 are attached synchronously and the rest are processed asynchronously to avoid DynamoDB throttling\n",
1921
2248
  "tags": [
@@ -1965,6 +2292,11 @@
1965
2292
  "/v1/entity/activity/{id}": {
1966
2293
  "get": {
1967
2294
  "operationId": "getActivity",
2295
+ "x-epilot-permissions": [
2296
+ {
2297
+ "access": "org"
2298
+ }
2299
+ ],
1968
2300
  "summary": "getActivity",
1969
2301
  "description": "Get activity by id",
1970
2302
  "tags": [
@@ -2019,6 +2351,11 @@
2019
2351
  "/v1/entity/activity/{id}:attach": {
2020
2352
  "post": {
2021
2353
  "operationId": "attachActivity",
2354
+ "x-epilot-permissions": [
2355
+ {
2356
+ "action": "entity:view"
2357
+ }
2358
+ ],
2022
2359
  "summary": "attachActivity",
2023
2360
  "description": "Attach existing activity to entity activity feeds",
2024
2361
  "tags": [
@@ -2065,6 +2402,12 @@
2065
2402
  "/v1/entity/{slug}/{id}/changesets/{attribute}:apply": {
2066
2403
  "post": {
2067
2404
  "operationId": "applyChangeset",
2405
+ "x-epilot-permissions": [
2406
+ {
2407
+ "action": "entity:edit",
2408
+ "resource": "{slug}:{id}"
2409
+ }
2410
+ ],
2068
2411
  "summary": "applyChangeset",
2069
2412
  "description": "Applies the proposed value from a pending changeset to the entity attribute\nand removes the changeset. Used for human approval of pending changes.\n",
2070
2413
  "tags": [
@@ -2107,6 +2450,12 @@
2107
2450
  "/v1/entity/{slug}/{id}/changesets/{attribute}:dismiss": {
2108
2451
  "post": {
2109
2452
  "operationId": "dismissChangeset",
2453
+ "x-epilot-permissions": [
2454
+ {
2455
+ "action": "entity:edit",
2456
+ "resource": "{slug}:{id}"
2457
+ }
2458
+ ],
2110
2459
  "summary": "dismissChangeset",
2111
2460
  "description": "Removes a pending changeset without applying it. The attribute value remains unchanged.\n",
2112
2461
  "tags": [
@@ -2164,6 +2513,12 @@
2164
2513
  "/v1/entity/{slug}/{id}/changesets": {
2165
2514
  "get": {
2166
2515
  "operationId": "listChangesets",
2516
+ "x-epilot-permissions": [
2517
+ {
2518
+ "action": "entity:view",
2519
+ "resource": "{slug}:{id}"
2520
+ }
2521
+ ],
2167
2522
  "summary": "listChangesets",
2168
2523
  "description": "Returns all pending changesets for an entity.",
2169
2524
  "tags": [
@@ -2200,6 +2555,12 @@
2200
2555
  "/v1/entity/{slug}/{id}/activity": {
2201
2556
  "get": {
2202
2557
  "operationId": "getEntityActivityFeed",
2558
+ "x-epilot-permissions": [
2559
+ {
2560
+ "action": "entity:view",
2561
+ "resource": "{slug}:{id}"
2562
+ }
2563
+ ],
2203
2564
  "summary": "getEntityActivityFeed",
2204
2565
  "description": "Get activity feed for an entity\n",
2205
2566
  "tags": [
@@ -2343,13 +2704,19 @@
2343
2704
  }
2344
2705
  }
2345
2706
  },
2346
- "/v1/entity/{slug}/{id}/relations": {
2707
+ "/v1/entity/{slug}/{id}/summary": {
2347
2708
  "get": {
2348
- "operationId": "getRelations",
2349
- "summary": "getRelations",
2350
- "description": "Returns 1st level direct relations for an entity.\n\nYou can control whether to return the full entity or just the relation item with the `?hydrate` query param.\n\nReverse relations i.e. entities referring to this entity are included with the `?include_reverse` query param.\n",
2709
+ "operationId": "getEntitySummary",
2710
+ "x-epilot-permissions": [
2711
+ {
2712
+ "action": "entity:view",
2713
+ "resource": "{slug}:{id}"
2714
+ }
2715
+ ],
2716
+ "summary": "getEntitySummary",
2717
+ "description": "Get the latest AI generated summary of an entity. Summaries are generated by the\nai-agents-api `skill:entity-summary` and stored here when the execution completes.\n",
2351
2718
  "tags": [
2352
- "Relations"
2719
+ "AI"
2353
2720
  ],
2354
2721
  "parameters": [
2355
2722
  {
@@ -2357,11 +2724,54 @@
2357
2724
  },
2358
2725
  {
2359
2726
  "$ref": "#/components/parameters/EntityIdPathParam"
2727
+ }
2728
+ ],
2729
+ "responses": {
2730
+ "200": {
2731
+ "description": "Success",
2732
+ "content": {
2733
+ "application/json": {
2734
+ "schema": {
2735
+ "$ref": "#/components/schemas/EntitySummary"
2736
+ }
2737
+ }
2738
+ }
2360
2739
  },
2361
- {
2362
- "$ref": "#/components/parameters/HydrateEntitiesQueryParam"
2363
- },
2364
- {
2740
+ "404": {
2741
+ "$ref": "#/components/responses/NotFoundError"
2742
+ }
2743
+ }
2744
+ }
2745
+ },
2746
+ "/v1/entity/{slug}/{id}/relations": {
2747
+ "get": {
2748
+ "operationId": "getRelations",
2749
+ "x-epilot-permissions": [
2750
+ {
2751
+ "action": "entity:view",
2752
+ "resource": "{slug}:{id}"
2753
+ },
2754
+ {
2755
+ "action": "entity:view",
2756
+ "filter": true
2757
+ }
2758
+ ],
2759
+ "summary": "getRelations",
2760
+ "description": "Returns 1st level direct relations for an entity.\n\nYou can control whether to return the full entity or just the relation item with the `?hydrate` query param.\n\nReverse relations i.e. entities referring to this entity are included with the `?include_reverse` query param.\n",
2761
+ "tags": [
2762
+ "Relations"
2763
+ ],
2764
+ "parameters": [
2765
+ {
2766
+ "$ref": "#/components/parameters/EntitySlugPathParam"
2767
+ },
2768
+ {
2769
+ "$ref": "#/components/parameters/EntityIdPathParam"
2770
+ },
2771
+ {
2772
+ "$ref": "#/components/parameters/HydrateEntitiesQueryParam"
2773
+ },
2774
+ {
2365
2775
  "$ref": "#/components/parameters/AnonymizeQueryParam"
2366
2776
  },
2367
2777
  {
@@ -2445,6 +2855,12 @@
2445
2855
  },
2446
2856
  "post": {
2447
2857
  "operationId": "addRelations",
2858
+ "x-epilot-permissions": [
2859
+ {
2860
+ "action": "entity:edit",
2861
+ "resource": "{slug}:{id}"
2862
+ }
2863
+ ],
2448
2864
  "summary": "addRelations",
2449
2865
  "description": "Relates one or more entities to parent entity by adding items to a relation attribute",
2450
2866
  "tags": [
@@ -2511,6 +2927,12 @@
2511
2927
  },
2512
2928
  "delete": {
2513
2929
  "operationId": "removeRelations",
2930
+ "x-epilot-permissions": [
2931
+ {
2932
+ "action": "entity:edit",
2933
+ "resource": "{slug}:{id}"
2934
+ }
2935
+ ],
2514
2936
  "summary": "removeRelations",
2515
2937
  "description": "Disassociate one or more entities to parent entity by removing items to a relation attribute",
2516
2938
  "tags": [
@@ -2575,6 +2997,16 @@
2575
2997
  "/v2/entity/{slug}/{id}/relations": {
2576
2998
  "get": {
2577
2999
  "operationId": "getRelationsV2",
3000
+ "x-epilot-permissions": [
3001
+ {
3002
+ "action": "entity:view",
3003
+ "resource": "{slug}:{id}"
3004
+ },
3005
+ {
3006
+ "action": "entity:view",
3007
+ "filter": true
3008
+ }
3009
+ ],
2578
3010
  "summary": "getRelationsV2",
2579
3011
  "description": "Returns 1st level direct relations for an entity with pagination.\n\nYou can control whether to return the full entity or just the relation item with the `?hydrate` query param.\n\nReverse relations i.e. entities referring to this entity are included with the `?include_reverse` query param.\n",
2580
3012
  "tags": [
@@ -2647,6 +3079,16 @@
2647
3079
  "/v3/entity/{slug}/{id}/relations": {
2648
3080
  "get": {
2649
3081
  "operationId": "getRelationsV3",
3082
+ "x-epilot-permissions": [
3083
+ {
3084
+ "action": "entity:view",
3085
+ "resource": "{slug}:{id}"
3086
+ },
3087
+ {
3088
+ "action": "entity:view",
3089
+ "filter": true
3090
+ }
3091
+ ],
2650
3092
  "summary": "getRelationsV3",
2651
3093
  "description": "Returns 1st level direct relations for an entity with pagination.\n\nYou can control whether to return the full entity or just the relation item with the `?hydrate` query param.\n\nReverse relations i.e. entities referring to this entity are included with the `?include_reverse` query param.\n",
2652
3094
  "tags": [
@@ -2730,6 +3172,12 @@
2730
3172
  "/v2/entity/{slug}/{id}/relations/count": {
2731
3173
  "get": {
2732
3174
  "operationId": "getRelatedEntitiesCount",
3175
+ "x-epilot-permissions": [
3176
+ {
3177
+ "action": "entity:view",
3178
+ "resource": "{slug}:{id}"
3179
+ }
3180
+ ],
2733
3181
  "summary": "getRelatedEntitiesCount",
2734
3182
  "description": "Returns the amount of unique related entities for an entity - includes direct and reverse relations.\n",
2735
3183
  "tags": [
@@ -2766,6 +3214,12 @@
2766
3214
  "/v1/entity/{slug}/{id}/relations/{attribute}/{entity_id}": {
2767
3215
  "put": {
2768
3216
  "operationId": "updateRelation",
3217
+ "x-epilot-permissions": [
3218
+ {
3219
+ "action": "entity:edit",
3220
+ "resource": "{slug}:{id}"
3221
+ }
3222
+ ],
2769
3223
  "summary": "updateRelation",
2770
3224
  "description": "Updates an existing relation between two entities.",
2771
3225
  "tags": [
@@ -2845,6 +3299,12 @@
2845
3299
  },
2846
3300
  "delete": {
2847
3301
  "operationId": "deleteRelation",
3302
+ "x-epilot-permissions": [
3303
+ {
3304
+ "action": "entity:edit",
3305
+ "resource": "{slug}:{id}"
3306
+ }
3307
+ ],
2848
3308
  "summary": "deleteRelation",
2849
3309
  "description": "Removes relation between two entities",
2850
3310
  "tags": [
@@ -2898,6 +3358,12 @@
2898
3358
  "/v1/entity:export": {
2899
3359
  "post": {
2900
3360
  "operationId": "exportEntities",
3361
+ "x-epilot-permissions": [
3362
+ {
3363
+ "action": "entity:view",
3364
+ "filter": true
3365
+ }
3366
+ ],
2901
3367
  "summary": "exportEntities",
2902
3368
  "description": "Export entity data in a CSV-format. The export will export data as close as possible to what is visible on Entity UI tables.\nThe values exported as in some cases, transformed to human-readable values.\n\nTo force the export of raw values, use the `#` prefix in front of your field name when specifying the field on the `fields` param.\n",
2903
3369
  "tags": [
@@ -2951,6 +3417,18 @@
2951
3417
  "/v1/entity:import": {
2952
3418
  "post": {
2953
3419
  "operationId": "importEntities",
3420
+ "x-epilot-permissions": [
3421
+ {
3422
+ "anyOf": [
3423
+ {
3424
+ "action": "entity:create"
3425
+ },
3426
+ {
3427
+ "action": "entity:edit"
3428
+ }
3429
+ ]
3430
+ }
3431
+ ],
2954
3432
  "summary": "Import Entities",
2955
3433
  "description": "This endpoint enables the import of entities into the platform.\nThe entities should be provided in a CSV format inside an S3 bucket.\nThis API will return the `job_id`` which can be used to fetch the status of the import process.\n",
2956
3434
  "tags": [
@@ -2977,7 +3455,146 @@
2977
3455
  },
2978
3456
  "responses": {
2979
3457
  "201": {
2980
- "description": "The import operation was initiated successfully.\nThe response includes the URLs for the files containing the successful and failed imported entities.\n"
3458
+ "description": "The import operation was initiated successfully.\nThe response includes the URLs for the files containing the successful and failed imported entities.\n",
3459
+ "content": {
3460
+ "application/json": {
3461
+ "schema": {
3462
+ "$ref": "#/components/schemas/ImportProgress"
3463
+ }
3464
+ }
3465
+ }
3466
+ },
3467
+ "429": {
3468
+ "$ref": "#/components/responses/TooManyRequestsError"
3469
+ }
3470
+ }
3471
+ }
3472
+ },
3473
+ "/v1/entity:import:latest": {
3474
+ "get": {
3475
+ "operationId": "getLatestEntityImport",
3476
+ "x-epilot-permissions": [
3477
+ {
3478
+ "anyOf": [
3479
+ {
3480
+ "action": "entity:create"
3481
+ },
3482
+ {
3483
+ "action": "entity:edit"
3484
+ }
3485
+ ]
3486
+ }
3487
+ ],
3488
+ "summary": "Get the latest import job of a schema",
3489
+ "description": "Returns the progress of the latest import job for the organization and schema: the running job,\nwhoever started it (it blocks every other import of the schema), otherwise the caller's own last\nfinished job if it finished within the last 24 hours. Used to show the state of an import (or dry\nrun) that was started earlier.\n",
3490
+ "tags": [
3491
+ "Import-Export"
3492
+ ],
3493
+ "parameters": [
3494
+ {
3495
+ "in": "query",
3496
+ "name": "schema",
3497
+ "required": true,
3498
+ "description": "Slug of the schema.",
3499
+ "schema": {
3500
+ "type": "string"
3501
+ }
3502
+ }
3503
+ ],
3504
+ "responses": {
3505
+ "200": {
3506
+ "description": "Progress of the latest import job.",
3507
+ "content": {
3508
+ "application/json": {
3509
+ "schema": {
3510
+ "$ref": "#/components/schemas/ImportProgress"
3511
+ }
3512
+ }
3513
+ }
3514
+ },
3515
+ "400": {
3516
+ "description": "Bad Request"
3517
+ },
3518
+ "403": {
3519
+ "description": "Forbidden"
3520
+ },
3521
+ "404": {
3522
+ "description": "No import job for this schema in the last 24 hours"
3523
+ },
3524
+ "429": {
3525
+ "$ref": "#/components/responses/TooManyRequestsError"
3526
+ }
3527
+ }
3528
+ }
3529
+ },
3530
+ "/v1/entity:importHistory": {
3531
+ "get": {
3532
+ "operationId": "getEntityImportHistory",
3533
+ "x-epilot-permissions": [
3534
+ {
3535
+ "anyOf": [
3536
+ {
3537
+ "action": "entity:create"
3538
+ },
3539
+ {
3540
+ "action": "entity:edit"
3541
+ }
3542
+ ]
3543
+ }
3544
+ ],
3545
+ "summary": "List the import jobs of a schema",
3546
+ "description": "Lists the import jobs (imports and dry runs) of a schema in the organization, newest first: the\nrunning job, if any, then the jobs that ended in the last 30 days. Every caller with access sees\nevery job. Without jobs the list is empty; this operation does not answer 404.\n",
3547
+ "tags": [
3548
+ "Import-Export"
3549
+ ],
3550
+ "parameters": [
3551
+ {
3552
+ "in": "query",
3553
+ "name": "schema",
3554
+ "required": true,
3555
+ "description": "Slug of the schema.",
3556
+ "schema": {
3557
+ "type": "string"
3558
+ }
3559
+ },
3560
+ {
3561
+ "in": "query",
3562
+ "name": "limit",
3563
+ "required": false,
3564
+ "description": "Maximum number of jobs to return. Values outside 1 to 50 are clamped.",
3565
+ "schema": {
3566
+ "type": "integer",
3567
+ "default": 50
3568
+ }
3569
+ }
3570
+ ],
3571
+ "responses": {
3572
+ "200": {
3573
+ "description": "The import jobs of the schema, newest first.",
3574
+ "content": {
3575
+ "application/json": {
3576
+ "schema": {
3577
+ "type": "object",
3578
+ "required": [
3579
+ "jobs"
3580
+ ],
3581
+ "properties": {
3582
+ "jobs": {
3583
+ "type": "array",
3584
+ "items": {
3585
+ "$ref": "#/components/schemas/ImportJobSummary"
3586
+ }
3587
+ }
3588
+ }
3589
+ }
3590
+ }
3591
+ }
3592
+ },
3593
+ "400": {
3594
+ "description": "Bad Request"
3595
+ },
3596
+ "403": {
3597
+ "description": "Forbidden"
2981
3598
  },
2982
3599
  "429": {
2983
3600
  "$ref": "#/components/responses/TooManyRequestsError"
@@ -2988,6 +3605,11 @@
2988
3605
  "/v1/entity:abortImport": {
2989
3606
  "post": {
2990
3607
  "operationId": "abortEntityImport",
3608
+ "x-epilot-permissions": [
3609
+ {
3610
+ "access": "org"
3611
+ }
3612
+ ],
2991
3613
  "summary": "Abort a running entity import",
2992
3614
  "description": "Asks a running import to stop. Rows already imported are **kept** - this is a stop, not a\nrollback - and the job still produces its result reports for everything that landed before\nthe stop, then reaches the terminal status `CANCELLED`.\n\nThe stop is cooperative: the worker notices the request at its next batch boundary, so the\njob typically reaches `CANCELLED` within seconds. Poll `POST /v1/entity:import` with the\n`job_id` as usual to observe it.\n\nIdempotent - aborting an already-aborted or already-finished job is not an error.\n",
2993
3615
  "tags": [
@@ -3048,9 +3670,85 @@
3048
3670
  }
3049
3671
  }
3050
3672
  },
3673
+ "/v1/entity:discardImport": {
3674
+ "post": {
3675
+ "operationId": "discardEntityImport",
3676
+ "x-epilot-permissions": [
3677
+ {
3678
+ "access": "org"
3679
+ }
3680
+ ],
3681
+ "summary": "Discard a finished dry run",
3682
+ "description": "Discards a dry run that has finished (`COMPLETED`), so it is no longer offered for import.\nThe job becomes `CANCELLED` and `GET /v1/entity:import:latest` stops returning it as ready.\nFor a file that requires a dry run (more than 50 rows), an import passing it as\n`dry_run_job_id` then fails with `dry_run_required`. The dry run wrote nothing, and its\nreport stays available.\n\nOnly the user who ran the dry run can discard it (403 otherwise). Idempotent - discarding an\nalready discarded dry run answers 200. A running dry run is stopped with\n`POST /v1/entity:abortImport` instead.\n",
3683
+ "tags": [
3684
+ "Import-Export"
3685
+ ],
3686
+ "parameters": [
3687
+ {
3688
+ "in": "query",
3689
+ "name": "job_id",
3690
+ "required": true,
3691
+ "description": "The ID of the dry run to discard.",
3692
+ "schema": {
3693
+ "$ref": "#/components/schemas/ExportJobId"
3694
+ }
3695
+ },
3696
+ {
3697
+ "in": "query",
3698
+ "name": "schema",
3699
+ "required": true,
3700
+ "description": "Slug of the schema of the dry run, used to authorize the caller.",
3701
+ "schema": {
3702
+ "type": "string"
3703
+ }
3704
+ }
3705
+ ],
3706
+ "responses": {
3707
+ "200": {
3708
+ "description": "The dry run is discarded.",
3709
+ "content": {
3710
+ "application/json": {
3711
+ "schema": {
3712
+ "type": "object",
3713
+ "properties": {
3714
+ "status": {
3715
+ "type": "string",
3716
+ "description": "`CANCELLED`"
3717
+ },
3718
+ "jobPollId": {
3719
+ "type": "string"
3720
+ }
3721
+ }
3722
+ }
3723
+ }
3724
+ }
3725
+ },
3726
+ "400": {
3727
+ "description": "Bad Request"
3728
+ },
3729
+ "403": {
3730
+ "description": "Forbidden"
3731
+ },
3732
+ "404": {
3733
+ "description": "No such import job"
3734
+ },
3735
+ "409": {
3736
+ "description": "The job is not a finished dry run (still running, or a real import)"
3737
+ },
3738
+ "429": {
3739
+ "$ref": "#/components/responses/TooManyRequestsError"
3740
+ }
3741
+ }
3742
+ }
3743
+ },
3051
3744
  "/v1/entity/views": {
3052
3745
  "get": {
3053
3746
  "operationId": "listSavedViews",
3747
+ "x-epilot-permissions": [
3748
+ {
3749
+ "access": "org"
3750
+ }
3751
+ ],
3054
3752
  "summary": "listSavedViews",
3055
3753
  "description": "Get the Saved Views based on the schema",
3056
3754
  "tags": [
@@ -3133,6 +3831,11 @@
3133
3831
  "/v1/entity/view": {
3134
3832
  "post": {
3135
3833
  "operationId": "createSavedView",
3834
+ "x-epilot-permissions": [
3835
+ {
3836
+ "access": "org"
3837
+ }
3838
+ ],
3136
3839
  "summary": "createSavedView",
3137
3840
  "description": "Creates a new saved view",
3138
3841
  "tags": [
@@ -3167,6 +3870,11 @@
3167
3870
  "/v1/entity/view/{id}": {
3168
3871
  "get": {
3169
3872
  "operationId": "getSavedView",
3873
+ "x-epilot-permissions": [
3874
+ {
3875
+ "access": "org"
3876
+ }
3877
+ ],
3170
3878
  "summary": "getSavedView",
3171
3879
  "description": "Gets Saved View configuration by id.",
3172
3880
  "tags": [
@@ -3195,6 +3903,12 @@
3195
3903
  },
3196
3904
  "put": {
3197
3905
  "operationId": "updateSavedView",
3906
+ "x-epilot-permissions": [
3907
+ {
3908
+ "action": "entity:view",
3909
+ "resource": "{slug}"
3910
+ }
3911
+ ],
3198
3912
  "summary": "updateSavedView",
3199
3913
  "description": "Updates a saved view",
3200
3914
  "tags": [
@@ -3229,6 +3943,12 @@
3229
3943
  },
3230
3944
  "patch": {
3231
3945
  "operationId": "patchSavedView",
3946
+ "x-epilot-permissions": [
3947
+ {
3948
+ "action": "entity:view",
3949
+ "resource": "{slug}"
3950
+ }
3951
+ ],
3232
3952
  "summary": "patchSavedView",
3233
3953
  "description": "Partially updates a saved view with the provided payload. If an updated_at is passed and the server contains a newer version of the view a `409` error is returned",
3234
3954
  "tags": [
@@ -3263,6 +3983,12 @@
3263
3983
  },
3264
3984
  "delete": {
3265
3985
  "operationId": "deleteSavedView",
3986
+ "x-epilot-permissions": [
3987
+ {
3988
+ "action": "entity:view",
3989
+ "resource": "{slug}"
3990
+ }
3991
+ ],
3266
3992
  "summary": "deleteSavedView",
3267
3993
  "description": "Deletes a saved view",
3268
3994
  "parameters": [
@@ -3289,6 +4015,11 @@
3289
4015
  "/v1/entity/views/favorites": {
3290
4016
  "get": {
3291
4017
  "operationId": "listFavoriteViewsForUser",
4018
+ "x-epilot-permissions": [
4019
+ {
4020
+ "access": "self"
4021
+ }
4022
+ ],
3292
4023
  "summary": "listFavoriteViewsForUser",
3293
4024
  "description": "Get the Favorite Saved Views for user based on the schema",
3294
4025
  "tags": [
@@ -3319,6 +4050,11 @@
3319
4050
  "/v1/entity/taxonomies": {
3320
4051
  "get": {
3321
4052
  "operationId": "listTaxonomies",
4053
+ "x-epilot-permissions": [
4054
+ {
4055
+ "access": "org"
4056
+ }
4057
+ ],
3322
4058
  "summary": "listTaxonomies",
3323
4059
  "description": "List taxonomies in an organization",
3324
4060
  "parameters": [
@@ -3371,6 +4107,11 @@
3371
4107
  },
3372
4108
  "post": {
3373
4109
  "operationId": "createTaxonomy",
4110
+ "x-epilot-permissions": [
4111
+ {
4112
+ "action": "label_builder:create"
4113
+ }
4114
+ ],
3374
4115
  "summary": "createTaxonomy",
3375
4116
  "description": "Create a new taxonomy",
3376
4117
  "tags": [
@@ -3408,6 +4149,11 @@
3408
4149
  "/v1/entity/taxonomies/{taxonomySlug}": {
3409
4150
  "get": {
3410
4151
  "operationId": "getTaxonomy",
4152
+ "x-epilot-permissions": [
4153
+ {
4154
+ "access": "org"
4155
+ }
4156
+ ],
3411
4157
  "summary": "getTaxonomy",
3412
4158
  "description": "Get taxonomy by slug",
3413
4159
  "tags": [
@@ -3436,6 +4182,11 @@
3436
4182
  },
3437
4183
  "put": {
3438
4184
  "operationId": "updateTaxonomy",
4185
+ "x-epilot-permissions": [
4186
+ {
4187
+ "action": "label_builder:edit"
4188
+ }
4189
+ ],
3439
4190
  "summary": "updateTaxonomy",
3440
4191
  "description": "Update a taxonomy",
3441
4192
  "tags": [
@@ -3470,6 +4221,11 @@
3470
4221
  },
3471
4222
  "delete": {
3472
4223
  "operationId": "deleteTaxonomy",
4224
+ "x-epilot-permissions": [
4225
+ {
4226
+ "action": "label_builder:delete"
4227
+ }
4228
+ ],
3473
4229
  "summary": "deleteTaxonomy",
3474
4230
  "description": "Delete a taxonomy",
3475
4231
  "tags": [
@@ -3503,6 +4259,21 @@
3503
4259
  "/v1/entity/taxonomies/{taxonomySlug}/classifications": {
3504
4260
  "post": {
3505
4261
  "operationId": "updateClassificationsForTaxonomy",
4262
+ "x-epilot-permissions": [
4263
+ {
4264
+ "anyOf": [
4265
+ {
4266
+ "action": "label_builder:create"
4267
+ },
4268
+ {
4269
+ "action": "label_builder:edit"
4270
+ },
4271
+ {
4272
+ "action": "label_builder:delete"
4273
+ }
4274
+ ]
4275
+ }
4276
+ ],
3506
4277
  "summary": "updateClassificationsForTaxonomy",
3507
4278
  "description": "Update the classifications for a taxonomy",
3508
4279
  "tags": [
@@ -3565,6 +4336,11 @@
3565
4336
  "/v2/entity/taxonomies/classifications": {
3566
4337
  "post": {
3567
4338
  "operationId": "createTaxonomyClassification",
4339
+ "x-epilot-permissions": [
4340
+ {
4341
+ "action": "label_builder:create"
4342
+ }
4343
+ ],
3568
4344
  "summary": "createTaxonomyClassification",
3569
4345
  "description": "Create a new classification for a taxonomy\n",
3570
4346
  "tags": [
@@ -3602,6 +4378,11 @@
3602
4378
  "/v2/entity/taxonomies/classifications/{classificationSlug}": {
3603
4379
  "get": {
3604
4380
  "operationId": "getTaxonomyClassification",
4381
+ "x-epilot-permissions": [
4382
+ {
4383
+ "access": "org"
4384
+ }
4385
+ ],
3605
4386
  "summary": "getTaxonomyClassification",
3606
4387
  "description": "Get a classification for a taxonomy by slug\n\nFor backwards compatibility with purposes, you can also pass the classification id instead of the slug.\n",
3607
4388
  "tags": [
@@ -3630,6 +4411,11 @@
3630
4411
  },
3631
4412
  "put": {
3632
4413
  "operationId": "updateTaxonomyClassification",
4414
+ "x-epilot-permissions": [
4415
+ {
4416
+ "action": "label_builder:edit"
4417
+ }
4418
+ ],
3633
4419
  "summary": "updateTaxonomyClassification",
3634
4420
  "description": "Update a classification for a taxonomy",
3635
4421
  "tags": [
@@ -3667,6 +4453,11 @@
3667
4453
  },
3668
4454
  "delete": {
3669
4455
  "operationId": "deleteTaxonomyClassification",
4456
+ "x-epilot-permissions": [
4457
+ {
4458
+ "action": "label_builder:delete"
4459
+ }
4460
+ ],
3670
4461
  "summary": "deleteTaxonomyClassification",
3671
4462
  "description": "Delete a classification for a taxonomy",
3672
4463
  "tags": [
@@ -3700,6 +4491,11 @@
3700
4491
  "/v1/entity/taxonomies/{taxonomySlug}:autocomplete": {
3701
4492
  "get": {
3702
4493
  "operationId": "taxonomyAutocomplete",
4494
+ "x-epilot-permissions": [
4495
+ {
4496
+ "access": "org"
4497
+ }
4498
+ ],
3703
4499
  "summary": "taxonomyAutocomplete",
3704
4500
  "description": "Taxonomies autocomplete",
3705
4501
  "tags": [
@@ -3751,6 +4547,11 @@
3751
4547
  "/v1/entity/taxonomies/classifications:search": {
3752
4548
  "post": {
3753
4549
  "operationId": "taxonomiesClassificationsSearch",
4550
+ "x-epilot-permissions": [
4551
+ {
4552
+ "access": "org"
4553
+ }
4554
+ ],
3754
4555
  "summary": "taxonomiesClassificationsSearch",
3755
4556
  "description": "List taxonomy classifications in an organization based on taxonomy slug",
3756
4557
  "tags": [
@@ -3879,6 +4680,11 @@
3879
4680
  "/v1/entity/schemas/{slug}/taxonomy/{taxonomySlug}": {
3880
4681
  "get": {
3881
4682
  "operationId": "listTaxonomyClassificationsForSchema",
4683
+ "x-epilot-permissions": [
4684
+ {
4685
+ "access": "org"
4686
+ }
4687
+ ],
3882
4688
  "summary": "listTaxonomyClassificationsForSchema",
3883
4689
  "description": "List taxonomy classifications for a given schema",
3884
4690
  "tags": [
@@ -3931,6 +4737,11 @@
3931
4737
  "/v1/entity/taxonomies/bulk-jobs": {
3932
4738
  "get": {
3933
4739
  "operationId": "getTaxonomyBulkActionJobs",
4740
+ "x-epilot-permissions": [
4741
+ {
4742
+ "access": "org"
4743
+ }
4744
+ ],
3934
4745
  "summary": "getTaxonomyBulkActionJobs",
3935
4746
  "description": "Gets bulk actions jobs by job status:\n- <undefined> = all active jobs\n- PENDING = all active jobs\n- FAILED = all failed jobs\n- COMPLETED = all completed jobs\n",
3936
4747
  "tags": [
@@ -4011,6 +4822,11 @@
4011
4822
  "/v1/entity/taxonomies/bulk-jobs/{job_id}": {
4012
4823
  "get": {
4013
4824
  "operationId": "getTaxonomyBulkActionJobById",
4825
+ "x-epilot-permissions": [
4826
+ {
4827
+ "access": "org"
4828
+ }
4829
+ ],
4014
4830
  "summary": "getTaxonomyBulkActionJobById",
4015
4831
  "description": "Gets a bulk action job by job id",
4016
4832
  "tags": [
@@ -4043,6 +4859,11 @@
4043
4859
  "/v1/entity/taxonomies/bulk-jobs/{job_id}/cancel": {
4044
4860
  "post": {
4045
4861
  "operationId": "cancelBulkAction",
4862
+ "x-epilot-permissions": [
4863
+ {
4864
+ "action": "label_builder:*"
4865
+ }
4866
+ ],
4046
4867
  "summary": "cancelBulkAction",
4047
4868
  "description": "Cancels a running bulk action job. The job status will be updated to CANCELLED\nand the job will be stopped.\n",
4048
4869
  "tags": [
@@ -4091,6 +4912,11 @@
4091
4912
  "/v1/entity/taxonomies/classifications:move": {
4092
4913
  "post": {
4093
4914
  "operationId": "bulkMoveClassifications",
4915
+ "x-epilot-permissions": [
4916
+ {
4917
+ "action": "label_builder:*"
4918
+ }
4919
+ ],
4094
4920
  "summary": "bulkMoveClassifications",
4095
4921
  "description": "Moves classifications from one taxonomy to another, through a bulk async operation which\nalso updates all references from the old classification to the new one under the target taxonomy.\n",
4096
4922
  "tags": [
@@ -4159,6 +4985,11 @@
4159
4985
  "/v1/entity/taxonomies/classifications:merge": {
4160
4986
  "post": {
4161
4987
  "operationId": "bulkMergeClassifications",
4988
+ "x-epilot-permissions": [
4989
+ {
4990
+ "action": "label_builder:*"
4991
+ }
4992
+ ],
4162
4993
  "summary": "bulkMergeClassifications",
4163
4994
  "description": "Merges classifications from one taxonomy into one individual classification, through a bulk async operation which\nalso updates all references from the old Classifications to the new one.\n",
4164
4995
  "tags": [
@@ -4227,6 +5058,11 @@
4227
5058
  "/v1/entity/taxonomies/classifications:delete": {
4228
5059
  "post": {
4229
5060
  "operationId": "bulkDeleteClassifications",
5061
+ "x-epilot-permissions": [
5062
+ {
5063
+ "action": "label_builder:*"
5064
+ }
5065
+ ],
4230
5066
  "summary": "bulkDeleteClassifications",
4231
5067
  "description": "Permanently deletes taxonomy classifications. The classifications are deleted through a bulk\nasync operation which also deletes all references of the deleted classifications from the entities\nreferencing them.\n",
4232
5068
  "tags": [
@@ -4285,6 +5121,11 @@
4285
5121
  "/v1/entity/schemas/attributes": {
4286
5122
  "post": {
4287
5123
  "operationId": "createSchemaAttribute",
5124
+ "x-epilot-permissions": [
5125
+ {
5126
+ "action": "schema:update"
5127
+ }
5128
+ ],
4288
5129
  "summary": "createSchemaAttribute",
4289
5130
  "description": "Create a schema attribute",
4290
5131
  "tags": [
@@ -4319,6 +5160,11 @@
4319
5160
  "/v1/entity/schemas/attributes/{composite_id}": {
4320
5161
  "get": {
4321
5162
  "operationId": "getSchemaAttribute",
5163
+ "x-epilot-permissions": [
5164
+ {
5165
+ "access": "org"
5166
+ }
5167
+ ],
4322
5168
  "summary": "getSchemaAttribute",
4323
5169
  "description": "Get a schema attribute from given attribute ID",
4324
5170
  "tags": [
@@ -4355,6 +5201,11 @@
4355
5201
  },
4356
5202
  "put": {
4357
5203
  "operationId": "putSchemaAttribute",
5204
+ "x-epilot-permissions": [
5205
+ {
5206
+ "action": "schema:update"
5207
+ }
5208
+ ],
4358
5209
  "summary": "putSchemaAttribute",
4359
5210
  "description": "Updates an attribute in the schema",
4360
5211
  "tags": [
@@ -4397,6 +5248,11 @@
4397
5248
  },
4398
5249
  "delete": {
4399
5250
  "operationId": "deleteSchemaAttribute",
5251
+ "x-epilot-permissions": [
5252
+ {
5253
+ "action": "schema:update"
5254
+ }
5255
+ ],
4400
5256
  "summary": "deleteSchemaAttribute",
4401
5257
  "description": "Deletes an attribute from a schema",
4402
5258
  "tags": [
@@ -4435,6 +5291,11 @@
4435
5291
  "/v1/entity/schemas/capabilities": {
4436
5292
  "post": {
4437
5293
  "operationId": "createSchemaCapability",
5294
+ "x-epilot-permissions": [
5295
+ {
5296
+ "action": "schema:update"
5297
+ }
5298
+ ],
4438
5299
  "summary": "createSchemaCapability",
4439
5300
  "description": "Create a schema capability",
4440
5301
  "tags": [
@@ -4469,6 +5330,11 @@
4469
5330
  "/v1/entity/schemas/capabilities/{composite_id}": {
4470
5331
  "get": {
4471
5332
  "operationId": "getSchemaCapability",
5333
+ "x-epilot-permissions": [
5334
+ {
5335
+ "access": "org"
5336
+ }
5337
+ ],
4472
5338
  "summary": "getSchemaCapability",
4473
5339
  "description": "Get a schema capability from given capability ID",
4474
5340
  "tags": [
@@ -4505,6 +5371,11 @@
4505
5371
  },
4506
5372
  "put": {
4507
5373
  "operationId": "putSchemaCapability",
5374
+ "x-epilot-permissions": [
5375
+ {
5376
+ "action": "schema:update"
5377
+ }
5378
+ ],
4508
5379
  "summary": "putSchemaCapability",
4509
5380
  "description": "Adds or updates an capability in the schema",
4510
5381
  "tags": [
@@ -4547,6 +5418,11 @@
4547
5418
  },
4548
5419
  "delete": {
4549
5420
  "operationId": "deleteSchemaCapability",
5421
+ "x-epilot-permissions": [
5422
+ {
5423
+ "action": "schema:update"
5424
+ }
5425
+ ],
4550
5426
  "summary": "deleteSchemaCapability",
4551
5427
  "description": "Deletes a Capability from a schema",
4552
5428
  "tags": [
@@ -4585,6 +5461,11 @@
4585
5461
  "/v1/entity/schemas/group": {
4586
5462
  "post": {
4587
5463
  "operationId": "createSchemaGroup",
5464
+ "x-epilot-permissions": [
5465
+ {
5466
+ "action": "schema:update"
5467
+ }
5468
+ ],
4588
5469
  "summary": "createSchemaGroup",
4589
5470
  "description": "Create a schema group",
4590
5471
  "tags": [
@@ -4619,6 +5500,11 @@
4619
5500
  "/v1/entity/schemas/group/{composite_id}": {
4620
5501
  "get": {
4621
5502
  "operationId": "getSchemaGroup",
5503
+ "x-epilot-permissions": [
5504
+ {
5505
+ "access": "org"
5506
+ }
5507
+ ],
4622
5508
  "summary": "getSchemaGroup",
4623
5509
  "description": "Get a schema group from given group composite ID",
4624
5510
  "tags": [
@@ -4655,6 +5541,11 @@
4655
5541
  },
4656
5542
  "put": {
4657
5543
  "operationId": "putSchemaGroup",
5544
+ "x-epilot-permissions": [
5545
+ {
5546
+ "action": "schema:update"
5547
+ }
5548
+ ],
4658
5549
  "summary": "putSchemaGroup",
4659
5550
  "description": "Adds or updates an capability in the schema",
4660
5551
  "tags": [
@@ -4697,6 +5588,11 @@
4697
5588
  },
4698
5589
  "delete": {
4699
5590
  "operationId": "deleteSchemaGroup",
5591
+ "x-epilot-permissions": [
5592
+ {
5593
+ "action": "schema:update"
5594
+ }
5595
+ ],
4700
5596
  "summary": "deleteSchemaGroup",
4701
5597
  "description": "Deletes a Capability from a schema",
4702
5598
  "tags": [
@@ -4735,6 +5631,11 @@
4735
5631
  "/v1/entity/schemas/headline": {
4736
5632
  "post": {
4737
5633
  "operationId": "createSchemaGroupHeadline",
5634
+ "x-epilot-permissions": [
5635
+ {
5636
+ "action": "schema:update"
5637
+ }
5638
+ ],
4738
5639
  "summary": "createSchemaGroupHeadline",
4739
5640
  "description": "Create a headline in a schema group",
4740
5641
  "tags": [
@@ -4769,6 +5670,11 @@
4769
5670
  "/v1/entity/schemas/headline/{composite_id}": {
4770
5671
  "get": {
4771
5672
  "operationId": "getSchemaGroupHeadline",
5673
+ "x-epilot-permissions": [
5674
+ {
5675
+ "access": "org"
5676
+ }
5677
+ ],
4772
5678
  "summary": "getSchemaGroupHeadline",
4773
5679
  "description": "Get a group headline from schema from given headline composite ID",
4774
5680
  "tags": [
@@ -4805,6 +5711,11 @@
4805
5711
  },
4806
5712
  "put": {
4807
5713
  "operationId": "putSchemaGroupHeadline",
5714
+ "x-epilot-permissions": [
5715
+ {
5716
+ "action": "schema:update"
5717
+ }
5718
+ ],
4808
5719
  "summary": "putSchemaGroupHeadline",
4809
5720
  "description": "Adds or updates a group headline in the schema",
4810
5721
  "tags": [
@@ -4847,6 +5758,11 @@
4847
5758
  },
4848
5759
  "delete": {
4849
5760
  "operationId": "deleteSchemaGroupHeadline",
5761
+ "x-epilot-permissions": [
5762
+ {
5763
+ "action": "schema:update"
5764
+ }
5765
+ ],
4850
5766
  "summary": "deleteSchemaGroupHeadline",
4851
5767
  "description": "Deletes a group headline from a schema",
4852
5768
  "tags": [
@@ -4975,6 +5891,11 @@
4975
5891
  "type": "boolean",
4976
5892
  "example": false
4977
5893
  },
5894
+ "require_change_comment": {
5895
+ "type": "boolean",
5896
+ "description": "When true, the entity builder requires a change comment before saving a new version of this schema. Absent is treated as false. Enforced by the builder UI only; the API does not reject schema writes without a comment.",
5897
+ "example": false
5898
+ },
4978
5899
  "icon": {
4979
5900
  "type": "string",
4980
5901
  "example": "person"
@@ -5341,47 +6262,239 @@
5341
6262
  }
5342
6263
  ]
5343
6264
  },
5344
- "_purpose": {
6265
+ "_purpose": {
6266
+ "type": "array",
6267
+ "items": {
6268
+ "type": "string"
6269
+ }
6270
+ },
6271
+ "_manifest": {
6272
+ "type": "array",
6273
+ "description": "Manifest ID used to create the schema",
6274
+ "items": {
6275
+ "type": "string",
6276
+ "format": "uuid",
6277
+ "example": "123e4567-e89b-12d3-a456-426614174000"
6278
+ },
6279
+ "nullable": true
6280
+ },
6281
+ "explicit_search_mappings": {
6282
+ "$ref": "#/components/schemas/SearchMappings"
6283
+ },
6284
+ "group_headlines": {
6285
+ "type": "array",
6286
+ "items": {
6287
+ "$ref": "#/components/schemas/GroupHeadline"
6288
+ }
6289
+ },
6290
+ "conditions": {
6291
+ "type": "array",
6292
+ "nullable": true,
6293
+ "description": "Dimensions that conditional variants of this entity type are keyed by.\n\nAbsent or `null` means entities of this type are not conditional. Attributes whose\nvalues a variant may override are marked with `overridable_attribute`.\n",
6294
+ "items": {
6295
+ "$ref": "#/components/schemas/ConditionDefinition"
6296
+ }
6297
+ }
6298
+ },
6299
+ "required": [
6300
+ "slug",
6301
+ "name",
6302
+ "plural",
6303
+ "attributes",
6304
+ "capabilities"
6305
+ ]
6306
+ },
6307
+ "SchemaHead": {
6308
+ "type": "object",
6309
+ "required": [
6310
+ "slug",
6311
+ "version"
6312
+ ],
6313
+ "properties": {
6314
+ "slug": {
6315
+ "$ref": "#/components/schemas/EntitySlug"
6316
+ },
6317
+ "id": {
6318
+ "type": "string"
6319
+ },
6320
+ "version": {
6321
+ "type": "integer"
6322
+ },
6323
+ "updated_at": {
6324
+ "type": "string",
6325
+ "format": "date-time"
6326
+ },
6327
+ "created_by": {
6328
+ "type": "string",
6329
+ "description": "Who saved this version"
6330
+ }
6331
+ }
6332
+ },
6333
+ "WipeJob": {
6334
+ "type": "object",
6335
+ "description": "A request to wipe entity data of an organization, and its progress",
6336
+ "required": [
6337
+ "id",
6338
+ "schemas",
6339
+ "status",
6340
+ "current_step",
6341
+ "created_at",
6342
+ "updated_at",
6343
+ "entity_totals",
6344
+ "total_entities",
6345
+ "progress"
6346
+ ],
6347
+ "properties": {
6348
+ "id": {
6349
+ "type": "string"
6350
+ },
6351
+ "schemas": {
6352
+ "type": "array",
6353
+ "nullable": true,
6354
+ "description": "The schemas being wiped. null means all schemas.",
6355
+ "items": {
6356
+ "$ref": "#/components/schemas/EntitySlug"
6357
+ }
6358
+ },
6359
+ "status": {
6360
+ "type": "string",
6361
+ "enum": [
6362
+ "running",
6363
+ "succeeded",
6364
+ "failed"
6365
+ ]
6366
+ },
6367
+ "current_step": {
6368
+ "type": "string",
6369
+ "enum": [
6370
+ "SANITY_CHECK",
6371
+ "DELETE_ELASTIC_INDICES",
6372
+ "DELETE_DYNAMODB_ENTITIES",
6373
+ "DELETE_DYNAMODB_RELATIONS",
6374
+ "DELETE_DYNAMODB_ACTIVITIES",
6375
+ "DELETE_CLICKHOUSE_ENTITIES",
6376
+ "DELETE_CLICKHOUSE_ENTITY_OPERATIONS",
6377
+ "DELETE_S3_FILES",
6378
+ "SUCCESS",
6379
+ "FAIL"
6380
+ ]
6381
+ },
6382
+ "created_at": {
6383
+ "type": "string",
6384
+ "format": "date-time"
6385
+ },
6386
+ "updated_at": {
6387
+ "type": "string",
6388
+ "format": "date-time"
6389
+ },
6390
+ "finished_at": {
6391
+ "type": "string",
6392
+ "format": "date-time"
6393
+ },
6394
+ "created_by": {
6395
+ "type": "object",
6396
+ "properties": {
6397
+ "user_id": {
6398
+ "type": "string"
6399
+ },
6400
+ "email": {
6401
+ "type": "string"
6402
+ },
6403
+ "display_name": {
6404
+ "type": "string"
6405
+ }
6406
+ }
6407
+ },
6408
+ "entity_totals": {
6409
+ "type": "object",
6410
+ "description": "Number of entities per schema at the time the wipe was requested",
6411
+ "additionalProperties": {
6412
+ "type": "integer"
6413
+ }
6414
+ },
6415
+ "total_entities": {
6416
+ "type": "integer",
6417
+ "description": "Sum of entity_totals"
6418
+ },
6419
+ "progress": {
6420
+ "type": "object",
6421
+ "properties": {
6422
+ "indices_deleted": {
6423
+ "type": "integer"
6424
+ },
6425
+ "entities_deleted": {
6426
+ "type": "integer"
6427
+ },
6428
+ "relations_deleted": {
6429
+ "type": "integer"
6430
+ },
6431
+ "activities_deleted": {
6432
+ "type": "integer"
6433
+ }
6434
+ }
6435
+ },
6436
+ "error": {
6437
+ "type": "string"
6438
+ }
6439
+ }
6440
+ },
6441
+ "WipeJobConflictError": {
6442
+ "type": "object",
6443
+ "required": [
6444
+ "message",
6445
+ "conflicting_schemas"
6446
+ ],
6447
+ "properties": {
6448
+ "status": {
6449
+ "type": "integer",
6450
+ "example": 409
6451
+ },
6452
+ "error": {
6453
+ "type": "string"
6454
+ },
6455
+ "message": {
6456
+ "type": "string"
6457
+ },
6458
+ "conflicting_schemas": {
5345
6459
  "type": "array",
6460
+ "description": "Requested schemas that are already being wiped",
5346
6461
  "items": {
5347
6462
  "type": "string"
5348
6463
  }
6464
+ }
6465
+ }
6466
+ },
6467
+ "SchemaVersionConflictError": {
6468
+ "type": "object",
6469
+ "properties": {
6470
+ "status": {
6471
+ "type": "integer",
6472
+ "example": 409
5349
6473
  },
5350
- "_manifest": {
5351
- "type": "array",
5352
- "description": "Manifest ID used to create the schema",
5353
- "items": {
5354
- "type": "string",
5355
- "format": "uuid",
5356
- "example": "123e4567-e89b-12d3-a456-426614174000"
5357
- },
5358
- "nullable": true
6474
+ "error": {
6475
+ "type": "string",
6476
+ "example": "SchemaVersionConflict"
5359
6477
  },
5360
- "explicit_search_mappings": {
5361
- "$ref": "#/components/schemas/SearchMappings"
6478
+ "message": {
6479
+ "type": "string"
5362
6480
  },
5363
- "group_headlines": {
5364
- "type": "array",
5365
- "items": {
5366
- "$ref": "#/components/schemas/GroupHeadline"
5367
- }
6481
+ "base_version": {
6482
+ "type": "integer",
6483
+ "description": "The version the rejected save was made on top of"
5368
6484
  },
5369
- "conditions": {
5370
- "type": "array",
5371
- "nullable": true,
5372
- "description": "Dimensions that conditional variants of this entity type are keyed by.\n\nAbsent or `null` means entities of this type are not conditional. Attributes whose\nvalues a variant may override are marked with `overridable_attribute`.\n",
5373
- "items": {
5374
- "$ref": "#/components/schemas/ConditionDefinition"
5375
- }
6485
+ "current_version": {
6486
+ "type": "integer",
6487
+ "description": "The version saves currently land on top of"
6488
+ },
6489
+ "current_updated_at": {
6490
+ "type": "string",
6491
+ "format": "date-time"
6492
+ },
6493
+ "current_created_by": {
6494
+ "type": "string",
6495
+ "description": "Who saved the current version"
5376
6496
  }
5377
- },
5378
- "required": [
5379
- "slug",
5380
- "name",
5381
- "plural",
5382
- "attributes",
5383
- "capabilities"
5384
- ]
6497
+ }
5385
6498
  },
5386
6499
  "EntitySchemaItem": {
5387
6500
  "allOf": [
@@ -9002,6 +10115,31 @@
9002
10115
  "type": "string",
9003
10116
  "description": "The schema of the entities being imported. This must match the schema of the entities on the platform.",
9004
10117
  "example": "contact"
10118
+ },
10119
+ "unique_key": {
10120
+ "type": "array",
10121
+ "maxItems": 5,
10122
+ "items": {
10123
+ "type": "string"
10124
+ },
10125
+ "description": "Attribute names (text, email or number) used to match rows to existing entities, combined with AND.\nUse `[\"_id\"]` to match by entity id only. Empty by default, which keeps the current behaviour.\n",
10126
+ "example": [
10127
+ "email"
10128
+ ]
10129
+ },
10130
+ "dry_run": {
10131
+ "type": "boolean",
10132
+ "default": false,
10133
+ "description": "Report the outcome of every row without writing any entities."
10134
+ },
10135
+ "dry_run_job_id": {
10136
+ "type": "string",
10137
+ "description": "The job id of a completed dry run that this import commits. Cannot be combined with `dry_run`."
10138
+ },
10139
+ "trigger_automations": {
10140
+ "type": "boolean",
10141
+ "default": false,
10142
+ "description": "Write committed rows as normal creates and updates: they emit entity events, so automations\nrun, and each entity gets its activities. Off by default, when imported rows trigger no\nautomations. Cannot be combined with `dry_run: true`.\n"
9005
10143
  }
9006
10144
  },
9007
10145
  "required": [
@@ -9010,6 +10148,282 @@
9010
10148
  ],
9011
10149
  "description": "The parameters for importing entities."
9012
10150
  },
10151
+ "ImportRowOutcomeCounts": {
10152
+ "type": "object",
10153
+ "description": "Number of rows per outcome, in the order the outcomes are evaluated.",
10154
+ "properties": {
10155
+ "error": {
10156
+ "type": "integer"
10157
+ },
10158
+ "skipped_empty_key": {
10159
+ "type": "integer"
10160
+ },
10161
+ "skipped_duplicate_in_file": {
10162
+ "type": "integer"
10163
+ },
10164
+ "skipped_id_not_found": {
10165
+ "type": "integer"
10166
+ },
10167
+ "skipped_ambiguous": {
10168
+ "type": "integer"
10169
+ },
10170
+ "create": {
10171
+ "type": "integer"
10172
+ },
10173
+ "unchanged": {
10174
+ "type": "integer"
10175
+ },
10176
+ "update": {
10177
+ "type": "integer"
10178
+ }
10179
+ }
10180
+ },
10181
+ "ImportJobSummary": {
10182
+ "type": "object",
10183
+ "description": "One import job (import or dry run) in the import history of a schema.",
10184
+ "required": [
10185
+ "job_id",
10186
+ "schema",
10187
+ "status",
10188
+ "dry_run",
10189
+ "started_at"
10190
+ ],
10191
+ "properties": {
10192
+ "job_id": {
10193
+ "type": "string",
10194
+ "description": "The ID of the import job, as returned in `jobPollId`. Poll it to resume the job."
10195
+ },
10196
+ "schema": {
10197
+ "type": "string"
10198
+ },
10199
+ "status": {
10200
+ "type": "string",
10201
+ "enum": [
10202
+ "PROCESSING",
10203
+ "COMPLETED",
10204
+ "FAILED",
10205
+ "CANCELLED"
10206
+ ]
10207
+ },
10208
+ "dry_run": {
10209
+ "type": "boolean"
10210
+ },
10211
+ "trigger_automations": {
10212
+ "type": "boolean"
10213
+ },
10214
+ "started_by": {
10215
+ "type": "string",
10216
+ "description": "User id of whoever started the job."
10217
+ },
10218
+ "started_at": {
10219
+ "type": "string",
10220
+ "format": "date-time"
10221
+ },
10222
+ "finished_at": {
10223
+ "type": "string",
10224
+ "format": "date-time"
10225
+ },
10226
+ "file_name": {
10227
+ "type": "string",
10228
+ "description": "Name of the imported file, for display."
10229
+ },
10230
+ "total": {
10231
+ "type": "integer"
10232
+ },
10233
+ "importedEntitiesCount": {
10234
+ "type": "integer"
10235
+ },
10236
+ "failedEntitiesCount": {
10237
+ "type": "integer"
10238
+ },
10239
+ "outcome_counts": {
10240
+ "$ref": "#/components/schemas/ImportRowOutcomeCounts"
10241
+ },
10242
+ "failure_code": {
10243
+ "$ref": "#/components/schemas/ImportFailureCode"
10244
+ },
10245
+ "unique_key": {
10246
+ "type": "array",
10247
+ "items": {
10248
+ "type": "string"
10249
+ }
10250
+ }
10251
+ }
10252
+ },
10253
+ "ImportIssue": {
10254
+ "type": "object",
10255
+ "description": "Rows of an import job that share one reason not to be written.",
10256
+ "required": [
10257
+ "severity",
10258
+ "reason",
10259
+ "count",
10260
+ "example_rows"
10261
+ ],
10262
+ "properties": {
10263
+ "severity": {
10264
+ "type": "string",
10265
+ "description": "`blocking` for rows with the outcome `error`, `warning` for the `skipped_*` outcomes.\n",
10266
+ "enum": [
10267
+ "blocking",
10268
+ "warning"
10269
+ ]
10270
+ },
10271
+ "reason": {
10272
+ "type": "string",
10273
+ "description": "Blocking: the row reason's text before its first `: `, one issue per `; `-separated part, e.g.\n`Invalid date for birthdate` or `Unknown purpose id`. Warning: the outcome, e.g. `skipped_duplicate_in_file`.\n"
10274
+ },
10275
+ "column": {
10276
+ "type": "string",
10277
+ "description": "The column the reason names (`… for <column>` or `… in <column>`), if any."
10278
+ },
10279
+ "count": {
10280
+ "type": "integer",
10281
+ "description": "Number of rows with this issue."
10282
+ },
10283
+ "example_rows": {
10284
+ "type": "array",
10285
+ "description": "The first (at most 5) row numbers with this issue, 1-based data rows as in the report.",
10286
+ "items": {
10287
+ "type": "integer"
10288
+ }
10289
+ }
10290
+ }
10291
+ },
10292
+ "ImportFailureCode": {
10293
+ "type": "string",
10294
+ "description": "Machine readable reason of a failed job. `failure_reason` holds the human text.\n- `invalid_csv_bad_headers`: the file has neither a `_schema` nor an `_id` column\n- `dry_run_required`, `dry_run_mismatch`, `dry_run_expired`: the dry-run rule rejected the commit before any row\n- `import_file_changed`: the file was replaced after the pre-scan\n- `prescan_missing`: the job cannot be continued after an update\n- `import_too_large`: the file has more rows than a single job can report on\n- `token_expired`: the session that started the job expired before it finished\n- `max_duration_exceeded`: the job ran longer than allowed\n- `no_progress`: consecutive runs made no progress\n- `internal_error`: an unexpected error ended the job\n",
10295
+ "enum": [
10296
+ "invalid_csv_bad_headers",
10297
+ "dry_run_required",
10298
+ "dry_run_mismatch",
10299
+ "dry_run_expired",
10300
+ "import_file_changed",
10301
+ "prescan_missing",
10302
+ "import_too_large",
10303
+ "token_expired",
10304
+ "max_duration_exceeded",
10305
+ "no_progress",
10306
+ "internal_error"
10307
+ ]
10308
+ },
10309
+ "ImportProgress": {
10310
+ "type": "object",
10311
+ "description": "Progress of an import job. The fields `dry_run`, `unique_key`, `outcome_counts`, `report_url`,\n`S3Reference` and `started_by` are only set for jobs started with `unique_key`, `dry_run` or `dry_run_job_id`. For those,\n`importedEntitiesCount` is `create` plus `update` and `failedEntitiesCount` counts `error` rows only.\n",
10312
+ "properties": {
10313
+ "jobPollId": {
10314
+ "type": "string",
10315
+ "description": "The ID of the import job."
10316
+ },
10317
+ "trigger_automations": {
10318
+ "type": "boolean",
10319
+ "description": "Whether committed rows of the job trigger automations."
10320
+ },
10321
+ "started_by": {
10322
+ "type": "string",
10323
+ "description": "User id of whoever started the job. A finished job is only returned by `entity:import:latest`\nto this user, and only this user can commit or discard a dry run.\n"
10324
+ },
10325
+ "status": {
10326
+ "type": "string",
10327
+ "enum": [
10328
+ "PROCESSING",
10329
+ "COMPLETED",
10330
+ "FAILED",
10331
+ "CANCELLED"
10332
+ ]
10333
+ },
10334
+ "total": {
10335
+ "type": "integer",
10336
+ "description": "Number of data rows in the file, once known."
10337
+ },
10338
+ "importedEntitiesCount": {
10339
+ "type": "integer"
10340
+ },
10341
+ "failedEntitiesCount": {
10342
+ "type": "integer"
10343
+ },
10344
+ "importedEntitiesUrl": {
10345
+ "type": "string"
10346
+ },
10347
+ "failedEntitiesUrl": {
10348
+ "type": "string"
10349
+ },
10350
+ "updated_at": {
10351
+ "type": "string",
10352
+ "format": "date-time"
10353
+ },
10354
+ "failure_reason": {
10355
+ "type": "string"
10356
+ },
10357
+ "failure_code": {
10358
+ "$ref": "#/components/schemas/ImportFailureCode"
10359
+ },
10360
+ "abortable": {
10361
+ "type": "boolean"
10362
+ },
10363
+ "dry_run": {
10364
+ "type": "boolean"
10365
+ },
10366
+ "unique_key": {
10367
+ "type": "array",
10368
+ "items": {
10369
+ "type": "string"
10370
+ }
10371
+ },
10372
+ "outcome_counts": {
10373
+ "$ref": "#/components/schemas/ImportRowOutcomeCounts"
10374
+ },
10375
+ "report_url": {
10376
+ "type": "string",
10377
+ "description": "Download link of the per-row report (CSV, UTF-8 with BOM)."
10378
+ },
10379
+ "S3Reference": {
10380
+ "type": "object",
10381
+ "description": "The imported file. Send it back with `dry_run_job_id` to commit a dry run.",
10382
+ "properties": {
10383
+ "bucket": {
10384
+ "type": "string"
10385
+ },
10386
+ "key": {
10387
+ "type": "string"
10388
+ }
10389
+ }
10390
+ },
10391
+ "issues": {
10392
+ "type": "array",
10393
+ "description": "The rows that are not written, grouped by why: blocking issues first, then by count, at most 20.\nThe warnings always get a place. Blocking issues beyond the 50 tracked are counted as `Other errors`.\nOnly for jobs started with `unique_key`, `dry_run` or `dry_run_job_id`.\n",
10394
+ "maxItems": 20,
10395
+ "items": {
10396
+ "$ref": "#/components/schemas/ImportIssue"
10397
+ }
10398
+ },
10399
+ "phase": {
10400
+ "type": "string",
10401
+ "description": "What the job is doing now: `scanning` the file (pre-scan), running the `dry_run` or `importing`\nrows, `finalizing` the report, or `done` (every terminal status).\n",
10402
+ "enum": [
10403
+ "scanning",
10404
+ "dry_run",
10405
+ "importing",
10406
+ "finalizing",
10407
+ "done"
10408
+ ]
10409
+ },
10410
+ "heartbeat_at": {
10411
+ "type": "string",
10412
+ "format": "date-time",
10413
+ "description": "Refreshed at every phase change and at least every few seconds while the job makes progress\n(rows or pre-scan). A PROCESSING job whose heartbeat is minutes old may be stuck.\n"
10414
+ },
10415
+ "started_at": {
10416
+ "type": "string",
10417
+ "format": "date-time",
10418
+ "description": "When the job started."
10419
+ },
10420
+ "finished_at": {
10421
+ "type": "string",
10422
+ "format": "date-time",
10423
+ "description": "When the job ended; set on a terminal status."
10424
+ }
10425
+ }
10426
+ },
9013
10427
  "GraphQueryRequest": {
9014
10428
  "type": "object",
9015
10429
  "required": [
@@ -9708,6 +11122,39 @@
9708
11122
  }
9709
11123
  ]
9710
11124
  },
11125
+ "EntitySummary": {
11126
+ "type": "object",
11127
+ "description": "Latest AI generated summary of an entity",
11128
+ "required": [
11129
+ "summary",
11130
+ "variant",
11131
+ "execution_id",
11132
+ "created_at"
11133
+ ],
11134
+ "properties": {
11135
+ "summary": {
11136
+ "type": "string",
11137
+ "description": "Markdown summary"
11138
+ },
11139
+ "variant": {
11140
+ "type": "string",
11141
+ "enum": [
11142
+ "short",
11143
+ "detailed",
11144
+ "action_points"
11145
+ ]
11146
+ },
11147
+ "execution_id": {
11148
+ "type": "string",
11149
+ "description": "ai-agents-api execution that generated the summary. Feedback is keyed by it.",
11150
+ "example": "7b4cfc0f-1d5e-4f3a-9b4a-2c7d1f9e8a10"
11151
+ },
11152
+ "created_at": {
11153
+ "type": "string",
11154
+ "format": "date-time"
11155
+ }
11156
+ }
11157
+ },
9711
11158
  "BlueprintEntityId": {
9712
11159
  "description": "Reference to blueprint",
9713
11160
  "type": "string",