@epilot/cli 0.1.203 → 0.1.205

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 (80) hide show
  1. package/README.md +1 -1
  2. package/definitions/app.json +17 -44
  3. package/definitions/customer-portal.json +566 -14
  4. package/definitions/email-settings.json +98 -36
  5. package/definitions/integration-toolkit.json +656 -2
  6. package/dist/{access-token-IZ7E4HVO.js → access-token-4QI7YZQP.js} +2 -2
  7. package/dist/{add-component-WVGCJHDE.js → add-component-G2OOG56P.js} +2 -2
  8. package/dist/{add-function-S7AKUMOF.js → add-function-JGOTYXER.js} +2 -2
  9. package/dist/{address-UNBSBAJZ.js → address-JM5HOVBK.js} +2 -2
  10. package/dist/{address-suggestions-LVTSQJBW.js → address-suggestions-OCQUOKBN.js} +2 -2
  11. package/dist/{ai-agents-O5ESWOHE.js → ai-agents-JVYTU5CF.js} +2 -2
  12. package/dist/{api-2ILOHM36.js → api-2JSH5M6V.js} +2 -2
  13. package/dist/app-IM6TG4KG.js +26 -0
  14. package/dist/{audit-logs-6KAPL3BU.js → audit-logs-YWMCBMMJ.js} +2 -2
  15. package/dist/{automation-2TJCU5MT.js → automation-PRHESUBC.js} +2 -2
  16. package/dist/{billing-OVMLBQY6.js → billing-5JEDTUQM.js} +2 -2
  17. package/dist/bin/epilot.js +61 -61
  18. package/dist/{blueprint-manifest-XIWAAMUJ.js → blueprint-manifest-TSRRX6VM.js} +2 -2
  19. package/dist/{calendar-NBPOJX4C.js → calendar-7K42OAMA.js} +2 -2
  20. package/dist/{chat-XYEZ4CEA.js → chat-YSNWP7FZ.js} +2 -2
  21. package/dist/{chunk-US264EE3.js → chunk-3XYGSRCG.js} +1 -1
  22. package/dist/{chunk-6QZJWRBN.js → chunk-DRTGD5R2.js} +9 -3
  23. package/dist/{chunk-TFLVQLUM.js → chunk-F5PY5C36.js} +1 -1
  24. package/dist/{chunk-VBTBSF6W.js → chunk-URL63EDY.js} +1 -1
  25. package/dist/{completion-OVOAA7NL.js → completion-C3FOYNSQ.js} +1 -1
  26. package/dist/{configuration-hub-OM5AQJD3.js → configuration-hub-TDQM43H3.js} +2 -2
  27. package/dist/{consent-TU2DFYRS.js → consent-5RGQ5FDR.js} +2 -2
  28. package/dist/{customer-portal-7O6CSBWV.js → customer-portal-RM4MYRVW.js} +2 -2
  29. package/dist/{dashboard-ZX2UGD7R.js → dashboard-BHDUE634.js} +2 -2
  30. package/dist/{data-governance-5INC4XIH.js → data-governance-B4PDYLRV.js} +2 -2
  31. package/dist/{deduplication-Y7E657AX.js → deduplication-IDAD4ESK.js} +2 -2
  32. package/dist/{deploy-VXURAJXA.js → deploy-3TTURE4C.js} +2 -2
  33. package/dist/{design-EN2MVSM4.js → design-Q3OPVP35.js} +2 -2
  34. package/dist/{dev-QV32YN5H.js → dev-X4UJRQ5Q.js} +2 -2
  35. package/dist/{document-MR63WTOT.js → document-XFGE6YMW.js} +2 -2
  36. package/dist/{email-settings-5JRBMYRL.js → email-settings-4N46SEKO.js} +2 -2
  37. package/dist/{email-template-YJN3YNUM.js → email-template-BO77S45X.js} +2 -2
  38. package/dist/{entity-WPQJVAKW.js → entity-NFAI52Y3.js} +2 -2
  39. package/dist/{entity-mapping-ZXPZLGIT.js → entity-mapping-LZBAOFAY.js} +2 -2
  40. package/dist/{environments-FYAI4J4T.js → environments-TLHE7ATR.js} +2 -2
  41. package/dist/{event-catalog-VTMXGW23.js → event-catalog-F2DSDAIM.js} +2 -2
  42. package/dist/{export-JRHLMWFD.js → export-MX3Z6MDG.js} +2 -2
  43. package/dist/{external-values-Y5YDA4WQ.js → external-values-B7XGKJQI.js} +2 -2
  44. package/dist/{file-ZLAHVARN.js → file-MMR4CYW5.js} +2 -2
  45. package/dist/{iban-FCMEBKOB.js → iban-SVBMEWEI.js} +2 -2
  46. package/dist/{identity-BQQVOMBV.js → identity-RFTHG6J5.js} +2 -2
  47. package/dist/{init-NV55QQGI.js → init-4ORDLRPM.js} +2 -2
  48. package/dist/{integration-toolkit-AEMJJ2WW.js → integration-toolkit-DQNRTP7E.js} +2 -2
  49. package/dist/{journey-PVBTMKCX.js → journey-UDEB3LLE.js} +2 -2
  50. package/dist/{kanban-VGBUGFYR.js → kanban-IGJYIPMC.js} +2 -2
  51. package/dist/{message-7ZND2YEC.js → message-MWHGVVMZ.js} +2 -2
  52. package/dist/{metering-4OZ5Y7J5.js → metering-USLJN62O.js} +2 -2
  53. package/dist/{notes-6HD5D443.js → notes-REYCJLE3.js} +2 -2
  54. package/dist/{notification-CWF3D6FU.js → notification-72UYQOAQ.js} +2 -2
  55. package/dist/{organization-SNIPP5W4.js → organization-3O5IU2X7.js} +2 -2
  56. package/dist/{partner-directory-EA4DETAP.js → partner-directory-O2QWOBCD.js} +2 -2
  57. package/dist/{permissions-J62Y5FN7.js → permissions-ZSSYUMHR.js} +2 -2
  58. package/dist/{phone-integration-4K4WZKLX.js → phone-integration-VIVW7ZLQ.js} +2 -2
  59. package/dist/{pricing-ZOKJ7FSZ.js → pricing-FUYF3AKR.js} +2 -2
  60. package/dist/{pricing-tier-RTJTTNS6.js → pricing-tier-MNTZGDKF.js} +2 -2
  61. package/dist/{purpose-T67T4IA6.js → purpose-JTQFEE2E.js} +2 -2
  62. package/dist/{query-EVXHXHHE.js → query-GIGSBWPM.js} +2 -2
  63. package/dist/{remove-component-TYUUZXHS.js → remove-component-CRH6BLBS.js} +2 -2
  64. package/dist/{review-Z56HLXMJ.js → review-MLCUEFVU.js} +2 -2
  65. package/dist/{sandbox-JJ2GV3C3.js → sandbox-QKJENY42.js} +2 -2
  66. package/dist/{sharing-INJV56L6.js → sharing-UCMQKUCL.js} +2 -2
  67. package/dist/{snapshot-NPMZDTBP.js → snapshot-BQAUBXY2.js} +2 -2
  68. package/dist/{submission-W2PIEUKR.js → submission-JX2CPO4U.js} +2 -2
  69. package/dist/{targeting-QSZ2H44G.js → targeting-JP4HM22G.js} +2 -2
  70. package/dist/{template-variables-L2W757CZ.js → template-variables-4W2SDOFN.js} +2 -2
  71. package/dist/{upgrade-G5RP66UK.js → upgrade-KCSZTJLB.js} +1 -1
  72. package/dist/{user-5I5X77SG.js → user-CXXCDDAJ.js} +2 -2
  73. package/dist/{validate-P662MSZV.js → validate-MIESMMZW.js} +2 -2
  74. package/dist/{validation-rules-TSLLRD2R.js → validation-rules-ABENGW45.js} +2 -2
  75. package/dist/{versions-ZJ7ZZ3GT.js → versions-KRS5WVPG.js} +2 -2
  76. package/dist/{webhooks-PQOIP2ON.js → webhooks-JI2GNTAJ.js} +2 -2
  77. package/dist/{workflow-Y3E32L52.js → workflow-D3WFPJLU.js} +2 -2
  78. package/dist/{workflow-definition-BXLRJZL2.js → workflow-definition-P6AQAET7.js} +2 -2
  79. package/package.json +1 -1
  80. package/dist/app-VOJOGGC5.js +0 -26
@@ -2,7 +2,7 @@
2
2
  "openapi": "3.0.3",
3
3
  "info": {
4
4
  "title": "Integration Toolkit API",
5
- "version": "1.45.0",
5
+ "version": "1.46.0",
6
6
  "description": "API for integrating with external systems in a standardised way."
7
7
  },
8
8
  "tags": [
@@ -364,6 +364,239 @@
364
364
  "$ref": "#/components/responses/InternalServerError"
365
365
  }
366
366
  }
367
+ },
368
+ "get": {
369
+ "operationId": "queryErpUpdateEvents",
370
+ "x-epilot-permissions": [
371
+ {
372
+ "action": "integration:view",
373
+ "resource": "integration:{integration_id}"
374
+ }
375
+ ],
376
+ "summary": "queryErpUpdateEvents",
377
+ "description": "Waits for the events of one correlation — the long poll behind interactive\nregistration — and returns the correlation's summary.\n\nPass the `correlation_id` returned by `POST /v3/erp/updates/events` and say\nwhat you are waiting for:\n\n- `wait_for_entities` — entity slugs, optionally with a selector:\n `contact`, `contract[billing_account_number=4711]`.\n- `wait_for_use_cases` — inbound use case slugs: `contract`, `meter_reading`.\n A meter reading is not an entity, so this is how a wait names one.\n\nThe call returns as soon as `completion` is decided, or after `wait`\nseconds. `completion` is one of:\n\n- `requirements_met` — every listed requirement is satisfied. This wins even\n if an unrelated event of the correlation failed; `errors` still lists it.\n- `complete` — the partner closed the correlation (`correlation_complete`)\n and every event it sent has finished. Nothing further can arrive, so the\n wait ends even if a requirement is unmet. A correlation closed with zero\n events is `complete` at once: the partner sent nothing and never will.\n- `error` — a requirement can no longer be met because an event it depends\n on failed: every event of a required use case ended in error, or an\n entity requirement is still missing when the correlation is complete and\n one of its events failed. Without requirements, `error` means the\n correlation completed with failures.\n- `timeout` — the budget ran out first. The body still shows what has\n landed so far; call again to keep waiting.\n\n**Every requirement is met by the first matching event.** A use case\nrequirement is satisfied by the first event of that use case to finish, and\nan entity requirement without a selector by the first entity of that slug;\nneither says anything about the rest. So, unless the partner sends\n`correlation_complete`, `requirements_met` does not mean the partner has\nfinished: more data for the same customer may still be arriving.\n`correlation_complete` is the only signal that nothing further is coming —\nstrongly recommended for every partner, never required. When you know the\nidentifier you are waiting for, an entity requirement with a selector is the\nprecise tool: `contract[billing_account_number=4711]` is satisfied by that\ncontract and by nothing else.\n\nA requirement is only as good as the use case configuration it refers to:\nmodel one inbound use case per partner event type, and give every use case a\nslug. A use case without a slug cannot be named here.\n\nAn unknown correlation, or one with no interactive events, reads as\n`events_received: 0, closed: false` — \"not yet\" and \"never\" look the same,\nwhich is why `correlation_complete` exists.\n\nWaiting holds a connection, so concurrent waits are capped per organization\nand overall. Over the cap the call is refused with 429 and `Retry-After`;\nfall back to calls with `wait=0` (they never need a slot) or retry later.\nCalls that do not have to wait — `wait=0`, or a correlation that is already\ndecided — are never refused.\n\nRequires `integration:view` on the correlation's integration. The organization\nis always the token's own, so no other organization's correlation is ever\nvisible.\n",
378
+ "tags": [
379
+ "erp"
380
+ ],
381
+ "parameters": [
382
+ {
383
+ "name": "correlation_id",
384
+ "in": "query",
385
+ "required": true,
386
+ "description": "The correlation to wait on, as returned by `POST /v3/erp/updates/events`:\n1-255 characters of letters, digits, hyphens and underscores.\n",
387
+ "schema": {
388
+ "type": "string",
389
+ "pattern": "^[A-Za-z0-9_-]{1,255}$"
390
+ }
391
+ },
392
+ {
393
+ "name": "wait",
394
+ "in": "query",
395
+ "required": false,
396
+ "description": "Seconds to wait for `completion` to be decided, `0` to `25`. `0` answers\nimmediately. A value outside the range is a 400 naming the maximum, never\na silent clamp: 25 seconds keeps the call inside the 30 second HTTP limit.\n",
397
+ "schema": {
398
+ "type": "integer",
399
+ "minimum": 0,
400
+ "maximum": 25,
401
+ "default": 0
402
+ }
403
+ },
404
+ {
405
+ "name": "wait_for_entities",
406
+ "in": "query",
407
+ "required": false,
408
+ "style": "form",
409
+ "explode": true,
410
+ "description": "Entities to wait for: `slug` or `slug[key=value]`, at most 20.\n\n- Repeat the parameter for several requirements, one per occurrence\n (`wait_for_entities=contact&wait_for_entities=contract`); a repeated\n occurrence is never split, so its value may contain a comma. Given only\n once, the parameter may instead hold a comma-separated list.\n- Inside the brackets the split is on the **first** `=`, and the value runs\n to the **final** `]`, so a value may contain `=` and `]`.\n- The value is percent-decoded once more after that split, on top of the\n normal URL decoding. That is how a comma travels in the comma-separated\n form (`%2C` inside the value, so `%252C` on the wire), and why a literal\n `%` in a value must be sent as `%25` inside the value.\n\nA selector matches only an attribute that is one of the use case's\nconfigured `unique_ids` for that entity — they are all the toolkit records\nper entity. The value is compared the way entity lookup compares unique ids:\nignoring letter case and surrounding whitespace on both sides, so\n`contact[customer_number=ab-1001]` matches a stored ` AB-1001 `. Whitespace\ninside the value stays significant. A selector whose key is not a unique id of that slug in ANY of\nthe organization's inbound use cases can never match, and is refused with a\n400 whose body names the `slug`, the `rejected_key` and the `allowed_keys`.\nA slug that no inbound use case writes is refused the same way. Treat that\n400 as a configuration error, not a reason to retry. Without a selector, any\nentity of the slug satisfies the requirement, which is only safe when the\nbundle cannot contain more than one of that type. A deleted entity never\nsatisfies a requirement.\n",
411
+ "schema": {
412
+ "type": "array",
413
+ "items": {
414
+ "type": "string"
415
+ }
416
+ },
417
+ "example": [
418
+ "contact[reenumber=4711]",
419
+ "contract"
420
+ ]
421
+ },
422
+ {
423
+ "name": "wait_for_use_cases",
424
+ "in": "query",
425
+ "required": false,
426
+ "style": "form",
427
+ "explode": true,
428
+ "description": "Inbound use case slugs to wait for, at most 20, repeated or comma-separated.\nNo selectors. Each is met when at least one event of that use case in the\ncorrelation has finished (`done`), not merely been received.\n",
429
+ "schema": {
430
+ "type": "array",
431
+ "items": {
432
+ "type": "string"
433
+ }
434
+ },
435
+ "example": [
436
+ "business_partner",
437
+ "contract"
438
+ ]
439
+ }
440
+ ],
441
+ "responses": {
442
+ "200": {
443
+ "description": "The correlation's summary and the wait's verdict",
444
+ "content": {
445
+ "application/json": {
446
+ "schema": {
447
+ "$ref": "#/components/schemas/CorrelationWaitResult"
448
+ }
449
+ }
450
+ }
451
+ },
452
+ "400": {
453
+ "description": "The request is invalid: a missing `correlation_id`, `wait` out of range, a\nmalformed requirement, or a `wait_for_entities` requirement that can never\nmatch. For the last, `slug`, `rejected_key` (absent when no inbound use case\nwrites the slug) and `allowed_keys` say what would have worked.\n",
454
+ "content": {
455
+ "application/json": {
456
+ "schema": {
457
+ "$ref": "#/components/schemas/CorrelationWaitBadRequest"
458
+ }
459
+ }
460
+ }
461
+ },
462
+ "401": {
463
+ "$ref": "#/components/responses/Unauthorized"
464
+ },
465
+ "403": {
466
+ "$ref": "#/components/responses/Forbidden"
467
+ },
468
+ "429": {
469
+ "$ref": "#/components/responses/CorrelationWaitRejected"
470
+ },
471
+ "500": {
472
+ "$ref": "#/components/responses/InternalServerError"
473
+ }
474
+ }
475
+ }
476
+ },
477
+ "/v3/erp/updates/events/{event_id}": {
478
+ "get": {
479
+ "operationId": "getErpUpdateEvent",
480
+ "x-epilot-permissions": [
481
+ {
482
+ "action": "integration:view",
483
+ "resource": "integration:{integration_id}"
484
+ }
485
+ ],
486
+ "summary": "getErpUpdateEvent",
487
+ "description": "Returns one interactive event's processing record, without waiting.\n\nRecords exist for events processed as interactive (the ingest result said\n`interactive: true`) and are kept for 24 hours. Any other event id is a 404.\n\nRequires `integration:view` on the event's integration.\n",
488
+ "tags": [
489
+ "erp"
490
+ ],
491
+ "parameters": [
492
+ {
493
+ "name": "event_id",
494
+ "in": "path",
495
+ "required": true,
496
+ "description": "The `event_id` from the ingest result.",
497
+ "schema": {
498
+ "type": "string",
499
+ "minLength": 1,
500
+ "maxLength": 255
501
+ }
502
+ }
503
+ ],
504
+ "responses": {
505
+ "200": {
506
+ "description": "The event's processing record",
507
+ "content": {
508
+ "application/json": {
509
+ "schema": {
510
+ "$ref": "#/components/schemas/ErpUpdateEventStatus"
511
+ }
512
+ }
513
+ }
514
+ },
515
+ "401": {
516
+ "$ref": "#/components/responses/Unauthorized"
517
+ },
518
+ "403": {
519
+ "$ref": "#/components/responses/Forbidden"
520
+ },
521
+ "404": {
522
+ "$ref": "#/components/responses/NotFound"
523
+ },
524
+ "500": {
525
+ "$ref": "#/components/responses/InternalServerError"
526
+ }
527
+ }
528
+ }
529
+ },
530
+ "/v3/erp/updates/correlations": {
531
+ "get": {
532
+ "operationId": "listErpUpdateCorrelations",
533
+ "x-epilot-permissions": [
534
+ {
535
+ "action": "integration:view",
536
+ "resource": "integration:{integration_id}"
537
+ }
538
+ ],
539
+ "summary": "listErpUpdateCorrelations",
540
+ "description": "Lists the organization's interactive correlations, newest first by the time\ntheir first event was ingested, with the same summary the correlation wait\nreturns.\n\nIt exists because looking a correlation up by id only finds the ones somebody\nalready has an id for. A correlation that is merely stuck emits no monitoring\ncode, so nothing points at it — and that is the case most worth seeing.\n\n**The listing covers the last 7 days** — the lifetime of a correlation record\n— and says so in `horizon_days`. Correlations older than that are not\nreturned, even when a wider range is being displayed.\n\nPass `next_cursor` back as `cursor` for the next page. A page can be shorter\nthan `limit` and still have more behind it, so stop on `next_cursor: null`.\n\nRequires `integration:view` on `integration_id` when it is given, and on every\nintegration of the organization when it is not.\n",
541
+ "tags": [
542
+ "erp"
543
+ ],
544
+ "parameters": [
545
+ {
546
+ "name": "integration_id",
547
+ "in": "query",
548
+ "required": false,
549
+ "description": "Only correlations of this integration.",
550
+ "schema": {
551
+ "type": "string",
552
+ "format": "uuid"
553
+ }
554
+ },
555
+ {
556
+ "name": "limit",
557
+ "in": "query",
558
+ "required": false,
559
+ "description": "Page size. Values above 100 are clamped to 100.",
560
+ "schema": {
561
+ "type": "integer",
562
+ "minimum": 1,
563
+ "default": 50
564
+ }
565
+ },
566
+ {
567
+ "name": "cursor",
568
+ "in": "query",
569
+ "required": false,
570
+ "description": "Opaque cursor from a prior page's `next_cursor`.",
571
+ "schema": {
572
+ "type": "string"
573
+ }
574
+ }
575
+ ],
576
+ "responses": {
577
+ "200": {
578
+ "description": "Correlations, newest first",
579
+ "content": {
580
+ "application/json": {
581
+ "schema": {
582
+ "$ref": "#/components/schemas/CorrelationStatusList"
583
+ }
584
+ }
585
+ }
586
+ },
587
+ "400": {
588
+ "$ref": "#/components/responses/BadRequest"
589
+ },
590
+ "401": {
591
+ "$ref": "#/components/responses/Unauthorized"
592
+ },
593
+ "403": {
594
+ "$ref": "#/components/responses/Forbidden"
595
+ },
596
+ "500": {
597
+ "$ref": "#/components/responses/InternalServerError"
598
+ }
599
+ }
367
600
  }
368
601
  },
369
602
  "/v2/erp/updates/mapping_simulation": {
@@ -6284,6 +6517,11 @@
6284
6517
  "maxLength": 255,
6285
6518
  "description": "Optional per-event trace id. Overrides the request-level `correlation_id` for THIS event, so a batch carrying several distinct business operations keeps its traces segregated in monitoring instead of merged under one request-level id. When absent, the event inherits the request-level `correlation_id`.\n",
6286
6519
  "example": "customer-42-sync-2026-08-26"
6520
+ },
6521
+ "interactive": {
6522
+ "type": "boolean",
6523
+ "description": "Optional per-event interactive opt-in. Overrides the request-level `interactive` for THIS event, so one batch can carry both the registration somebody is waiting on and the routine updates that came along with it. When absent, the event inherits the request-level `interactive`.\n",
6524
+ "example": true
6287
6525
  }
6288
6526
  }
6289
6527
  },
@@ -6309,15 +6547,354 @@
6309
6547
  "maxLength": 128,
6310
6548
  "example": "customer-42"
6311
6549
  },
6550
+ "interactive": {
6551
+ "type": "boolean",
6552
+ "description": "Request interactive processing for this request's events.\n\nInteractive events are carried on a dedicated, low-latency lane and\nrecorded, so a caller can wait for their result with\n`GET /v3/erp/updates/events?correlation_id=...`. Use it for the pushes a\nperson is waiting on — a registration, a self-service lookup — not for\nbatch loads.\n\nThe use case has to allow it: its `interactive` setting must be\n`on_request` (this flag then selects the lane) or `always` (every event of\nthat use case is interactive and this flag is unnecessary). On a use case\nthat does not allow it the events are processed normally and the result\nsays `interactive: false`.\n\nAn organization that asks for interactive processing faster than its agreed\nrate has the excess carried on its normal lane instead. Nothing is rejected\nand nothing is lost: those results still say `interactive: true`, with\n`lane` naming the queue that actually carried them, and the correlation can\nstill be waited on - it will simply take as long as a bulk event does.\n\nIndividual events may set their own `interactive`, which overrides this\nrequest-level value for that event only.\n",
6553
+ "example": true
6554
+ },
6555
+ "correlation_complete": {
6556
+ "type": "boolean",
6557
+ "description": "Declares that no further events will follow for this request's\n`correlation_id`. A caller waiting on that correlation is answered as soon\nas the events already sent have finished, instead of waiting out its full\nbudget.\n\nRequires a request-level `correlation_id` - it closes that correlation and\nis never inferred from per-event `correlation_id` values; sending it\nwithout one is a 400.\n\nIt is valid on a request with an empty `events` array, which is how a\nbridge closes a correlation whose terminal marker arrived on its own. If\nnothing was ever pushed under that correlation id, it is created closed and\nempty, so a waiter is told straight away that nothing is coming rather than\nwaiting for data that will never arrive.\n\nClosing a correlation twice is a no-op. Events that arrive afterwards are\nstill processed, and raise a `CORRELATION_LATE_EVENT` monitoring warning.\n",
6558
+ "example": true
6559
+ },
6312
6560
  "events": {
6313
6561
  "type": "array",
6314
- "description": "List of ERP events to process",
6562
+ "description": "List of ERP events to process. At least one is required, unless\n`correlation_complete` is `true` - a request that only closes a correlation\nmay send an empty array.\n\nNote: `wait` is NOT accepted on this endpoint and returns 400. Ingest never\nblocks; poll `GET /v3/erp/updates/events` to wait for a correlation.\n",
6315
6563
  "items": {
6316
6564
  "$ref": "#/components/schemas/ErpEventV3"
6317
6565
  }
6318
6566
  }
6319
6567
  }
6320
6568
  },
6569
+ "ErpUpdateProcessedEntity": {
6570
+ "type": "object",
6571
+ "description": "An entity an interactive event wrote.",
6572
+ "required": [
6573
+ "slug",
6574
+ "_id",
6575
+ "operation",
6576
+ "unique_ids"
6577
+ ],
6578
+ "properties": {
6579
+ "slug": {
6580
+ "type": "string",
6581
+ "description": "Entity schema slug, e.g. `contact`.",
6582
+ "example": "contact"
6583
+ },
6584
+ "_id": {
6585
+ "type": "string",
6586
+ "description": "The entity id."
6587
+ },
6588
+ "operation": {
6589
+ "type": "string",
6590
+ "enum": [
6591
+ "created",
6592
+ "updated",
6593
+ "deleted",
6594
+ "unchanged"
6595
+ ],
6596
+ "description": "What the write did. `unchanged` means the entity already matched the\nevent; it still counts as written.\n"
6597
+ },
6598
+ "unique_ids": {
6599
+ "type": "object",
6600
+ "description": "The unique ids the entity was looked up by — exactly the use case's\nconfigured `unique_ids` for that entity and nothing else. These and `_id`\nare what a caller can tell several entities of one slug apart by, and the\nonly attributes a `wait_for_entities` selector can match.\n",
6601
+ "additionalProperties": {
6602
+ "type": "string"
6603
+ },
6604
+ "example": {
6605
+ "reenumber": "4711"
6606
+ }
6607
+ }
6608
+ }
6609
+ },
6610
+ "ErpUpdateProcessingError": {
6611
+ "type": "object",
6612
+ "description": "A failure nothing will retry.",
6613
+ "required": [
6614
+ "code",
6615
+ "message",
6616
+ "occurred_at"
6617
+ ],
6618
+ "properties": {
6619
+ "code": {
6620
+ "description": "The v2 monitoring code of the failure.",
6621
+ "type": "string"
6622
+ },
6623
+ "message": {
6624
+ "type": "string"
6625
+ },
6626
+ "event_id": {
6627
+ "type": "string",
6628
+ "description": "Which event of the correlation failed. Present on the correlation's\nerrors only; on an event's own errors it would repeat the event's id.\n"
6629
+ },
6630
+ "occurred_at": {
6631
+ "type": "string",
6632
+ "format": "date-time"
6633
+ }
6634
+ }
6635
+ },
6636
+ "ErpUpdateEventStatus": {
6637
+ "type": "object",
6638
+ "description": "One interactive event's processing record.",
6639
+ "required": [
6640
+ "event_id",
6641
+ "status",
6642
+ "lane",
6643
+ "ingested_at",
6644
+ "writes_total",
6645
+ "writes_done",
6646
+ "entities",
6647
+ "errors"
6648
+ ],
6649
+ "properties": {
6650
+ "event_id": {
6651
+ "type": "string"
6652
+ },
6653
+ "correlation_id": {
6654
+ "type": "string"
6655
+ },
6656
+ "integration_id": {
6657
+ "type": "string"
6658
+ },
6659
+ "status": {
6660
+ "type": "string",
6661
+ "enum": [
6662
+ "accepted",
6663
+ "processing",
6664
+ "done",
6665
+ "partial",
6666
+ "error"
6667
+ ],
6668
+ "description": "`accepted` until the mapping ran, `processing` while its writes run, then\none of the terminal states: `done`, `partial` (some writes failed) or\n`error`.\n"
6669
+ },
6670
+ "lane": {
6671
+ "type": "string",
6672
+ "enum": [
6673
+ "interactive",
6674
+ "priority",
6675
+ "default",
6676
+ "deferred"
6677
+ ],
6678
+ "description": "Which processing lane carried the event."
6679
+ },
6680
+ "use_case_id": {
6681
+ "type": "string"
6682
+ },
6683
+ "use_case_slug": {
6684
+ "type": "string"
6685
+ },
6686
+ "event_name": {
6687
+ "type": "string",
6688
+ "description": "The partner's own name for the event, as pushed."
6689
+ },
6690
+ "ingested_at": {
6691
+ "type": "string",
6692
+ "format": "date-time"
6693
+ },
6694
+ "mapped_at": {
6695
+ "type": "string",
6696
+ "format": "date-time",
6697
+ "description": "When the event's mapping finished."
6698
+ },
6699
+ "done_at": {
6700
+ "type": "string",
6701
+ "format": "date-time",
6702
+ "description": "When the event reached a terminal status."
6703
+ },
6704
+ "writes_total": {
6705
+ "type": "integer",
6706
+ "description": "The entity writes the event fanned out into so far."
6707
+ },
6708
+ "writes_done": {
6709
+ "type": "integer",
6710
+ "description": "The entity writes that have finished."
6711
+ },
6712
+ "entities": {
6713
+ "type": "array",
6714
+ "items": {
6715
+ "$ref": "#/components/schemas/ErpUpdateProcessedEntity"
6716
+ }
6717
+ },
6718
+ "errors": {
6719
+ "type": "array",
6720
+ "items": {
6721
+ "$ref": "#/components/schemas/ErpUpdateProcessingError"
6722
+ }
6723
+ }
6724
+ }
6725
+ },
6726
+ "CorrelationUseCaseCounts": {
6727
+ "type": "object",
6728
+ "description": "How many of a correlation's events belong to one use case, and how they ended.",
6729
+ "required": [
6730
+ "use_case_slug",
6731
+ "received",
6732
+ "done",
6733
+ "error"
6734
+ ],
6735
+ "properties": {
6736
+ "use_case_slug": {
6737
+ "type": "string",
6738
+ "description": "The use case's slug, or its id for a use case that has no slug — such a\nuse case is counted but cannot be named in `wait_for_use_cases`.\n"
6739
+ },
6740
+ "received": {
6741
+ "type": "integer"
6742
+ },
6743
+ "done": {
6744
+ "type": "integer"
6745
+ },
6746
+ "error": {
6747
+ "type": "integer",
6748
+ "description": "Events of this use case that ended `error` or `partial`."
6749
+ }
6750
+ }
6751
+ },
6752
+ "CorrelationStatus": {
6753
+ "type": "object",
6754
+ "description": "One correlation's summary.",
6755
+ "required": [
6756
+ "correlation_id",
6757
+ "closed",
6758
+ "events_received",
6759
+ "events_done",
6760
+ "late_events",
6761
+ "use_cases",
6762
+ "entities",
6763
+ "errors"
6764
+ ],
6765
+ "properties": {
6766
+ "correlation_id": {
6767
+ "type": "string"
6768
+ },
6769
+ "integration_id": {
6770
+ "type": "string"
6771
+ },
6772
+ "closed": {
6773
+ "type": "boolean",
6774
+ "description": "The partner sent `correlation_complete`."
6775
+ },
6776
+ "closed_at": {
6777
+ "type": "string",
6778
+ "format": "date-time"
6779
+ },
6780
+ "events_received": {
6781
+ "type": "integer"
6782
+ },
6783
+ "events_done": {
6784
+ "type": "integer",
6785
+ "description": "Events that reached a terminal status, failed ones included."
6786
+ },
6787
+ "late_events": {
6788
+ "type": "integer",
6789
+ "description": "Events that arrived after the correlation was closed."
6790
+ },
6791
+ "first_ingested_at": {
6792
+ "type": "string",
6793
+ "format": "date-time"
6794
+ },
6795
+ "last_done_at": {
6796
+ "type": "string",
6797
+ "format": "date-time"
6798
+ },
6799
+ "use_cases": {
6800
+ "type": "array",
6801
+ "items": {
6802
+ "$ref": "#/components/schemas/CorrelationUseCaseCounts"
6803
+ }
6804
+ },
6805
+ "entities": {
6806
+ "type": "array",
6807
+ "description": "Every entity the correlation's events wrote.",
6808
+ "items": {
6809
+ "$ref": "#/components/schemas/ErpUpdateProcessedEntity"
6810
+ }
6811
+ },
6812
+ "errors": {
6813
+ "type": "array",
6814
+ "description": "Every failure in the correlation, whatever `completion` says.",
6815
+ "items": {
6816
+ "$ref": "#/components/schemas/ErpUpdateProcessingError"
6817
+ }
6818
+ }
6819
+ }
6820
+ },
6821
+ "CorrelationWaitResult": {
6822
+ "allOf": [
6823
+ {
6824
+ "$ref": "#/components/schemas/CorrelationStatus"
6825
+ },
6826
+ {
6827
+ "type": "object",
6828
+ "required": [
6829
+ "completion"
6830
+ ],
6831
+ "properties": {
6832
+ "completion": {
6833
+ "type": "string",
6834
+ "enum": [
6835
+ "requirements_met",
6836
+ "complete",
6837
+ "timeout",
6838
+ "error"
6839
+ ],
6840
+ "description": "Why the wait ended. See the operation description."
6841
+ }
6842
+ }
6843
+ }
6844
+ ]
6845
+ },
6846
+ "CorrelationWaitBadRequest": {
6847
+ "type": "object",
6848
+ "required": [
6849
+ "message"
6850
+ ],
6851
+ "properties": {
6852
+ "message": {
6853
+ "type": "string"
6854
+ },
6855
+ "slug": {
6856
+ "type": "string",
6857
+ "description": "The entity slug of a requirement that can never match."
6858
+ },
6859
+ "rejected_key": {
6860
+ "type": "string",
6861
+ "description": "The selector key that is not a unique id of `slug`."
6862
+ },
6863
+ "allowed_keys": {
6864
+ "type": "array",
6865
+ "description": "Every unique id of `slug` across the organization's inbound use cases —\nthe keys a selector on `slug` may name. Empty when no use case writes it.\n",
6866
+ "items": {
6867
+ "type": "string"
6868
+ }
6869
+ }
6870
+ }
6871
+ },
6872
+ "CorrelationStatusList": {
6873
+ "type": "object",
6874
+ "required": [
6875
+ "results",
6876
+ "next_cursor",
6877
+ "horizon_days"
6878
+ ],
6879
+ "properties": {
6880
+ "results": {
6881
+ "type": "array",
6882
+ "items": {
6883
+ "$ref": "#/components/schemas/CorrelationStatus"
6884
+ }
6885
+ },
6886
+ "next_cursor": {
6887
+ "type": "string",
6888
+ "nullable": true,
6889
+ "description": "Cursor for the next page, or null when there are no more rows."
6890
+ },
6891
+ "horizon_days": {
6892
+ "type": "integer",
6893
+ "description": "How many days back the listing reaches — the lifetime of a correlation\nrecord. Nothing older is ever returned.\n",
6894
+ "example": 7
6895
+ }
6896
+ }
6897
+ },
6321
6898
  "TriggerErpActionRequest": {
6322
6899
  "type": "object",
6323
6900
  "required": [
@@ -7105,6 +7682,16 @@
7105
7682
  "type": "boolean",
7106
7683
  "description": "Enables direct mode for this use case. When `true`, every event routed to this use\ncase must carry a `DirectPayload` - pre-mapped entity and meter reading operations -\ninstead of raw ERP data, and the mapping engine is skipped entirely. Everything else\nin the inbound pipeline (deduplication, ordering, create-vs-update resolution,\nrelation resolution, monitoring) behaves exactly as in mapped mode.\n\nIn direct mode, `entities` doubles as an optional allowlist: when non-empty, each\noperation's `entity_slug` must match an entry's `entity_schema`, and when that entry\ndeclares `unique_ids`, the operation's unique-id keys must be exactly that set (or\njust `_id`). Entries need only `entity_schema` and `unique_ids` - `fields` is not\nrequired and is ignored. `meter_readings` is ignored in direct mode.\n\nFlag changes take up to 5 minutes to propagate (configuration cache).\n"
7107
7684
  },
7685
+ "interactive": {
7686
+ "type": "string",
7687
+ "enum": [
7688
+ "disabled",
7689
+ "on_request",
7690
+ "always"
7691
+ ],
7692
+ "description": "Whether events of this use case may be processed on the interactive lane -\na dedicated low-latency lane whose events are recorded, so a caller can wait\nfor their result with `GET /v3/erp/updates/events?correlation_id=...`.\n\n- `on_request`: the ingest request's own `interactive: true` selects the\n lane. The normal setting for a mapping that serves both the nightly batch\n and a registration push.\n- `always`: every event of this use case is interactive, and the caller does\n not have to ask. For use cases that exist only to serve a person waiting.\n- `disabled`: requests asking for interactive processing are processed\n normally and told so in the result.\n\nTHE FIELD IS OPTIONAL AND ABSENT MEANS `disabled`. It is resolved when the\nconfiguration is read and is never written into a stored configuration: a\n`disabled` materialised on save would give a configuration a key its source\ndoes not have, which configuration-synchronisation tooling reports as drift\non every comparison. Send it only when you mean `on_request` or `always`,\nand remove it rather than setting it to `disabled`.\n\nThe per-organization interactive rate limit still applies to `always`.\n",
7693
+ "example": "on_request"
7694
+ },
7108
7695
  "entities": {
7109
7696
  "type": "array",
7110
7697
  "description": "Array of entity configurations for this event",
@@ -12863,6 +13450,16 @@
12863
13450
  "CONDITIONAL_VARIANTS_WRITTEN",
12864
13451
  "CONDITIONAL_VARIANT_WRITE_FAILED",
12865
13452
  "CONDITIONAL_VARIANT_WRITE_WARNING",
13453
+ "CORRELATION_CLOSED_EMPTY",
13454
+ "CORRELATION_CLOSED_INCOMPLETE",
13455
+ "CORRELATION_CLOSE_IGNORED",
13456
+ "CORRELATION_COMPLETED",
13457
+ "CORRELATION_EVENT_LIMIT_EXCEEDED",
13458
+ "CORRELATION_ID_MISSING",
13459
+ "CORRELATION_LATE_EVENT",
13460
+ "CORRELATION_REQUIREMENT_FAILED",
13461
+ "CORRELATION_WAIT_REJECTED",
13462
+ "CORRELATION_WAIT_TIMEOUT",
12866
13463
  "DEPRECATED_ENDPOINT",
12867
13464
  "DIRECT_ENTITY_NOT_ALLOWED",
12868
13465
  "DIRECT_PAYLOAD_INVALID",
@@ -12890,6 +13487,9 @@
12890
13487
  "FILE_PROXY_UPLOAD_RETRYING",
12891
13488
  "FILE_TOO_LARGE",
12892
13489
  "INTEGRATION_NOT_FOUND",
13490
+ "INTERACTIVE_CROSS_LANE_WRITE",
13491
+ "INTERACTIVE_NOT_ALLOWED",
13492
+ "INTERACTIVE_RATE_LIMITED",
12893
13493
  "INVALID_METER_READING_ATTRIBUTES",
12894
13494
  "LOOKUP_UNMAPPED",
12895
13495
  "MALFORMED_PAYLOAD",
@@ -13601,6 +14201,24 @@
13601
14201
  }
13602
14202
  }
13603
14203
  },
14204
+ "CorrelationWaitRejected": {
14205
+ "description": "Too many correlation waits are open — for this organization or overall — so\nthis one was not admitted. Nothing about the correlation changed. Retry after\n`Retry-After`, or call with `wait=0`, which never needs a slot.\n",
14206
+ "headers": {
14207
+ "Retry-After": {
14208
+ "description": "Seconds to wait before retrying",
14209
+ "schema": {
14210
+ "type": "integer"
14211
+ }
14212
+ }
14213
+ },
14214
+ "content": {
14215
+ "application/json": {
14216
+ "schema": {
14217
+ "$ref": "#/components/schemas/ErrorResponseBase"
14218
+ }
14219
+ }
14220
+ }
14221
+ },
13604
14222
  "QueryInboundMonitoringEventsResponse": {
13605
14223
  "description": "Inbound monitoring events queried successfully",
13606
14224
  "content": {
@@ -13841,6 +14459,10 @@
13841
14459
  "schema": {
13842
14460
  "type": "object",
13843
14461
  "properties": {
14462
+ "correlation_id": {
14463
+ "type": "string",
14464
+ "description": "The request's correlation id, echoed, or the one generated for it when the caller omitted it. This is the id to pass to `GET /v3/erp/updates/events?correlation_id=...` to wait for these events. Omitted when the request carried no correlation id and none was generated (v1 and v2).\n"
14465
+ },
13844
14466
  "results": {
13845
14467
  "type": "array",
13846
14468
  "items": {
@@ -13864,6 +14486,20 @@
13864
14486
  ],
13865
14487
  "description": "Processing status for the event (skipped indicates duplicate deduplication_id, ignored indicates unconfigured event)"
13866
14488
  },
14489
+ "interactive": {
14490
+ "type": "boolean",
14491
+ "description": "Whether the event was PROCESSED as interactive - its processing record exists and the correlation wait works on it. Present only when interactive processing was requested or the use case is configured `always`. `true` with a `lane` other than `interactive` means the organization was over its rate and the event was carried on its normal lane; the wait still works, it is just slower. `false` means the use case does not allow interactive processing, and `message` says so.\n"
14492
+ },
14493
+ "lane": {
14494
+ "type": "string",
14495
+ "enum": [
14496
+ "interactive",
14497
+ "priority",
14498
+ "default",
14499
+ "deferred"
14500
+ ],
14501
+ "description": "Which processing lane carried the event. Present only alongside `interactive`.\n"
14502
+ },
13867
14503
  "message": {
13868
14504
  "type": "string"
13869
14505
  }
@@ -13890,6 +14526,10 @@
13890
14526
  "schema": {
13891
14527
  "type": "object",
13892
14528
  "properties": {
14529
+ "correlation_id": {
14530
+ "type": "string",
14531
+ "description": "The request's correlation id, echoed, or the one generated for it when the caller omitted it. This is the id to pass to `GET /v3/erp/updates/events?correlation_id=...` to wait for these events. Omitted when the request carried no correlation id and none was generated (v1 and v2).\n"
14532
+ },
13893
14533
  "results": {
13894
14534
  "type": "array",
13895
14535
  "items": {
@@ -13913,6 +14553,20 @@
13913
14553
  ],
13914
14554
  "description": "Processing status for the event (skipped indicates duplicate deduplication_id, ignored indicates unconfigured event)"
13915
14555
  },
14556
+ "interactive": {
14557
+ "type": "boolean",
14558
+ "description": "Whether the event was PROCESSED as interactive - its processing record exists and the correlation wait works on it. Present only when interactive processing was requested or the use case is configured `always`. `true` with a `lane` other than `interactive` means the organization was over its rate and the event was carried on its normal lane; the wait still works, it is just slower. `false` means the use case does not allow interactive processing, and `message` says so.\n"
14559
+ },
14560
+ "lane": {
14561
+ "type": "string",
14562
+ "enum": [
14563
+ "interactive",
14564
+ "priority",
14565
+ "default",
14566
+ "deferred"
14567
+ ],
14568
+ "description": "Which processing lane carried the event. Present only alongside `interactive`.\n"
14569
+ },
13916
14570
  "message": {
13917
14571
  "type": "string"
13918
14572
  }