@lerianstudio/matcher-mcp 5.0.0-beta.8 → 5.0.0-beta.80

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 (273) hide show
  1. package/README.md +28 -13
  2. package/dist/auth/request-token.js +11 -69
  3. package/dist/auth/request-token.js.map +1 -1
  4. package/dist/config.js +6 -21
  5. package/dist/config.js.map +1 -1
  6. package/dist/copilot/agent.js +5 -9
  7. package/dist/copilot/agent.js.map +1 -1
  8. package/dist/copilot/provider-anthropic.js +75 -23
  9. package/dist/copilot/provider-anthropic.js.map +1 -1
  10. package/dist/copilot/provider-openrouter.js +5 -18
  11. package/dist/copilot/provider-openrouter.js.map +1 -1
  12. package/dist/copilot/provider-shared.js +11 -0
  13. package/dist/copilot/provider-shared.js.map +1 -1
  14. package/dist/copilot/speech-provider.js +84 -0
  15. package/dist/copilot/speech-provider.js.map +1 -0
  16. package/dist/copilot/sse.js +5 -0
  17. package/dist/copilot/sse.js.map +1 -1
  18. package/dist/copilot/tools.js +14 -65
  19. package/dist/copilot/tools.js.map +1 -1
  20. package/dist/copilot/transcribe-handler.js +8 -93
  21. package/dist/copilot/transcribe-handler.js.map +1 -1
  22. package/dist/copilot/turn-request.js +76 -0
  23. package/dist/copilot/turn-request.js.map +1 -0
  24. package/dist/copilot/turns-handler.js +11 -102
  25. package/dist/copilot/turns-handler.js.map +1 -1
  26. package/dist/matcher/client.js +14 -0
  27. package/dist/matcher/client.js.map +1 -1
  28. package/dist/matcher/idempotency.js +94 -0
  29. package/dist/matcher/idempotency.js.map +1 -0
  30. package/dist/observability/otel.js +7 -29
  31. package/dist/observability/otel.js.map +1 -1
  32. package/dist/server.js +12 -81
  33. package/dist/server.js.map +1 -1
  34. package/dist/spec/curated-operations.js +111 -95
  35. package/dist/spec/curated-operations.js.map +1 -1
  36. package/dist/spec/enum-policy.js +21 -26
  37. package/dist/spec/enum-policy.js.map +1 -1
  38. package/dist/spec/openapi.yaml +841 -56
  39. package/dist/spec/schema-parity.js +23 -28
  40. package/dist/spec/schema-parity.js.map +1 -1
  41. package/dist/tools/context/create.js +3 -2
  42. package/dist/tools/context/create.js.map +1 -1
  43. package/dist/tools/context/index.js +137 -17
  44. package/dist/tools/context/index.js.map +1 -1
  45. package/dist/tools/context/list.js +9 -35
  46. package/dist/tools/context/list.js.map +1 -1
  47. package/dist/tools/context/setup-progress.js +3 -2
  48. package/dist/tools/context/setup-progress.js.map +1 -1
  49. package/dist/tools/context/shared.js +7 -48
  50. package/dist/tools/context/shared.js.map +1 -1
  51. package/dist/tools/context/update.js +5 -5
  52. package/dist/tools/context/update.js.map +1 -1
  53. package/dist/tools/curated-tool.js +39 -0
  54. package/dist/tools/curated-tool.js.map +1 -0
  55. package/dist/tools/dashboard/index.js +124 -19
  56. package/dist/tools/dashboard/index.js.map +1 -1
  57. package/dist/tools/dashboard/shared.js +9 -68
  58. package/dist/tools/dashboard/shared.js.map +1 -1
  59. package/dist/tools/dispute/close.js +5 -5
  60. package/dist/tools/dispute/close.js.map +1 -1
  61. package/dist/tools/dispute/index.js +34 -6
  62. package/dist/tools/dispute/index.js.map +1 -1
  63. package/dist/tools/dispute/list.js +18 -47
  64. package/dist/tools/dispute/list.js.map +1 -1
  65. package/dist/tools/dispute/shared.js +4 -43
  66. package/dist/tools/dispute/shared.js.map +1 -1
  67. package/dist/tools/dispute/submit-evidence.js +5 -5
  68. package/dist/tools/dispute/submit-evidence.js.map +1 -1
  69. package/dist/tools/exception/add-comment.js +3 -2
  70. package/dist/tools/exception/add-comment.js.map +1 -1
  71. package/dist/tools/exception/adjust-entry.js +5 -5
  72. package/dist/tools/exception/adjust-entry.js.map +1 -1
  73. package/dist/tools/exception/bulk-assign.js +3 -2
  74. package/dist/tools/exception/bulk-assign.js.map +1 -1
  75. package/dist/tools/exception/bulk-dispatch.js +12 -4
  76. package/dist/tools/exception/bulk-dispatch.js.map +1 -1
  77. package/dist/tools/exception/bulk-resolve.js +3 -2
  78. package/dist/tools/exception/bulk-resolve.js.map +1 -1
  79. package/dist/tools/exception/dispatch.js +13 -5
  80. package/dist/tools/exception/dispatch.js.map +1 -1
  81. package/dist/tools/exception/force-match.js +3 -2
  82. package/dist/tools/exception/force-match.js.map +1 -1
  83. package/dist/tools/exception/history.js +8 -24
  84. package/dist/tools/exception/history.js.map +1 -1
  85. package/dist/tools/exception/index.js +88 -18
  86. package/dist/tools/exception/index.js.map +1 -1
  87. package/dist/tools/exception/list.js +14 -57
  88. package/dist/tools/exception/list.js.map +1 -1
  89. package/dist/tools/exception/open-dispute.js +3 -2
  90. package/dist/tools/exception/open-dispute.js.map +1 -1
  91. package/dist/tools/exception/shared.js +10 -46
  92. package/dist/tools/exception/shared.js.map +1 -1
  93. package/dist/tools/fee-rule/create.js +5 -5
  94. package/dist/tools/fee-rule/create.js.map +1 -1
  95. package/dist/tools/fee-rule/index.js +50 -8
  96. package/dist/tools/fee-rule/index.js.map +1 -1
  97. package/dist/tools/fee-rule/list.js +9 -29
  98. package/dist/tools/fee-rule/list.js.map +1 -1
  99. package/dist/tools/fee-rule/shared.js +5 -47
  100. package/dist/tools/fee-rule/shared.js.map +1 -1
  101. package/dist/tools/fee-rule/update.js +5 -5
  102. package/dist/tools/fee-rule/update.js.map +1 -1
  103. package/dist/tools/fee-schedule/create.js +8 -3
  104. package/dist/tools/fee-schedule/create.js.map +1 -1
  105. package/dist/tools/fee-schedule/index.js +62 -11
  106. package/dist/tools/fee-schedule/index.js.map +1 -1
  107. package/dist/tools/fee-schedule/list.js +8 -24
  108. package/dist/tools/fee-schedule/list.js.map +1 -1
  109. package/dist/tools/fee-schedule/shared.js +5 -44
  110. package/dist/tools/fee-schedule/shared.js.map +1 -1
  111. package/dist/tools/fee-schedule/simulate.js +5 -5
  112. package/dist/tools/fee-schedule/simulate.js.map +1 -1
  113. package/dist/tools/fee-schedule/update.js +5 -5
  114. package/dist/tools/fee-schedule/update.js.map +1 -1
  115. package/dist/tools/field-map/create.js +3 -2
  116. package/dist/tools/field-map/create.js.map +1 -1
  117. package/dist/tools/field-map/index.js +65 -11
  118. package/dist/tools/field-map/index.js.map +1 -1
  119. package/dist/tools/field-map/list.js +9 -29
  120. package/dist/tools/field-map/list.js.map +1 -1
  121. package/dist/tools/field-map/shared.js +6 -42
  122. package/dist/tools/field-map/shared.js.map +1 -1
  123. package/dist/tools/field-map/update.js +3 -2
  124. package/dist/tools/field-map/update.js.map +1 -1
  125. package/dist/tools/generic/invoke.js +16 -39
  126. package/dist/tools/generic/invoke.js.map +1 -1
  127. package/dist/tools/ingestion/index.js +100 -12
  128. package/dist/tools/ingestion/index.js.map +1 -1
  129. package/dist/tools/ingestion/job-transactions-list.js +10 -40
  130. package/dist/tools/ingestion/job-transactions-list.js.map +1 -1
  131. package/dist/tools/ingestion/jobs-list.js +9 -35
  132. package/dist/tools/ingestion/jobs-list.js.map +1 -1
  133. package/dist/tools/ingestion/shared.js +4 -41
  134. package/dist/tools/ingestion/shared.js.map +1 -1
  135. package/dist/tools/ingestion/transactions-search.js +9 -44
  136. package/dist/tools/ingestion/transactions-search.js.map +1 -1
  137. package/dist/tools/ingestion/upload-begin.js +5 -2
  138. package/dist/tools/ingestion/upload-begin.js.map +1 -1
  139. package/dist/tools/ingestion/upload.js +3 -2
  140. package/dist/tools/ingestion/upload.js.map +1 -1
  141. package/dist/tools/input-fields.js +51 -0
  142. package/dist/tools/input-fields.js.map +1 -0
  143. package/dist/tools/match-rule/index.js +130 -13
  144. package/dist/tools/match-rule/index.js.map +1 -1
  145. package/dist/tools/match-rule/list.js +9 -33
  146. package/dist/tools/match-rule/list.js.map +1 -1
  147. package/dist/tools/match-rule/shared.js +16 -46
  148. package/dist/tools/match-rule/shared.js.map +1 -1
  149. package/dist/tools/match-rule/update.js +7 -11
  150. package/dist/tools/match-rule/update.js.map +1 -1
  151. package/dist/tools/matching/get.js +5 -5
  152. package/dist/tools/matching/get.js.map +1 -1
  153. package/dist/tools/matching/groups.js +6 -14
  154. package/dist/tools/matching/groups.js.map +1 -1
  155. package/dist/tools/matching/index.js +77 -5
  156. package/dist/tools/matching/index.js.map +1 -1
  157. package/dist/tools/matching/list.js +9 -32
  158. package/dist/tools/matching/list.js.map +1 -1
  159. package/dist/tools/matching/shared.js +5 -46
  160. package/dist/tools/matching/shared.js.map +1 -1
  161. package/dist/tools/query-handler.js +9 -0
  162. package/dist/tools/query-handler.js.map +1 -0
  163. package/dist/tools/report/index.js +260 -30
  164. package/dist/tools/report/index.js.map +1 -1
  165. package/dist/tools/report/shared.js +24 -98
  166. package/dist/tools/report/shared.js.map +1 -1
  167. package/dist/tools/request-fields.js +17 -0
  168. package/dist/tools/request-fields.js.map +1 -0
  169. package/dist/tools/shared-dispatch.js +38 -0
  170. package/dist/tools/shared-dispatch.js.map +1 -0
  171. package/dist/tools/source/create.js +146 -23
  172. package/dist/tools/source/create.js.map +1 -1
  173. package/dist/tools/source/index.js +101 -13
  174. package/dist/tools/source/index.js.map +1 -1
  175. package/dist/tools/source/list.js +9 -32
  176. package/dist/tools/source/list.js.map +1 -1
  177. package/dist/tools/source/shared.js +5 -42
  178. package/dist/tools/source/shared.js.map +1 -1
  179. package/dist/tools/source/update.js +16 -33
  180. package/dist/tools/source/update.js.map +1 -1
  181. package/dist/tools/workspace/usage.js +12 -40
  182. package/dist/tools/workspace/usage.js.map +1 -1
  183. package/package.json +4 -4
  184. package/dist/tools/context/archive.js +0 -37
  185. package/dist/tools/context/archive.js.map +0 -1
  186. package/dist/tools/context/get.js +0 -31
  187. package/dist/tools/context/get.js.map +0 -1
  188. package/dist/tools/context/next-step.js +0 -99
  189. package/dist/tools/context/next-step.js.map +0 -1
  190. package/dist/tools/context/restore.js +0 -34
  191. package/dist/tools/context/restore.js.map +0 -1
  192. package/dist/tools/dashboard/aggregates.js +0 -37
  193. package/dist/tools/dashboard/aggregates.js.map +0 -1
  194. package/dist/tools/dashboard/cash-impact.js +0 -37
  195. package/dist/tools/dashboard/cash-impact.js.map +0 -1
  196. package/dist/tools/dashboard/match-rate.js +0 -37
  197. package/dist/tools/dashboard/match-rate.js.map +0 -1
  198. package/dist/tools/dashboard/metrics.js +0 -37
  199. package/dist/tools/dashboard/metrics.js.map +0 -1
  200. package/dist/tools/dashboard/sla.js +0 -34
  201. package/dist/tools/dashboard/sla.js.map +0 -1
  202. package/dist/tools/dashboard/source-breakdown.js +0 -37
  203. package/dist/tools/dashboard/source-breakdown.js.map +0 -1
  204. package/dist/tools/dashboard/volume.js +0 -37
  205. package/dist/tools/dashboard/volume.js.map +0 -1
  206. package/dist/tools/dispute/get.js +0 -27
  207. package/dist/tools/dispute/get.js.map +0 -1
  208. package/dist/tools/exception/delete-comment.js +0 -40
  209. package/dist/tools/exception/delete-comment.js.map +0 -1
  210. package/dist/tools/exception/get.js +0 -34
  211. package/dist/tools/exception/get.js.map +0 -1
  212. package/dist/tools/exception/list-comments.js +0 -35
  213. package/dist/tools/exception/list-comments.js.map +0 -1
  214. package/dist/tools/fee-rule/delete.js +0 -27
  215. package/dist/tools/fee-rule/delete.js.map +0 -1
  216. package/dist/tools/fee-rule/get.js +0 -27
  217. package/dist/tools/fee-rule/get.js.map +0 -1
  218. package/dist/tools/fee-schedule/delete.js +0 -32
  219. package/dist/tools/fee-schedule/delete.js.map +0 -1
  220. package/dist/tools/fee-schedule/get.js +0 -30
  221. package/dist/tools/fee-schedule/get.js.map +0 -1
  222. package/dist/tools/field-map/delete.js +0 -37
  223. package/dist/tools/field-map/delete.js.map +0 -1
  224. package/dist/tools/field-map/get.js +0 -43
  225. package/dist/tools/field-map/get.js.map +0 -1
  226. package/dist/tools/ingestion/job-errors-list.js +0 -45
  227. package/dist/tools/ingestion/job-errors-list.js.map +0 -1
  228. package/dist/tools/ingestion/job-get.js +0 -42
  229. package/dist/tools/ingestion/job-get.js.map +0 -1
  230. package/dist/tools/ingestion/transaction-ignore.js +0 -51
  231. package/dist/tools/ingestion/transaction-ignore.js.map +0 -1
  232. package/dist/tools/match-rule/create.js +0 -67
  233. package/dist/tools/match-rule/create.js.map +0 -1
  234. package/dist/tools/match-rule/delete.js +0 -35
  235. package/dist/tools/match-rule/delete.js.map +0 -1
  236. package/dist/tools/match-rule/get.js +0 -32
  237. package/dist/tools/match-rule/get.js.map +0 -1
  238. package/dist/tools/match-rule/reorder.js +0 -45
  239. package/dist/tools/match-rule/reorder.js.map +0 -1
  240. package/dist/tools/matching/start.js +0 -81
  241. package/dist/tools/matching/start.js.map +0 -1
  242. package/dist/tools/report/count-exceptions.js +0 -46
  243. package/dist/tools/report/count-exceptions.js.map +0 -1
  244. package/dist/tools/report/count-matched.js +0 -47
  245. package/dist/tools/report/count-matched.js.map +0 -1
  246. package/dist/tools/report/count-transactions.js +0 -45
  247. package/dist/tools/report/count-transactions.js.map +0 -1
  248. package/dist/tools/report/count-unmatched.js +0 -45
  249. package/dist/tools/report/count-unmatched.js.map +0 -1
  250. package/dist/tools/report/export-exceptions.js +0 -48
  251. package/dist/tools/report/export-exceptions.js.map +0 -1
  252. package/dist/tools/report/export-matched.js +0 -49
  253. package/dist/tools/report/export-matched.js.map +0 -1
  254. package/dist/tools/report/export-summary.js +0 -49
  255. package/dist/tools/report/export-summary.js.map +0 -1
  256. package/dist/tools/report/export-unmatched.js +0 -49
  257. package/dist/tools/report/export-unmatched.js.map +0 -1
  258. package/dist/tools/report/export-variance.js +0 -48
  259. package/dist/tools/report/export-variance.js.map +0 -1
  260. package/dist/tools/report/matched.js +0 -48
  261. package/dist/tools/report/matched.js.map +0 -1
  262. package/dist/tools/report/summary.js +0 -43
  263. package/dist/tools/report/summary.js.map +0 -1
  264. package/dist/tools/report/unmatched.js +0 -48
  265. package/dist/tools/report/unmatched.js.map +0 -1
  266. package/dist/tools/report/variance.js +0 -48
  267. package/dist/tools/report/variance.js.map +0 -1
  268. package/dist/tools/source/archive.js +0 -46
  269. package/dist/tools/source/archive.js.map +0 -1
  270. package/dist/tools/source/get.js +0 -57
  271. package/dist/tools/source/get.js.map +0 -1
  272. package/dist/tools/source/restore.js +0 -39
  273. package/dist/tools/source/restore.js.map +0 -1
@@ -184,6 +184,9 @@ components:
184
184
  type: string
185
185
  direction:
186
186
  description: "Direction of the entry: DEBIT explains a shortfall (moves the outstanding variance up, toward zero), CREDIT explains a surplus (moves it down)"
187
+ enum:
188
+ - DEBIT
189
+ - CREDIT
187
190
  examples:
188
191
  - DEBIT
189
192
  type: string
@@ -209,6 +212,12 @@ components:
209
212
  type: string
210
213
  type:
211
214
  description: "Adjustment type: BANK_FEE (bank charge), FX_DIFFERENCE (currency conversion variance), ROUNDING (minor-unit rounding), WRITE_OFF (uncollectible balance), or MISCELLANEOUS (other)"
215
+ enum:
216
+ - BANK_FEE
217
+ - FX_DIFFERENCE
218
+ - ROUNDING
219
+ - WRITE_OFF
220
+ - MISCELLANEOUS
212
221
  examples:
213
222
  - BANK_FEE
214
223
  type: string
@@ -230,6 +239,33 @@ components:
230
239
  - createdAt
231
240
  - updatedAt
232
241
  type: object
242
+ AdminAssignPlanInputBody:
243
+ additionalProperties: false
244
+ properties:
245
+ plan:
246
+ description: "The plan code to assign. ONLY \"enterprise\" is accepted: self-serve plans are bought through checkout and converged from the live subscription's price, so assigning one here would be a payment-processor bypass the next processor delivery silently reverts. Any other code is refused with 409."
247
+ maxLength: 64
248
+ type: string
249
+ required:
250
+ - plan
251
+ type: object
252
+ AdminAssignPlanResult:
253
+ additionalProperties: false
254
+ properties:
255
+ billingStatus:
256
+ description: The commercial standing the workspace now holds. An enterprise contract is in good standing the moment it is signed, so this is always "active".
257
+ type: string
258
+ plan:
259
+ description: The plan the workspace now holds.
260
+ type: string
261
+ slug:
262
+ description: The workspace assigned.
263
+ type: string
264
+ required:
265
+ - slug
266
+ - plan
267
+ - billingStatus
268
+ type: object
233
269
  AdminWorkspaceBilling:
234
270
  additionalProperties: false
235
271
  properties:
@@ -321,10 +357,15 @@ components:
321
357
  additionalProperties: false
322
358
  properties:
323
359
  accountRef:
324
- description: Stored opaque vendor account reference (Pluggy itemId, Belvo link id)
360
+ description: Stored opaque vendor account reference (Pluggy itemId, Belvo link id); empty while the connection is awaiting consent
325
361
  examples:
326
362
  - a1b2c3d4-5678-90ab-cdef-1234567890ab
327
363
  type: string
364
+ awaitingConsent:
365
+ description: Whether the connection is still awaiting the end customer's vendor consent (no vendor item/link bound yet)
366
+ examples:
367
+ - false
368
+ type: boolean
328
369
  baseUrl:
329
370
  description: Stored vendor API base URL
330
371
  examples:
@@ -342,7 +383,7 @@ components:
342
383
  - a1b2c3d4-5678-90ab-cdef-1234567890ab
343
384
  type: string
344
385
  testable:
345
- description: Whether Matcher can run a connectivity test for this connection's aggregator vendor
386
+ description: Whether Matcher can run a connectivity test for this connection right now (its vendor has a test path AND it is bound to a vendor item/link)
346
387
  examples:
347
388
  - true
348
389
  type: boolean
@@ -361,6 +402,7 @@ components:
361
402
  - baseUrl
362
403
  - accountRef
363
404
  - testable
405
+ - awaitingConsent
364
406
  type: object
365
407
  AggregatorConnectionListResponse:
366
408
  additionalProperties: false
@@ -400,10 +442,9 @@ components:
400
442
  additionalProperties: false
401
443
  properties:
402
444
  accountRef:
403
- description: Opaque vendor account reference (Pluggy itemId, Belvo link id) the webhook pull threads onto its request
445
+ description: Opaque vendor account reference (Pluggy itemId, Belvo link id) the webhook pull threads onto its request. Omit to create a connection awaiting consent — the connect flow binds it after the end customer authorizes.
404
446
  examples:
405
447
  - a1b2c3d4-5678-90ab-cdef-1234567890ab
406
- minLength: 1
407
448
  type: string
408
449
  baseUrl:
409
450
  description: Vendor API base URL, stored as the connection host
@@ -438,7 +479,6 @@ components:
438
479
  - vendor
439
480
  - configName
440
481
  - baseUrl
441
- - accountRef
442
482
  - clientId
443
483
  - secret
444
484
  type: object
@@ -446,10 +486,15 @@ components:
446
486
  additionalProperties: false
447
487
  properties:
448
488
  accountRef:
449
- description: Stored opaque vendor account reference (Pluggy itemId, Belvo link id)
489
+ description: Stored opaque vendor account reference (Pluggy itemId, Belvo link id); empty while the connection is awaiting consent
450
490
  examples:
451
491
  - a1b2c3d4-5678-90ab-cdef-1234567890ab
452
492
  type: string
493
+ awaitingConsent:
494
+ description: Whether the connection is still awaiting the end customer's vendor consent (no vendor item/link bound yet)
495
+ examples:
496
+ - false
497
+ type: boolean
453
498
  baseUrl:
454
499
  description: Stored vendor API base URL
455
500
  examples:
@@ -474,6 +519,52 @@ components:
474
519
  - configName
475
520
  - baseUrl
476
521
  - accountRef
522
+ - awaitingConsent
523
+ type: object
524
+ AggregatorConsentTokenResponse:
525
+ additionalProperties: false
526
+ properties:
527
+ accountRef:
528
+ description: Vendor item/link id this token was scoped to (the stored binding); empty on a first consent. Pass it to the vendor widget's update mode alongside the token — do not substitute a locally cached value.
529
+ examples:
530
+ - a1b2c3d4-5678-90ab-cdef-1234567890ab
531
+ type: string
532
+ configName:
533
+ description: Config name of the connection the token was minted for
534
+ examples:
535
+ - pluggy-main
536
+ type: string
537
+ expiresAt:
538
+ description: UTC instant after which the vendor rejects this consent token
539
+ examples:
540
+ - "2026-08-23T12:30:00Z"
541
+ format: date-time
542
+ type: string
543
+ reconsent:
544
+ description: Whether the token re-authorizes the connection's existing vendor item/link (true) or will create a new one (false)
545
+ examples:
546
+ - false
547
+ type: boolean
548
+ token:
549
+ description: Short-lived, widget-ready consent token. Returned exactly once and never stored — pass it to the vendor widget and discard it.
550
+ examples:
551
+ - eyJhbGciOi...
552
+ type: string
553
+ vendor:
554
+ description: Aggregator vendor the consent token was minted against
555
+ enum:
556
+ - pluggy
557
+ - belvo
558
+ examples:
559
+ - pluggy
560
+ type: string
561
+ required:
562
+ - vendor
563
+ - configName
564
+ - token
565
+ - expiresAt
566
+ - reconsent
567
+ - accountRef
477
568
  type: object
478
569
  ApproveExtractionResponse:
479
570
  additionalProperties: false
@@ -638,6 +729,12 @@ components:
638
729
  - 0
639
730
  format: int64
640
731
  type: integer
732
+ fromSeq:
733
+ description: "Effective verification floor: the first tenant_seq eligible for inspection (1 when fromSeq was omitted). Resume a truncated run at fromSeq + verifiedCount"
734
+ examples:
735
+ - 1
736
+ format: int64
737
+ type: integer
641
738
  intact:
642
739
  description: True when every inspected record links to the previous one and matches its stored hash
643
740
  examples:
@@ -656,6 +753,7 @@ components:
656
753
  type: integer
657
754
  required:
658
755
  - intact
756
+ - fromSeq
659
757
  - verifiedCount
660
758
  - truncated
661
759
  type: object
@@ -884,6 +982,11 @@ components:
884
982
  BulkFailure:
885
983
  additionalProperties: false
886
984
  properties:
985
+ code:
986
+ description: Stable product error code for this row, when the failure has one
987
+ examples:
988
+ - MTCH-0514
989
+ type: string
887
990
  error:
888
991
  description: Human-readable reason the exception could not be processed
889
992
  examples:
@@ -932,7 +1035,15 @@ components:
932
1035
  additionalProperties: false
933
1036
  properties:
934
1037
  canonicalKey:
935
- description: Canonical field-map key (e.g. amount, external_id, currency, date)
1038
+ description: Canonical field-map key. The closed vocabulary is the required keys (external_id, amount, currency, date) plus the optional ones (description, fee_amount, fee_currency); the extractor drops any key outside it before a candidate is persisted
1039
+ enum:
1040
+ - external_id
1041
+ - amount
1042
+ - currency
1043
+ - date
1044
+ - description
1045
+ - fee_amount
1046
+ - fee_currency
936
1047
  examples:
937
1048
  - amount
938
1049
  type: string
@@ -1002,6 +1113,11 @@ components:
1002
1113
  type: string
1003
1114
  ruleType:
1004
1115
  description: Strategy of the rule that produced the best score
1116
+ enum:
1117
+ - EXACT
1118
+ - TOLERANCE
1119
+ - DATE_LAG
1120
+ - FUZZY
1005
1121
  examples:
1006
1122
  - EXACT
1007
1123
  type: string
@@ -1060,6 +1176,9 @@ components:
1060
1176
  - "null"
1061
1177
  source:
1062
1178
  description: "Extraction lane that produced this candidate: text_layer (PDF text, higher trust) or vision (OCR/vision model, lower trust)"
1179
+ enum:
1180
+ - text_layer
1181
+ - vision
1063
1182
  examples:
1064
1183
  - text_layer
1065
1184
  type: string
@@ -1801,7 +1920,91 @@ components:
1801
1920
  properties:
1802
1921
  config:
1803
1922
  additionalProperties: {}
1804
- description: "Source-specific configuration object (connection and parsing settings). Optional; defaults to an empty object when omitted. Reserved key duplicate_key: the ordered list of mapped fields that make two rows the same row — any of external_id, amount, currency, date, description, fee_amount, fee_currency. Omit it and rows are deduplicated on external_id alone. A field this source's field map does not fill is refused, because a key over a field that is always empty makes every row a duplicate of every other. A source bound to an aggregator connection (reserved key connection_config_name) cannot carry a duplicate key of its own: the aggregator retracts a movement by naming its external id, so that id has to stay this source's row identity. A config holding both is refused in either direction — drop duplicate_key from a bound source, or disconnect the aggregator connection first. Reserved read-only key duplicate_key_changed_at: the RFC 3339 moment duplicate-key detection last changed meaning on this source, set by the server; a value sent by a client is discarded. It moves for either change that re-keys future rows — editing duplicate_key, or the field map remapping the column a declared field reads (a source keyed on description whose description column moves derives a different key for the same movement). Reserved key duplicate_policy: what happens to a row repeating the duplicate key — FLAG_AS_EXCEPTION (the default: the repeat is kept out of the import and raised as a duplicate exception on the row it repeated), KEEP_FIRST (the repeat is dropped and nothing is raised), or REJECT (the repeat is counted as an import error). Changing duplicate_key governs later imports only — rows already imported keep the key they were deduplicated under."
1923
+ description: "Source-specific configuration object. Cross-key rules the schema cannot express: a duplicate_key component this source's field map does not fill is refused, because a key over an always-empty field makes every row a duplicate of every other; a source bound to an aggregator connection (reserved key connection_config_name) cannot carry a duplicate_key of its own, and a config holding both is refused in either direction; and editing duplicate_key governs later imports only — rows already imported keep the key they were deduplicated under, so a duplicate straddling the change is knowingly not detected."
1924
+ properties:
1925
+ blank_external_id:
1926
+ description: What happens to a row whose mapped external id is blank. REJECT (the default when the key is absent) fails the row. NEEDS_REVIEW imports it under a synthetic reference with status PENDING_REVIEW, so a blank reference becomes a reviewable import instead of an import failure.
1927
+ enum:
1928
+ - REJECT
1929
+ - NEEDS_REVIEW
1930
+ type: string
1931
+ camt053:
1932
+ additionalProperties: false
1933
+ description: How this source's camt.053 files map onto the canonical fields. Every other field is fixed by ISO 20022 itself. An absent object, or an absent sub-key, keeps the ISO defaults (booking, ntry_ref).
1934
+ properties:
1935
+ date_basis:
1936
+ description: "Entry date element: booking is BookgDt/Dt, valuation is ValDt/Dt. Default booking."
1937
+ enum:
1938
+ - booking
1939
+ - valuation
1940
+ type: string
1941
+ external_id_source:
1942
+ description: "Entry reference element: ntry_ref is NtryRef, end_to_end_id is NtryDtls/TxDtls/Refs/EndToEndId, tx_id is NtryDtls/TxDtls/Refs/TxId. Default ntry_ref."
1943
+ enum:
1944
+ - ntry_ref
1945
+ - end_to_end_id
1946
+ - tx_id
1947
+ type: string
1948
+ type: object
1949
+ dialect:
1950
+ additionalProperties: false
1951
+ description: How this source's delimited files are encoded and formatted. Declaration-driven only — there is no auto-detection. An absent object, or an absent sub-key, keeps the defaults (utf-8, comma, dot, iso).
1952
+ properties:
1953
+ date_style:
1954
+ enum:
1955
+ - iso
1956
+ - iso_offset
1957
+ - dmy
1958
+ - mdy
1959
+ type: string
1960
+ decimal_style:
1961
+ description: dot is 1234.56, comma is 1.234,56.
1962
+ enum:
1963
+ - dot
1964
+ - comma
1965
+ type: string
1966
+ delimiter:
1967
+ enum:
1968
+ - comma
1969
+ - semicolon
1970
+ - tab
1971
+ - pipe
1972
+ type: string
1973
+ encoding:
1974
+ enum:
1975
+ - utf-8
1976
+ - utf-8-sig
1977
+ - cp1252
1978
+ - iso-8859-1
1979
+ type: string
1980
+ type: object
1981
+ duplicate_key:
1982
+ description: The ordered list of mapped fields that make two rows the same row. Absent means external_id alone. On a source bound to an aggregator connection the aggregator retracts a movement by naming its external id, so that id has to stay the row identity.
1983
+ items:
1984
+ enum:
1985
+ - external_id
1986
+ - amount
1987
+ - currency
1988
+ - date
1989
+ - description
1990
+ - fee_amount
1991
+ - fee_currency
1992
+ type: string
1993
+ minItems: 1
1994
+ type: array
1995
+ uniqueItems: true
1996
+ duplicate_policy:
1997
+ description: What happens to a row that repeats this source's duplicate key. FLAG_AS_EXCEPTION (the default when the key is absent) keeps the repeat out of the import and raises a duplicate exception on the row it repeated. KEEP_FIRST drops the repeat and raises nothing, so a collision leaves no trace anyone can act on. REJECT counts the repeat as an import error.
1998
+ enum:
1999
+ - FLAG_AS_EXCEPTION
2000
+ - KEEP_FIRST
2001
+ - REJECT
2002
+ type: string
2003
+ fail_on_error_rate_percent:
2004
+ description: "Fail the whole import when the percentage of failed rows exceeds this whole number. Absent means never auto-fail. The ceiling is 99, not 100: the comparison is strict, so 100 could never fire."
2005
+ maximum: 99
2006
+ minimum: 1
2007
+ type: integer
1805
2008
  type: object
1806
2009
  mapping:
1807
2010
  additionalProperties: {}
@@ -1971,10 +2174,10 @@ components:
1971
2174
  type: integer
1972
2175
  structure:
1973
2176
  additionalProperties: {}
1974
- description: "Type-specific structure. FLAT: {\"amount\":\"1.50\"}. PERCENTAGE: {\"rate\":\"0.029\"} where rate is a 0..1 fraction of the base amount (0.029 means 2.9%), not a percent value. TIERED: {\"tiers\":[{\"rate\":\"0.01\",\"upTo\":\"1000\"},...]} with the same 0..1 fraction semantics per tier rate. EXPRESSION: {\"expression\":\"gross - desconto + multa + juros_dia * days_late(due_date, pay_date)\"} a formula over metadata fields (+ - * /, parentheses, and the functions days_late, days_between, max, min, abs, clamp)."
2177
+ description: "Type-specific structure. FLAT: {\"amount\":\"1.50\"}. PERCENTAGE: {\"rate\":\"0.029\"} where rate is a 0..1 fraction of the base amount (0.029 means 2.9%), not a percent value. TIERED: {\"tiers\":[{\"rate\":\"0.01\",\"upTo\":\"1000\"},...]} with the same 0..1 fraction semantics per tier rate. EXPRESSION: {\"expression\":\"gross - desconto + multa + juros_dia * days_late(due_date, pay_date)\"} a formula over metadata fields (+ - * /, parentheses, and the functions days_late, days_between, max, min, abs, clamp). A formula that is only the base amount times numeric literals is a percentage rate and is bounded 0..1: gross * 0.029 is 2.9%, gross * 2.9 is refused; any other formula is unbounded."
1975
2178
  type: object
1976
2179
  structureType:
1977
- description: Shape of the fee structure. FLAT is a fixed amount; PERCENTAGE is a rate of the base; TIERED applies different rates per amount tier; EXPRESSION computes the fee from a bounded arithmetic formula over transaction metadata.
2180
+ description: Shape of the fee structure; the structure field documents the object each one takes.
1978
2181
  enum:
1979
2182
  - FLAT
1980
2183
  - PERCENTAGE
@@ -2231,7 +2434,91 @@ components:
2231
2434
  properties:
2232
2435
  config:
2233
2436
  additionalProperties: {}
2234
- description: "Source-specific configuration object (connection and parsing settings). Optional; defaults to an empty object when omitted. Reserved key duplicate_key: the ordered list of mapped fields that make two rows the same row — any of external_id, amount, currency, date, description, fee_amount, fee_currency. Omit it and rows are deduplicated on external_id alone. A field this source's field map does not fill is refused, because a key over a field that is always empty makes every row a duplicate of every other. A source bound to an aggregator connection (reserved key connection_config_name) cannot carry a duplicate key of its own: the aggregator retracts a movement by naming its external id, so that id has to stay this source's row identity. A config holding both is refused in either direction — drop duplicate_key from a bound source, or disconnect the aggregator connection first. Reserved read-only key duplicate_key_changed_at: the RFC 3339 moment duplicate-key detection last changed meaning on this source, set by the server; a value sent by a client is discarded. It moves for either change that re-keys future rows — editing duplicate_key, or the field map remapping the column a declared field reads (a source keyed on description whose description column moves derives a different key for the same movement). Reserved key duplicate_policy: what happens to a row repeating the duplicate key — FLAG_AS_EXCEPTION (the default: the repeat is kept out of the import and raised as a duplicate exception on the row it repeated), KEEP_FIRST (the repeat is dropped and nothing is raised), or REJECT (the repeat is counted as an import error). Changing duplicate_key governs later imports only — rows already imported keep the key they were deduplicated under."
2437
+ description: "Source-specific configuration object. Cross-key rules the schema cannot express: a duplicate_key component this source's field map does not fill is refused, because a key over an always-empty field makes every row a duplicate of every other; a source bound to an aggregator connection (reserved key connection_config_name) cannot carry a duplicate_key of its own, and a config holding both is refused in either direction; and editing duplicate_key governs later imports only — rows already imported keep the key they were deduplicated under, so a duplicate straddling the change is knowingly not detected."
2438
+ properties:
2439
+ blank_external_id:
2440
+ description: What happens to a row whose mapped external id is blank. REJECT (the default when the key is absent) fails the row. NEEDS_REVIEW imports it under a synthetic reference with status PENDING_REVIEW, so a blank reference becomes a reviewable import instead of an import failure.
2441
+ enum:
2442
+ - REJECT
2443
+ - NEEDS_REVIEW
2444
+ type: string
2445
+ camt053:
2446
+ additionalProperties: false
2447
+ description: How this source's camt.053 files map onto the canonical fields. Every other field is fixed by ISO 20022 itself. An absent object, or an absent sub-key, keeps the ISO defaults (booking, ntry_ref).
2448
+ properties:
2449
+ date_basis:
2450
+ description: "Entry date element: booking is BookgDt/Dt, valuation is ValDt/Dt. Default booking."
2451
+ enum:
2452
+ - booking
2453
+ - valuation
2454
+ type: string
2455
+ external_id_source:
2456
+ description: "Entry reference element: ntry_ref is NtryRef, end_to_end_id is NtryDtls/TxDtls/Refs/EndToEndId, tx_id is NtryDtls/TxDtls/Refs/TxId. Default ntry_ref."
2457
+ enum:
2458
+ - ntry_ref
2459
+ - end_to_end_id
2460
+ - tx_id
2461
+ type: string
2462
+ type: object
2463
+ dialect:
2464
+ additionalProperties: false
2465
+ description: How this source's delimited files are encoded and formatted. Declaration-driven only — there is no auto-detection. An absent object, or an absent sub-key, keeps the defaults (utf-8, comma, dot, iso).
2466
+ properties:
2467
+ date_style:
2468
+ enum:
2469
+ - iso
2470
+ - iso_offset
2471
+ - dmy
2472
+ - mdy
2473
+ type: string
2474
+ decimal_style:
2475
+ description: dot is 1234.56, comma is 1.234,56.
2476
+ enum:
2477
+ - dot
2478
+ - comma
2479
+ type: string
2480
+ delimiter:
2481
+ enum:
2482
+ - comma
2483
+ - semicolon
2484
+ - tab
2485
+ - pipe
2486
+ type: string
2487
+ encoding:
2488
+ enum:
2489
+ - utf-8
2490
+ - utf-8-sig
2491
+ - cp1252
2492
+ - iso-8859-1
2493
+ type: string
2494
+ type: object
2495
+ duplicate_key:
2496
+ description: The ordered list of mapped fields that make two rows the same row. Absent means external_id alone. On a source bound to an aggregator connection the aggregator retracts a movement by naming its external id, so that id has to stay the row identity.
2497
+ items:
2498
+ enum:
2499
+ - external_id
2500
+ - amount
2501
+ - currency
2502
+ - date
2503
+ - description
2504
+ - fee_amount
2505
+ - fee_currency
2506
+ type: string
2507
+ minItems: 1
2508
+ type: array
2509
+ uniqueItems: true
2510
+ duplicate_policy:
2511
+ description: What happens to a row that repeats this source's duplicate key. FLAG_AS_EXCEPTION (the default when the key is absent) keeps the repeat out of the import and raises a duplicate exception on the row it repeated. KEEP_FIRST drops the repeat and raises nothing, so a collision leaves no trace anyone can act on. REJECT counts the repeat as an import error.
2512
+ enum:
2513
+ - FLAG_AS_EXCEPTION
2514
+ - KEEP_FIRST
2515
+ - REJECT
2516
+ type: string
2517
+ fail_on_error_rate_percent:
2518
+ description: "Fail the whole import when the percentage of failed rows exceeds this whole number. Absent means never auto-fail. The ceiling is 99, not 100: the comparison is strict, so 100 could never fire."
2519
+ maximum: 99
2520
+ minimum: 1
2521
+ type: integer
2235
2522
  type: object
2236
2523
  name:
2237
2524
  description: Human-readable name of the source.
@@ -2427,6 +2714,11 @@ components:
2427
2714
  sla:
2428
2715
  $ref: "#/components/schemas/SLAStatsResponse"
2429
2716
  description: SLA compliance statistics for the window.
2717
+ unmatchedByCurrency:
2718
+ description: Unreconciled exposure split by currency; the amounts sum to volume.unmatchedAmount. Empty when no transaction in the window is UNMATCHED or PENDING_REVIEW; always an array, never null. volume.unmatchedAmount is the engine's arithmetic sum of those amounts across currencies, so it is a meaningful money figure only when this split carries a single currency. Clients must not render it as money when the split names more than one currency.
2719
+ items:
2720
+ $ref: "#/components/schemas/CurrencyExposureResponse"
2721
+ type: array
2430
2722
  updatedAt:
2431
2723
  description: Timestamp when these aggregates were computed (RFC 3339, UTC).
2432
2724
  examples:
@@ -2440,6 +2732,7 @@ components:
2440
2732
  - volume
2441
2733
  - matchRate
2442
2734
  - sla
2735
+ - unmatchedByCurrency
2443
2736
  - updatedAt
2444
2737
  type: object
2445
2738
  Detail:
@@ -2495,21 +2788,39 @@ components:
2495
2788
  properties:
2496
2789
  dateStyle:
2497
2790
  description: "Detected date convention: iso (YYYY-MM-DD), iso_offset (RFC 3339 with offset), dmy (DD/MM/YYYY), or mdy (MM/DD/YYYY)"
2791
+ enum:
2792
+ - iso
2793
+ - iso_offset
2794
+ - dmy
2795
+ - mdy
2498
2796
  examples:
2499
2797
  - iso
2500
2798
  type: string
2501
2799
  decimalStyle:
2502
2800
  description: "Detected amount decimal convention: dot (1234.56) or comma (1234,56)"
2801
+ enum:
2802
+ - dot
2803
+ - comma
2503
2804
  examples:
2504
2805
  - comma
2505
2806
  type: string
2506
2807
  delimiter:
2507
2808
  description: "Detected CSV field separator: comma, semicolon, tab, or pipe"
2809
+ enum:
2810
+ - comma
2811
+ - semicolon
2812
+ - tab
2813
+ - pipe
2508
2814
  examples:
2509
2815
  - semicolon
2510
2816
  type: string
2511
2817
  encoding:
2512
2818
  description: "Detected file character encoding: utf-8, utf-8-sig (UTF-8 with BOM), cp1252 (Windows Latin-1), or iso-8859-1"
2819
+ enum:
2820
+ - utf-8
2821
+ - utf-8-sig
2822
+ - cp1252
2823
+ - iso-8859-1
2513
2824
  examples:
2514
2825
  - utf-8
2515
2826
  type: string
@@ -2601,11 +2912,12 @@ components:
2601
2912
  additionalProperties: false
2602
2913
  properties:
2603
2914
  category:
2604
- description: "Dispute category: BANK_FEE_ERROR (incorrect fee), UNRECOGNIZED_CHARGE, DUPLICATE_TRANSACTION, or OTHER"
2915
+ description: "Dispute category: BANK_FEE_ERROR (incorrect fee), UNRECOGNIZED_CHARGE, DUPLICATE_TRANSACTION, AMOUNT_MISMATCH, or OTHER"
2605
2916
  enum:
2606
2917
  - BANK_FEE_ERROR
2607
2918
  - UNRECOGNIZED_CHARGE
2608
2919
  - DUPLICATE_TRANSACTION
2920
+ - AMOUNT_MISMATCH
2609
2921
  - OTHER
2610
2922
  examples:
2611
2923
  - BANK_FEE_ERROR
@@ -2765,7 +3077,7 @@ components:
2765
3077
  additionalProperties: false
2766
3078
  properties:
2767
3079
  amount:
2768
- description: "Enrichment: the exception transaction's amount as a decimal string in the transaction's currency. Present on list rows whose transaction still exists; absent on the get-by-id/resolution paths and when the transaction was deleted."
3080
+ description: "Enrichment: the exception transaction's amount as a decimal string in the transaction's currency. Present on list rows and get-by-id when the transaction still exists."
2769
3081
  examples:
2770
3082
  - "1250.50"
2771
3083
  type: string
@@ -2775,7 +3087,7 @@ components:
2775
3087
  - user@example.com
2776
3088
  type: string
2777
3089
  contextId:
2778
- description: "Enrichment: id of the reconciliation context the exception's source belongs to (UUID). Present on list rows whose transaction and source still exist; powers the global triage queue's context attribution."
3090
+ description: "Enrichment: id of the reconciliation context the exception's source belongs to (UUID). Present on list rows and get-by-id when the transaction and source still exist; powers the global triage queue's context attribution."
2779
3091
  examples:
2780
3092
  - 550e8400-e29b-41d4-a716-446655440004
2781
3093
  type: string
@@ -2785,7 +3097,7 @@ components:
2785
3097
  - "2025-01-15T10:30:00Z"
2786
3098
  type: string
2787
3099
  currency:
2788
- description: "Enrichment: ISO 4217 currency code of the exception transaction's amount. Present on list rows whose transaction still exists."
3100
+ description: "Enrichment: ISO 4217 currency code of the exception transaction's amount. Present on list rows and get-by-id when the transaction still exists."
2789
3101
  examples:
2790
3102
  - USD
2791
3103
  type: string
@@ -2847,6 +3159,9 @@ components:
2847
3159
  examples:
2848
3160
  - 550e8400-e29b-41d4-a716-446655440002
2849
3161
  type: string
3162
+ settlement:
3163
+ $ref: "#/components/schemas/ExceptionSettlementResponse"
3164
+ description: Settlement figures for a fee break (expected vs credited and the signed difference), derived from the live fee-variance snapshot recorded for the exception's transaction. Present on get-by-id only, and only when the snapshot and the transaction amount are both available in the same currency.
2850
3165
  severity:
2851
3166
  description: "Severity level: LOW and MEDIUM are informational, HIGH needs prompt review, CRITICAL requires immediate action"
2852
3167
  enum:
@@ -2858,21 +3173,27 @@ components:
2858
3173
  - HIGH
2859
3174
  type: string
2860
3175
  sourceId:
2861
- description: "Enrichment: id of the reconciliation source the exception transaction belongs to (UUID). Present on list rows whose transaction still exists."
3176
+ description: "Enrichment: id of the reconciliation source the exception transaction belongs to (UUID). Present on list rows and get-by-id when the transaction still exists."
2862
3177
  examples:
2863
3178
  - 550e8400-e29b-41d4-a716-446655440003
2864
3179
  type: string
3180
+ sourceName:
3181
+ description: "Enrichment: display name of the reconciliation source. Present on get-by-id when the transaction and its source still exist."
3182
+ examples:
3183
+ - Bank feed
3184
+ type: string
2865
3185
  status:
2866
- description: "Lifecycle status: OPEN (unhandled), ASSIGNED (owned by a user), RESOLVED (closed out)"
3186
+ description: "Lifecycle status: OPEN (unhandled), ASSIGNED (owned by a user), PENDING_RESOLUTION (a resolution is in flight), RESOLVED (closed out)"
2867
3187
  enum:
2868
3188
  - OPEN
2869
3189
  - ASSIGNED
3190
+ - PENDING_RESOLUTION
2870
3191
  - RESOLVED
2871
3192
  examples:
2872
3193
  - OPEN
2873
3194
  type: string
2874
3195
  transactionDate:
2875
- description: "Enrichment: the exception transaction's value date as an RFC 3339 timestamp. Present on list rows whose transaction still exists."
3196
+ description: "Enrichment: the exception transaction's value date as an RFC 3339 timestamp. Present on list rows and get-by-id when the transaction still exists."
2876
3197
  examples:
2877
3198
  - "2025-01-14T00:00:00Z"
2878
3199
  type: string
@@ -2894,6 +3215,35 @@ components:
2894
3215
  - createdAt
2895
3216
  - updatedAt
2896
3217
  type: object
3218
+ ExceptionSettlementResponse:
3219
+ additionalProperties: false
3220
+ properties:
3221
+ credited:
3222
+ description: Amount actually credited (the transaction amount), as a decimal string
3223
+ examples:
3224
+ - "95.00"
3225
+ type: string
3226
+ currency:
3227
+ description: ISO 4217 currency code of the settlement amounts (the transaction's currency)
3228
+ examples:
3229
+ - BRL
3230
+ type: string
3231
+ difference:
3232
+ description: Signed difference credited minus expected, as a decimal string; negative when the credit fell short
3233
+ examples:
3234
+ - "-2.00"
3235
+ type: string
3236
+ expected:
3237
+ description: Amount the transaction should have credited under the expected fee, as a decimal string
3238
+ examples:
3239
+ - "97.00"
3240
+ type: string
3241
+ required:
3242
+ - expected
3243
+ - credited
3244
+ - difference
3245
+ - currency
3246
+ type: object
2897
3247
  ExportCountResponse:
2898
3248
  additionalProperties: false
2899
3249
  properties:
@@ -3069,6 +3419,8 @@ components:
3069
3419
  type: string
3070
3420
  status:
3071
3421
  description: Lifecycle status of the queued review (always PENDING_REVIEW on enqueue)
3422
+ enum:
3423
+ - PENDING_REVIEW
3072
3424
  examples:
3073
3425
  - PENDING_REVIEW
3074
3426
  type: string
@@ -3223,6 +3575,10 @@ components:
3223
3575
  type: string
3224
3576
  status:
3225
3577
  description: "Review lifecycle: PENDING_REVIEW (awaiting decision), APPROVED (candidates ingested), REJECTED (discarded)"
3578
+ enum:
3579
+ - PENDING_REVIEW
3580
+ - APPROVED
3581
+ - REJECTED
3226
3582
  examples:
3227
3583
  - PENDING_REVIEW
3228
3584
  type: string
@@ -3362,7 +3718,7 @@ components:
3362
3718
  type: integer
3363
3719
  structure:
3364
3720
  additionalProperties: {}
3365
- description: "Type-specific structure. FLAT: {\"amount\":\"1.50\"}. PERCENTAGE: {\"rate\":\"0.029\"} where rate is a 0..1 fraction of the base amount (0.029 means 2.9%), not a percent value. TIERED: {\"tiers\":[{\"rate\":\"0.01\",\"upTo\":\"1000\"},...]} with the same 0..1 fraction semantics per tier rate. EXPRESSION: {\"expression\":\"gross - desconto + multa + juros_dia * days_late(due_date, pay_date)\"} a formula over metadata fields (+ - * /, parentheses, and the functions days_late, days_between, max, min, abs, clamp)."
3721
+ description: "Type-specific structure. FLAT: {\"amount\":\"1.50\"}. PERCENTAGE: {\"rate\":\"0.029\"} where rate is a 0..1 fraction of the base amount (0.029 means 2.9%), not a percent value. TIERED: {\"tiers\":[{\"rate\":\"0.01\",\"upTo\":\"1000\"},...]} with the same 0..1 fraction semantics per tier rate. EXPRESSION: {\"expression\":\"gross - desconto + multa + juros_dia * days_late(due_date, pay_date)\"} a formula over metadata fields (+ - * /, parentheses, and the functions days_late, days_between, max, min, abs, clamp). A formula that is only the base amount times numeric literals is a percentage rate and is bounded 0..1: gross * 0.029 is 2.9%, gross * 2.9 is refused; any other formula is unbounded."
3366
3722
  type: object
3367
3723
  structureType:
3368
3724
  description: Shape of the fee structure. FLAT is a fixed amount; PERCENTAGE is a rate of the base; TIERED applies different rates per amount tier; EXPRESSION computes the fee from a bounded arithmetic formula over transaction metadata.
@@ -3675,7 +4031,15 @@ components:
3675
4031
  additionalProperties: false
3676
4032
  properties:
3677
4033
  canonicalKey:
3678
- description: Canonical field-map key the proposal targets
4034
+ description: Canonical field-map key the proposal targets. The closed vocabulary is the required keys (external_id, amount, currency, date) plus the optional ones (description, fee_amount, fee_currency); the advisor drops any key outside it before the proposal is returned
4035
+ enum:
4036
+ - external_id
4037
+ - amount
4038
+ - currency
4039
+ - date
4040
+ - description
4041
+ - fee_amount
4042
+ - fee_currency
3679
4043
  examples:
3680
4044
  - amount
3681
4045
  type: string
@@ -3988,9 +4352,13 @@ components:
3988
4352
  - TXN-12345
3989
4353
  type: string
3990
4354
  extractionStatus:
3991
- description: "Field-extraction status: PENDING (queued), EXTRACTED (fields parsed), FAILED (extraction error)"
4355
+ description: "Field-extraction status: PENDING (queued), COMPLETE (fields parsed), FAILED (extraction error)"
4356
+ enum:
4357
+ - PENDING
4358
+ - COMPLETE
4359
+ - FAILED
3992
4360
  examples:
3993
- - EXTRACTED
4361
+ - COMPLETE
3994
4362
  type: string
3995
4363
  id:
3996
4364
  description: Unique identifier for the transaction
@@ -4015,9 +4383,14 @@ components:
4015
4383
  format: uuid
4016
4384
  type: string
4017
4385
  status:
4018
- description: "Matching status: PENDING (not yet evaluated), MATCHED (reconciled), UNMATCHED (no match found)"
4386
+ description: "Matching status: UNMATCHED (no match found), MATCHED (reconciled), IGNORED (excluded from reconciliation by an operator), PENDING_REVIEW (imported under the blank-external-id review policy and awaiting an operator decision)"
4387
+ enum:
4388
+ - UNMATCHED
4389
+ - MATCHED
4390
+ - IGNORED
4391
+ - PENDING_REVIEW
4019
4392
  examples:
4020
- - PENDING
4393
+ - UNMATCHED
4021
4394
  type: string
4022
4395
  required:
4023
4396
  - id
@@ -4060,7 +4433,7 @@ components:
4060
4433
  format: date-time
4061
4434
  type: string
4062
4435
  diagnosis:
4063
- description: Safe one-line diagnosis for a FAILED job (dialect diagnosis, rate-policy message, or generic safe message); empty for partial completed-with-errors jobs — internal error detail is never surfaced here
4436
+ description: Safe one-line diagnosis of anything the parser found worth reporting about the file (dialect mismatch, degraded settlement re-join, zero-detail file), the rate-policy message for policy-FAILED jobs, or a generic safe message for other FAILED jobs. Present on COMPLETED jobs too, including ones with zero failed rows; empty when there is nothing to report — internal error detail is never surfaced here
4064
4437
  examples:
4065
4438
  - file appears semicolon-delimited but the source declares comma; declare delimiter semicolon in the source dialect
4066
4439
  type: string
@@ -4137,6 +4510,11 @@ components:
4137
4510
  type: string
4138
4511
  status:
4139
4512
  description: "Job lifecycle status: QUEUED (awaiting a worker), PROCESSING (parsing/normalizing rows), COMPLETED (finished), FAILED (aborted wholesale)"
4513
+ enum:
4514
+ - QUEUED
4515
+ - PROCESSING
4516
+ - COMPLETED
4517
+ - FAILED
4140
4518
  examples:
4141
4519
  - PROCESSING
4142
4520
  type: string
@@ -4207,7 +4585,11 @@ components:
4207
4585
  additionalProperties: false
4208
4586
  properties:
4209
4587
  kind:
4210
- description: "Value type: string (raw text), decimal (money/numeric verbatim token, parsed downstream), or date. A money column MUST be decimal"
4588
+ description: "Value type: string (raw text), decimal (money/numeric verbatim token, parsed downstream), or date. A money column MUST be decimal — declaring it string or date is refused by the server-side submission gate, which the schema enum does not replace"
4589
+ enum:
4590
+ - string
4591
+ - decimal
4592
+ - date
4211
4593
  examples:
4212
4594
  - decimal
4213
4595
  type: string
@@ -4239,6 +4621,10 @@ components:
4239
4621
  properties:
4240
4622
  kind:
4241
4623
  description: "Value type: string (raw text), decimal (money/numeric verbatim token, parsed downstream), or date"
4624
+ enum:
4625
+ - string
4626
+ - decimal
4627
+ - date
4242
4628
  examples:
4243
4629
  - decimal
4244
4630
  type: string
@@ -5204,7 +5590,12 @@ components:
5204
5590
  - 550e8400-e29b-41d4-a716-446655440000
5205
5591
  type: string
5206
5592
  status:
5207
- description: "Current status of the group: PROPOSED (awaiting review), CONFIRMED (accepted), or REJECTED (broken/unmatched)"
5593
+ description: "Current status of the group: PROPOSED (awaiting review), CONFIRMED (accepted), REJECTED (a proposed group discarded before confirmation), or REVOKED (a confirmed group whose confirmation was later undone by an unmatch; the original confirmation timestamp is kept for audit)"
5594
+ enum:
5595
+ - PROPOSED
5596
+ - CONFIRMED
5597
+ - REJECTED
5598
+ - REVOKED
5208
5599
  examples:
5209
5600
  - PROPOSED
5210
5601
  type: string
@@ -5263,6 +5654,9 @@ components:
5263
5654
  type: string
5264
5655
  side:
5265
5656
  description: "Reconciliation side of the item's source: LEFT or RIGHT. Resolved from the transaction's source; absent when the source side could not be resolved"
5657
+ enum:
5658
+ - LEFT
5659
+ - RIGHT
5266
5660
  examples:
5267
5661
  - LEFT
5268
5662
  type: string
@@ -5421,6 +5815,9 @@ components:
5421
5815
  type: string
5422
5816
  mode:
5423
5817
  description: "Execution mode: DRY_RUN evaluates rules without committing matches; COMMIT persists matches"
5818
+ enum:
5819
+ - DRY_RUN
5820
+ - COMMIT
5424
5821
  examples:
5425
5822
  - DRY_RUN
5426
5823
  type: string
@@ -5488,14 +5885,18 @@ components:
5488
5885
  - 550e8400-e29b-41d4-a716-446655440000
5489
5886
  type: string
5490
5887
  type:
5491
- description: "Rule type at run time: EXACT (strict equality), TOLERANCE (within an amount band), DATE_LAG (allowing a settlement-date offset), or FUZZY (normalized/similarity-scored references, always proposes)"
5888
+ description: "Rule type at run time: EXACT (strict equality), TOLERANCE (within an amount band), DATE_LAG (allowing a settlement-date offset), or FUZZY (normalized/similarity-scored references, always proposes). Absent when the run recorded a match count for the rule without its metadata sibling"
5889
+ enum:
5890
+ - EXACT
5891
+ - TOLERANCE
5892
+ - DATE_LAG
5893
+ - FUZZY
5492
5894
  examples:
5493
5895
  - EXACT
5494
5896
  type: string
5495
5897
  required:
5496
5898
  - ruleId
5497
5899
  - priority
5498
- - type
5499
5900
  - matched
5500
5901
  type: object
5501
5902
  MatchedItemResponse:
@@ -5708,6 +6109,12 @@ components:
5708
6109
  type: string
5709
6110
  status:
5710
6111
  description: "Lifecycle status: OPEN (fresh residual), PARTIALLY_CLEARED (a leg netted but a residual remains), CLEARED (netted within tolerance), AGED (exceeded its aging threshold while still open), or WITHDRAWN (the confirmed match that opened it was un-matched, so the obligation was taken back with it)"
6112
+ enum:
6113
+ - OPEN
6114
+ - PARTIALLY_CLEARED
6115
+ - CLEARED
6116
+ - AGED
6117
+ - WITHDRAWN
5711
6118
  examples:
5712
6119
  - PARTIALLY_CLEARED
5713
6120
  type: string
@@ -6042,7 +6449,96 @@ components:
6042
6449
  type: string
6043
6450
  config:
6044
6451
  additionalProperties: {}
6045
- description: Source-specific configuration object (connection and parsing settings). duplicate_key holds the ordered list of mapped fields that make two rows the same row; absent means rows are deduplicated on external_id alone. duplicate_key_changed_at is the server-set RFC 3339 moment duplicate-key detection last changed meaning on this source — either that list changing, or the field map remapping the column a declared field reads; rows imported before it keep the key they were deduplicated under.
6452
+ description: "Source-specific configuration object. Cross-key rules the schema cannot express: a duplicate_key component this source's field map does not fill is refused, because a key over an always-empty field makes every row a duplicate of every other; a source bound to an aggregator connection (reserved key connection_config_name) cannot carry a duplicate_key of its own, and a config holding both is refused in either direction; and editing duplicate_key governs later imports only — rows already imported keep the key they were deduplicated under, so a duplicate straddling the change is knowingly not detected."
6453
+ properties:
6454
+ blank_external_id:
6455
+ description: What happens to a row whose mapped external id is blank. REJECT (the default when the key is absent) fails the row. NEEDS_REVIEW imports it under a synthetic reference with status PENDING_REVIEW, so a blank reference becomes a reviewable import instead of an import failure.
6456
+ enum:
6457
+ - REJECT
6458
+ - NEEDS_REVIEW
6459
+ type: string
6460
+ camt053:
6461
+ additionalProperties: false
6462
+ description: How this source's camt.053 files map onto the canonical fields. Every other field is fixed by ISO 20022 itself. An absent object, or an absent sub-key, keeps the ISO defaults (booking, ntry_ref).
6463
+ properties:
6464
+ date_basis:
6465
+ description: "Entry date element: booking is BookgDt/Dt, valuation is ValDt/Dt. Default booking."
6466
+ enum:
6467
+ - booking
6468
+ - valuation
6469
+ type: string
6470
+ external_id_source:
6471
+ description: "Entry reference element: ntry_ref is NtryRef, end_to_end_id is NtryDtls/TxDtls/Refs/EndToEndId, tx_id is NtryDtls/TxDtls/Refs/TxId. Default ntry_ref."
6472
+ enum:
6473
+ - ntry_ref
6474
+ - end_to_end_id
6475
+ - tx_id
6476
+ type: string
6477
+ type: object
6478
+ dialect:
6479
+ additionalProperties: false
6480
+ description: How this source's delimited files are encoded and formatted. Declaration-driven only — there is no auto-detection. An absent object, or an absent sub-key, keeps the defaults (utf-8, comma, dot, iso).
6481
+ properties:
6482
+ date_style:
6483
+ enum:
6484
+ - iso
6485
+ - iso_offset
6486
+ - dmy
6487
+ - mdy
6488
+ type: string
6489
+ decimal_style:
6490
+ description: dot is 1234.56, comma is 1.234,56.
6491
+ enum:
6492
+ - dot
6493
+ - comma
6494
+ type: string
6495
+ delimiter:
6496
+ enum:
6497
+ - comma
6498
+ - semicolon
6499
+ - tab
6500
+ - pipe
6501
+ type: string
6502
+ encoding:
6503
+ enum:
6504
+ - utf-8
6505
+ - utf-8-sig
6506
+ - cp1252
6507
+ - iso-8859-1
6508
+ type: string
6509
+ type: object
6510
+ duplicate_key:
6511
+ description: The ordered list of mapped fields that make two rows the same row. Absent means external_id alone. On a source bound to an aggregator connection the aggregator retracts a movement by naming its external id, so that id has to stay the row identity.
6512
+ items:
6513
+ enum:
6514
+ - external_id
6515
+ - amount
6516
+ - currency
6517
+ - date
6518
+ - description
6519
+ - fee_amount
6520
+ - fee_currency
6521
+ type: string
6522
+ minItems: 1
6523
+ type: array
6524
+ uniqueItems: true
6525
+ duplicate_key_changed_at:
6526
+ description: SERVER-OWNED. The moment duplicate-key detection last changed meaning on this source, either because duplicate_key was edited or because the field map remapped the column a declared component reads. Rows imported before it keep the key they were deduplicated under. A value sent by a client is discarded.
6527
+ format: date-time
6528
+ readOnly: true
6529
+ type: string
6530
+ duplicate_policy:
6531
+ description: What happens to a row that repeats this source's duplicate key. FLAG_AS_EXCEPTION (the default when the key is absent) keeps the repeat out of the import and raises a duplicate exception on the row it repeated. KEEP_FIRST drops the repeat and raises nothing, so a collision leaves no trace anyone can act on. REJECT counts the repeat as an import error.
6532
+ enum:
6533
+ - FLAG_AS_EXCEPTION
6534
+ - KEEP_FIRST
6535
+ - REJECT
6536
+ type: string
6537
+ fail_on_error_rate_percent:
6538
+ description: "Fail the whole import when the percentage of failed rows exceeds this whole number. Absent means never auto-fail. The ceiling is 99, not 100: the comparison is strict, so 100 could never fire."
6539
+ maximum: 99
6540
+ minimum: 1
6541
+ type: integer
6046
6542
  type: object
6047
6543
  contextId:
6048
6544
  description: Identifier of the context this source belongs to.
@@ -6218,7 +6714,11 @@ components:
6218
6714
  - near-miss amounts cluster under 1%
6219
6715
  type: string
6220
6716
  type:
6221
- description: "Proposed rule type from the closed vocabulary: EXACT (strict equality), TOLERANCE (within an amount band), or DATE_LAG (allowing a settlement-date offset)"
6717
+ description: "Proposed rule type from the closed vocabulary: EXACT (strict equality), TOLERANCE (within an amount band), or DATE_LAG (allowing a settlement-date offset). FUZZY is excluded on purpose: a fuzzy rule only ever proposes graded-confidence links a human must review, so an operator configures one deliberately rather than accepting it from a suggestion"
6718
+ enum:
6719
+ - EXACT
6720
+ - TOLERANCE
6721
+ - DATE_LAG
6222
6722
  examples:
6223
6723
  - TOLERANCE
6224
6724
  type: string
@@ -6297,6 +6797,10 @@ components:
6297
6797
  type: string
6298
6798
  status:
6299
6799
  description: "Lifecycle status: PENDING_REVIEW (awaiting human decision), APPROVED (rule created), or REJECTED (discarded)"
6800
+ enum:
6801
+ - PENDING_REVIEW
6802
+ - APPROVED
6803
+ - REJECTED
6300
6804
  examples:
6301
6805
  - PENDING_REVIEW
6302
6806
  type: string
@@ -6663,7 +7167,9 @@ components:
6663
7167
  required:
6664
7168
  - id
6665
7169
  - status
6666
- type: object
7170
+ type:
7171
+ - object
7172
+ - "null"
6667
7173
  SetupProgressMatchRulesResponse:
6668
7174
  additionalProperties: false
6669
7175
  properties:
@@ -6725,7 +7231,9 @@ components:
6725
7231
  - method
6726
7232
  - path
6727
7233
  - requiredFields
6728
- type: object
7234
+ type:
7235
+ - object
7236
+ - "null"
6729
7237
  SetupProgressReadinessResponse:
6730
7238
  additionalProperties: false
6731
7239
  properties:
@@ -7055,6 +7563,11 @@ components:
7055
7563
  type: string
7056
7564
  ruleType:
7057
7565
  description: Strategy of the previewed rule
7566
+ enum:
7567
+ - EXACT
7568
+ - TOLERANCE
7569
+ - DATE_LAG
7570
+ - FUZZY
7058
7571
  examples:
7059
7572
  - EXACT
7060
7573
  type: string
@@ -7102,6 +7615,11 @@ components:
7102
7615
  type: object
7103
7616
  type:
7104
7617
  description: Rule strategy of the inline candidate rule
7618
+ enum:
7619
+ - EXACT
7620
+ - TOLERANCE
7621
+ - DATE_LAG
7622
+ - FUZZY
7105
7623
  examples:
7106
7624
  - EXACT
7107
7625
  type: string
@@ -7368,7 +7886,96 @@ components:
7368
7886
  type: string
7369
7887
  config:
7370
7888
  additionalProperties: {}
7371
- description: Source-specific configuration object (connection and parsing settings). duplicate_key holds the ordered list of mapped fields that make two rows the same row; absent means rows are deduplicated on external_id alone. duplicate_key_changed_at is the server-set RFC 3339 moment duplicate-key detection last changed meaning on this source — either that list changing, or the field map remapping the column a declared field reads; rows imported before it keep the key they were deduplicated under.
7889
+ description: "Source-specific configuration object. Cross-key rules the schema cannot express: a duplicate_key component this source's field map does not fill is refused, because a key over an always-empty field makes every row a duplicate of every other; a source bound to an aggregator connection (reserved key connection_config_name) cannot carry a duplicate_key of its own, and a config holding both is refused in either direction; and editing duplicate_key governs later imports only — rows already imported keep the key they were deduplicated under, so a duplicate straddling the change is knowingly not detected."
7890
+ properties:
7891
+ blank_external_id:
7892
+ description: What happens to a row whose mapped external id is blank. REJECT (the default when the key is absent) fails the row. NEEDS_REVIEW imports it under a synthetic reference with status PENDING_REVIEW, so a blank reference becomes a reviewable import instead of an import failure.
7893
+ enum:
7894
+ - REJECT
7895
+ - NEEDS_REVIEW
7896
+ type: string
7897
+ camt053:
7898
+ additionalProperties: false
7899
+ description: How this source's camt.053 files map onto the canonical fields. Every other field is fixed by ISO 20022 itself. An absent object, or an absent sub-key, keeps the ISO defaults (booking, ntry_ref).
7900
+ properties:
7901
+ date_basis:
7902
+ description: "Entry date element: booking is BookgDt/Dt, valuation is ValDt/Dt. Default booking."
7903
+ enum:
7904
+ - booking
7905
+ - valuation
7906
+ type: string
7907
+ external_id_source:
7908
+ description: "Entry reference element: ntry_ref is NtryRef, end_to_end_id is NtryDtls/TxDtls/Refs/EndToEndId, tx_id is NtryDtls/TxDtls/Refs/TxId. Default ntry_ref."
7909
+ enum:
7910
+ - ntry_ref
7911
+ - end_to_end_id
7912
+ - tx_id
7913
+ type: string
7914
+ type: object
7915
+ dialect:
7916
+ additionalProperties: false
7917
+ description: How this source's delimited files are encoded and formatted. Declaration-driven only — there is no auto-detection. An absent object, or an absent sub-key, keeps the defaults (utf-8, comma, dot, iso).
7918
+ properties:
7919
+ date_style:
7920
+ enum:
7921
+ - iso
7922
+ - iso_offset
7923
+ - dmy
7924
+ - mdy
7925
+ type: string
7926
+ decimal_style:
7927
+ description: dot is 1234.56, comma is 1.234,56.
7928
+ enum:
7929
+ - dot
7930
+ - comma
7931
+ type: string
7932
+ delimiter:
7933
+ enum:
7934
+ - comma
7935
+ - semicolon
7936
+ - tab
7937
+ - pipe
7938
+ type: string
7939
+ encoding:
7940
+ enum:
7941
+ - utf-8
7942
+ - utf-8-sig
7943
+ - cp1252
7944
+ - iso-8859-1
7945
+ type: string
7946
+ type: object
7947
+ duplicate_key:
7948
+ description: The ordered list of mapped fields that make two rows the same row. Absent means external_id alone. On a source bound to an aggregator connection the aggregator retracts a movement by naming its external id, so that id has to stay the row identity.
7949
+ items:
7950
+ enum:
7951
+ - external_id
7952
+ - amount
7953
+ - currency
7954
+ - date
7955
+ - description
7956
+ - fee_amount
7957
+ - fee_currency
7958
+ type: string
7959
+ minItems: 1
7960
+ type: array
7961
+ uniqueItems: true
7962
+ duplicate_key_changed_at:
7963
+ description: SERVER-OWNED. The moment duplicate-key detection last changed meaning on this source, either because duplicate_key was edited or because the field map remapped the column a declared component reads. Rows imported before it keep the key they were deduplicated under. A value sent by a client is discarded.
7964
+ format: date-time
7965
+ readOnly: true
7966
+ type: string
7967
+ duplicate_policy:
7968
+ description: What happens to a row that repeats this source's duplicate key. FLAG_AS_EXCEPTION (the default when the key is absent) keeps the repeat out of the import and raises a duplicate exception on the row it repeated. KEEP_FIRST drops the repeat and raises nothing, so a collision leaves no trace anyone can act on. REJECT counts the repeat as an import error.
7969
+ enum:
7970
+ - FLAG_AS_EXCEPTION
7971
+ - KEEP_FIRST
7972
+ - REJECT
7973
+ type: string
7974
+ fail_on_error_rate_percent:
7975
+ description: "Fail the whole import when the percentage of failed rows exceeds this whole number. Absent means never auto-fail. The ceiling is 99, not 100: the comparison is strict, so 100 could never fire."
7976
+ maximum: 99
7977
+ minimum: 1
7978
+ type: integer
7372
7979
  type: object
7373
7980
  contextId:
7374
7981
  description: Identifier of the context this source belongs to.
@@ -7687,9 +8294,13 @@ components:
7687
8294
  - TXN-12345
7688
8295
  type: string
7689
8296
  extractionStatus:
7690
- description: "Field-extraction status: PENDING (queued), EXTRACTED (fields parsed), FAILED (extraction error)"
8297
+ description: "Field-extraction status: PENDING (queued), COMPLETE (fields parsed), FAILED (extraction error)"
8298
+ enum:
8299
+ - PENDING
8300
+ - COMPLETE
8301
+ - FAILED
7691
8302
  examples:
7692
- - EXTRACTED
8303
+ - COMPLETE
7693
8304
  type: string
7694
8305
  id:
7695
8306
  description: Unique identifier for the transaction
@@ -7714,9 +8325,14 @@ components:
7714
8325
  format: uuid
7715
8326
  type: string
7716
8327
  status:
7717
- description: "Matching status: PENDING (not yet evaluated), MATCHED (reconciled), UNMATCHED (no match found)"
8328
+ description: "Matching status: UNMATCHED (no match found), MATCHED (reconciled), IGNORED (excluded from reconciliation by an operator), PENDING_REVIEW (imported under the blank-external-id review policy and awaiting an operator decision)"
8329
+ enum:
8330
+ - UNMATCHED
8331
+ - MATCHED
8332
+ - IGNORED
8333
+ - PENDING_REVIEW
7718
8334
  examples:
7719
- - PENDING
8335
+ - UNMATCHED
7720
8336
  type: string
7721
8337
  required:
7722
8338
  - id
@@ -7863,34 +8479,27 @@ components:
7863
8479
  additionalProperties: false
7864
8480
  properties:
7865
8481
  accountRef:
7866
- description: Opaque vendor account reference (Pluggy itemId, Belvo link id) the webhook pull threads onto its request
8482
+ description: Opaque vendor account reference (Pluggy itemId, Belvo link id). Supply it to bind (or re-bind) the connection after the vendor's consent widget returns one; omit it to leave the stored value untouched.
7867
8483
  examples:
7868
8484
  - a1b2c3d4-5678-90ab-cdef-1234567890ab
7869
- minLength: 1
7870
8485
  type: string
7871
8486
  baseUrl:
7872
- description: Vendor API base URL, stored as the connection host
8487
+ description: Vendor API base URL, stored as the connection host. Omit it to leave the stored URL untouched.
7873
8488
  examples:
7874
8489
  - https://api.pluggy.ai
7875
8490
  format: uri
7876
- minLength: 1
7877
8491
  type: string
7878
8492
  clientId:
7879
8493
  description: Aggregator API client id (optional; supply with secret to rotate, omit both to keep the stored credential; sealed; never emitted)
7880
8494
  type: string
7881
8495
  configName:
7882
- description: Unique connection config name (tenant-scoped); the mint endpoint binds a token to this name
8496
+ description: Unique connection config name (tenant-scoped); the mint endpoint binds a token to this name. Omit it to leave the stored name untouched.
7883
8497
  examples:
7884
8498
  - pluggy-main
7885
- minLength: 1
7886
8499
  type: string
7887
8500
  secret:
7888
8501
  description: Aggregator API client secret (optional; supply with clientId to rotate, omit both to keep the stored credential; sealed; never emitted)
7889
8502
  type: string
7890
- required:
7891
- - configName
7892
- - baseUrl
7893
- - accountRef
7894
8503
  type: object
7895
8504
  UpdateContextRequest:
7896
8505
  additionalProperties: false
@@ -8111,7 +8720,91 @@ components:
8111
8720
  properties:
8112
8721
  config:
8113
8722
  additionalProperties: {}
8114
- description: "Source-specific configuration object (connection and parsing settings). Reserved key duplicate_key: the ordered list of mapped fields that make two rows the same row — any of external_id, amount, currency, date, description, fee_amount, fee_currency. Send it empty of that key and rows are deduplicated on external_id alone. A field this source's field map does not fill is refused, because a key over a field that is always empty makes every row a duplicate of every other. A source bound to an aggregator connection (reserved key connection_config_name) cannot carry a duplicate key of its own: the aggregator retracts a movement by naming its external id, so that id has to stay this source's row identity. A config holding both is refused in either direction — drop duplicate_key from a bound source, or disconnect the aggregator connection first. Editing duplicate_key is allowed at any time and governs later imports only: rows already imported keep the key they were deduplicated under, and a duplicate straddling the change is knowingly not detected. Reserved read-only key duplicate_key_changed_at: the RFC 3339 moment duplicate-key detection last changed meaning on this source, set by the server; a value sent by a client is discarded. It moves for either change that re-keys future rows — editing duplicate_key, or the field map remapping the column a declared field reads (a source keyed on description whose description column moves derives a different key for the same movement). Reserved key duplicate_policy: what happens to a row repeating the duplicate key — FLAG_AS_EXCEPTION (the default: the repeat is kept out of the import and raised as a duplicate exception on the row it repeated), KEEP_FIRST (the repeat is dropped and nothing is raised), or REJECT (the repeat is counted as an import error)."
8723
+ description: "Source-specific configuration object. Cross-key rules the schema cannot express: a duplicate_key component this source's field map does not fill is refused, because a key over an always-empty field makes every row a duplicate of every other; a source bound to an aggregator connection (reserved key connection_config_name) cannot carry a duplicate_key of its own, and a config holding both is refused in either direction; and editing duplicate_key governs later imports only — rows already imported keep the key they were deduplicated under, so a duplicate straddling the change is knowingly not detected."
8724
+ properties:
8725
+ blank_external_id:
8726
+ description: What happens to a row whose mapped external id is blank. REJECT (the default when the key is absent) fails the row. NEEDS_REVIEW imports it under a synthetic reference with status PENDING_REVIEW, so a blank reference becomes a reviewable import instead of an import failure.
8727
+ enum:
8728
+ - REJECT
8729
+ - NEEDS_REVIEW
8730
+ type: string
8731
+ camt053:
8732
+ additionalProperties: false
8733
+ description: How this source's camt.053 files map onto the canonical fields. Every other field is fixed by ISO 20022 itself. An absent object, or an absent sub-key, keeps the ISO defaults (booking, ntry_ref).
8734
+ properties:
8735
+ date_basis:
8736
+ description: "Entry date element: booking is BookgDt/Dt, valuation is ValDt/Dt. Default booking."
8737
+ enum:
8738
+ - booking
8739
+ - valuation
8740
+ type: string
8741
+ external_id_source:
8742
+ description: "Entry reference element: ntry_ref is NtryRef, end_to_end_id is NtryDtls/TxDtls/Refs/EndToEndId, tx_id is NtryDtls/TxDtls/Refs/TxId. Default ntry_ref."
8743
+ enum:
8744
+ - ntry_ref
8745
+ - end_to_end_id
8746
+ - tx_id
8747
+ type: string
8748
+ type: object
8749
+ dialect:
8750
+ additionalProperties: false
8751
+ description: How this source's delimited files are encoded and formatted. Declaration-driven only — there is no auto-detection. An absent object, or an absent sub-key, keeps the defaults (utf-8, comma, dot, iso).
8752
+ properties:
8753
+ date_style:
8754
+ enum:
8755
+ - iso
8756
+ - iso_offset
8757
+ - dmy
8758
+ - mdy
8759
+ type: string
8760
+ decimal_style:
8761
+ description: dot is 1234.56, comma is 1.234,56.
8762
+ enum:
8763
+ - dot
8764
+ - comma
8765
+ type: string
8766
+ delimiter:
8767
+ enum:
8768
+ - comma
8769
+ - semicolon
8770
+ - tab
8771
+ - pipe
8772
+ type: string
8773
+ encoding:
8774
+ enum:
8775
+ - utf-8
8776
+ - utf-8-sig
8777
+ - cp1252
8778
+ - iso-8859-1
8779
+ type: string
8780
+ type: object
8781
+ duplicate_key:
8782
+ description: The ordered list of mapped fields that make two rows the same row. Absent means external_id alone. On a source bound to an aggregator connection the aggregator retracts a movement by naming its external id, so that id has to stay the row identity.
8783
+ items:
8784
+ enum:
8785
+ - external_id
8786
+ - amount
8787
+ - currency
8788
+ - date
8789
+ - description
8790
+ - fee_amount
8791
+ - fee_currency
8792
+ type: string
8793
+ minItems: 1
8794
+ type: array
8795
+ uniqueItems: true
8796
+ duplicate_policy:
8797
+ description: What happens to a row that repeats this source's duplicate key. FLAG_AS_EXCEPTION (the default when the key is absent) keeps the repeat out of the import and raises a duplicate exception on the row it repeated. KEEP_FIRST drops the repeat and raises nothing, so a collision leaves no trace anyone can act on. REJECT counts the repeat as an import error.
8798
+ enum:
8799
+ - FLAG_AS_EXCEPTION
8800
+ - KEEP_FIRST
8801
+ - REJECT
8802
+ type: string
8803
+ fail_on_error_rate_percent:
8804
+ description: "Fail the whole import when the percentage of failed rows exceeds this whole number. Absent means never auto-fail. The ceiling is 99, not 100: the comparison is strict, so 100 could never fire."
8805
+ maximum: 99
8806
+ minimum: 1
8807
+ type: integer
8115
8808
  type: object
8116
8809
  name:
8117
8810
  description: New human-readable name of the source.
@@ -8386,7 +9079,7 @@ components:
8386
9079
  format: int64
8387
9080
  type: integer
8388
9081
  monthlyLineAllowance:
8389
- description: Billable lines the plan includes per month, from the price list. Monthly on every plan regardless of billing interval. 0 when the stored plan code is not in the catalogue.
9082
+ description: Billable lines the plan includes per month, from the price list. Monthly on every plan regardless of billing interval. 0 when the plan is unmetered (see volumeUnmetered) or the stored plan code is not in the catalogue.
8390
9083
  format: int64
8391
9084
  type: integer
8392
9085
  overageCreditBalanceCents:
@@ -8394,7 +9087,7 @@ components:
8394
9087
  format: int64
8395
9088
  type: integer
8396
9089
  overageRateCentsPerThousandLines:
8397
- description: What lines beyond the allowance cost, in integer BRL cents per THOUSAND lines (per-thousand because the entry rate is 0,4 cents a line and would truncate to zero). 0 when the stored plan code is not in the catalogue.
9090
+ description: What lines beyond the allowance cost, in integer BRL cents per THOUSAND lines (per-thousand because the entry rate is 0,4 cents a line and would truncate to zero). 0 when the plan is unmetered (see volumeUnmetered) or the stored plan code is not in the catalogue.
8398
9091
  format: int64
8399
9092
  type: integer
8400
9093
  overageUncoveredCents:
@@ -8411,7 +9104,7 @@ components:
8411
9104
  description: "Setup lifecycle of the workspace: \"provisioning\" (still being built), \"active\" (ready to use), or \"failed\" (setup will not complete on its own — we have been told)."
8412
9105
  type: string
8413
9106
  provisioningStep:
8414
- description: "The setup step that is owed: \"create_tenant\", \"associate_service\", \"migrate_tenant\", \"provision_console\", or \"\" when nothing is owed. On a failed workspace this is the step it died on."
9107
+ description: "The setup step that is owed: \"create_tenant\", \"associate_service\", \"migrate_tenant\", \"provision_console\", \"grant_admin\", or \"\" when nothing is owed. On a failed workspace this is the step it died on."
8415
9108
  type: string
8416
9109
  trialEndsAt:
8417
9110
  description: When the free trial ends (UTC). Omitted for a paid plan that never trialed.
@@ -8420,6 +9113,9 @@ components:
8420
9113
  trialExpired:
8421
9114
  description: Whether the trial is over on EITHER axis (time or volume), or the workspace is already suspended.
8422
9115
  type: boolean
9116
+ volumeUnmetered:
9117
+ description: "Whether this plan is unmetered: its volume ceiling and its overage price are contractual (enterprise) rather than from the price list. When true, monthlyLineAllowance and overageRateCentsPerThousandLines are both 0 because no figure applies — do NOT render them as terms, and do not read the zero rate as free overage."
9118
+ type: boolean
8423
9119
  required:
8424
9120
  - plan
8425
9121
  - billingStatus
@@ -8432,6 +9128,7 @@ components:
8432
9128
  - provisioningState
8433
9129
  - provisioningStep
8434
9130
  - provisioningFailed
9131
+ - volumeUnmetered
8435
9132
  - monthlyLineAllowance
8436
9133
  - overageRateCentsPerThousandLines
8437
9134
  - overageCreditBalanceCents
@@ -8468,7 +9165,16 @@ info:
8468
9165
  email: support@lerian.studio
8469
9166
  name: Lerian Studio Support
8470
9167
  url: https://discord.gg/DnhqKwkGv3
8471
- description: Reconciliation engine for the Lerian Studio ecosystem. Provides automated transaction matching between Midaz ledger and external systems.
9168
+ description: |-
9169
+ Reconciliation engine for the Lerian Studio ecosystem. Provides automated transaction matching between Midaz ledger and external systems.
9170
+
9171
+ ## Idempotency
9172
+
9173
+ POST, PUT and PATCH requests accept an optional `Idempotency-Key` header (`X-Idempotency-Key` is also honoured, and wins if both are sent). Keys are 1-128 characters of letters, digits, hyphen, underscore or colon, are scoped per tenant, caller, method and request target, and are strictly opt-in: a request sent without the header is never de-duplicated. A retry under a key whose first attempt completed replays that stored response and carries `Idempotency-Replayed: true`; a retry that arrives while the first attempt is still in flight is refused with 409.
9174
+
9175
+ A request that FAILED normally releases its key, so a caller can correct the cause and retry under the same key. The exception is a dispatch whose outcome could not be confirmed (502, code `MTCH-0514`): the exception may already have been created in the target system, so that answer HOLDS its key — every retry under it replays the same 502 and no second dispatch is sent. Deliberately attempting that dispatch again therefore requires a NEW idempotency key. A dispatch the target answered and rejected (502, code `MTCH-0513`) created nothing there and releases its key as usual.
9176
+
9177
+ Secret mints are the other, sharper exception. `POST /v1/discovery/aggregator-connections/{id}/connect-token`, `POST /v1/discovery/webhooks/tokens`, `POST /v1/exceptions/callbacks/credentials` and `POST /v1/exceptions/callbacks/credentials/{credentialId}/rotate` each return a raw credential exactly ONCE, and storing that answer would keep the secret re-readable for the life of the key — so those four routes IGNORE the idempotency header entirely. Nothing is stored, nothing is replayed, and `Idempotency-Replayed` is never sent on them. A retry under the same key MINTS AGAIN and leaves a second live credential behind, so treat a mint as non-idempotent: read the first attempt's response rather than resending it. A surplus callback credential can be revoked through its own operation; a surplus aggregator webhook token has no revoke operation today and stays live.
8472
9178
  license:
8473
9179
  name: Lerian Studio General License
8474
9180
  title: Matcher Reconciliation API
@@ -8553,6 +9259,43 @@ paths:
8553
9259
  summary: Read a workspace's invoicing identification (backoffice)
8554
9260
  tags:
8555
9261
  - Onboarding
9262
+ /v1/admin/workspaces/{slug}/plan:
9263
+ put:
9264
+ description: "Puts a workspace on the contractual enterprise plan: persists plan=enterprise and billing_status=active together, then evicts the billing edge-gate and volume-resolver caches so the contractual ceiling applies immediately. ONLY \"enterprise\" is accepted. This is not a generic set-plan operation: self-serve plans are bought through hosted checkout and converged from the live subscription's price, so assigning one by hand would be a payment-processor bypass that the next processor delivery silently reverts — any other plan code returns 409. It REFUSES a workspace whose subscription the payment processor could still bill (409): the operator cancels there first, where the proration and refund decision gets human eyes, and this route never moves processor money. That refusal covers every subscription that is not permanently over — one awaiting card authentication or one that is paused is not charging today and resumes tomorrow, and it would revert this plan the moment it does; only a cancelled or expired subscription is assignable over. If the processor cannot be asked, the request is refused as retryable (503) rather than allowed through. A suspended workspace is refused (409) because this operation moves no access posture — reactivate it first, and the write is compare-and-swapped on the status read, so a suspension landing mid-request is refused rather than reversed. There is no reverse: removing the enterprise plan is not offered. The target slug comes from the URL path (backoffice operation, workspace admin action). An unknown workspace returns 404. Errors use RFC 9457 problem+json."
9265
+ operationId: admin-assign-workspace-plan
9266
+ parameters:
9267
+ - description: Slug of the workspace to assign the plan to.
9268
+ in: path
9269
+ name: slug
9270
+ required: true
9271
+ schema:
9272
+ description: Slug of the workspace to assign the plan to.
9273
+ maxLength: 255
9274
+ type: string
9275
+ requestBody:
9276
+ content:
9277
+ application/json:
9278
+ schema:
9279
+ $ref: "#/components/schemas/AdminAssignPlanInputBody"
9280
+ required: true
9281
+ responses:
9282
+ "200":
9283
+ content:
9284
+ application/json:
9285
+ schema:
9286
+ $ref: "#/components/schemas/AdminAssignPlanResult"
9287
+ description: OK
9288
+ default:
9289
+ content:
9290
+ application/problem+json:
9291
+ schema:
9292
+ $ref: "#/components/schemas/Detail"
9293
+ description: Error
9294
+ security:
9295
+ - BearerAuth: []
9296
+ summary: Assign the enterprise plan to a workspace (backoffice)
9297
+ tags:
9298
+ - Onboarding
8556
9299
  /v1/admin/workspaces/{slug}/reactivate:
8557
9300
  put:
8558
9301
  description: "Restores a suspended workspace: persists billing_status=active, re-enables interactive console login at the IdP, reactivates the tenant at the Tenant Manager (best-effort), and evicts the billing edge-gate cache. The target slug comes from the URL path (backoffice operation, workspace admin action). Idempotent. Errors use RFC 9457 problem+json."
@@ -10352,6 +11095,36 @@ paths:
10352
11095
  summary: Update aggregator connection
10353
11096
  tags:
10354
11097
  - Discovery
11098
+ /v1/discovery/aggregator-connections/{id}/connect-token:
11099
+ post:
11100
+ description: "Mints the short-lived token the aggregator vendor's OWN consent widget (Pluggy Connect / the Belvo widget) consumes in the end customer's browser, using the connection's already-sealed credential. The token is returned exactly once: it is never persisted, never logged, and there is no endpoint that reads it back. Nothing is supplied in the request — the vendor is read off the stored connection, and the mode is derived from it: a connection already bound to a vendor item/link gets a RE-CONSENT token for that same item (`reconsent: true`, and `accountRef` echoes the exact item/link the token was scoped to), while a connection awaiting consent gets a first-consent token that mints a new one (`accountRef` empty). Pass the returned `accountRef` to the vendor widget's update mode rather than a locally cached value: the token is item-scoped, and pairing it with a stale id makes the vendor run the create flow and orphan the original item. The item/link id the widget returns is bound back through PUT /v1/discovery/aggregator-connections/{id} with `accountRef` (no credential needs re-supplying). A non-aggregator connection id returns 404; a vendor with no consent path on this deployment returns 422 MTCH-0213."
11101
+ operationId: mintAggregatorConsentToken
11102
+ parameters:
11103
+ - description: Opaque aggregator connection id
11104
+ in: path
11105
+ name: id
11106
+ required: true
11107
+ schema:
11108
+ description: Opaque aggregator connection id
11109
+ type: string
11110
+ responses:
11111
+ "201":
11112
+ content:
11113
+ application/json:
11114
+ schema:
11115
+ $ref: "#/components/schemas/AggregatorConsentTokenResponse"
11116
+ description: Created
11117
+ default:
11118
+ content:
11119
+ application/problem+json:
11120
+ schema:
11121
+ $ref: "#/components/schemas/Detail"
11122
+ description: Error
11123
+ security:
11124
+ - BearerAuth: []
11125
+ summary: Mint aggregator consent token
11126
+ tags:
11127
+ - Discovery
10355
11128
  /v1/discovery/connections:
10356
11129
  get:
10357
11130
  description: Returns all discovered Fetcher database connections.
@@ -11705,7 +12478,7 @@ paths:
11705
12478
  - Exception
11706
12479
  /v1/exceptions/{exceptionId}:
11707
12480
  get:
11708
- description: Retrieves a single exception by its ID.
12481
+ description: Retrieves a single exception by its ID, including the amount/currency/date/source/context of its transaction and, for fee breaks, the expected vs credited settlement figures.
11709
12482
  operationId: getException
11710
12483
  parameters:
11711
12484
  - description: Exception ID (UUID)
@@ -13036,7 +13809,10 @@ paths:
13036
13809
  - Governance
13037
13810
  /v1/governance/audit-logs/verify:
13038
13811
  get:
13039
- description: "Re-verifies the calling tenant's tamper-evident audit hash chain and returns a structured verdict (intact, verified count, and the first broken tenant_seq when a break is found). The check is strictly read-only: it recomputes nothing into storage and never mutates an audit record. Use the optional maxRecords query parameter to bound how many records are inspected."
13812
+ description: |-
13813
+ Re-verifies the calling tenant's tamper-evident audit hash chain and returns a structured verdict (intact, verified count, and the first broken tenant_seq when a break is found). The check is strictly read-only: it recomputes nothing into storage and never mutates an audit record. Use the optional maxRecords query parameter to bound how many records are inspected.
13814
+
13815
+ Use the optional fromSeq query parameter to bind the verification floor: the first record inspected is the one with tenant_seq == fromSeq. A floor above 1 TRUSTS that record's stored prev_hash instead of validating it against the genesis hash, so tampering BELOW the floor is out of scope for that run and is not reported. Two uses follow from that: (1) resuming — when a verdict comes back truncated, re-run with fromSeq = fromSeq + verifiedCount to verify the remainder; (2) archived-partition tenants — once the archival worker has dropped the bottom partitions, verify from the current floor, because a run from seq 1 no longer has the records it would need. The verdict always echoes the effective fromSeq, so an empty range (verifiedCount 0 with a high fromSeq) is never mistaken for an intact chain verified from genesis.
13040
13816
  operationId: verifyAuditLogChain
13041
13817
  parameters:
13042
13818
  - description: Maximum number of records to inspect; clamped to the server bound. Omit to use the default bound.
@@ -13049,6 +13825,15 @@ paths:
13049
13825
  maximum: 10000
13050
13826
  minimum: 1
13051
13827
  type: integer
13828
+ - description: "Verification floor: the first record inspected is the one with this tenant_seq. Omit to start at the chain start (seq 1)."
13829
+ explode: false
13830
+ in: query
13831
+ name: fromSeq
13832
+ schema:
13833
+ description: "Verification floor: the first record inspected is the one with this tenant_seq. Omit to start at the chain start (seq 1)."
13834
+ format: int64
13835
+ minimum: 1
13836
+ type: integer
13052
13837
  responses:
13053
13838
  "200":
13054
13839
  content:
@@ -16378,7 +17163,7 @@ paths:
16378
17163
  - Onboarding
16379
17164
  /v1/workspace/credit-purchase:
16380
17165
  post:
16381
- description: "Opens a ONE-OFF hosted payment session that buys prepaid overage credit for the AUTHENTICATED tenant's own workspace, and returns the URL to redirect the browser to. It is never a subscription. The workspace is resolved from the JWT tenant-slug claim: this endpoint never accepts a tenant identifier in the body, path, query or headers. Any workspace may buy — trialing, lapsed, monthly or annual — because the customer who has run out of allowance is the one being told to buy. Payment is by CARD on every plan, including annual: the instrument that funds overage credit is deliberately not the subscription's instrument, and the card is saved for future CREDIT purchases only. An amount outside the price list's minimum and maximum is refused before the processor is called. The credit balance moves ONLY when the processor confirms the payment through the verified webhook — never on the return page and never in this response. Errors use the RFC 9457 application/problem+json contract."
17166
+ description: "Opens a ONE-OFF hosted payment session that buys prepaid overage credit for the AUTHENTICATED tenant's own workspace, and returns the URL to redirect the browser to. It is never a subscription. The workspace is resolved from the JWT tenant-slug claim: this endpoint never accepts a tenant identifier in the body, path, query or headers. Any workspace on a self-serve plan may buy — trialing, lapsed, monthly or annual — because the customer who has run out of allowance is the one being told to buy. A workspace on a CONTRACTUAL plan is refused with 409: its volume is not metered, so prepaid overage credit buys it nothing. Payment is by CARD on every plan, including annual: the instrument that funds overage credit is deliberately not the subscription's instrument, and the card is saved for future CREDIT purchases only. An amount outside the price list's minimum and maximum is refused before the processor is called. The credit balance moves ONLY when the processor confirms the payment through the verified webhook — never on the return page and never in this response. Errors use the RFC 9457 application/problem+json contract."
16382
17167
  operationId: workspace-credit-purchase
16383
17168
  requestBody:
16384
17169
  content: