@distyra/sdk 0.4.0 → 0.6.0

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.
package/README.md CHANGED
@@ -36,8 +36,9 @@ if (error) {
36
36
  throw new Error(error.detail ?? error.error);
37
37
  }
38
38
 
39
- // `data` is fully typed against the EnrichResponse schema
40
- console.log(data.merchant.name, data.category.primary);
39
+ // `data` is fully typed against the EnrichResponse schema. `merchant` is null
40
+ // for non-merchant transactions (bank fees, transfers), so guard it.
41
+ console.log(data.merchant?.name ?? '(no merchant)', data.category.primary);
41
42
  ```
42
43
 
43
44
  ## Options
@@ -52,6 +53,30 @@ console.log(data.merchant.name, data.category.primary);
52
53
 
53
54
  The returned client is a typed [`openapi-fetch`](https://openapi-ts.dev/openapi-fetch/) client — use `.GET`, `.POST`, etc. against any path in the spec, with full request/response typing.
54
55
 
56
+ ## Handling unknown merchants (eventual consistency)
57
+
58
+ The first time anyone enriches a brand-new merchant, the response may be unresolved
59
+ (`resolution.status` other than `resolved`). The system then discovers and confirms that
60
+ merchant in the background, so the same descriptor resolves shortly after, for every
61
+ caller, with no model call.
62
+
63
+ Read `resolution.retry_after`:
64
+
65
+ - A number (seconds) means a confirmed answer is likely coming. Retry the same descriptor
66
+ once after that delay, or just let your next natural re-sync pick it up.
67
+ - `null` means the result is definitive; no retry will help.
68
+
69
+ ```ts
70
+ const { data } = await distyra.POST('/v1/enrich', { body: { descriptor, country_hint } });
71
+ if (data.resolution.status !== 'resolved' && data.resolution.retry_after != null) {
72
+ // retry once after data.resolution.retry_after seconds, or wait for your next sync
73
+ }
74
+ ```
75
+
76
+ Note: `resolution.retryable` is a different signal. It is `true` only for a transient
77
+ backend error (`timed_out` / `transient_error`), which you retry within seconds. See the
78
+ full resolution-and-retries guide at <https://api.distyra.com/docs>.
79
+
55
80
  ## Lower-level access
56
81
 
57
82
  The generated `paths` and `operations` types are re-exported if you want to build your own `openapi-fetch` client or reference response shapes directly:
@@ -23,6 +23,23 @@ export interface paths {
23
23
  patch?: never;
24
24
  trace?: never;
25
25
  };
26
+ "/v1/connect/coverage": {
27
+ parameters: {
28
+ query?: never;
29
+ header?: never;
30
+ path?: never;
31
+ cookie?: never;
32
+ };
33
+ /** List the banks (ASPSPs) Connect covers across Europe */
34
+ get: operations["connectCoverage"];
35
+ put?: never;
36
+ post?: never;
37
+ delete?: never;
38
+ options?: never;
39
+ head?: never;
40
+ patch?: never;
41
+ trace?: never;
42
+ };
26
43
  "/v1/enrich": {
27
44
  parameters: {
28
45
  query?: never;
@@ -34,7 +51,7 @@ export interface paths {
34
51
  put?: never;
35
52
  /**
36
53
  * Enrich a single transaction
37
- * @description Single-transaction enrichment. Resolution flow: normalize, then cache, catalog match, classifier, and LLM fallback. Returns the full response shape with an `availability` block; fields not yet available (logos, location, subscription/recurring detection) are returned as `null`/`false` and flagged as unavailable. Confidence values are uncalibrated similarity scores.
54
+ * @description Single-transaction enrichment. Resolution flow: normalize, then cache, catalog match, classifier, and LLM fallback. Returns the full response shape with an `availability` block; fields not yet available (logos, location, subscription) are returned as `null`/`false` and flagged. `metadata.is_subscription` is a merchant-category hint, not per-transaction recurrence,as unavailable. Confidence values are uncalibrated similarity scores.
38
55
  */
39
56
  post: operations["enrichSingle"];
40
57
  delete?: never;
@@ -757,7 +774,11 @@ export interface paths {
757
774
  delete: operations["deleteWebhookEndpoint"];
758
775
  options?: never;
759
776
  head?: never;
760
- patch?: never;
777
+ /**
778
+ * Update a webhook endpoint (url, events, status)
779
+ * @description Partial update. Provide any subset of url, events, status. `events` fully replaces the subscription list. Setting status=active clears the failure counter and re-enables an auto-disabled endpoint. The signing secret is unchanged — use rotate_secret for that.
780
+ */
781
+ patch: operations["updateWebhookEndpoint"];
761
782
  trace?: never;
762
783
  };
763
784
  "/v1/webhook_endpoints/{id}/rotate_secret": {
@@ -780,6 +801,26 @@ export interface paths {
780
801
  patch?: never;
781
802
  trace?: never;
782
803
  };
804
+ "/v1/webhook_deliveries": {
805
+ parameters: {
806
+ query?: never;
807
+ header?: never;
808
+ path?: never;
809
+ cookie?: never;
810
+ };
811
+ /**
812
+ * List webhook delivery attempts for the caller org
813
+ * @description Per-attempt delivery log, most-recent-first, scoped to the caller org. Filter by endpoint_id and/or status; page backwards with the `before` cursor. Payload bytes are not included — response_excerpt, error_excerpt and http_status are provided for debugging.
814
+ */
815
+ get: operations["listWebhookDeliveries"];
816
+ put?: never;
817
+ post?: never;
818
+ delete?: never;
819
+ options?: never;
820
+ head?: never;
821
+ patch?: never;
822
+ trace?: never;
823
+ };
783
824
  "/v1/connect/aspsps": {
784
825
  parameters: {
785
826
  query?: never;
@@ -850,6 +891,26 @@ export interface paths {
850
891
  patch?: never;
851
892
  trace?: never;
852
893
  };
894
+ "/v1/connect/connections/{id}/identity": {
895
+ parameters: {
896
+ query?: never;
897
+ header?: never;
898
+ path?: never;
899
+ cookie?: never;
900
+ };
901
+ /**
902
+ * Account-holder identity for a connection (ownership verification)
903
+ * @description Returns the account holder name the bank reports for each account. Pass applicant_name to get a token-match verdict (match / partial / no_match) per account, to confirm an account belongs to your applicant. Holder names are provided by the bank and vary in format; use the verdict as a confirmation signal.
904
+ */
905
+ get: operations["getConnectionIdentity"];
906
+ put?: never;
907
+ post?: never;
908
+ delete?: never;
909
+ options?: never;
910
+ head?: never;
911
+ patch?: never;
912
+ trace?: never;
913
+ };
853
914
  "/v1/connect/connections/{id}/transactions": {
854
915
  parameters: {
855
916
  query?: never;
@@ -857,7 +918,10 @@ export interface paths {
857
918
  path?: never;
858
919
  cookie?: never;
859
920
  };
860
- /** Fetch normalized transactions for a connection */
921
+ /**
922
+ * Fetch normalized transactions for a connection
923
+ * @description Transactions are fetched live from the bank on each call and never stored, so this is a pull API. Sync contract for keeping your own system up to date: on the first pull omit the date filters (you get the default 90-day backfill, the PSD2 no-SCA window); on each later pull pass since=<the next_cursor from your previous response> to fetch only from where you left off. The response always returns next_cursor (the end of the window just fetched) — poll on your own cadence and use it as the next since. Because the boundary day can overlap, DEDUPLICATE by each transaction's id. A pull reuses the connection's existing bank session, so it does not consume a new Active Session — poll as often as your freshness needs require.
924
+ */
861
925
  get: operations["getConnectionTransactions"];
862
926
  put?: never;
863
927
  post?: never;
@@ -1023,6 +1087,62 @@ export interface operations {
1023
1087
  };
1024
1088
  };
1025
1089
  };
1090
+ connectCoverage: {
1091
+ parameters: {
1092
+ query?: never;
1093
+ header?: never;
1094
+ path?: never;
1095
+ cookie?: never;
1096
+ };
1097
+ requestBody?: never;
1098
+ responses: {
1099
+ /** @description Default Response */
1100
+ 200: {
1101
+ headers: {
1102
+ [name: string]: unknown;
1103
+ };
1104
+ content: {
1105
+ "application/json": {
1106
+ [key: string]: unknown;
1107
+ };
1108
+ };
1109
+ };
1110
+ /** @description Standard error envelope used for all non-2xx responses. */
1111
+ 502: {
1112
+ headers: {
1113
+ [name: string]: unknown;
1114
+ };
1115
+ content: {
1116
+ "application/json": {
1117
+ /**
1118
+ * @description Stable machine-readable code. SDK consumers should switch on this.
1119
+ * @example invalid_key
1120
+ */
1121
+ error: string;
1122
+ /** @description Free-form human-readable explanation. Safe to surface. */
1123
+ detail?: string;
1124
+ };
1125
+ };
1126
+ };
1127
+ /** @description Standard error envelope used for all non-2xx responses. */
1128
+ 503: {
1129
+ headers: {
1130
+ [name: string]: unknown;
1131
+ };
1132
+ content: {
1133
+ "application/json": {
1134
+ /**
1135
+ * @description Stable machine-readable code. SDK consumers should switch on this.
1136
+ * @example invalid_key
1137
+ */
1138
+ error: string;
1139
+ /** @description Free-form human-readable explanation. Safe to surface. */
1140
+ detail?: string;
1141
+ };
1142
+ };
1143
+ };
1144
+ };
1145
+ };
1026
1146
  enrichSingle: {
1027
1147
  parameters: {
1028
1148
  query?: {
@@ -1041,6 +1161,16 @@ export interface operations {
1041
1161
  * @example true
1042
1162
  */
1043
1163
  cache_only?: "true" | "false";
1164
+ /**
1165
+ * @description When `true` and the request mints a brand-new (cold) merchant, block up to `wait_timeout_ms` for the background logo crawl to finish, then return the real logo instead of `logo_url: null`. No effect for already-known merchants (no new crawl fires). On timeout, returns the normal async response (which carries the low-quality favicon floor when one is available).
1166
+ * @example true
1167
+ */
1168
+ wait_for_crawl?: "true" | "false";
1169
+ /**
1170
+ * @description Upper bound in milliseconds for `wait_for_crawl` (default 8000, max 15000). Ignored unless `wait_for_crawl=true`.
1171
+ * @example 8000
1172
+ */
1173
+ wait_timeout_ms?: string;
1044
1174
  };
1045
1175
  header?: never;
1046
1176
  path?: never;
@@ -1100,9 +1230,11 @@ export interface operations {
1100
1230
  * @example {
1101
1231
  * "merchant": {
1102
1232
  * "name": "Albert Heijn",
1103
- * "parent": null,
1233
+ * "parent": "Ahold Delhaize",
1234
+ * "parent_catalog_id": 9001,
1104
1235
  * "domain": "ah.nl",
1105
1236
  * "logo_url": "https://cdn.distyra.com/saas/142/a3f2b9e7d4c1f8a0/v1/light.png?token=…&expires=…",
1237
+ * "logo_quality_score": 0.8,
1106
1238
  * "brand_colors": {
1107
1239
  * "primary": "#0FAEEF"
1108
1240
  * },
@@ -1127,7 +1259,6 @@ export interface operations {
1127
1259
  * "is_subscription": false,
1128
1260
  * "is_marketplace": false,
1129
1261
  * "facilitator": null,
1130
- * "is_recurring_candidate": false,
1131
1262
  * "transaction_type": "merchant_payment",
1132
1263
  * "is_transfer": false,
1133
1264
  * "is_bank_internal": false,
@@ -1139,6 +1270,13 @@ export interface operations {
1139
1270
  * "transaction_type": 1,
1140
1271
  * "overall": 0.96
1141
1272
  * },
1273
+ * "resolution": {
1274
+ * "status": "resolved",
1275
+ * "proposed_name": null,
1276
+ * "confidence": null,
1277
+ * "retryable": false,
1278
+ * "retry_after": null
1279
+ * },
1142
1280
  * "alternatives": [],
1143
1281
  * "trace_id": "req-01HXYZ...",
1144
1282
  * "cache_hit": true,
@@ -1149,8 +1287,7 @@ export interface operations {
1149
1287
  * "transaction_type": true,
1150
1288
  * "logos": false,
1151
1289
  * "location": false,
1152
- * "subscription_detection": false,
1153
- * "recurring_detection": false
1290
+ * "subscription_detection": false
1154
1291
  * },
1155
1292
  * "livemode": true
1156
1293
  * }
@@ -1159,8 +1296,10 @@ export interface operations {
1159
1296
  merchant: {
1160
1297
  name: string | null;
1161
1298
  parent: string | null;
1299
+ parent_catalog_id: number | null;
1162
1300
  domain: string | null;
1163
1301
  logo_url: string | null;
1302
+ logo_quality_score: number | null;
1164
1303
  brand_colors: {
1165
1304
  [key: string]: unknown;
1166
1305
  };
@@ -1185,10 +1324,10 @@ export interface operations {
1185
1324
  country: string | null;
1186
1325
  };
1187
1326
  metadata: {
1327
+ /** @description Merchant-category hint: true when the resolved merchant predominantly bills on subscription (streaming, SaaS, telco, gym, insurance). This reflects the MERCHANT, not this transaction — a single charge at a subscription merchant may still be a one-off. True only for conservatively curated brands; false also means "not flagged / unknown". Per-account recurrence detection needs the transaction series and lives in the banking/iOS layer, not this stateless API. */
1188
1328
  is_subscription: boolean;
1189
1329
  is_marketplace: boolean;
1190
1330
  facilitator: string | null;
1191
- is_recurring_candidate: boolean;
1192
1331
  transaction_type: string | null;
1193
1332
  is_transfer: boolean;
1194
1333
  is_bank_internal: boolean;
@@ -1200,6 +1339,20 @@ export interface operations {
1200
1339
  transaction_type: number;
1201
1340
  overall: number;
1202
1341
  };
1342
+ /** @description Structured reason for the resolution outcome, so callers can act on null results. */
1343
+ resolution: {
1344
+ /**
1345
+ * @description resolved: a merchant or non-merchant transaction_type was resolved. unresolved_unknown: Tier 4 ran and genuinely couldn't identify the merchant (or was blocked before the call). low_signal_descriptor: the descriptor was too thin to resolve — send the fuller statement form. below_mint_threshold: Tier 4 proposed a name but the quality gate declined it (see proposed_name/confidence). timed_out / transient_error: a transient Tier-4 failure — RETRYABLE, not a verdict.
1346
+ * @enum {string}
1347
+ */
1348
+ status: "resolved" | "unresolved_unknown" | "low_signal_descriptor" | "below_mint_threshold" | "timed_out" | "transient_error";
1349
+ proposed_name: string | null;
1350
+ confidence: number | null;
1351
+ /** @description true for timed_out / transient_error — retry the same request; the null is transient, not a definitive "unknown". */
1352
+ retryable: boolean;
1353
+ /** @description Seconds after which retrying the SAME descriptor is worthwhile, or null when it is not. Set when an unknown merchant triggered background discovery: the system is fetching + confirming the brand, so the descriptor typically resolves after this delay (eventual consistency). Retry once after this many seconds, or just let your next natural re-sync pick it up. null = a definitive non-result, no retry will help. */
1354
+ retry_after: number | null;
1355
+ };
1203
1356
  alternatives: {
1204
1357
  name: string;
1205
1358
  confidence: number;
@@ -1215,7 +1368,6 @@ export interface operations {
1215
1368
  logos: boolean;
1216
1369
  location: boolean;
1217
1370
  subscription_detection: boolean;
1218
- recurring_detection: boolean;
1219
1371
  };
1220
1372
  /** @description true when served to a live key; false when served to a test-mode (sk_test_) key. Test-mode responses run the full cascade but carry no billing or quota impact. */
1221
1373
  livemode: boolean;
@@ -1327,6 +1479,16 @@ export interface operations {
1327
1479
  * @example true
1328
1480
  */
1329
1481
  cache_only?: "true" | "false";
1482
+ /**
1483
+ * @description When `true` and the request mints a brand-new (cold) merchant, block up to `wait_timeout_ms` for the background logo crawl to finish, then return the real logo instead of `logo_url: null`. No effect for already-known merchants (no new crawl fires). On timeout, returns the normal async response (which carries the low-quality favicon floor when one is available).
1484
+ * @example true
1485
+ */
1486
+ wait_for_crawl?: "true" | "false";
1487
+ /**
1488
+ * @description Upper bound in milliseconds for `wait_for_crawl` (default 8000, max 15000). Ignored unless `wait_for_crawl=true`.
1489
+ * @example 8000
1490
+ */
1491
+ wait_timeout_ms?: string;
1330
1492
  };
1331
1493
  header?: never;
1332
1494
  path?: never;
@@ -1617,7 +1779,7 @@ export interface operations {
1617
1779
  /** Format: date */
1618
1780
  end: string;
1619
1781
  };
1620
- /** @description Computed feature bundle: `aggregation` (turnover, cash_position, customer_concentration, credit_line_utilization — the latter null unless an account declares a committed limit), `recurring` (recurring_revenue, recurring_expense, returned_dd counts), `counterparty` (tax_payments, statutory_contributions, debt_service, supplier_payments — payment-regularity streams over supplier-tagged counterparties; suppliers_tagged=0 means no supplier coverage for this applicant, not "pays nobody"), `debt_capacity` (DSCR + capacity at policy thresholds, with a transparent assumptions block), `anomaly` (null; Engine 4 deferred). Amount fields are stringified micro-EUR bigints so 12-digit values round-trip cleanly through JSON. */
1782
+ /** @description Computed feature bundle: `aggregation` (turnover, cash_position, customer_concentration, credit_line_utilization — the latter null unless an account declares a committed limit), `recurring` (recurring_revenue, recurring_expense, returned_dd counts), `counterparty` (tax_payments, statutory_contributions, debt_service, supplier_payments — payment-regularity streams over supplier-tagged counterparties; suppliers_tagged=0 means no supplier coverage for this applicant, not "pays nobody"; debt_collection — payments to debt-collection agencies, an adverse signal; collectors_tagged=0 = no collector activity), `debt_capacity` (DSCR + capacity at policy thresholds, with a transparent assumptions block), `anomaly` (null; Engine 4 deferred). Amount fields are stringified micro-EUR bigints so 12-digit values round-trip cleanly through JSON. */
1621
1783
  features: {
1622
1784
  [key: string]: unknown;
1623
1785
  };
@@ -1680,12 +1842,16 @@ export interface operations {
1680
1842
  merchant_id: string | null;
1681
1843
  merchant_industry: string | null;
1682
1844
  merchant_subindustry: string | null;
1845
+ /** @description health / pension / accident / sectoral / social_secretariat / social_security / other / null. Set only for statutory bodies (drives the statutory_contributions split); null for everything else, including genuine tax authorities. */
1846
+ merchant_statutory_kind: string | null;
1683
1847
  transaction_type: string;
1684
1848
  is_transfer: boolean;
1685
1849
  is_bank_internal: boolean;
1686
1850
  counterparty_iban: string | null;
1687
1851
  /** @description tax_authority / lender / customer / supplier / employee / payment_processor / internal_transfer / null. The EU-correctness signal. */
1688
1852
  counterparty_role: string | null;
1853
+ /** @description Provenance of an institutional counterparty_role / merchant_statutory_kind: 'confirmed' (curated catalog row or payer-declared ISO 20022 purpose code) vs 'inferred' (AI category guess). Lets a lender tell a solid obligation from a likely one; inferred rows still count in the totals. Absent on regular merchants. */
1854
+ counterparty_source?: "confirmed" | "inferred" | null;
1689
1855
  } & {
1690
1856
  [key: string]: unknown;
1691
1857
  })[];
@@ -1884,7 +2050,7 @@ export interface operations {
1884
2050
  /** Format: date */
1885
2051
  end: string;
1886
2052
  };
1887
- /** @description Computed feature bundle: `aggregation` (turnover, cash_position, customer_concentration, credit_line_utilization — the latter null unless an account declares a committed limit), `recurring` (recurring_revenue, recurring_expense, returned_dd counts), `counterparty` (tax_payments, statutory_contributions, debt_service, supplier_payments — payment-regularity streams over supplier-tagged counterparties; suppliers_tagged=0 means no supplier coverage for this applicant, not "pays nobody"), `debt_capacity` (DSCR + capacity at policy thresholds, with a transparent assumptions block), `anomaly` (null; Engine 4 deferred). Amount fields are stringified micro-EUR bigints so 12-digit values round-trip cleanly through JSON. */
2053
+ /** @description Computed feature bundle: `aggregation` (turnover, cash_position, customer_concentration, credit_line_utilization — the latter null unless an account declares a committed limit), `recurring` (recurring_revenue, recurring_expense, returned_dd counts), `counterparty` (tax_payments, statutory_contributions, debt_service, supplier_payments — payment-regularity streams over supplier-tagged counterparties; suppliers_tagged=0 means no supplier coverage for this applicant, not "pays nobody"; debt_collection — payments to debt-collection agencies, an adverse signal; collectors_tagged=0 = no collector activity), `debt_capacity` (DSCR + capacity at policy thresholds, with a transparent assumptions block), `anomaly` (null; Engine 4 deferred). Amount fields are stringified micro-EUR bigints so 12-digit values round-trip cleanly through JSON. */
1888
2054
  features: {
1889
2055
  [key: string]: unknown;
1890
2056
  };
@@ -1947,12 +2113,16 @@ export interface operations {
1947
2113
  merchant_id: string | null;
1948
2114
  merchant_industry: string | null;
1949
2115
  merchant_subindustry: string | null;
2116
+ /** @description health / pension / accident / sectoral / social_secretariat / social_security / other / null. Set only for statutory bodies (drives the statutory_contributions split); null for everything else, including genuine tax authorities. */
2117
+ merchant_statutory_kind: string | null;
1950
2118
  transaction_type: string;
1951
2119
  is_transfer: boolean;
1952
2120
  is_bank_internal: boolean;
1953
2121
  counterparty_iban: string | null;
1954
2122
  /** @description tax_authority / lender / customer / supplier / employee / payment_processor / internal_transfer / null. The EU-correctness signal. */
1955
2123
  counterparty_role: string | null;
2124
+ /** @description Provenance of an institutional counterparty_role / merchant_statutory_kind: 'confirmed' (curated catalog row or payer-declared ISO 20022 purpose code) vs 'inferred' (AI category guess). Lets a lender tell a solid obligation from a likely one; inferred rows still count in the totals. Absent on regular merchants. */
2125
+ counterparty_source?: "confirmed" | "inferred" | null;
1956
2126
  } & {
1957
2127
  [key: string]: unknown;
1958
2128
  })[];
@@ -2401,7 +2571,7 @@ export interface operations {
2401
2571
  /** Format: date */
2402
2572
  end: string;
2403
2573
  };
2404
- /** @description Computed feature bundle: `aggregation` (turnover, cash_position, customer_concentration, credit_line_utilization — the latter null unless an account declares a committed limit), `recurring` (recurring_revenue, recurring_expense, returned_dd counts), `counterparty` (tax_payments, statutory_contributions, debt_service, supplier_payments — payment-regularity streams over supplier-tagged counterparties; suppliers_tagged=0 means no supplier coverage for this applicant, not "pays nobody"), `debt_capacity` (DSCR + capacity at policy thresholds, with a transparent assumptions block), `anomaly` (null; Engine 4 deferred). Amount fields are stringified micro-EUR bigints so 12-digit values round-trip cleanly through JSON. */
2574
+ /** @description Computed feature bundle: `aggregation` (turnover, cash_position, customer_concentration, credit_line_utilization — the latter null unless an account declares a committed limit), `recurring` (recurring_revenue, recurring_expense, returned_dd counts), `counterparty` (tax_payments, statutory_contributions, debt_service, supplier_payments — payment-regularity streams over supplier-tagged counterparties; suppliers_tagged=0 means no supplier coverage for this applicant, not "pays nobody"; debt_collection — payments to debt-collection agencies, an adverse signal; collectors_tagged=0 = no collector activity), `debt_capacity` (DSCR + capacity at policy thresholds, with a transparent assumptions block), `anomaly` (null; Engine 4 deferred). Amount fields are stringified micro-EUR bigints so 12-digit values round-trip cleanly through JSON. */
2405
2575
  features: {
2406
2576
  [key: string]: unknown;
2407
2577
  };
@@ -2464,12 +2634,16 @@ export interface operations {
2464
2634
  merchant_id: string | null;
2465
2635
  merchant_industry: string | null;
2466
2636
  merchant_subindustry: string | null;
2637
+ /** @description health / pension / accident / sectoral / social_secretariat / social_security / other / null. Set only for statutory bodies (drives the statutory_contributions split); null for everything else, including genuine tax authorities. */
2638
+ merchant_statutory_kind: string | null;
2467
2639
  transaction_type: string;
2468
2640
  is_transfer: boolean;
2469
2641
  is_bank_internal: boolean;
2470
2642
  counterparty_iban: string | null;
2471
2643
  /** @description tax_authority / lender / customer / supplier / employee / payment_processor / internal_transfer / null. The EU-correctness signal. */
2472
2644
  counterparty_role: string | null;
2645
+ /** @description Provenance of an institutional counterparty_role / merchant_statutory_kind: 'confirmed' (curated catalog row or payer-declared ISO 20022 purpose code) vs 'inferred' (AI category guess). Lets a lender tell a solid obligation from a likely one; inferred rows still count in the totals. Absent on regular merchants. */
2646
+ counterparty_source?: "confirmed" | "inferred" | null;
2473
2647
  } & {
2474
2648
  [key: string]: unknown;
2475
2649
  })[];
@@ -2924,7 +3098,7 @@ export interface operations {
2924
3098
  /** Format: date */
2925
3099
  end: string;
2926
3100
  };
2927
- /** @description Computed feature bundle: `aggregation` (turnover, cash_position, customer_concentration, credit_line_utilization — the latter null unless an account declares a committed limit), `recurring` (recurring_revenue, recurring_expense, returned_dd counts), `counterparty` (tax_payments, statutory_contributions, debt_service, supplier_payments — payment-regularity streams over supplier-tagged counterparties; suppliers_tagged=0 means no supplier coverage for this applicant, not "pays nobody"), `debt_capacity` (DSCR + capacity at policy thresholds, with a transparent assumptions block), `anomaly` (null; Engine 4 deferred). Amount fields are stringified micro-EUR bigints so 12-digit values round-trip cleanly through JSON. */
3101
+ /** @description Computed feature bundle: `aggregation` (turnover, cash_position, customer_concentration, credit_line_utilization — the latter null unless an account declares a committed limit), `recurring` (recurring_revenue, recurring_expense, returned_dd counts), `counterparty` (tax_payments, statutory_contributions, debt_service, supplier_payments — payment-regularity streams over supplier-tagged counterparties; suppliers_tagged=0 means no supplier coverage for this applicant, not "pays nobody"; debt_collection — payments to debt-collection agencies, an adverse signal; collectors_tagged=0 = no collector activity), `debt_capacity` (DSCR + capacity at policy thresholds, with a transparent assumptions block), `anomaly` (null; Engine 4 deferred). Amount fields are stringified micro-EUR bigints so 12-digit values round-trip cleanly through JSON. */
2928
3102
  features: {
2929
3103
  [key: string]: unknown;
2930
3104
  };
@@ -2987,12 +3161,16 @@ export interface operations {
2987
3161
  merchant_id: string | null;
2988
3162
  merchant_industry: string | null;
2989
3163
  merchant_subindustry: string | null;
3164
+ /** @description health / pension / accident / sectoral / social_secretariat / social_security / other / null. Set only for statutory bodies (drives the statutory_contributions split); null for everything else, including genuine tax authorities. */
3165
+ merchant_statutory_kind: string | null;
2990
3166
  transaction_type: string;
2991
3167
  is_transfer: boolean;
2992
3168
  is_bank_internal: boolean;
2993
3169
  counterparty_iban: string | null;
2994
3170
  /** @description tax_authority / lender / customer / supplier / employee / payment_processor / internal_transfer / null. The EU-correctness signal. */
2995
3171
  counterparty_role: string | null;
3172
+ /** @description Provenance of an institutional counterparty_role / merchant_statutory_kind: 'confirmed' (curated catalog row or payer-declared ISO 20022 purpose code) vs 'inferred' (AI category guess). Lets a lender tell a solid obligation from a likely one; inferred rows still count in the totals. Absent on regular merchants. */
3173
+ counterparty_source?: "confirmed" | "inferred" | null;
2996
3174
  } & {
2997
3175
  [key: string]: unknown;
2998
3176
  })[];
@@ -5745,7 +5923,7 @@ export interface operations {
5745
5923
  */
5746
5924
  url: string;
5747
5925
  /** @description Subset of supported events to subscribe to. Defaults to all currently-supported. */
5748
- events?: ("batch.completed" | "batch.failed" | "analysis.completed" | "ingestion.completed" | "connect.connection.activated")[];
5926
+ events?: ("batch.completed" | "batch.failed" | "analysis.completed" | "ingestion.completed" | "connect.connection.activated" | "connect.connection.reconsent_required" | "connect.connection.expired" | "connect.connection.error")[];
5749
5927
  };
5750
5928
  };
5751
5929
  };
@@ -5985,6 +6163,123 @@ export interface operations {
5985
6163
  };
5986
6164
  };
5987
6165
  };
6166
+ updateWebhookEndpoint: {
6167
+ parameters: {
6168
+ query?: never;
6169
+ header?: never;
6170
+ path: {
6171
+ id: string;
6172
+ };
6173
+ cookie?: never;
6174
+ };
6175
+ requestBody: {
6176
+ content: {
6177
+ "application/json": {
6178
+ /**
6179
+ * Format: uri
6180
+ * @description New HTTPS URL. Plain HTTP rejected.
6181
+ */
6182
+ url?: string;
6183
+ /** @description Replacement event subscription list (full replace, not merge). */
6184
+ events?: ("batch.completed" | "batch.failed" | "analysis.completed" | "ingestion.completed" | "connect.connection.activated" | "connect.connection.reconsent_required" | "connect.connection.expired" | "connect.connection.error")[];
6185
+ /** @description Set 'disabled' to pause deliveries, 'active' to resume (also clears the failure counter). */
6186
+ status?: "active" | "disabled";
6187
+ };
6188
+ };
6189
+ };
6190
+ responses: {
6191
+ /** @description Default Response */
6192
+ 200: {
6193
+ headers: {
6194
+ [name: string]: unknown;
6195
+ };
6196
+ content: {
6197
+ "application/json": {
6198
+ /** Format: uuid */
6199
+ id: string;
6200
+ /** Format: uri */
6201
+ url: string;
6202
+ secret_prefix: string;
6203
+ events: string[];
6204
+ status: "active" | "disabled" | "auto_disabled";
6205
+ consecutive_failures: number;
6206
+ /** Format: date-time */
6207
+ created_at: string;
6208
+ rotated_at: string | null;
6209
+ last_delivered_at: string | null;
6210
+ };
6211
+ };
6212
+ };
6213
+ /** @description Standard error envelope used for all non-2xx responses. */
6214
+ 400: {
6215
+ headers: {
6216
+ [name: string]: unknown;
6217
+ };
6218
+ content: {
6219
+ "application/json": {
6220
+ /**
6221
+ * @description Stable machine-readable code. SDK consumers should switch on this.
6222
+ * @example invalid_key
6223
+ */
6224
+ error: string;
6225
+ /** @description Free-form human-readable explanation. Safe to surface. */
6226
+ detail?: string;
6227
+ };
6228
+ };
6229
+ };
6230
+ /** @description Standard error envelope used for all non-2xx responses. */
6231
+ 401: {
6232
+ headers: {
6233
+ [name: string]: unknown;
6234
+ };
6235
+ content: {
6236
+ "application/json": {
6237
+ /**
6238
+ * @description Stable machine-readable code. SDK consumers should switch on this.
6239
+ * @example invalid_key
6240
+ */
6241
+ error: string;
6242
+ /** @description Free-form human-readable explanation. Safe to surface. */
6243
+ detail?: string;
6244
+ };
6245
+ };
6246
+ };
6247
+ /** @description Standard error envelope used for all non-2xx responses. */
6248
+ 403: {
6249
+ headers: {
6250
+ [name: string]: unknown;
6251
+ };
6252
+ content: {
6253
+ "application/json": {
6254
+ /**
6255
+ * @description Stable machine-readable code. SDK consumers should switch on this.
6256
+ * @example invalid_key
6257
+ */
6258
+ error: string;
6259
+ /** @description Free-form human-readable explanation. Safe to surface. */
6260
+ detail?: string;
6261
+ };
6262
+ };
6263
+ };
6264
+ /** @description Standard error envelope used for all non-2xx responses. */
6265
+ 404: {
6266
+ headers: {
6267
+ [name: string]: unknown;
6268
+ };
6269
+ content: {
6270
+ "application/json": {
6271
+ /**
6272
+ * @description Stable machine-readable code. SDK consumers should switch on this.
6273
+ * @example invalid_key
6274
+ */
6275
+ error: string;
6276
+ /** @description Free-form human-readable explanation. Safe to surface. */
6277
+ detail?: string;
6278
+ };
6279
+ };
6280
+ };
6281
+ };
6282
+ };
5988
6283
  rotateWebhookEndpointSecret: {
5989
6284
  parameters: {
5990
6285
  query?: never;
@@ -6074,6 +6369,101 @@ export interface operations {
6074
6369
  };
6075
6370
  };
6076
6371
  };
6372
+ listWebhookDeliveries: {
6373
+ parameters: {
6374
+ query?: {
6375
+ /** @description Only deliveries for this endpoint. */
6376
+ endpoint_id?: string;
6377
+ status?: "pending" | "delivered" | "failed" | "exhausted";
6378
+ limit?: number;
6379
+ /** @description Cursor: return deliveries created strictly before this timestamp (page backwards in time). */
6380
+ before?: string;
6381
+ };
6382
+ header?: never;
6383
+ path?: never;
6384
+ cookie?: never;
6385
+ };
6386
+ requestBody?: never;
6387
+ responses: {
6388
+ /** @description Default Response */
6389
+ 200: {
6390
+ headers: {
6391
+ [name: string]: unknown;
6392
+ };
6393
+ content: {
6394
+ "application/json": {
6395
+ deliveries: {
6396
+ /** Format: uuid */
6397
+ id: string;
6398
+ /** Format: uuid */
6399
+ endpoint_id: string;
6400
+ event: string;
6401
+ status: "pending" | "delivered" | "failed" | "exhausted";
6402
+ attempt: number;
6403
+ http_status: number | null;
6404
+ response_excerpt: string | null;
6405
+ error_excerpt: string | null;
6406
+ next_attempt_at: string | null;
6407
+ delivered_at: string | null;
6408
+ /** Format: date-time */
6409
+ created_at: string;
6410
+ }[];
6411
+ };
6412
+ };
6413
+ };
6414
+ /** @description Standard error envelope used for all non-2xx responses. */
6415
+ 400: {
6416
+ headers: {
6417
+ [name: string]: unknown;
6418
+ };
6419
+ content: {
6420
+ "application/json": {
6421
+ /**
6422
+ * @description Stable machine-readable code. SDK consumers should switch on this.
6423
+ * @example invalid_key
6424
+ */
6425
+ error: string;
6426
+ /** @description Free-form human-readable explanation. Safe to surface. */
6427
+ detail?: string;
6428
+ };
6429
+ };
6430
+ };
6431
+ /** @description Standard error envelope used for all non-2xx responses. */
6432
+ 401: {
6433
+ headers: {
6434
+ [name: string]: unknown;
6435
+ };
6436
+ content: {
6437
+ "application/json": {
6438
+ /**
6439
+ * @description Stable machine-readable code. SDK consumers should switch on this.
6440
+ * @example invalid_key
6441
+ */
6442
+ error: string;
6443
+ /** @description Free-form human-readable explanation. Safe to surface. */
6444
+ detail?: string;
6445
+ };
6446
+ };
6447
+ };
6448
+ /** @description Standard error envelope used for all non-2xx responses. */
6449
+ 403: {
6450
+ headers: {
6451
+ [name: string]: unknown;
6452
+ };
6453
+ content: {
6454
+ "application/json": {
6455
+ /**
6456
+ * @description Stable machine-readable code. SDK consumers should switch on this.
6457
+ * @example invalid_key
6458
+ */
6459
+ error: string;
6460
+ /** @description Free-form human-readable explanation. Safe to surface. */
6461
+ detail?: string;
6462
+ };
6463
+ };
6464
+ };
6465
+ };
6466
+ };
6077
6467
  listAspsps: {
6078
6468
  parameters: {
6079
6469
  query: {
@@ -6208,11 +6598,12 @@ export interface operations {
6208
6598
  connections: {
6209
6599
  /** Format: uuid */
6210
6600
  id: string;
6601
+ external_ref: string | null;
6211
6602
  applicant_ref: string | null;
6212
6603
  aspsp_name: string | null;
6213
6604
  country: string | null;
6214
6605
  psu_type: "business" | "personal";
6215
- status: "pending" | "active" | "expired" | "revoked";
6606
+ status: "pending" | "active" | "expired" | "revoked" | "error";
6216
6607
  consent_expires_at: string | null;
6217
6608
  /** Format: date-time */
6218
6609
  created_at: string;
@@ -6272,6 +6663,8 @@ export interface operations {
6272
6663
  aspsp_name: string;
6273
6664
  /** @description Your reference for the applicant/deal (model 2). Omit for a self-link of your own accounts (model 1). */
6274
6665
  applicant_ref?: string;
6666
+ /** @description Your own stable id for this connection (e.g. your user or account id). Unlike the connection id, it survives reconsent: pass the same value when a customer re-authorizes and key your integration off it. Echoed in list responses and every connect.connection.* webhook. */
6667
+ external_ref?: string;
6275
6668
  /**
6276
6669
  * Format: uri
6277
6670
  * @description Where to send the applicant after consent. Defaults to a Distyra-hosted page.
@@ -6439,11 +6832,12 @@ export interface operations {
6439
6832
  "application/json": {
6440
6833
  /** Format: uuid */
6441
6834
  id: string;
6835
+ external_ref: string | null;
6442
6836
  applicant_ref: string | null;
6443
6837
  aspsp_name: string | null;
6444
6838
  country: string | null;
6445
6839
  psu_type: "business" | "personal";
6446
- status: "pending" | "active" | "expired" | "revoked";
6840
+ status: "pending" | "active" | "expired" | "revoked" | "error";
6447
6841
  consent_expires_at: string | null;
6448
6842
  /** Format: date-time */
6449
6843
  created_at: string;
@@ -6596,6 +6990,7 @@ export interface operations {
6596
6990
  account_id: string;
6597
6991
  uid?: string;
6598
6992
  name: string;
6993
+ holder_name?: string;
6599
6994
  currency: string;
6600
6995
  iban?: string;
6601
6996
  account_type?: string;
@@ -6603,6 +6998,146 @@ export interface operations {
6603
6998
  amount: number;
6604
6999
  currency: string;
6605
7000
  };
7001
+ balance_known: boolean;
7002
+ }[];
7003
+ };
7004
+ };
7005
+ };
7006
+ /** @description Standard error envelope used for all non-2xx responses. */
7007
+ 401: {
7008
+ headers: {
7009
+ [name: string]: unknown;
7010
+ };
7011
+ content: {
7012
+ "application/json": {
7013
+ /**
7014
+ * @description Stable machine-readable code. SDK consumers should switch on this.
7015
+ * @example invalid_key
7016
+ */
7017
+ error: string;
7018
+ /** @description Free-form human-readable explanation. Safe to surface. */
7019
+ detail?: string;
7020
+ };
7021
+ };
7022
+ };
7023
+ /** @description Standard error envelope used for all non-2xx responses. */
7024
+ 403: {
7025
+ headers: {
7026
+ [name: string]: unknown;
7027
+ };
7028
+ content: {
7029
+ "application/json": {
7030
+ /**
7031
+ * @description Stable machine-readable code. SDK consumers should switch on this.
7032
+ * @example invalid_key
7033
+ */
7034
+ error: string;
7035
+ /** @description Free-form human-readable explanation. Safe to surface. */
7036
+ detail?: string;
7037
+ };
7038
+ };
7039
+ };
7040
+ /** @description Standard error envelope used for all non-2xx responses. */
7041
+ 404: {
7042
+ headers: {
7043
+ [name: string]: unknown;
7044
+ };
7045
+ content: {
7046
+ "application/json": {
7047
+ /**
7048
+ * @description Stable machine-readable code. SDK consumers should switch on this.
7049
+ * @example invalid_key
7050
+ */
7051
+ error: string;
7052
+ /** @description Free-form human-readable explanation. Safe to surface. */
7053
+ detail?: string;
7054
+ };
7055
+ };
7056
+ };
7057
+ /** @description Standard error envelope used for all non-2xx responses. */
7058
+ 409: {
7059
+ headers: {
7060
+ [name: string]: unknown;
7061
+ };
7062
+ content: {
7063
+ "application/json": {
7064
+ /**
7065
+ * @description Stable machine-readable code. SDK consumers should switch on this.
7066
+ * @example invalid_key
7067
+ */
7068
+ error: string;
7069
+ /** @description Free-form human-readable explanation. Safe to surface. */
7070
+ detail?: string;
7071
+ };
7072
+ };
7073
+ };
7074
+ /** @description Standard error envelope used for all non-2xx responses. */
7075
+ 502: {
7076
+ headers: {
7077
+ [name: string]: unknown;
7078
+ };
7079
+ content: {
7080
+ "application/json": {
7081
+ /**
7082
+ * @description Stable machine-readable code. SDK consumers should switch on this.
7083
+ * @example invalid_key
7084
+ */
7085
+ error: string;
7086
+ /** @description Free-form human-readable explanation. Safe to surface. */
7087
+ detail?: string;
7088
+ };
7089
+ };
7090
+ };
7091
+ /** @description Standard error envelope used for all non-2xx responses. */
7092
+ 503: {
7093
+ headers: {
7094
+ [name: string]: unknown;
7095
+ };
7096
+ content: {
7097
+ "application/json": {
7098
+ /**
7099
+ * @description Stable machine-readable code. SDK consumers should switch on this.
7100
+ * @example invalid_key
7101
+ */
7102
+ error: string;
7103
+ /** @description Free-form human-readable explanation. Safe to surface. */
7104
+ detail?: string;
7105
+ };
7106
+ };
7107
+ };
7108
+ };
7109
+ };
7110
+ getConnectionIdentity: {
7111
+ parameters: {
7112
+ query?: {
7113
+ /** @description Name to match holders against. */
7114
+ applicant_name?: string;
7115
+ };
7116
+ header?: never;
7117
+ path: {
7118
+ id: string;
7119
+ };
7120
+ cookie?: never;
7121
+ };
7122
+ requestBody?: never;
7123
+ responses: {
7124
+ /** @description Default Response */
7125
+ 200: {
7126
+ headers: {
7127
+ [name: string]: unknown;
7128
+ };
7129
+ content: {
7130
+ "application/json": {
7131
+ accounts: {
7132
+ account_id: string;
7133
+ holder_name: string | null;
7134
+ iban?: string;
7135
+ account_type?: string;
7136
+ currency: string;
7137
+ name_match?: {
7138
+ verdict: "match" | "partial" | "no_match";
7139
+ score: number;
7140
+ };
6606
7141
  }[];
6607
7142
  };
6608
7143
  };
@@ -6716,6 +7251,9 @@ export interface operations {
6716
7251
  query?: {
6717
7252
  /** @description EB account uid; omit to fetch all accounts on the connection. */
6718
7253
  account_id?: string;
7254
+ /** @description Incremental cursor: the next_cursor from your previous response. Sets the window start when date_from is not given. Dedupe by transaction id across the boundary. */
7255
+ since?: string;
7256
+ /** @description Explicit window start (overrides since). */
6719
7257
  date_from?: string;
6720
7258
  date_to?: string;
6721
7259
  /** @description Run enrichment on each transaction (bills the enrichment meter; needs enrichment:read). */
@@ -6892,6 +7430,17 @@ export interface operations {
6892
7430
  "application/json": {
6893
7431
  country: string;
6894
7432
  applicant_ref?: string;
7433
+ /** @description Your own stable id for the connection this link creates. Survives reconsent; echoed in list responses and every connect.connection.* webhook. */
7434
+ external_ref?: string;
7435
+ /** @description Override the hosted page brand name for this link (defaults to your org branding). */
7436
+ brand_name?: string;
7437
+ /**
7438
+ * Format: uri
7439
+ * @description Override brand logo (https URL) for this link.
7440
+ */
7441
+ brand_logo_url?: string;
7442
+ /** @description Override brand accent colour (#RRGGBB) for this link. */
7443
+ brand_color?: string;
6895
7444
  /** Format: uri */
6896
7445
  return_url?: string;
6897
7446
  /** @default 72 */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@distyra/sdk",
3
- "version": "0.4.0",
3
+ "version": "0.6.0",
4
4
  "description": "TypeScript SDK for the Distyra Transaction Enrichment & SME Underwriting API. Generated from the committed OpenAPI spec; thin, typed wrapper around openapi-fetch.",
5
5
  "license": "MIT",
6
6
  "author": "Brightfield Software",