@ecodrix/erix-api 3.1.1 → 3.1.2

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.
@@ -45,7 +45,7 @@ declare class Notes extends APIResource {
45
45
  * @param leadId - The unique ID of the lead.
46
46
  * @example
47
47
  * ```typescript
48
- * const notes = await erixClient.crm.activities.notes.list("lead_123");
48
+ * const notes = await ecod.product.erix.activities.notes.list("lead_123");
49
49
  * ```
50
50
  */
51
51
  list<T = any>(leadId: string): Promise<T>;
@@ -56,7 +56,7 @@ declare class Notes extends APIResource {
56
56
  * @param params - The note content.
57
57
  * @example
58
58
  * ```typescript
59
- * await erixClient.crm.activities.notes.create("lead_123", {
59
+ * await ecod.product.erix.activities.notes.create("lead_123", {
60
60
  * content: "Customer is interested in the enterprise plan."
61
61
  * });
62
62
  * ```
@@ -87,7 +87,7 @@ declare class Activities extends APIResource {
87
87
  * @param params - Optional pagination parameters.
88
88
  * @example
89
89
  * ```typescript
90
- * const timeline = await erixClient.crm.activities.timeline("lead_123", { limit: 10 });
90
+ * const timeline = await ecod.product.erix.activities.timeline("lead_123", { limit: 10 });
91
91
  * ```
92
92
  */
93
93
  timeline<T = any>(leadId: string, params?: {
@@ -108,7 +108,7 @@ declare class Activities extends APIResource {
108
108
  * @param params - Activity details (leadId, type, title, body).
109
109
  * @example
110
110
  * ```typescript
111
- * await erixClient.crm.activities.log({
111
+ * await ecod.product.erix.activities.log({
112
112
  * leadId: "lead_123",
113
113
  * type: "system",
114
114
  * title: "Meeting Scheduled",
@@ -139,7 +139,7 @@ declare class Analytics extends APIResource {
139
139
  * @returns {Promise<any>} KPI summary object containing core business metrics.
140
140
  * @example
141
141
  * ```typescript
142
- * const stats = await erixClient.crm.analytics.overview({ range: "30d" });
142
+ * const stats = await ecod.product.erix.analytics.overview({ range: "30d" });
143
143
  * console.log(stats.avgScore);
144
144
  * ```
145
145
  */
@@ -152,7 +152,7 @@ declare class Analytics extends APIResource {
152
152
  * @returns {Promise<any>} Array of funnel stages with count and conversion data.
153
153
  * @example
154
154
  * ```typescript
155
- * const funnel = await erixClient.crm.analytics.funnel("pipe_123");
155
+ * const funnel = await ecod.product.erix.analytics.funnel("pipe_123");
156
156
  * ```
157
157
  */
158
158
  funnel<T = any>(pipelineId: string): Promise<T>;
@@ -164,7 +164,7 @@ declare class Analytics extends APIResource {
164
164
  * @returns {Promise<any>} Forecast data including weighted expected revenue.
165
165
  * @example
166
166
  * ```typescript
167
- * const prognosis = await erixClient.crm.analytics.forecast("pipe_123");
167
+ * const prognosis = await ecod.product.erix.analytics.forecast("pipe_123");
168
168
  * ```
169
169
  */
170
170
  forecast<T = any>(pipelineId?: string): Promise<T>;
@@ -217,7 +217,7 @@ declare class Analytics extends APIResource {
217
217
  * @returns {Promise<any>} Consolidated analytics object containing CRM overview and WhatsApp messaging metrics.
218
218
  * @example
219
219
  * ```typescript
220
- * const stats = await erixClient.crm.analytics.summary({ range: "30d" });
220
+ * const stats = await ecod.product.erix.analytics.summary({ range: "30d" });
221
221
  * console.log(stats.overview.totalLeads);
222
222
  * ```
223
223
  */
@@ -229,7 +229,7 @@ declare class Analytics extends APIResource {
229
229
  * @param params - Optional filters (time range).
230
230
  * @example
231
231
  * ```typescript
232
- * const waStats = await erixClient.crm.analytics.whatsapp({ range: "7d" });
232
+ * const waStats = await ecod.product.erix.analytics.whatsapp({ range: "7d" });
233
233
  * console.log(waStats.totalSent);
234
234
  * ```
235
235
  */
@@ -261,10 +261,10 @@ declare class Analytics extends APIResource {
261
261
  *
262
262
  * @example
263
263
  * ```typescript
264
- * const checklist = await ecod.crm.documents.getChecklist("lead-id");
265
- * await ecod.crm.documents.createChecklist("lead-id", "consultant__business");
266
- * await ecod.crm.documents.markReceived("lead-id", "pan_card", fileUrl);
267
- * await ecod.crm.documents.sendReminder("lead-id");
264
+ * const checklist = await ecod.product.erix.documents.getChecklist("lead-id");
265
+ * await ecod.product.erix.documents.createChecklist("lead-id", "consultant__business");
266
+ * await ecod.product.erix.documents.markReceived("lead-id", "pan_card", fileUrl);
267
+ * await ecod.product.erix.documents.sendReminder("lead-id");
268
268
  * ```
269
269
  */
270
270
  declare class CRMDocuments extends APIResource {
@@ -299,9 +299,9 @@ declare class CRMDocuments extends APIResource {
299
299
  *
300
300
  * @example
301
301
  * ```typescript
302
- * const csv = await ecod.crm.invoiceExport.csv({ from: "2026-01-01", status: "paid" });
303
- * const tally = await ecod.crm.invoiceExport.tally();
304
- * const zoho = await ecod.crm.invoiceExport.zoho({ from: "2026-06-01", to: "2026-08-31" });
302
+ * const csv = await ecod.product.erix.invoiceExport.csv({ from: "2026-01-01", status: "paid" });
303
+ * const tally = await ecod.product.erix.invoiceExport.tally();
304
+ * const zoho = await ecod.product.erix.invoiceExport.zoho({ from: "2026-06-01", to: "2026-08-31" });
305
305
  * ```
306
306
  */
307
307
  declare class CRMInvoiceExport extends APIResource {
@@ -559,11 +559,11 @@ interface UpsertLeadParams {
559
559
  /**
560
560
  * CRM Lead resource — full lifecycle management.
561
561
  *
562
- * Access via `ecod.crm.leads`.
562
+ * Access via `ecod.product.erix.leads`.
563
563
  *
564
564
  * @example
565
565
  * ```typescript
566
- * const { data: lead } = await ecod.crm.leads.create({
566
+ * const { data: lead } = await ecod.product.erix.leads.create({
567
567
  * firstName: "Alice",
568
568
  * phone: "+919876543210",
569
569
  * source: "website",
@@ -578,7 +578,7 @@ declare class Leads extends APIResource {
578
578
  * @returns The newly created Lead document.
579
579
  * @example
580
580
  * ```typescript
581
- * const lead = await erixClient.crm.leads.create({
581
+ * const lead = await ecod.product.erix.leads.create({
582
582
  * firstName: "Alice",
583
583
  * phone: "+919876543210",
584
584
  * source: "website"
@@ -602,7 +602,7 @@ declare class Leads extends APIResource {
602
602
  * @returns The newly created or updated Lead document.
603
603
  * @example
604
604
  * ```typescript
605
- * await erixClient.crm.leads.upsert({
605
+ * await ecod.product.erix.leads.upsert({
606
606
  * leadData: { phone: "+919876543210", firstName: "Alice" }
607
607
  * });
608
608
  * ```
@@ -638,8 +638,8 @@ declare class Leads extends APIResource {
638
638
  * @returns Paginated list of Lead documents.
639
639
  * @example
640
640
  * ```typescript
641
- * const leads = await erixClient.crm.leads.list({
642
- * status: "new",
641
+ * const leads = await ecod.product.erix.leads.list({
642
+ * status: "open",
643
643
  * source: "website",
644
644
  * limit: 20
645
645
  * });
@@ -652,7 +652,7 @@ declare class Leads extends APIResource {
652
652
  *
653
653
  * @example
654
654
  * ```typescript
655
- * for await (const lead of ecod.crm.leads.listAutoPaging<Lead>()) {
655
+ * for await (const lead of ecod.product.erix.leads.listAutoPaging<Lead>()) {
656
656
  * console.log(lead.firstName);
657
657
  * }
658
658
  * ```
@@ -665,7 +665,7 @@ declare class Leads extends APIResource {
665
665
  * @returns The Lead document, or a 404 error if not found.
666
666
  * @example
667
667
  * ```typescript
668
- * const lead = await erixClient.crm.leads.retrieve("64abc...");
668
+ * const lead = await ecod.product.erix.leads.retrieve("64abc...");
669
669
  * ```
670
670
  */
671
671
  retrieve<T = any>(leadId: string): Promise<T>;
@@ -704,9 +704,9 @@ declare class Leads extends APIResource {
704
704
  * @returns The updated Lead document.
705
705
  * @example
706
706
  * ```typescript
707
- * await erixClient.crm.leads.update("64abc...", {
707
+ * await ecod.product.erix.leads.update("64abc...", {
708
708
  * lastName: "Smith",
709
- * status: "qualified"
709
+ * status: "won"
710
710
  * });
711
711
  * ```
712
712
  */
@@ -792,12 +792,31 @@ declare class Leads extends APIResource {
792
792
  */
793
793
  deleteNote<T = any>(leadId: string, noteId: string): Promise<unknown>;
794
794
  /**
795
- * Delete a single lead permanently.
795
+ * Archive a single lead (the server soft-deletes: the lead leaves lists and
796
+ * the board but its history stays). To remove a person's data for good,
797
+ * use {@link erase}.
796
798
  *
797
- * @param leadId - The ID of the lead to delete.
798
- * ---- **Done** ---- API Endpoint
799
+ * @param leadId - The ID of the lead to archive.
799
800
  */
800
801
  delete(leadId: string): Promise<unknown>;
802
+ /**
803
+ * Everything held about one contact as JSON (DPDP right of access):
804
+ * profile, consent, notes, activity, form answers, appointments, meetings,
805
+ * invoices, conversations with messages, automation runs. Owner/admin only.
806
+ */
807
+ export<T = any>(leadId: string): Promise<T>;
808
+ /**
809
+ * Erase a contact's personal data (DPDP right to erasure) across CRM,
810
+ * inbox, channels and automations; invoices are kept for GST records.
811
+ * Irreversible. Owner/admin only.
812
+ */
813
+ erase(leadId: string): Promise<{
814
+ success: boolean;
815
+ data: {
816
+ erased: true;
817
+ invoicesKept: number;
818
+ };
819
+ }>;
801
820
  /**
802
821
  * Bulk archive multiple leads.
803
822
  *
@@ -861,7 +880,7 @@ declare class Payments extends APIResource {
861
880
  * @param payload - Payment details (leadId, amount, currency, description).
862
881
  * @example
863
882
  * ```typescript
864
- * await erixClient.crm.payments.capture({
883
+ * await ecod.product.erix.payments.capture({
865
884
  * leadId: "lead_123",
866
885
  * amount: 5000,
867
886
  * currency: "INR",
@@ -920,7 +939,7 @@ declare class Pipelines extends APIResource {
920
939
  * @returns Array of pipeline objects with nested stages.
921
940
  * @example
922
941
  * ```typescript
923
- * const pipelines = await erixClient.crm.pipelines.list();
942
+ * const pipelines = await ecod.product.erix.pipelines.list();
924
943
  * ```
925
944
  */
926
945
  list<T = any>(): Promise<T>;
@@ -940,7 +959,7 @@ declare class Pipelines extends APIResource {
940
959
  * @returns The created pipeline record.
941
960
  * @example
942
961
  * ```typescript
943
- * await erixClient.crm.pipelines.create({
962
+ * await ecod.product.erix.pipelines.create({
944
963
  * name: "Sales Pipeline",
945
964
  * stages: ["Lead", "Contacted", "Proposal", "Negotiation", "Closed"]
946
965
  * });
@@ -956,7 +975,7 @@ declare class Pipelines extends APIResource {
956
975
  * @param pipelineId - The unique ID of the pipeline.
957
976
  * @example
958
977
  * ```typescript
959
- * const pipeline = await erixClient.crm.pipelines.retrieve("pipe_123");
978
+ * const pipeline = await ecod.product.erix.pipelines.retrieve("pipe_123");
960
979
  * ```
961
980
  */
962
981
  retrieve<T = any>(pipelineId: string): Promise<T>;
@@ -993,7 +1012,7 @@ declare class Pipelines extends APIResource {
993
1012
  * @param pipelineId - The unique ID of the pipeline.
994
1013
  * @example
995
1014
  * ```typescript
996
- * const board = await erixClient.crm.pipelines.board("pipe_123");
1015
+ * const board = await ecod.product.erix.pipelines.board("pipe_123");
997
1016
  * ```
998
1017
  */
999
1018
  board<T = any>(pipelineId: string): Promise<T>;
@@ -1008,7 +1027,7 @@ declare class Pipelines extends APIResource {
1008
1027
  * @param params - Stage details (name, color, probability).
1009
1028
  * @example
1010
1029
  * ```typescript
1011
- * await erixClient.crm.pipelines.addStage("pipe_123", {
1030
+ * await ecod.product.erix.pipelines.addStage("pipe_123", {
1012
1031
  * name: "Decision Maker Bought In",
1013
1032
  * color: "#FF5733",
1014
1033
  * probability: 80
@@ -1067,7 +1086,7 @@ declare class Scoring extends APIResource {
1067
1086
  * @returns The scoring configuration object.
1068
1087
  * @example
1069
1088
  * ```typescript
1070
- * const config = await erixClient.crm.scoring.getConfig();
1089
+ * const config = await ecod.product.erix.scoring.getConfig();
1071
1090
  * ```
1072
1091
  */
1073
1092
  getConfig<T = any>(): Promise<T>;
@@ -1082,7 +1101,7 @@ declare class Scoring extends APIResource {
1082
1101
  * @param leadId - The unique ID of the lead.
1083
1102
  * @example
1084
1103
  * ```typescript
1085
- * await erixClient.crm.scoring.recalculate("lead_123");
1104
+ * await ecod.product.erix.scoring.recalculate("lead_123");
1086
1105
  * ```
1087
1106
  */
1088
1107
  recalculate<T = any>(leadId: string): Promise<T>;
@@ -1306,54 +1325,71 @@ declare class Checkout extends APIResource {
1306
1325
  }
1307
1326
 
1308
1327
  /**
1309
- * Payload to programmatically trigger an event/workflow.
1328
+ * Event definition representing an entry point capable of triggering automations.
1329
+ */
1330
+ interface EventDefinition {
1331
+ name: string;
1332
+ displayName: string;
1333
+ description?: string;
1334
+ pipelineId?: string;
1335
+ stageId?: string;
1336
+ defaultSource?: string;
1337
+ [key: string]: any;
1338
+ }
1339
+ /**
1340
+ * Payload to register/assign a new custom event definition.
1341
+ */
1342
+ interface AssignEventPayload {
1343
+ /** The internal machine-readable name of the event (e.g. "webinar_joined") */
1344
+ name: string;
1345
+ /** Human-readable display name */
1346
+ displayName: string;
1347
+ /** Event description */
1348
+ description?: string;
1349
+ /** ID of the pipeline to associate with matching leads */
1350
+ pipelineId?: string;
1351
+ /** ID of the stage within the pipeline */
1352
+ stageId?: string;
1353
+ /** Default source tag for leads created via this event */
1354
+ defaultSource?: string;
1355
+ }
1356
+ /**
1357
+ * Payload to programmatically trigger an event/workflow. Matches what
1358
+ * `POST /product/erix/events/trigger` accepts; unknown keys are dropped.
1310
1359
  */
1311
1360
  interface TriggerPayload {
1312
- /** The name of the event to fire (e.g., "webinar_joined") */
1361
+ /** The name of the event to fire (e.g., "webinar_joined"); no spaces, max 100. */
1313
1362
  trigger: string;
1314
1363
  /**
1315
- * Phone number of the lead (E.164 format). Phone OR email is required —
1316
- * at least one of `phone`/`email` must be provided (enforced server-side).
1364
+ * Phone number of the lead (E.164 format). Phone OR email is required unless
1365
+ * the workspace has Flow v1 (events without a contact).
1317
1366
  */
1318
1367
  phone?: string;
1319
- /**
1320
- * Email of the lead. Phone OR email is required — at least one of
1321
- * `phone`/`email` must be provided (enforced server-side).
1322
- */
1368
+ /** Email of the lead. Phone OR email is required (see `phone`). */
1323
1369
  email?: string;
1324
- /** Key-value pairs for string templates */
1325
- variables?: Record<string, string>;
1326
- /** Deep payload data mapping to the event */
1327
- data?: any;
1328
- /** URL to receive an acknowledgment callback when processing completes */
1329
- callbackUrl?: string;
1330
- /** Secret metadata passed back to the callback URL */
1331
- callbackMetadata?: any;
1332
- /** Auto-create lead if phone does not exist in CRM */
1333
- createLeadIfMissing?: boolean;
1334
- /** Pre-fill data if creating a new lead */
1370
+ /** Key-value pairs for message templates (values are sent as text). */
1371
+ variables?: Record<string, string | number | boolean>;
1372
+ /** Extra event data the flow can read. */
1373
+ data?: Record<string, unknown>;
1374
+ /** Pre-fill data if `createLeadIfMissing` creates the contact. */
1335
1375
  leadData?: {
1336
1376
  firstName?: string;
1337
1377
  lastName?: string;
1338
1378
  source?: string;
1339
1379
  };
1340
- /** Delay execution of matched workflows (in seconds) */
1380
+ /**
1381
+ * Your id for this event (max 200). A retry with the same key and trigger
1382
+ * doesn't start the flows twice. Generated by the server when omitted.
1383
+ */
1384
+ idempotencyKey?: string;
1385
+ /** Flow v1: create the contact when phone/email matches none. */
1386
+ createLeadIfMissing?: boolean;
1387
+ /** Flow v1: delay matched flows (seconds). Use one of the three delays. */
1341
1388
  delaySeconds?: number;
1342
- /** Delay execution of matched workflows (in minutes) */
1389
+ /** Flow v1: delay matched flows (minutes). */
1343
1390
  delayMinutes?: number;
1344
- /** Explicit ISO timestamp to trigger the workflow run */
1391
+ /** Flow v1: start matched flows at this ISO time (with offset). */
1345
1392
  runAt?: string;
1346
- /** Automatically generate a Google Meet appointment if matched actions require it */
1347
- requiresMeet?: boolean;
1348
- /** Configuration details for the generated Google Meet appointment */
1349
- meetConfig?: {
1350
- summary?: string;
1351
- description?: string;
1352
- startTime?: string;
1353
- duration?: number;
1354
- timezone?: string;
1355
- attendees?: string[];
1356
- };
1357
1393
  }
1358
1394
  /**
1359
1395
  * Response returned when triggering an event.
@@ -1361,9 +1397,14 @@ interface TriggerPayload {
1361
1397
  interface TriggerResponse {
1362
1398
  success: boolean;
1363
1399
  data?: {
1364
- eventLogId: string;
1365
1400
  trigger: string;
1366
- leadId: string;
1401
+ /** Yours, or the one the server generated. */
1402
+ idempotencyKey: string;
1403
+ leadId?: string;
1404
+ /** Set when a delay was applied. */
1405
+ scheduledFor?: string;
1406
+ /** Flow v1 fields sent to a workspace without Flow v1: accepted, not applied. */
1407
+ ignored?: string[];
1367
1408
  };
1368
1409
  message?: string;
1369
1410
  code?: string;
@@ -1375,10 +1416,10 @@ declare class EventsResource extends APIResource {
1375
1416
  * engine) and starts each flow whose declared trigger matches.
1376
1417
  *
1377
1418
  * @param payload - The trigger details (event name, lead phone/email, variables).
1378
- * @returns Trigger response with diagnostic info (eventLogId, trigger, leadId).
1419
+ * @returns Trigger response with diagnostic info (trigger, idempotencyKey, leadId, scheduledFor).
1379
1420
  * @example
1380
1421
  * ```typescript
1381
- * await erixClient.events.trigger({
1422
+ * await ecod.product.erix.events.trigger({
1382
1423
  * trigger: "webinar_joined",
1383
1424
  * phone: "+919876543210",
1384
1425
  * variables: { webinar_name: "AI Masterclass" },
@@ -1414,9 +1455,13 @@ declare class EventsResource extends APIResource {
1414
1455
  *
1415
1456
  * @example
1416
1457
  * ```typescript
1417
- * const invoices = await ecod.invoices.list();
1418
- * const inv = await ecod.invoices.create({ leadId, items, currency: "INR" });
1419
- * await ecod.invoices.sendViaWhatsApp(inv.id);
1458
+ * const invoices = await ecod.product.erix.invoices.list();
1459
+ * const { data: inv } = await ecod.product.erix.invoices.create({
1460
+ * clientName: "Customer name",
1461
+ * leadId,
1462
+ * items: [{ description: "Consultation", quantity: 1, rate: 1500 }],
1463
+ * });
1464
+ * await ecod.product.erix.invoices.sendWhatsApp(inv.id);
1420
1465
  * ```
1421
1466
  */
1422
1467
  declare class Invoices extends APIResource {
@@ -1454,6 +1499,30 @@ declare class Invoices extends APIResource {
1454
1499
  * Update invoice settings.
1455
1500
  */
1456
1501
  updateSettings<T = any>(payload: Record<string, unknown>): Promise<T>;
1502
+ /** Create (or reuse) the invoice's payment link on the workspace's gateway. */
1503
+ paymentLink(id: string): Promise<{
1504
+ success: boolean;
1505
+ data: {
1506
+ paymentLinkId: string;
1507
+ paymentLinkUrl: string;
1508
+ };
1509
+ }>;
1510
+ /**
1511
+ * Record money received outside the gateway (UPI, bank transfer, cash).
1512
+ * Less than the balance → `partially_paid`; covering it → `paid`. Owner or
1513
+ * admin only. `paymentId` (a UUID you generate) makes a retried call count
1514
+ * the payment once.
1515
+ */
1516
+ recordPayment<T = any>(id: string, payload: {
1517
+ amount: number;
1518
+ paidAt?: string;
1519
+ reference?: string;
1520
+ paymentId?: string;
1521
+ }): Promise<T>;
1522
+ /** Send the invoice (with its payment link) to the client on WhatsApp. */
1523
+ sendWhatsApp<T = any>(id: string): Promise<T>;
1524
+ /** Email the invoice PDF (and payment link) to the client. */
1525
+ sendEmail<T = any>(id: string): Promise<T>;
1457
1526
  }
1458
1527
 
1459
1528
  /**
@@ -1461,10 +1530,10 @@ declare class Invoices extends APIResource {
1461
1530
  *
1462
1531
  * @example
1463
1532
  * ```typescript
1464
- * const packs = await ecod.niche.workflowPacks();
1465
- * const detail = await ecod.niche.workflowPackDetail("pack_healthcare");
1466
- * const result = await ecod.niche.installWorkflowPack("pack_healthcare");
1467
- * const templates = await ecod.niche.templateSuggestions();
1533
+ * const packs = await ecod.product.erix.niche.workflowPacks();
1534
+ * const detail = await ecod.product.erix.niche.workflowPackDetail("pack_healthcare");
1535
+ * const result = await ecod.product.erix.niche.installWorkflowPack("pack_healthcare");
1536
+ * const templates = await ecod.product.erix.niche.templateSuggestions();
1468
1537
  * ```
1469
1538
  */
1470
1539
  declare class NicheResources extends APIResource {
@@ -1494,11 +1563,11 @@ declare class NicheResources extends APIResource {
1494
1563
  *
1495
1564
  * @example
1496
1565
  * ```typescript
1497
- * const docs = await ecod.projectDocuments.list(projectId);
1498
- * await ecod.projectDocuments.upload(projectId, { name: "Contract.pdf", fileKey, mimeType });
1499
- * await ecod.projectDocuments.toggleSignature(projectId, docId, true);
1500
- * await ecod.projectDocuments.addSigner(projectId, docId, { role: "client", name: "Alice" });
1501
- * await ecod.projectDocuments.stampSign(projectId, docId, { signatureImage: base64Png });
1566
+ * const docs = await ecod.product.erix.projects.list(projectId);
1567
+ * await ecod.product.erix.projects.upload(projectId, { name: "Contract.pdf", fileKey, mimeType });
1568
+ * await ecod.product.erix.projects.toggleSignature(projectId, docId, true);
1569
+ * await ecod.product.erix.projects.addSigner(projectId, docId, { role: "client", name: "Alice" });
1570
+ * await ecod.product.erix.projects.stampSign(projectId, docId, { signatureImage: base64Png });
1502
1571
  * ```
1503
1572
  */
1504
1573
  declare class ProjectDocuments extends APIResource {
@@ -1529,22 +1598,19 @@ declare class ProjectDocuments extends APIResource {
1529
1598
  email?: string;
1530
1599
  userId?: string;
1531
1600
  }): Promise<T>;
1532
- /**
1533
- * Team user signs a document (simple mark — no PDF stamp).
1534
- */
1535
- sign<T = any>(projectId: string, docId: string, payload?: {
1536
- signedFileKey?: string;
1537
- }): Promise<T>;
1538
1601
  /**
1539
1602
  * Team user declines signing a document.
1540
1603
  */
1541
1604
  decline<T = any>(projectId: string, docId: string): Promise<T>;
1542
1605
  /**
1543
- * Full signing ceremony — stamps a signature image onto the PDF,
1544
- * computes an audit seal, and re-uploads the signed copy.
1606
+ * The team's signing ceremony (owners/admins): stamps a signature image onto
1607
+ * the PDF, computes an audit seal, and re-uploads the signed copy. Signers
1608
+ * sign in the order they were added, so the team signs after the client
1609
+ * (409 `SIGN_ORDER` before that). Click-to-sign with an audit seal, not an
1610
+ * Aadhaar eSign.
1545
1611
  *
1546
1612
  * @param signatureImage - Base64-encoded PNG of the drawn/typed signature
1547
- * @param signerName - Name to stamp on the PDF
1613
+ * @param signerName - Ignored: the server stamps the signed-in person's name
1548
1614
  * @param position - Optional position override { page?, x?, y?, width?, height? }
1549
1615
  */
1550
1616
  stampSign<T = any>(projectId: string, docId: string, payload: {
@@ -1746,7 +1812,7 @@ declare class Email extends APIResource {
1746
1812
  * @returns A promise resolving to the result of the test email dispatch.
1747
1813
  * @example
1748
1814
  * ```typescript
1749
- * await erixClient.email.sendTest("admin@mycompany.com");
1815
+ * await ecod.infra.connect.email.templates.sendTest("admin@mycompany.com");
1750
1816
  * ```
1751
1817
  */
1752
1818
  sendTest(to: string): Promise<CampaignResult>;
@@ -1757,7 +1823,7 @@ declare class Email extends APIResource {
1757
1823
  * @returns A promise resolving to a paginated or filtered list of templates.
1758
1824
  * @example
1759
1825
  * ```typescript
1760
- * const response = await erixClient.email.listTemplates({ category: "marketing" });
1826
+ * const response = await ecod.infra.connect.email.templates.listTemplates({ category: "marketing" });
1761
1827
  * console.log(response.data);
1762
1828
  * ```
1763
1829
  */
@@ -1772,7 +1838,7 @@ declare class Email extends APIResource {
1772
1838
  * @returns A promise resolving to the requested template details.
1773
1839
  * @example
1774
1840
  * ```typescript
1775
- * const template = await erixClient.email.getTemplate("tpl_123abc");
1841
+ * const template = await ecod.infra.connect.email.templates.getTemplate("tpl_123abc");
1776
1842
  * ```
1777
1843
  */
1778
1844
  getTemplate(id: string): Promise<{
@@ -1786,7 +1852,7 @@ declare class Email extends APIResource {
1786
1852
  * @returns A promise resolving to the newly created template.
1787
1853
  * @example
1788
1854
  * ```typescript
1789
- * const newTpl = await erixClient.email.createTemplate({
1855
+ * const newTpl = await ecod.infra.connect.email.templates.createTemplate({
1790
1856
  * name: "Welcome Series 1",
1791
1857
  * subject: "Welcome to our platform!",
1792
1858
  * htmlBody: "<h1>Welcome</h1><p>We are glad you are here.</p>"
@@ -1805,7 +1871,7 @@ declare class Email extends APIResource {
1805
1871
  * @returns A promise resolving to the updated template.
1806
1872
  * @example
1807
1873
  * ```typescript
1808
- * await erixClient.email.updateTemplate("tpl_123abc", {
1874
+ * await ecod.infra.connect.email.templates.updateTemplate("tpl_123abc", {
1809
1875
  * subject: "Updated Welcome Subject"
1810
1876
  * });
1811
1877
  * ```
@@ -1822,7 +1888,7 @@ declare class Email extends APIResource {
1822
1888
  * @returns A promise resolving to a success indicator.
1823
1889
  * @example
1824
1890
  * ```typescript
1825
- * await erixClient.email.deleteTemplate("tpl_123abc");
1891
+ * await ecod.infra.connect.email.templates.deleteTemplate("tpl_123abc");
1826
1892
  * ```
1827
1893
  */
1828
1894
  deleteTemplate(id: string, force?: boolean): Promise<{
@@ -1837,7 +1903,7 @@ declare class Email extends APIResource {
1837
1903
  * @returns A promise resolving to the rendered HTML and subject.
1838
1904
  * @example
1839
1905
  * ```typescript
1840
- * const preview = await erixClient.email.previewTemplate("tpl_123abc", {
1906
+ * const preview = await ecod.infra.connect.email.templates.previewTemplate("tpl_123abc", {
1841
1907
  * variables: { first_name: "Jane" }
1842
1908
  * });
1843
1909
  * console.log(preview.data.html);
@@ -1908,11 +1974,11 @@ interface UpdateMeetingParams {
1908
1974
  /**
1909
1975
  * Google Meet appointment scheduling resource.
1910
1976
  *
1911
- * Access via `ecod.meet`.
1977
+ * Access via `ecod.infra.connect.meet`.
1912
1978
  *
1913
1979
  * @example
1914
1980
  * ```typescript
1915
- * const { data } = await ecod.meet.create({
1981
+ * const { data } = await ecod.infra.connect.meet.create({
1916
1982
  * leadId: "64abc...",
1917
1983
  * participantName: "Alice",
1918
1984
  * participantPhone: "+919876543210",
@@ -1934,7 +2000,7 @@ declare class Meetings extends APIResource {
1934
2000
  *
1935
2001
  * @example
1936
2002
  * ```typescript
1937
- * const { data } = await ecod.meet.create({
2003
+ * const { data } = await ecod.infra.connect.meet.create({
1938
2004
  * leadId: "64abc...",
1939
2005
  * participantName: "Alice",
1940
2006
  * participantPhone: "+91...",
@@ -1952,7 +2018,7 @@ declare class Meetings extends APIResource {
1952
2018
  *
1953
2019
  * @example
1954
2020
  * ```typescript
1955
- * const { data } = await ecod.meet.list({ status: "scheduled" });
2021
+ * const { data } = await ecod.infra.connect.meet.list({ status: "scheduled" });
1956
2022
  * ```
1957
2023
  */
1958
2024
  list(params?: {
@@ -1967,7 +2033,7 @@ declare class Meetings extends APIResource {
1967
2033
  *
1968
2034
  * @example
1969
2035
  * ```typescript
1970
- * const { data } = await ecod.meet.retrieve("meeting_id");
2036
+ * const { data } = await ecod.infra.connect.meet.retrieve("meeting_id");
1971
2037
  * ```
1972
2038
  */
1973
2039
  retrieve(meetingId: string): Promise<any>;
@@ -1983,7 +2049,7 @@ declare class Meetings extends APIResource {
1983
2049
  * @example
1984
2050
  * ```typescript
1985
2051
  * // Reschedule
1986
- * await ecod.meet.update("meeting_id", {
2052
+ * await ecod.infra.connect.meet.update("meeting_id", {
1987
2053
  * startTime: "2026-04-11T11:00:00Z",
1988
2054
  * endTime: "2026-04-11T11:30:00Z",
1989
2055
  * });
@@ -2005,7 +2071,7 @@ declare class Meetings extends APIResource {
2005
2071
  *
2006
2072
  * @example
2007
2073
  * ```typescript
2008
- * await ecod.meet.delete("meeting_id");
2074
+ * await ecod.infra.connect.meet.delete("meeting_id");
2009
2075
  * ```
2010
2076
  */
2011
2077
  delete(meetingId: string): Promise<any>;
@@ -2148,7 +2214,7 @@ declare class Templates extends APIResource {
2148
2214
  * @returns List of message templates.
2149
2215
  * @example
2150
2216
  * ```typescript
2151
- * const templates = await erixClient.whatsapp.templates.list({ status: "APPROVED" });
2217
+ * const templates = await ecod.infra.connect.whatsapp.templates.list({ status: "APPROVED" });
2152
2218
  * ```
2153
2219
  */
2154
2220
  list<T = any>(params?: {
@@ -2163,7 +2229,7 @@ declare class Templates extends APIResource {
2163
2229
  * @returns Success status of the sync operation.
2164
2230
  * @example
2165
2231
  * ```typescript
2166
- * await erixClient.whatsapp.templates.sync();
2232
+ * await ecod.infra.connect.whatsapp.templates.sync();
2167
2233
  * ```
2168
2234
  */
2169
2235
  sync<T = any>(): Promise<T>;
@@ -2174,7 +2240,7 @@ declare class Templates extends APIResource {
2174
2240
  * @returns Detailed template object including components and status.
2175
2241
  * @example
2176
2242
  * ```typescript
2177
- * const template = await erixClient.whatsapp.templates.retrieve("welcome_message");
2243
+ * const template = await ecod.infra.connect.whatsapp.templates.retrieve("welcome_message");
2178
2244
  * ```
2179
2245
  */
2180
2246
  retrieve<T = any>(templateIdentifier: string): Promise<T>;
@@ -2184,7 +2250,7 @@ declare class Templates extends APIResource {
2184
2250
  * @param payload - Template configuration (name, category, language, components).
2185
2251
  * @example
2186
2252
  * ```typescript
2187
- * await erixClient.whatsapp.templates.create({
2253
+ * await ecod.infra.connect.whatsapp.templates.create({
2188
2254
  * name: "new_promotion",
2189
2255
  * category: "MARKETING",
2190
2256
  * language: "en_US",
@@ -2207,7 +2273,7 @@ declare class Templates extends APIResource {
2207
2273
  * @param force - If true, attempts to delete from Meta API as well.
2208
2274
  * @example
2209
2275
  * ```typescript
2210
- * await erixClient.whatsapp.templates.deleteTemplate("old_template", true);
2276
+ * await ecod.infra.connect.whatsapp.templates.deleteTemplate("old_template", true);
2211
2277
  * ```
2212
2278
  */
2213
2279
  deleteTemplate<T = any>(templateName: string, force?: boolean): Promise<T>;
@@ -2216,7 +2282,7 @@ declare class Templates extends APIResource {
2216
2282
  *
2217
2283
  * @example
2218
2284
  * ```typescript
2219
- * const config = await erixClient.whatsapp.templates.mappingConfig();
2285
+ * const config = await ecod.infra.connect.whatsapp.templates.mappingConfig();
2220
2286
  * ```
2221
2287
  */
2222
2288
  mappingConfig<T = any>(): Promise<T>;
@@ -2283,7 +2349,7 @@ interface UploadOptions {
2283
2349
  /**
2284
2350
  * Cloudflare R2-backed media resource.
2285
2351
  *
2286
- * Access via `ecod.media`.
2352
+ * Access via `ecod.infra.storage.media`.
2287
2353
  *
2288
2354
  * The `upload()` method is the recommended approach. It acts as a client-side
2289
2355
  * orchestrator: it fetches a presigned URL from the backend, uploads directly
@@ -2291,7 +2357,7 @@ interface UploadOptions {
2291
2357
  *
2292
2358
  * @example
2293
2359
  * ```typescript
2294
- * const { data } = await ecod.media.upload(fileBuffer, {
2360
+ * const { data } = await ecod.infra.storage.media.upload(fileBuffer, {
2295
2361
  * folder: "invoices",
2296
2362
  * filename: "invoice-001.pdf",
2297
2363
  * contentType: "application/pdf",
@@ -2307,7 +2373,7 @@ declare class Media extends APIResource {
2307
2373
  *
2308
2374
  * @example
2309
2375
  * ```typescript
2310
- * const { data } = await ecod.media.getUsage();
2376
+ * const { data } = await ecod.infra.storage.media.getUsage();
2311
2377
  * console.log(`${data.usedMB} / ${data.limitMB} MB used`);
2312
2378
  * ```
2313
2379
  */
@@ -2319,7 +2385,7 @@ declare class Media extends APIResource {
2319
2385
  *
2320
2386
  * @example
2321
2387
  * ```typescript
2322
- * await ecod.media.createFolder("patient_records");
2388
+ * await ecod.infra.storage.media.createFolder("patient_records");
2323
2389
  * ```
2324
2390
  */
2325
2391
  createFolder(name: string): Promise<unknown>;
@@ -2334,13 +2400,13 @@ declare class Media extends APIResource {
2334
2400
  *
2335
2401
  * @example Single folder
2336
2402
  * ```typescript
2337
- * const { data } = await ecod.media.list("invoices", { q: "contract" });
2403
+ * const { data } = await ecod.infra.storage.media.list("invoices", { q: "contract" });
2338
2404
  * // data.files → files only from the "invoices" folder
2339
2405
  * ```
2340
2406
  *
2341
2407
  * @example All folders
2342
2408
  * ```typescript
2343
- * const { data } = await ecod.media.list("*");
2409
+ * const { data } = await ecod.infra.storage.media.list("*");
2344
2410
  * // data.files → merged files from every folder the tenant has
2345
2411
  * // Each file has a `folder` field indicating its source folder
2346
2412
  * ```
@@ -2357,7 +2423,7 @@ declare class Media extends APIResource {
2357
2423
  *
2358
2424
  * @example
2359
2425
  * ```typescript
2360
- * await ecod.media.delete("invoices/old-contract.pdf");
2426
+ * await ecod.infra.storage.media.delete("invoices/old-contract.pdf");
2361
2427
  * ```
2362
2428
  */
2363
2429
  delete(key: string): Promise<unknown>;
@@ -2365,12 +2431,12 @@ declare class Media extends APIResource {
2365
2431
  * Request a temporary presigned download URL for a private file.
2366
2432
  *
2367
2433
  * @param key - The full storage key of the file.
2368
- * @returns `{ url }` — a time-limited download URL.
2434
+ * @returns `{ data: { downloadUrl, expiresAt } }` — a time-limited download URL.
2369
2435
  *
2370
2436
  * @example
2371
2437
  * ```typescript
2372
- * const { data } = await ecod.media.getDownloadUrl("invoices/contract.pdf");
2373
- * // → { url: "https://cdn.ecodrix.com/...?token=..." }
2438
+ * const res: any = await ecod.infra.storage.media.getDownloadUrl("invoices/contract.pdf");
2439
+ * // res.data.downloadUrl → "https://...?X-Amz-Signature=..."
2374
2440
  * ```
2375
2441
  */
2376
2442
  getDownloadUrl(key: string): Promise<unknown>;
@@ -2386,7 +2452,7 @@ declare class Media extends APIResource {
2386
2452
  *
2387
2453
  * @example
2388
2454
  * ```typescript
2389
- * const { data } = await ecod.media.aiDescribe("website/hero.jpg");
2455
+ * const { data } = await ecod.infra.storage.media.aiDescribe("website/hero.jpg");
2390
2456
  * // data.tags → ["office", "team", "modern"]
2391
2457
  * ```
2392
2458
  */
@@ -2410,7 +2476,7 @@ declare class Media extends APIResource {
2410
2476
  * ```typescript
2411
2477
  * import { readFileSync } from "fs";
2412
2478
  * const buf = readFileSync("./invoice.pdf");
2413
- * const { data } = await ecod.media.upload(buf, {
2479
+ * const { data } = await ecod.infra.storage.media.upload(buf, {
2414
2480
  * folder: "invoices",
2415
2481
  * filename: "invoice-001.pdf",
2416
2482
  * contentType: "application/pdf",
@@ -2420,7 +2486,7 @@ declare class Media extends APIResource {
2420
2486
  * @example Browser
2421
2487
  * ```typescript
2422
2488
  * const file = inputElement.files[0];
2423
- * const { data } = await ecod.media.upload(file, {
2489
+ * const { data } = await ecod.infra.storage.media.upload(file, {
2424
2490
  * folder: "avatars",
2425
2491
  * filename: file.name,
2426
2492
  * contentType: file.type,
@@ -2437,7 +2503,7 @@ declare class Folders extends APIResource {
2437
2503
  * @param name - The name of the folder to create.
2438
2504
  * @example
2439
2505
  * ```typescript
2440
- * await erixClient.storage.folders.create("Invoices");
2506
+ * await ecod.infra.storage.folders.create("Invoices");
2441
2507
  * ```
2442
2508
  */
2443
2509
  create<T = any>(name: string): Promise<T>;
@@ -2450,7 +2516,7 @@ declare class Files extends APIResource {
2450
2516
  * @param params - Optional year/month filters for organized storage.
2451
2517
  * @example
2452
2518
  * ```typescript
2453
- * const files = await erixClient.storage.files.list("Invoices", { year: "2026" });
2519
+ * const files = await ecod.infra.storage.files.list("Invoices", { year: "2026" });
2454
2520
  * ```
2455
2521
  */
2456
2522
  list<T = any>(folder: string, params?: {
@@ -2464,12 +2530,12 @@ declare class Files extends APIResource {
2464
2530
  * @param params - Upload parameters (folder, filename, contentType).
2465
2531
  * @example
2466
2532
  * ```typescript
2467
- * const { data } = await erixClient.storage.files.getUploadUrl({
2533
+ * const { data } = await ecod.infra.storage.files.getUploadUrl({
2468
2534
  * folder: "Invoices",
2469
2535
  * filename: "inv_1.pdf",
2470
2536
  * contentType: "application/pdf"
2471
2537
  * });
2472
- * // Now use data.url with a PUT request
2538
+ * // Now PUT the file to data.uploadUrl, then call confirmUpload({ key: data.key, sizeBytes })
2473
2539
  * ```
2474
2540
  */
2475
2541
  getUploadUrl<T = any>(params: {
@@ -2517,22 +2583,13 @@ declare class Health extends APIResource {
2517
2583
  }
2518
2584
 
2519
2585
  /**
2520
- * Automation event log and provider callback resource.
2521
- *
2522
- * Access via `ecod.notifications`.
2586
+ * In-app notifications (alerts) for the workspace.
2523
2587
  *
2524
- * This resource is **read-only**. It exposes platform audit trails — useful
2525
- * for debugging automation failures, monitoring webhook callbacks, and
2526
- * building internal ops dashboards.
2588
+ * Access via `ecod.platform.users.notifications`.
2527
2589
  *
2528
2590
  * @example
2529
2591
  * ```typescript
2530
- * // Find failed automations in April
2531
- * const { data } = await ecod.notifications.listLogs({
2532
- * status: "failed",
2533
- * startDate: "2026-04-01",
2534
- * endDate: "2026-04-30",
2535
- * });
2592
+ * const { data } = await ecod.platform.users.notifications.listAlerts({ unreadOnly: true });
2536
2593
  * ```
2537
2594
  */
2538
2595
  declare class Notifications extends APIResource {
@@ -2543,7 +2600,7 @@ declare class Notifications extends APIResource {
2543
2600
  * @returns Paginated list of notification objects.
2544
2601
  * @example
2545
2602
  * ```typescript
2546
- * const alerts = await erixClient.notifications.listAlerts({ unreadOnly: true });
2603
+ * const alerts = await ecod.platform.users.notifications.listAlerts({ unreadOnly: true });
2547
2604
  * ```
2548
2605
  */
2549
2606
  listAlerts<T = any>(params?: {
@@ -2556,7 +2613,7 @@ declare class Notifications extends APIResource {
2556
2613
  * @param notificationId - The unique ID of the notification.
2557
2614
  * @example
2558
2615
  * ```typescript
2559
- * await erixClient.notifications.dismissAlert("alert_123");
2616
+ * await ecod.platform.users.notifications.dismissAlert("alert_123");
2560
2617
  * ```
2561
2618
  */
2562
2619
  dismissAlert<T = any>(notificationId: string): Promise<T>;
@@ -2565,7 +2622,7 @@ declare class Notifications extends APIResource {
2565
2622
  *
2566
2623
  * @example
2567
2624
  * ```typescript
2568
- * await erixClient.notifications.clearAllAlerts();
2625
+ * await ecod.platform.users.notifications.clearAllAlerts();
2569
2626
  * ```
2570
2627
  */
2571
2628
  clearAllAlerts<T = any>(): Promise<T>;
@@ -3103,21 +3160,21 @@ interface EditOnboardingResponse {
3103
3160
  /**
3104
3161
  * Adaptive onboarding resource.
3105
3162
  *
3106
- * Mounted on the main client as `ecod.onboarding`. Mirrors the seven
3163
+ * Mounted on the main client as `ecod.platform.tenants.onboarding`. Mirrors the seven
3107
3164
  * tenant-facing routes documented in `design.md` § "API surface".
3108
3165
  *
3109
3166
  * @example
3110
3167
  * ```typescript
3111
- * await ecod.onboarding.global({
3168
+ * await ecod.platform.tenants.onboarding.global({
3112
3169
  * workspaceName: "Acme Health",
3113
3170
  * displayName: "Alice",
3114
3171
  * timezone: "Asia/Kolkata",
3115
3172
  * primaryProduct: "crm",
3116
3173
  * });
3117
3174
  *
3118
- * const { sessionId, firstStep } = await ecod.onboarding.start({ productId: "crm" });
3119
- * await ecod.onboarding.answer({ sessionId, stepId: firstStep.stepId, answer: "healthcare" });
3120
- * await ecod.onboarding.complete({ sessionId });
3175
+ * const { sessionId, firstStep } = await ecod.platform.tenants.onboarding.start({ productId: "crm" });
3176
+ * await ecod.platform.tenants.onboarding.answer({ sessionId, stepId: firstStep.stepId, answer: "healthcare" });
3177
+ * await ecod.platform.tenants.onboarding.complete({ sessionId });
3121
3178
  * ```
3122
3179
  */
3123
3180
  declare class Onboarding extends APIResource {
@@ -3672,14 +3729,14 @@ interface PersonaFollowupsResponse {
3672
3729
  /**
3673
3730
  * AI persona resource.
3674
3731
  *
3675
- * Mounted on the main client as `ecod.persona`. Reads the persona row,
3732
+ * Mounted on the main client as `ecod.platform.tenants.persona`. Reads the persona row,
3676
3733
  * accepts reinforcement events, and exposes the live confidence score.
3677
3734
  *
3678
3735
  * @example
3679
3736
  * ```typescript
3680
- * const persona = await ecod.persona.get("crm");
3737
+ * const persona = await ecod.platform.tenants.persona.get("crm");
3681
3738
  *
3682
- * await ecod.persona.reinforce({
3739
+ * await ecod.platform.tenants.persona.reinforce({
3683
3740
  * eventId: crypto.randomUUID(),
3684
3741
  * productId: "laie",
3685
3742
  * kind: "lead_approved",
@@ -3687,7 +3744,7 @@ interface PersonaFollowupsResponse {
3687
3744
  * signals: [{ signal: "funding_stage", value: "series_a" }],
3688
3745
  * });
3689
3746
  *
3690
- * const { score } = await ecod.persona.confidence("laie");
3747
+ * const { score } = await ecod.platform.tenants.persona.confidence("laie");
3691
3748
  * ```
3692
3749
  */
3693
3750
  declare class Persona extends APIResource {
@@ -3817,6 +3874,12 @@ interface KnowledgeSource {
3817
3874
  /** Why it failed, readable as-is. */
3818
3875
  error: string | null;
3819
3876
  chunkCount: number;
3877
+ /**
3878
+ * Ready, but some passages have no embedding yet (the provider refused
3879
+ * when it was read): found by keyword search only until the server's
3880
+ * automatic retry embeds them.
3881
+ */
3882
+ keywordOnly?: boolean;
3820
3883
  createdAt: string;
3821
3884
  updatedAt: string;
3822
3885
  }
@@ -3894,6 +3957,61 @@ interface AiAgentSettings {
3894
3957
  * connected but not yet allowed for Flow, so the agent can't answer there.
3895
3958
  */
3896
3959
  needsFlowGrant?: string[];
3960
+ /**
3961
+ * Read-only: whether the workspace's plan includes AI replies. `false` →
3962
+ * the agent never answers or drafts, even when switched on.
3963
+ */
3964
+ planAllows?: boolean;
3965
+ /**
3966
+ * Topics the AI never answers on its own — handed to a person instead:
3967
+ * preset ids that are on, plus the workspace's own keywords. `null` = never
3968
+ * chosen (every preset on). Send `null` to go back to that.
3969
+ */
3970
+ aiHumanTopics?: AiHumanTopics | null;
3971
+ /** Read-only: the always-human presets (refund, complaint, medical…). */
3972
+ humanTopicPresets?: {
3973
+ id: string;
3974
+ label: string;
3975
+ examples: string[];
3976
+ }[];
3977
+ /** Read-only: answer-review verdicts in the last 30 days. */
3978
+ reviewStats?: AiReviewStats | null;
3979
+ }
3980
+ /** Topics that always go to a person. */
3981
+ interface AiHumanTopics {
3982
+ presets: string[];
3983
+ keywords: string[];
3984
+ }
3985
+ /** Answer review, last 30 days. */
3986
+ interface AiReviewStats {
3987
+ reviewed: number;
3988
+ wrong: number;
3989
+ risky: number;
3990
+ /** Sampled, not reviewed yet. */
3991
+ waiting: number;
3992
+ }
3993
+ type AiReviewVerdict = "correct" | "wrong" | "risky";
3994
+ /** An AI reply sampled for the weekly answer review. */
3995
+ interface AiReviewItem {
3996
+ id: string;
3997
+ conversationId: string;
3998
+ /** What went out (auto-sent, or the draft as a person sent it). */
3999
+ text: string;
4000
+ /** `auto_sent` or `sent` (an approved draft). */
4001
+ status: string;
4002
+ confidence: number;
4003
+ /** How much a person edited the draft before sending (0 = as written). */
4004
+ editDistanceRatio: number | null;
4005
+ /** What auto-send decided on: grounded, chunks, tools, question… */
4006
+ grounding: unknown;
4007
+ sources: {
4008
+ sourceId: string;
4009
+ title: string;
4010
+ }[] | null;
4011
+ verdict: AiReviewVerdict | null;
4012
+ note: string | null;
4013
+ reviewedAt: string | null;
4014
+ createdAt: string;
3897
4015
  }
3898
4016
  /** An AI draft waiting for a person in the inbox (kept up to 7 days). */
3899
4017
  interface AiSuggestion {
@@ -3967,12 +4085,19 @@ interface PausedRun {
3967
4085
  recordsHeld: number | null;
3968
4086
  startedAt: string | null;
3969
4087
  createdAt: string;
4088
+ /** The held step; pass it to `decideRun` so a stale view can't decide another step. */
4089
+ nodeId?: string;
3970
4090
  /** Set when an AI agent step is held: what approving it runs. */
3971
4091
  pendingAction?: {
3972
4092
  action: string;
3973
4093
  label: string;
3974
4094
  input: Record<string, unknown>;
3975
4095
  };
4096
+ /** The held approval step's name and its "What to check" text. */
4097
+ stepName?: string;
4098
+ check?: string;
4099
+ /** Who the run is about: the contact's name, else their masked phone/email. */
4100
+ contact?: string;
3976
4101
  }
3977
4102
  /**
3978
4103
  * The AI agent: its settings and the drafts it leaves in the inbox. Drafts
@@ -3986,10 +4111,20 @@ declare class AiAgent extends APIResource {
3986
4111
  data: AiAgentSettings;
3987
4112
  }>;
3988
4113
  /** Change settings (workspace admins only). */
3989
- updateSettings(patch: Partial<Omit<AiAgentSettings, "availableTools">>): Promise<{
4114
+ updateSettings(patch: Partial<Omit<AiAgentSettings, "availableTools" | "humanTopicPresets" | "reviewStats">>): Promise<{
3990
4115
  success: boolean;
3991
4116
  data: AiAgentSettings;
3992
4117
  }>;
4118
+ /** Answer review: sampled AI replies (last 30 days), waiting first. */
4119
+ reviews(status?: "waiting" | "reviewed"): Promise<{
4120
+ success: boolean;
4121
+ data: AiReviewItem[];
4122
+ }>;
4123
+ /** Answer review: mark one reply Correct / Wrong / Risky (owners and admins). */
4124
+ review(id: string, verdict: AiReviewVerdict, note?: string): Promise<{
4125
+ success: boolean;
4126
+ data: Pick<AiReviewItem, "id" | "verdict" | "note" | "reviewedAt">;
4127
+ }>;
3993
4128
  /** The draft waiting on a conversation (`data: null` when none). */
3994
4129
  suggestion(conversationId: string): Promise<{
3995
4130
  success: boolean;
@@ -4035,7 +4170,7 @@ declare class AiAgent extends APIResource {
4035
4170
  data: ModuleAgentSettings;
4036
4171
  }>;
4037
4172
  /** Let a held run continue, or stop it. */
4038
- decideRun(runId: string, decision: "approve" | "reject"): Promise<{
4173
+ decideRun(runId: string, decision: "approve" | "reject", nodeId?: string): Promise<{
4039
4174
  success: boolean;
4040
4175
  decision: string;
4041
4176
  }>;
@@ -4522,7 +4657,7 @@ declare class PlatformDomain {
4522
4657
  * import { APIError, AuthenticationError, RateLimitError } from "@ecodrix/erix-api";
4523
4658
  *
4524
4659
  * try {
4525
- * await ecod.crm.leads.retrieve("invalid_id");
4660
+ * await ecod.product.erix.leads.retrieve("invalid_id");
4526
4661
  * } catch (err) {
4527
4662
  * if (err instanceof AuthenticationError) {
4528
4663
  * console.error("Invalid API key or client code.");
@@ -4551,10 +4686,19 @@ declare class APIError extends EcodrixError {
4551
4686
  }
4552
4687
  /**
4553
4688
  * Thrown when the API key or client code is missing, invalid, or expired.
4554
- * HTTP 401.
4689
+ * HTTP 401. `code` is the server's (e.g. `INVALID_KEY`) when it sends one.
4555
4690
  */
4556
4691
  declare class AuthenticationError extends APIError {
4557
- constructor(message?: string);
4692
+ constructor(message?: string, code?: string, status?: number);
4693
+ }
4694
+ /**
4695
+ * Thrown when the caller is signed in but not allowed: role, plan, or no
4696
+ * longer a member (`code` `FORBIDDEN`, `NOT_A_MEMBER`, …). HTTP 403. Extends
4697
+ * AuthenticationError so existing 401/403 handling keeps working; check
4698
+ * `status` or `code` to tell a dead key from a missing permission.
4699
+ */
4700
+ declare class PermissionError extends AuthenticationError {
4701
+ constructor(message?: string, code?: string);
4558
4702
  }
4559
4703
  /**
4560
4704
  * Thrown when the rate limit for the API key has been exceeded.
@@ -4563,7 +4707,16 @@ declare class AuthenticationError extends APIError {
4563
4707
  declare class RateLimitError extends APIError {
4564
4708
  constructor(message?: string);
4565
4709
  }
4710
+ /**
4711
+ * Turn an HTTP client error into the typed SDK error: 401 → AuthenticationError,
4712
+ * 403 → PermissionError, 429 → RateLimitError, else APIError. Keeps the
4713
+ * server's status and code (sent in `code`, or in `error` as UPPER_SNAKE).
4714
+ */
4715
+ declare function toAPIError(error: any): APIError;
4566
4716
 
4717
+ declare class WebhookSignatureError extends APIError {
4718
+ constructor(message: string);
4719
+ }
4567
4720
  /**
4568
4721
  * Validates and constructs webhook events sent by the ECODrIx platform.
4569
4722
  * Ensures the payload has not been tampered with.
@@ -4618,7 +4771,7 @@ interface ECODrIxAPIOptions {
4618
4771
  /**
4619
4772
  * Your tenant ID (Client Code).
4620
4773
  * This scopes all API requests to your specific organisation.
4621
- * @example "ERIX_CLNT_JHBJHF"
4774
+ * @example "ERIX_CLNT_XXXXXX"
4622
4775
  */
4623
4776
  clientCode?: string;
4624
4777
  /**
@@ -4685,7 +4838,7 @@ interface ECODrIxAPIOptions {
4685
4838
  *
4686
4839
  * const ecod = new ECODrIxAPI({
4687
4840
  * apiKey: process.env.ECOD_API_KEY!,
4688
- * clientCode: "ERIX_CLNT_JHBJHF",
4841
+ * clientCode: "ERIX_CLNT_XXXXXX",
4689
4842
  * });
4690
4843
  *
4691
4844
  * await ecod.product.erix.chat.messages.send({ to: "+91...", text: "Hello!" });
@@ -4701,6 +4854,8 @@ declare class ECODrIxAPI {
4701
4854
  * @internal Socket.io client for real-time events.
4702
4855
  */
4703
4856
  private socket;
4857
+ /** Opens the realtime socket; set by the constructor, called on first use. */
4858
+ private startSocket;
4704
4859
  private socketPromise;
4705
4860
  private socketQueue;
4706
4861
  /**
@@ -4780,8 +4935,8 @@ declare class ECODrIxAPI {
4780
4935
  * @example
4781
4936
  * ```typescript
4782
4937
  * ecod
4783
- * .on("whatsapp.message_received", (msg) => console.log(msg.body))
4784
- * .on("automation.failed", (err) => alertTeam(err));
4938
+ * .on("inbox.message", ({ conversationId, message }) => console.log(conversationId, message.text))
4939
+ * .on("resync", () => refetchEverything());
4785
4940
  * ```
4786
4941
  */
4787
4942
  on(event: string, callback: (...args: any[]) => void): this;
@@ -4817,7 +4972,12 @@ declare class ECODrIxAPI {
4817
4972
  *
4818
4973
  * @example
4819
4974
  * ```typescript
4820
- * const { data } = await ecod.request("POST", "/api/saas/experimental-feature", { flag: true });
4975
+ * // Paths are relative to `<host>/<version>/api`.
4976
+ * const { data } = await ecod.request("POST", "/infra/connect/send/email", {
4977
+ * to: "customer@example.com",
4978
+ * subject: "Your order",
4979
+ * html: "<p>Thanks!</p>",
4980
+ * });
4821
4981
  * console.log(data);
4822
4982
  * ```
4823
4983
  */
@@ -5065,7 +5225,7 @@ interface CustomFieldFilter {
5065
5225
  * HTTP status code to exception type mapping
5066
5226
  * Maps specific HTTP status codes to appropriate typed exceptions
5067
5227
  */
5068
- declare const HTTP_STATUS_ERROR_MAP: Record<number, typeof APIError>;
5228
+ declare const HTTP_STATUS_ERROR_MAP: Record<number, abstract new (...args: any[]) => APIError>;
5069
5229
  /**
5070
5230
  * Enhanced error handler that maps HTTP status codes to typed exceptions
5071
5231
  *
@@ -5092,7 +5252,7 @@ declare function handleAPIError(error: any): never;
5092
5252
  * @example
5093
5253
  * ```typescript
5094
5254
  * try {
5095
- * await ecod.crm.leads.create(leadData);
5255
+ * await ecod.product.erix.leads.create(leadData);
5096
5256
  * } catch (error) {
5097
5257
  * if (isAPIError(error, AuthenticationError)) {
5098
5258
  * console.log('Authentication failed - check your API key');
@@ -5112,7 +5272,7 @@ declare function isAPIError(error: any, errorType: typeof APIError): boolean;
5112
5272
  * @example
5113
5273
  * ```typescript
5114
5274
  * try {
5115
- * await ecod.crm.leads.get('invalid_id');
5275
+ * await ecod.product.erix.leads.retrieve('invalid_id');
5116
5276
  * } catch (error) {
5117
5277
  * const details = getErrorDetails(error);
5118
5278
  * console.log(`Error ${details.status}: ${details.message} (${details.code})`);
@@ -5158,7 +5318,7 @@ declare const ERROR_RETRY_CONFIG: {
5158
5318
  * @example
5159
5319
  * ```typescript
5160
5320
  * try {
5161
- * await ecod.crm.leads.list();
5321
+ * await ecod.product.erix.leads.list();
5162
5322
  * } catch (error) {
5163
5323
  * const retryConfig = getRetryConfig(error);
5164
5324
  * if (retryConfig.shouldRetry) {
@@ -5188,4 +5348,4 @@ declare function getRetryConfig(error: any): {
5188
5348
  readonly reason: "Generic API errors may be transient and worth retrying";
5189
5349
  };
5190
5350
 
5191
- export { type AIPersona, APIError, APIResource, type AgentAutonomy, type AgentBudget, AiAgent, type AiAgentSettings, type AiAgentTool, type AiSuggestion, type AnswerFollowupBody, type AnswerOnboardingPayload, type AnswerOnboardingResponse, type ApplyCouponPayload, AuthenticationError, type BehaviorRules, type CheckboxConfig, type CheckoutAmountBreakdown, type CheckoutOrderResponse, type CheckoutProduct, type CheckoutSession, type ColorRule, type ColumnConfig, type CompleteOnboardingPayload, type CompleteOnboardingResponse, type ConfidenceResponse, ConnectInfra, type Conversation, type ListParams as ConversationListParams, type Correction, type CreateLeadParams, type CreateOrderPayload, type CreatePipelineParams, type CreateSessionPayload, type CrmView, type CurrencyConfig, type CurrencyValue, type CustomFieldFilter, type DateConfig, type DateTimeConfig, type DropdownConfig, ECODrIxAPI as ECODrIx, ECODrIxAPI, type ECODrIxAPIOptions, ERROR_RETRY_CONFIG, EcodrixError, type EditOnboardingPayload, type EditOnboardingResponse, type EmailConfig, EmailConnect, ErixChat, ErixProduct, type FieldConfig, type FieldDefinition, type FieldManifest, type FieldType, type FileConfig, type FilterOperator, type FilterRule, type FormulaConfig, type GlobalOnboardingPayload, HTTP_STATUS_ERROR_MAP, type ICP, type InboxChannel, InfraDomain, KNOWLEDGE_FILE_TYPES, Knowledge, type KnowledgePassage, type KnowledgeSource, LEAD_STATUS_VALUES, type LayoutType, type Lead, type LeadPattern, type LeadSource, type LeadStatus, type LearningMemory, type ListLeadsParams, type ManifestFieldType, type MappingField, type MappingPreviewResult, type MappingSources, type MappingValidationResult, type Message, type ModuleAgent, type ModuleAgentPatch, type ModuleAgentSettings, type ModuleAgentTool, type NichePack, type NichePackResearchConfig, type NichePackStatus, type NormalizedFieldValue, type NumberConfig, Onboarding, type OnboardingCohortRange, type OnboardingConfig, type OnboardingExperiment, type OnboardingExperimentStatus, type OnboardingExperimentVariant, type OnboardingMemoryMapping, type OnboardingOption, type OnboardingSession, type OnboardingSessionStatus, type OnboardingStateResponse, type OnboardingStep, type OnboardingStepType, type OutboundMedia, type OutreachEdit, type PaginatedResponse, type PausedRun, Persona, type PersonaFollowupQuestion, type PersonaFollowupsResponse, type PersonaIdentity, type PersonaTimelineEntry, type PersonaTimelineOptions, type PersonaTimelineResponse, type PhoneConfig, type Pipeline, type PipelineStage, type PipelineStageParams, PlatformDomain, PlatformTenants, PlatformUsers, ProductDomain, type ProgressConfig, RateLimitError, type RatingConfig, type ReinforceResponse, type ReinforcementEvent, type RelationConfig, type RelationValue, type RequestOptions, type ResourceManifest, type SendMessageParams, type SendTemplateParams, type ServiceConfig, type ServiceConfigGlobal, type ServiceConfigPerProduct, type SortRule, type StartOnboardingPayload, type StartOnboardingResponse, StorageInfra, type StoredFieldValue, type SuggestionEvent, type TagsConfig, type Template, type TemplateApiResponse, type TemplateBinding, type TemplateBindingSource, type TemplateComponent, type TemplateEmptyPolicy, type TemplateMapping, type TextConfig, type UpsertLeadParams, type UrlConfig, type VerifyPayload, type ViewConfig, type Vocabulary, WhatsAppConnect, type WorkspaceDashboardLayout, type WorkspaceDefaultAutomation, type WorkspaceDefaultField, type WorkspaceDefaultPipeline, type WorkspaceModuleConfig, type WorkspaceProfile, ECODrIxAPI as default, getErrorDetails, getRetryConfig, handleAPIError, isAPIError };
5351
+ export { type AIPersona, APIError, APIResource, type AgentAutonomy, type AgentBudget, AiAgent, type AiAgentSettings, type AiAgentTool, type AiHumanTopics, type AiReviewItem, type AiReviewStats, type AiReviewVerdict, type AiSuggestion, type AnswerFollowupBody, type AnswerOnboardingPayload, type AnswerOnboardingResponse, type ApplyCouponPayload, type AssignEventPayload, AuthenticationError, type BehaviorRules, type CheckboxConfig, type CheckoutAmountBreakdown, type CheckoutOrderResponse, type CheckoutProduct, type CheckoutSession, type ColorRule, type ColumnConfig, type CompleteOnboardingPayload, type CompleteOnboardingResponse, type ConfidenceResponse, ConnectInfra, type Conversation, type ListParams as ConversationListParams, type Correction, type CreateLeadParams, type CreateOrderPayload, type CreatePipelineParams, type CreateSessionPayload, type CrmView, type CurrencyConfig, type CurrencyValue, type CustomFieldFilter, type DateConfig, type DateTimeConfig, type DropdownConfig, ECODrIxAPI as ECODrIx, ECODrIxAPI, type ECODrIxAPIOptions, ERROR_RETRY_CONFIG, EcodrixError, type EditOnboardingPayload, type EditOnboardingResponse, type EmailConfig, EmailConnect, ErixChat, ErixProduct, type EventDefinition, type FieldConfig, type FieldDefinition, type FieldManifest, type FieldType, type FileConfig, type FilterOperator, type FilterRule, type FormulaConfig, type GlobalOnboardingPayload, HTTP_STATUS_ERROR_MAP, type ICP, type InboxChannel, InfraDomain, KNOWLEDGE_FILE_TYPES, Knowledge, type KnowledgePassage, type KnowledgeSource, LEAD_STATUS_VALUES, type LayoutType, type Lead, type LeadPattern, type LeadSource, type LeadStatus, type LearningMemory, type ListLeadsParams, type ManifestFieldType, type MappingField, type MappingPreviewResult, type MappingSources, type MappingValidationResult, type Message, type ModuleAgent, type ModuleAgentPatch, type ModuleAgentSettings, type ModuleAgentTool, type NichePack, type NichePackResearchConfig, type NichePackStatus, type NormalizedFieldValue, type NumberConfig, Onboarding, type OnboardingCohortRange, type OnboardingConfig, type OnboardingExperiment, type OnboardingExperimentStatus, type OnboardingExperimentVariant, type OnboardingMemoryMapping, type OnboardingOption, type OnboardingSession, type OnboardingSessionStatus, type OnboardingStateResponse, type OnboardingStep, type OnboardingStepType, type OutboundMedia, type OutreachEdit, type PaginatedResponse, type PausedRun, PermissionError, Persona, type PersonaFollowupQuestion, type PersonaFollowupsResponse, type PersonaIdentity, type PersonaTimelineEntry, type PersonaTimelineOptions, type PersonaTimelineResponse, type PhoneConfig, type Pipeline, type PipelineStage, type PipelineStageParams, PlatformDomain, PlatformTenants, PlatformUsers, ProductDomain, type ProgressConfig, RateLimitError, type RatingConfig, type ReinforceResponse, type ReinforcementEvent, type RelationConfig, type RelationValue, type RequestOptions, type ResourceManifest, type SendMessageParams, type SendTemplateParams, type ServiceConfig, type ServiceConfigGlobal, type ServiceConfigPerProduct, type SortRule, type StartOnboardingPayload, type StartOnboardingResponse, StorageInfra, type StoredFieldValue, type SuggestionEvent, type TagsConfig, type Template, type TemplateApiResponse, type TemplateBinding, type TemplateBindingSource, type TemplateComponent, type TemplateEmptyPolicy, type TemplateMapping, type TextConfig, type TriggerPayload, type TriggerResponse, type UpsertLeadParams, type UrlConfig, type VerifyPayload, type ViewConfig, type Vocabulary, WebhookSignatureError, Webhooks, WhatsAppConnect, type WorkspaceDashboardLayout, type WorkspaceDefaultAutomation, type WorkspaceDefaultField, type WorkspaceDefaultPipeline, type WorkspaceModuleConfig, type WorkspaceProfile, ECODrIxAPI as default, getErrorDetails, getRetryConfig, handleAPIError, isAPIError, toAPIError };