@vuevox/sdk 0.5.0 → 0.7.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
@@ -32,6 +32,8 @@ spaces:read
32
32
  agents:read
33
33
  calls:read
34
34
  leads:read
35
+ leads:write
36
+ lead_custom_fields:manage
35
37
  ```
36
38
 
37
39
  The token request can only request scopes that were granted to that API client.
@@ -105,7 +107,12 @@ vuevox.calls.get("call-id");
105
107
  vuevox.calls.paginate();
106
108
  vuevox.leads.list();
107
109
  vuevox.leads.get("lead-id");
110
+ vuevox.leads.update("lead-id", { customFields: { crm_stage: "qualified" } });
111
+ vuevox.leads.upsertByExternalId("crm-lead-id", { firstName: "Ada", lastName: "Lovelace" });
108
112
  vuevox.leads.paginate();
113
+ vuevox.leadCustomFields.list();
114
+ vuevox.leadCustomFields.create({ key: "crm_stage", label: "CRM Stage", type: "select", options: ["new", "qualified"] });
115
+ vuevox.leadCustomFields.update("crm_stage", { label: "CRM Stage" });
109
116
  vuevox.raw.GET("/v1/hello", { headers: { Authorization: `Bearer ${await vuevox.getAccessToken()}` } });
110
117
  ```
111
118
 
@@ -218,6 +225,8 @@ Returns: `AsyncGenerator<Space>`.
218
225
 
219
226
  Lists organization agents.
220
227
 
228
+ Agent records include nullable `externalId` when you store an ID from another system.
229
+
221
230
  Required scope: `agents:read`.
222
231
 
223
232
  Options: `ListAgentsOptions`
@@ -232,7 +241,7 @@ Options: `ListAgentsOptions`
232
241
  const response = await vuevox.agents.list({ limit: 50, spaceId: "space-id" });
233
242
 
234
243
  for (const agent of response.data.data) {
235
- console.log(agent.id, agent.name);
244
+ console.log(agent.id, agent.externalId, agent.name);
236
245
  }
237
246
  ```
238
247
 
@@ -248,7 +257,7 @@ Options: `ListAgentsOptions`
248
257
 
249
258
  ```ts
250
259
  for await (const agent of vuevox.agents.paginate({ spaceId: "space-id" })) {
251
- console.log(agent.id, agent.name);
260
+ console.log(agent.id, agent.externalId, agent.name);
252
261
  }
253
262
  ```
254
263
 
@@ -271,12 +280,16 @@ Options: `ListCallsOptions`
271
280
  | `agentId` | `string` | Optional agent ID filter. |
272
281
  | `createdAfter` | `string` | Optional ISO 8601 lower bound for call creation time. |
273
282
  | `createdBefore` | `string` | Optional ISO 8601 upper bound for call creation time. |
283
+ | `leadCustomFields` | `Record<string, CustomFieldFilterValue>` | Optional filters on lead custom fields attached to calls. |
274
284
 
275
285
  ```ts
276
286
  const response = await vuevox.calls.list({
277
287
  limit: 50,
278
288
  spaceId: "space-id",
279
289
  createdAfter: "2026-01-01T00:00:00.000Z",
290
+ leadCustomFields: {
291
+ crm_stage: "qualified",
292
+ },
280
293
  });
281
294
 
282
295
  for (const call of response.data.data) {
@@ -319,6 +332,8 @@ Returns: `AsyncGenerator<CallSummary>`.
319
332
 
320
333
  Lists organization leads. The `leads:read` scope includes lead email and phone contact details.
321
334
 
335
+ Lead records include nullable `externalId` when you store an ID from another system, and a `customFields` object for organization-defined CRM fields.
336
+
322
337
  Required scope: `leads:read`.
323
338
 
324
339
  Options: `ListLeadsOptions`
@@ -330,12 +345,20 @@ Options: `ListLeadsOptions`
330
345
  | `spaceId` | `string` | Optional space ID filter. |
331
346
  | `createdAfter` | `string` | Optional ISO 8601 lower bound for lead creation time. |
332
347
  | `createdBefore` | `string` | Optional ISO 8601 upper bound for lead creation time. |
348
+ | `customFields` | `Record<string, CustomFieldFilterValue>` | Optional filters on lead custom fields. |
333
349
 
334
350
  ```ts
335
- const response = await vuevox.leads.list({ limit: 50, spaceId: "space-id" });
351
+ const response = await vuevox.leads.list({
352
+ limit: 50,
353
+ spaceId: "space-id",
354
+ customFields: {
355
+ crm_stage: "qualified",
356
+ deal_value: { gte: 10000 },
357
+ },
358
+ });
336
359
 
337
360
  for (const lead of response.data.data) {
338
- console.log(lead.id, lead.email, lead.phone);
361
+ console.log(lead.id, lead.externalId, lead.email, lead.phone, lead.customFields);
339
362
  }
340
363
  ```
341
364
 
@@ -349,7 +372,53 @@ Required scope: `leads:read`.
349
372
 
350
373
  ```ts
351
374
  const response = await vuevox.leads.get("lead-id");
352
- console.log(response.data.email, response.data.phone);
375
+ console.log(response.data.data.externalId, response.data.data.email, response.data.data.phone, response.data.data.customFields);
376
+ ```
377
+
378
+ Returns: `Promise<VueVoxApiResponse<LeadDetailResponse>>`.
379
+
380
+ ### `vuevox.leads.update(leadId, input)`
381
+
382
+ Updates a lead and/or its custom fields.
383
+
384
+ Required scope: `leads:write`.
385
+
386
+ Input: `LeadUpdateRequest`
387
+
388
+ ```ts
389
+ const response = await vuevox.leads.update("lead-id", {
390
+ email: "ada@example.com",
391
+ customFields: {
392
+ crm_stage: "qualified",
393
+ renewal_date: "2026-09-01",
394
+ },
395
+ });
396
+
397
+ console.log(response.data.data.customFields);
398
+ ```
399
+
400
+ Returns: `Promise<VueVoxApiResponse<LeadDetailResponse>>`.
401
+
402
+ ### `vuevox.leads.upsertByExternalId(externalId, input)`
403
+
404
+ Creates or updates a lead by the integrating CRM/system ID. This is the preferred write method for CRM integrations because callers can use their own stable lead ID.
405
+
406
+ Required scope: `leads:write`.
407
+
408
+ Input: `LeadUpsertRequest`
409
+
410
+ ```ts
411
+ const response = await vuevox.leads.upsertByExternalId("hubspot_123", {
412
+ firstName: "Ada",
413
+ lastName: "Lovelace",
414
+ email: "ada@example.com",
415
+ customFields: {
416
+ crm_stage: "qualified",
417
+ deal_value: 12000,
418
+ },
419
+ });
420
+
421
+ console.log(response.data.data.id, response.data.data.customFields);
353
422
  ```
354
423
 
355
424
  Returns: `Promise<VueVoxApiResponse<LeadDetailResponse>>`.
@@ -364,12 +433,70 @@ Options: `ListLeadsOptions`
364
433
 
365
434
  ```ts
366
435
  for await (const lead of vuevox.leads.paginate({ createdAfter: "2026-01-01T00:00:00.000Z" })) {
367
- console.log(lead.id);
436
+ console.log(lead.id, lead.externalId);
368
437
  }
369
438
  ```
370
439
 
371
440
  Returns: `AsyncGenerator<Lead>`.
372
441
 
442
+ ### `vuevox.leadCustomFields.list(options?)`
443
+
444
+ Lists organization lead custom field definitions.
445
+
446
+ Required scope: `leads:read`.
447
+
448
+ Options: `ListLeadCustomFieldsOptions`
449
+
450
+ | Option | Type | Description |
451
+ | --- | --- | --- |
452
+ | `includeArchived` | `boolean` | Include archived definitions. Defaults to `false`. |
453
+
454
+ ```ts
455
+ const response = await vuevox.leadCustomFields.list();
456
+ console.log(response.data.data);
457
+ ```
458
+
459
+ Returns: `Promise<VueVoxApiResponse<LeadCustomFieldsListResponse>>`.
460
+
461
+ ### `vuevox.leadCustomFields.create(input)`
462
+
463
+ Creates a lead custom field definition. Supported types are `text`, `number`, `boolean`, `date`, `datetime`, `select`, and `multi_select`.
464
+
465
+ Required scope: `lead_custom_fields:manage`.
466
+
467
+ Input: `LeadCustomFieldCreateRequest`
468
+
469
+ ```ts
470
+ const response = await vuevox.leadCustomFields.create({
471
+ key: "crm_stage",
472
+ label: "CRM Stage",
473
+ type: "select",
474
+ options: ["new", "qualified", "customer"],
475
+ isFilterable: true,
476
+ });
477
+
478
+ console.log(response.data.data.key);
479
+ ```
480
+
481
+ Returns: `Promise<VueVoxApiResponse<LeadCustomFieldResponse>>`.
482
+
483
+ ### `vuevox.leadCustomFields.update(key, input)`
484
+
485
+ Updates mutable metadata for a lead custom field definition. Field keys and types are immutable.
486
+
487
+ Required scope: `lead_custom_fields:manage`.
488
+
489
+ Input: `LeadCustomFieldUpdateRequest`
490
+
491
+ ```ts
492
+ await vuevox.leadCustomFields.update("crm_stage", {
493
+ label: "CRM Pipeline Stage",
494
+ archived: false,
495
+ });
496
+ ```
497
+
498
+ Returns: `Promise<VueVoxApiResponse<LeadCustomFieldResponse>>`.
499
+
373
500
  ## Lower-Level Calls
374
501
 
375
502
  For advanced integrations, `raw` exposes a typed lower-level OpenAPI client. You must attach authorization yourself.
@@ -425,6 +552,8 @@ rate_limited
425
552
  invalid_request
426
553
  call_not_found
427
554
  lead_not_found
555
+ custom_field_not_found
556
+ custom_field_conflict
428
557
  ```
429
558
 
430
559
  ## Retries
@@ -481,12 +610,22 @@ import type {
481
610
  CallDetailResponse,
482
611
  CallsListResponse,
483
612
  CallSummary,
613
+ CustomFieldFilters,
614
+ CustomFieldFilterValue,
484
615
  HelloResponse,
485
616
  Lead,
617
+ LeadCustomField,
618
+ LeadCustomFieldCreateRequest,
619
+ LeadCustomFieldResponse,
620
+ LeadCustomFieldUpdateRequest,
621
+ LeadCustomFieldsListResponse,
486
622
  LeadDetailResponse,
623
+ LeadUpdateRequest,
624
+ LeadUpsertRequest,
487
625
  LeadsListResponse,
488
626
  ListAgentsOptions,
489
627
  ListCallsOptions,
628
+ ListLeadCustomFieldsOptions,
490
629
  ListLeadsOptions,
491
630
  ListSpacesOptions,
492
631
  Space,
package/dist/client.d.ts CHANGED
@@ -1,15 +1,33 @@
1
1
  import type { components, paths } from "./generated/schema.js";
2
- type HelloResponse = components["schemas"]["HelloResponse"];
3
- type SpacesListResponse = components["schemas"]["SpacesListResponse"];
4
- type AgentsListResponse = components["schemas"]["AgentsListResponse"];
5
- type CallsListResponse = components["schemas"]["CallsListResponse"];
6
- type CallDetailResponse = components["schemas"]["CallDetailResponse"];
7
- type LeadsListResponse = components["schemas"]["LeadsListResponse"];
8
- type LeadDetailResponse = components["schemas"]["LeadDetailResponse"];
9
- type Space = components["schemas"]["Space"];
10
- type Agent = components["schemas"]["Agent"];
11
- type CallSummary = components["schemas"]["CallSummary"];
12
- type Lead = components["schemas"]["Lead"];
2
+ export type HelloResponse = components["schemas"]["HelloResponse"];
3
+ export type SpacesListResponse = components["schemas"]["SpacesListResponse"];
4
+ export type AgentsListResponse = components["schemas"]["AgentsListResponse"];
5
+ export type CallsListResponse = components["schemas"]["CallsListResponse"];
6
+ export type CallDetailResponse = components["schemas"]["CallDetailResponse"];
7
+ export type LeadsListResponse = components["schemas"]["LeadsListResponse"];
8
+ export type LeadDetailResponse = components["schemas"]["LeadDetailResponse"];
9
+ export type LeadCustomFieldsListResponse = components["schemas"]["LeadCustomFieldsListResponse"];
10
+ export type LeadCustomFieldResponse = components["schemas"]["LeadCustomFieldResponse"];
11
+ export type LeadCustomFieldCreateRequest = components["schemas"]["LeadCustomFieldCreateRequest"];
12
+ export type LeadCustomFieldUpdateRequest = components["schemas"]["LeadCustomFieldUpdateRequest"];
13
+ export type LeadUpsertRequest = components["schemas"]["LeadUpsertRequest"];
14
+ export type LeadUpdateRequest = components["schemas"]["LeadUpdateRequest"];
15
+ export type Space = components["schemas"]["Space"];
16
+ export type Agent = components["schemas"]["Agent"];
17
+ export type CallSummary = components["schemas"]["CallSummary"];
18
+ export type Lead = components["schemas"]["Lead"];
19
+ export type LeadCustomField = components["schemas"]["LeadCustomField"];
20
+ export type CustomFieldFilterValue = string | number | boolean | {
21
+ eq?: string | number | boolean;
22
+ gt?: string | number;
23
+ gte?: string | number;
24
+ lt?: string | number;
25
+ lte?: string | number;
26
+ before?: string;
27
+ after?: string;
28
+ contains?: string;
29
+ };
30
+ export type CustomFieldFilters = Record<string, CustomFieldFilterValue>;
13
31
  export interface ListSpacesOptions {
14
32
  limit?: number;
15
33
  cursor?: string;
@@ -20,6 +38,7 @@ export interface ListCallsOptions extends ListSpacesOptions {
20
38
  agentId?: string;
21
39
  createdAfter?: string;
22
40
  createdBefore?: string;
41
+ leadCustomFields?: CustomFieldFilters;
23
42
  }
24
43
  export interface ListAgentsOptions extends ListSpacesOptions {
25
44
  spaceId?: string;
@@ -28,6 +47,10 @@ export interface ListLeadsOptions extends ListSpacesOptions {
28
47
  spaceId?: string;
29
48
  createdAfter?: string;
30
49
  createdBefore?: string;
50
+ customFields?: CustomFieldFilters;
51
+ }
52
+ export interface ListLeadCustomFieldsOptions {
53
+ includeArchived?: boolean;
31
54
  }
32
55
  export interface VueVoxResponseMetadata {
33
56
  requestId?: string;
@@ -71,6 +94,7 @@ export declare function createVueVoxClient(options: VueVoxClientOptions): {
71
94
  list: (listOptions?: ListAgentsOptions) => Promise<VueVoxApiResponse<AgentsListResponse>>;
72
95
  paginate: (listOptions?: ListAgentsOptions) => AsyncGenerator<{
73
96
  id: string;
97
+ externalId: string | null;
74
98
  name: string;
75
99
  spaces: components["schemas"]["ResourceSummary"][];
76
100
  createdAt: string;
@@ -84,7 +108,7 @@ export declare function createVueVoxClient(options: VueVoxClientOptions): {
84
108
  id: string;
85
109
  space: components["schemas"]["ResourceSummary"];
86
110
  lead: components["schemas"]["LeadSummary"];
87
- agent: components["schemas"]["ResourceSummary"];
111
+ agent: components["schemas"]["AgentSummary"];
88
112
  duration: number;
89
113
  score: number | null;
90
114
  sentiment: string | null;
@@ -97,17 +121,25 @@ export declare function createVueVoxClient(options: VueVoxClientOptions): {
97
121
  leads: {
98
122
  list: (listOptions?: ListLeadsOptions) => Promise<VueVoxApiResponse<LeadsListResponse>>;
99
123
  get: (leadId: string) => Promise<VueVoxApiResponse<LeadDetailResponse>>;
124
+ update: (leadId: string, input: LeadUpdateRequest) => Promise<VueVoxApiResponse<LeadDetailResponse>>;
125
+ upsertByExternalId: (externalId: string, input: LeadUpsertRequest) => Promise<VueVoxApiResponse<LeadDetailResponse>>;
100
126
  paginate: (listOptions?: ListLeadsOptions) => AsyncGenerator<{
101
127
  id: string;
128
+ externalId: string | null;
102
129
  firstName: string;
103
130
  lastName: string;
104
131
  email: string | null;
105
132
  phone: string | null;
133
+ customFields: components["schemas"]["CustomFields"];
106
134
  space: components["schemas"]["ResourceSummary"];
107
135
  createdAt: string;
108
136
  updatedAt: string;
109
137
  }, any, any>;
110
138
  };
139
+ leadCustomFields: {
140
+ list: (listOptions?: ListLeadCustomFieldsOptions) => Promise<VueVoxApiResponse<LeadCustomFieldsListResponse>>;
141
+ create: (input: LeadCustomFieldCreateRequest) => Promise<VueVoxApiResponse<LeadCustomFieldResponse>>;
142
+ update: (key: string, input: LeadCustomFieldUpdateRequest) => Promise<VueVoxApiResponse<LeadCustomFieldResponse>>;
143
+ };
111
144
  raw: import("openapi-fetch").Client<paths, `${string}/${string}`>;
112
145
  };
113
- export type { Agent, AgentsListResponse, CallDetailResponse, CallsListResponse, CallSummary, HelloResponse, Lead, LeadDetailResponse, LeadsListResponse, Space, SpacesListResponse };
package/dist/client.js CHANGED
@@ -52,6 +52,21 @@ export function createVueVoxClient(options) {
52
52
  async function getLead(leadId) {
53
53
  return apiGet(`/v1/leads/${encodeURIComponent(leadId)}`);
54
54
  }
55
+ async function updateLead(leadId, input) {
56
+ return apiJson("PATCH", `/v1/leads/${encodeURIComponent(leadId)}`, input);
57
+ }
58
+ async function upsertLeadByExternalId(externalId, input) {
59
+ return apiJson("PUT", `/v1/leads/by-external-id/${encodeURIComponent(externalId)}`, input);
60
+ }
61
+ async function listLeadCustomFields(listOptions = {}) {
62
+ return apiGet("/v1/lead-custom-fields", listOptions);
63
+ }
64
+ async function createLeadCustomField(input) {
65
+ return apiJson("POST", "/v1/lead-custom-fields", input);
66
+ }
67
+ async function updateLeadCustomField(key, input) {
68
+ return apiJson("PATCH", `/v1/lead-custom-fields/${encodeURIComponent(key)}`, input);
69
+ }
55
70
  async function apiGet(path, query) {
56
71
  const accessToken = await getAccessToken();
57
72
  const result = await requestJson("GET", path, {
@@ -63,6 +78,18 @@ export function createVueVoxClient(options) {
63
78
  });
64
79
  return withMetadata(result.data, result.response, result.requestId);
65
80
  }
81
+ async function apiJson(method, path, body) {
82
+ const accessToken = await getAccessToken();
83
+ const result = await requestJson(method, path, {
84
+ method,
85
+ headers: {
86
+ Authorization: `Bearer ${accessToken}`,
87
+ "Content-Type": "application/json",
88
+ },
89
+ body: JSON.stringify(body),
90
+ });
91
+ return withMetadata(result.data, result.response, result.requestId);
92
+ }
66
93
  async function requestJson(method, path, init) {
67
94
  for (let attempt = 0;; attempt++) {
68
95
  const response = await fetchFn(buildUrl(baseUrl, path, init.query), init);
@@ -76,7 +103,7 @@ export function createVueVoxClient(options) {
76
103
  }
77
104
  return { data: body, requestId, response };
78
105
  }
79
- if (attempt < retries && shouldRetry(response.status)) {
106
+ if (attempt < retries && (method === "GET" || path === "/oauth/token") && shouldRetry(response.status)) {
80
107
  await sleep(retryDelayMs(attempt, retryAfter));
81
108
  continue;
82
109
  }
@@ -111,8 +138,15 @@ export function createVueVoxClient(options) {
111
138
  leads: {
112
139
  list: listLeads,
113
140
  get: getLead,
141
+ update: updateLead,
142
+ upsertByExternalId: upsertLeadByExternalId,
114
143
  paginate: (listOptions = {}) => paginate(listLeads, listOptions),
115
144
  },
145
+ leadCustomFields: {
146
+ list: listLeadCustomFields,
147
+ create: createLeadCustomField,
148
+ update: updateLeadCustomField,
149
+ },
116
150
  raw,
117
151
  };
118
152
  }
@@ -127,12 +161,27 @@ function trimTrailingSlash(value) {
127
161
  }
128
162
  function buildUrl(baseUrl, path, query) {
129
163
  const url = new URL(`${baseUrl}${path}`);
130
- for (const [key, value] of Object.entries(query ?? {})) {
131
- if ((typeof value === "string" || typeof value === "number") && value !== "") {
132
- url.searchParams.set(key, String(value));
164
+ appendQueryParams(url.searchParams, query ?? {});
165
+ return url.toString();
166
+ }
167
+ function appendQueryParams(searchParams, query, prefix) {
168
+ for (const [rawKey, value] of Object.entries(query)) {
169
+ if (value === undefined || value === null || value === "") {
170
+ continue;
171
+ }
172
+ const key = queryKey(rawKey, prefix);
173
+ if (typeof value === "string" || typeof value === "number" || typeof value === "boolean") {
174
+ searchParams.set(key, String(value));
175
+ continue;
176
+ }
177
+ if (typeof value === "object" && !Array.isArray(value)) {
178
+ appendQueryParams(searchParams, value, key);
133
179
  }
134
180
  }
135
- return url.toString();
181
+ }
182
+ function queryKey(key, prefix) {
183
+ const publicKey = key === "customFields" ? "custom" : key === "leadCustomFields" ? "leadCustom" : key;
184
+ return prefix ? `${prefix}[${publicKey}]` : publicKey;
136
185
  }
137
186
  async function parseJson(response) {
138
187
  try {
@@ -161,9 +161,77 @@ export interface paths {
161
161
  delete?: never;
162
162
  options?: never;
163
163
  head?: never;
164
+ /**
165
+ * Update a lead
166
+ * @description Updates an organization-scoped lead and its custom fields.
167
+ */
168
+ patch: operations["updateLead"];
169
+ trace?: never;
170
+ };
171
+ "/v1/leads/by-external-id/{externalId}": {
172
+ parameters: {
173
+ query?: never;
174
+ header?: never;
175
+ path?: never;
176
+ cookie?: never;
177
+ };
178
+ get?: never;
179
+ /**
180
+ * Upsert a lead by external ID
181
+ * @description Creates or updates a lead identified by the CRM/system external ID.
182
+ */
183
+ put: operations["upsertLeadByExternalId"];
184
+ post?: never;
185
+ delete?: never;
186
+ options?: never;
187
+ head?: never;
164
188
  patch?: never;
165
189
  trace?: never;
166
190
  };
191
+ "/v1/lead-custom-fields": {
192
+ parameters: {
193
+ query?: never;
194
+ header?: never;
195
+ path?: never;
196
+ cookie?: never;
197
+ };
198
+ /**
199
+ * List lead custom field definitions
200
+ * @description Returns lead custom field definitions for the API client's organization.
201
+ */
202
+ get: operations["listLeadCustomFields"];
203
+ put?: never;
204
+ /**
205
+ * Create a lead custom field definition
206
+ * @description Creates a typed lead custom field definition for CRM integrations and platform filters.
207
+ */
208
+ post: operations["createLeadCustomField"];
209
+ delete?: never;
210
+ options?: never;
211
+ head?: never;
212
+ patch?: never;
213
+ trace?: never;
214
+ };
215
+ "/v1/lead-custom-fields/{key}": {
216
+ parameters: {
217
+ query?: never;
218
+ header?: never;
219
+ path?: never;
220
+ cookie?: never;
221
+ };
222
+ get?: never;
223
+ put?: never;
224
+ post?: never;
225
+ delete?: never;
226
+ options?: never;
227
+ head?: never;
228
+ /**
229
+ * Update a lead custom field definition
230
+ * @description Updates mutable metadata for a lead custom field definition. Keys and types are immutable.
231
+ */
232
+ patch: operations["updateLeadCustomField"];
233
+ trace?: never;
234
+ };
167
235
  }
168
236
  export type webhooks = Record<string, never>;
169
237
  export interface components {
@@ -175,7 +243,7 @@ export interface components {
175
243
  client_secret: string;
176
244
  /**
177
245
  * @description Space-separated scopes requested for the access token.
178
- * @example hello:read spaces:read agents:read calls:read leads:read
246
+ * @example hello:read spaces:read agents:read calls:read leads:read leads:write lead_custom_fields:manage
179
247
  */
180
248
  scope?: string;
181
249
  };
@@ -185,7 +253,7 @@ export interface components {
185
253
  token_type: "Bearer";
186
254
  /** @example 3600 */
187
255
  expires_in: number;
188
- /** @example hello:read spaces:read agents:read calls:read leads:read */
256
+ /** @example hello:read spaces:read agents:read calls:read leads:read leads:write lead_custom_fields:manage */
189
257
  scope: string;
190
258
  };
191
259
  HelloResponse: {
@@ -211,6 +279,8 @@ export interface components {
211
279
  Agent: {
212
280
  /** Format: uuid */
213
281
  id: string;
282
+ /** @description Optional ID from an external system. */
283
+ externalId: string | null;
214
284
  /** @example Morgan Agent */
215
285
  name: string;
216
286
  spaces: components["schemas"]["ResourceSummary"][];
@@ -231,15 +301,25 @@ export interface components {
231
301
  LeadSummary: {
232
302
  /** Format: uuid */
233
303
  id: string;
304
+ /** @description Optional ID from an external system. */
305
+ externalId: string | null;
234
306
  firstName: string;
235
307
  lastName: string;
308
+ customFields: components["schemas"]["CustomFields"];
309
+ } | null;
310
+ AgentSummary: {
311
+ /** Format: uuid */
312
+ id: string;
313
+ /** @description Optional ID from an external system. */
314
+ externalId: string | null;
315
+ name: string;
236
316
  } | null;
237
317
  CallSummary: {
238
318
  /** Format: uuid */
239
319
  id: string;
240
320
  space: components["schemas"]["ResourceSummary"];
241
321
  lead: components["schemas"]["LeadSummary"];
242
- agent: components["schemas"]["ResourceSummary"];
322
+ agent: components["schemas"]["AgentSummary"];
243
323
  /** @description Call duration in seconds. */
244
324
  duration: number;
245
325
  score: number | null;
@@ -280,11 +360,14 @@ export interface components {
280
360
  Lead: {
281
361
  /** Format: uuid */
282
362
  id: string;
363
+ /** @description Optional ID from an external system. */
364
+ externalId: string | null;
283
365
  firstName: string;
284
366
  lastName: string;
285
367
  /** Format: email */
286
368
  email: string | null;
287
369
  phone: string | null;
370
+ customFields: components["schemas"]["CustomFields"];
288
371
  space: components["schemas"]["ResourceSummary"];
289
372
  /** Format: date-time */
290
373
  createdAt: string;
@@ -298,6 +381,72 @@ export interface components {
298
381
  LeadDetailResponse: {
299
382
  data: components["schemas"]["Lead"];
300
383
  };
384
+ LeadUpsertRequest: {
385
+ firstName: string;
386
+ lastName: string;
387
+ /** Format: email */
388
+ email?: string | null;
389
+ phone?: string | null;
390
+ /** Format: uuid */
391
+ spaceId?: string | null;
392
+ customFields?: components["schemas"]["CustomFields"];
393
+ };
394
+ LeadUpdateRequest: {
395
+ firstName?: string;
396
+ lastName?: string;
397
+ /** Format: email */
398
+ email?: string | null;
399
+ phone?: string | null;
400
+ /** Format: uuid */
401
+ spaceId?: string | null;
402
+ customFields?: components["schemas"]["CustomFields"];
403
+ };
404
+ /** @description Lead custom field values keyed by custom field key. */
405
+ CustomFields: {
406
+ [key: string]: string | number | boolean | string[] | null;
407
+ };
408
+ /** @description Custom field filters keyed by custom field key. Scalar values use equality; objects specify one operator. */
409
+ CustomFieldFilters: {
410
+ [key: string]: string | number | boolean | {
411
+ [key: string]: string | number | boolean;
412
+ };
413
+ };
414
+ LeadCustomField: {
415
+ /** @example crm_stage */
416
+ key: string;
417
+ /** @example CRM Stage */
418
+ label: string;
419
+ /** @enum {string} */
420
+ type: "text" | "number" | "boolean" | "date" | "datetime" | "select" | "multi_select";
421
+ options: string[];
422
+ isFilterable: boolean;
423
+ archived: boolean;
424
+ /** Format: date-time */
425
+ createdAt: string;
426
+ /** Format: date-time */
427
+ updatedAt: string;
428
+ };
429
+ LeadCustomFieldsListResponse: {
430
+ data: components["schemas"]["LeadCustomField"][];
431
+ };
432
+ LeadCustomFieldResponse: {
433
+ data: components["schemas"]["LeadCustomField"];
434
+ };
435
+ LeadCustomFieldCreateRequest: {
436
+ key: string;
437
+ label: string;
438
+ /** @enum {string} */
439
+ type: "text" | "number" | "boolean" | "date" | "datetime" | "select" | "multi_select";
440
+ options?: string[];
441
+ /** @default true */
442
+ isFilterable: boolean;
443
+ };
444
+ LeadCustomFieldUpdateRequest: {
445
+ label?: string;
446
+ options?: string[];
447
+ isFilterable?: boolean;
448
+ archived?: boolean;
449
+ };
301
450
  CursorPagination: {
302
451
  /** @example 50 */
303
452
  limit: number;
@@ -580,6 +729,8 @@ export interface operations {
580
729
  createdAfter?: string;
581
730
  /** @description Return calls created at or before this timestamp. */
582
731
  createdBefore?: string;
732
+ /** @description Filter calls by lead custom fields. Use equality by default, or one operator such as gte, lte, contains, before, or after. */
733
+ leadCustom?: components["schemas"]["CustomFieldFilters"];
583
734
  };
584
735
  header?: never;
585
736
  path?: never;
@@ -714,6 +865,8 @@ export interface operations {
714
865
  createdAfter?: string;
715
866
  /** @description Return leads created at or before this timestamp. */
716
867
  createdBefore?: string;
868
+ /** @description Filter leads by custom fields. Use equality by default, or one operator such as gte, lte, contains, before, or after. */
869
+ custom?: components["schemas"]["CustomFieldFilters"];
717
870
  };
718
871
  header?: never;
719
872
  path?: never;
@@ -835,4 +988,294 @@ export interface operations {
835
988
  };
836
989
  };
837
990
  };
991
+ updateLead: {
992
+ parameters: {
993
+ query?: never;
994
+ header?: never;
995
+ path: {
996
+ /** @description Lead ID. */
997
+ leadId: string;
998
+ };
999
+ cookie?: never;
1000
+ };
1001
+ requestBody: {
1002
+ content: {
1003
+ "application/json": components["schemas"]["LeadUpdateRequest"];
1004
+ };
1005
+ };
1006
+ responses: {
1007
+ /** @description Lead updated. */
1008
+ 200: {
1009
+ headers: {
1010
+ [name: string]: unknown;
1011
+ };
1012
+ content: {
1013
+ "application/json": components["schemas"]["LeadDetailResponse"];
1014
+ };
1015
+ };
1016
+ /** @description Bearer token is missing, invalid, or expired. */
1017
+ 401: {
1018
+ headers: {
1019
+ [name: string]: unknown;
1020
+ };
1021
+ content: {
1022
+ "application/json": components["schemas"]["ErrorResponse"];
1023
+ };
1024
+ };
1025
+ /** @description Bearer token does not include the required scope. */
1026
+ 403: {
1027
+ headers: {
1028
+ [name: string]: unknown;
1029
+ };
1030
+ content: {
1031
+ "application/json": components["schemas"]["ErrorResponse"];
1032
+ };
1033
+ };
1034
+ /** @description Lead was not found in the API client's organization. */
1035
+ 404: {
1036
+ headers: {
1037
+ [name: string]: unknown;
1038
+ };
1039
+ content: {
1040
+ "application/json": components["schemas"]["ErrorResponse"];
1041
+ };
1042
+ };
1043
+ /** @description Request body failed validation. */
1044
+ 422: {
1045
+ headers: {
1046
+ [name: string]: unknown;
1047
+ };
1048
+ content: {
1049
+ "application/json": components["schemas"]["ErrorResponse"];
1050
+ };
1051
+ };
1052
+ };
1053
+ };
1054
+ upsertLeadByExternalId: {
1055
+ parameters: {
1056
+ query?: never;
1057
+ header?: never;
1058
+ path: {
1059
+ /** @description External lead ID from the integrating system. */
1060
+ externalId: string;
1061
+ };
1062
+ cookie?: never;
1063
+ };
1064
+ requestBody: {
1065
+ content: {
1066
+ "application/json": components["schemas"]["LeadUpsertRequest"];
1067
+ };
1068
+ };
1069
+ responses: {
1070
+ /** @description Existing lead updated. */
1071
+ 200: {
1072
+ headers: {
1073
+ [name: string]: unknown;
1074
+ };
1075
+ content: {
1076
+ "application/json": components["schemas"]["LeadDetailResponse"];
1077
+ };
1078
+ };
1079
+ /** @description New lead created. */
1080
+ 201: {
1081
+ headers: {
1082
+ [name: string]: unknown;
1083
+ };
1084
+ content: {
1085
+ "application/json": components["schemas"]["LeadDetailResponse"];
1086
+ };
1087
+ };
1088
+ /** @description Bearer token is missing, invalid, or expired. */
1089
+ 401: {
1090
+ headers: {
1091
+ [name: string]: unknown;
1092
+ };
1093
+ content: {
1094
+ "application/json": components["schemas"]["ErrorResponse"];
1095
+ };
1096
+ };
1097
+ /** @description Bearer token does not include the required scope. */
1098
+ 403: {
1099
+ headers: {
1100
+ [name: string]: unknown;
1101
+ };
1102
+ content: {
1103
+ "application/json": components["schemas"]["ErrorResponse"];
1104
+ };
1105
+ };
1106
+ /** @description Request body failed validation. */
1107
+ 422: {
1108
+ headers: {
1109
+ [name: string]: unknown;
1110
+ };
1111
+ content: {
1112
+ "application/json": components["schemas"]["ErrorResponse"];
1113
+ };
1114
+ };
1115
+ };
1116
+ };
1117
+ listLeadCustomFields: {
1118
+ parameters: {
1119
+ query?: {
1120
+ /** @description Include archived field definitions. */
1121
+ includeArchived?: boolean;
1122
+ };
1123
+ header?: never;
1124
+ path?: never;
1125
+ cookie?: never;
1126
+ };
1127
+ requestBody?: never;
1128
+ responses: {
1129
+ /** @description Lead custom field definitions. */
1130
+ 200: {
1131
+ headers: {
1132
+ [name: string]: unknown;
1133
+ };
1134
+ content: {
1135
+ "application/json": components["schemas"]["LeadCustomFieldsListResponse"];
1136
+ };
1137
+ };
1138
+ /** @description Bearer token is missing, invalid, or expired. */
1139
+ 401: {
1140
+ headers: {
1141
+ [name: string]: unknown;
1142
+ };
1143
+ content: {
1144
+ "application/json": components["schemas"]["ErrorResponse"];
1145
+ };
1146
+ };
1147
+ /** @description Bearer token does not include the required scope. */
1148
+ 403: {
1149
+ headers: {
1150
+ [name: string]: unknown;
1151
+ };
1152
+ content: {
1153
+ "application/json": components["schemas"]["ErrorResponse"];
1154
+ };
1155
+ };
1156
+ };
1157
+ };
1158
+ createLeadCustomField: {
1159
+ parameters: {
1160
+ query?: never;
1161
+ header?: never;
1162
+ path?: never;
1163
+ cookie?: never;
1164
+ };
1165
+ requestBody: {
1166
+ content: {
1167
+ "application/json": components["schemas"]["LeadCustomFieldCreateRequest"];
1168
+ };
1169
+ };
1170
+ responses: {
1171
+ /** @description Lead custom field created. */
1172
+ 201: {
1173
+ headers: {
1174
+ [name: string]: unknown;
1175
+ };
1176
+ content: {
1177
+ "application/json": components["schemas"]["LeadCustomFieldResponse"];
1178
+ };
1179
+ };
1180
+ /** @description Bearer token is missing, invalid, or expired. */
1181
+ 401: {
1182
+ headers: {
1183
+ [name: string]: unknown;
1184
+ };
1185
+ content: {
1186
+ "application/json": components["schemas"]["ErrorResponse"];
1187
+ };
1188
+ };
1189
+ /** @description Bearer token does not include the required scope. */
1190
+ 403: {
1191
+ headers: {
1192
+ [name: string]: unknown;
1193
+ };
1194
+ content: {
1195
+ "application/json": components["schemas"]["ErrorResponse"];
1196
+ };
1197
+ };
1198
+ /** @description A custom field with this key already exists. */
1199
+ 409: {
1200
+ headers: {
1201
+ [name: string]: unknown;
1202
+ };
1203
+ content: {
1204
+ "application/json": components["schemas"]["ErrorResponse"];
1205
+ };
1206
+ };
1207
+ /** @description Request body failed validation. */
1208
+ 422: {
1209
+ headers: {
1210
+ [name: string]: unknown;
1211
+ };
1212
+ content: {
1213
+ "application/json": components["schemas"]["ErrorResponse"];
1214
+ };
1215
+ };
1216
+ };
1217
+ };
1218
+ updateLeadCustomField: {
1219
+ parameters: {
1220
+ query?: never;
1221
+ header?: never;
1222
+ path: {
1223
+ /** @description Custom field key. */
1224
+ key: string;
1225
+ };
1226
+ cookie?: never;
1227
+ };
1228
+ requestBody: {
1229
+ content: {
1230
+ "application/json": components["schemas"]["LeadCustomFieldUpdateRequest"];
1231
+ };
1232
+ };
1233
+ responses: {
1234
+ /** @description Lead custom field updated. */
1235
+ 200: {
1236
+ headers: {
1237
+ [name: string]: unknown;
1238
+ };
1239
+ content: {
1240
+ "application/json": components["schemas"]["LeadCustomFieldResponse"];
1241
+ };
1242
+ };
1243
+ /** @description Bearer token is missing, invalid, or expired. */
1244
+ 401: {
1245
+ headers: {
1246
+ [name: string]: unknown;
1247
+ };
1248
+ content: {
1249
+ "application/json": components["schemas"]["ErrorResponse"];
1250
+ };
1251
+ };
1252
+ /** @description Bearer token does not include the required scope. */
1253
+ 403: {
1254
+ headers: {
1255
+ [name: string]: unknown;
1256
+ };
1257
+ content: {
1258
+ "application/json": components["schemas"]["ErrorResponse"];
1259
+ };
1260
+ };
1261
+ /** @description Custom field was not found in the API client's organization. */
1262
+ 404: {
1263
+ headers: {
1264
+ [name: string]: unknown;
1265
+ };
1266
+ content: {
1267
+ "application/json": components["schemas"]["ErrorResponse"];
1268
+ };
1269
+ };
1270
+ /** @description Request body failed validation. */
1271
+ 422: {
1272
+ headers: {
1273
+ [name: string]: unknown;
1274
+ };
1275
+ content: {
1276
+ "application/json": components["schemas"]["ErrorResponse"];
1277
+ };
1278
+ };
1279
+ };
1280
+ };
838
1281
  }
package/dist/index.d.ts CHANGED
@@ -1,4 +1,4 @@
1
1
  export { createVueVoxClient } from "./client.js";
2
- export type { Agent, AgentsListResponse, CallDetailResponse, CallsListResponse, CallSummary, HelloResponse, Lead, LeadDetailResponse, LeadsListResponse, ListAgentsOptions, ListCallsOptions, ListLeadsOptions, ListSpacesOptions, Space, SpacesListResponse, VueVoxApiResponse, VueVoxClientOptions, VueVoxResponseEvent, VueVoxResponseMetadata, } from "./client.js";
2
+ export type { Agent, AgentsListResponse, CallDetailResponse, CallsListResponse, CallSummary, CustomFieldFilters, CustomFieldFilterValue, HelloResponse, Lead, LeadCustomField, LeadCustomFieldCreateRequest, LeadCustomFieldResponse, LeadCustomFieldUpdateRequest, LeadCustomFieldsListResponse, LeadDetailResponse, LeadUpdateRequest, LeadUpsertRequest, LeadsListResponse, ListAgentsOptions, ListCallsOptions, ListLeadCustomFieldsOptions, ListLeadsOptions, ListSpacesOptions, Space, SpacesListResponse, VueVoxApiResponse, VueVoxClientOptions, VueVoxResponseEvent, VueVoxResponseMetadata, } from "./client.js";
3
3
  export { VueVoxApiError } from "./errors.js";
4
4
  export type { VueVoxErrorResponse } from "./errors.js";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vuevox/sdk",
3
- "version": "0.5.0",
3
+ "version": "0.7.0",
4
4
  "description": "TypeScript SDK for the VueVox Developer API.",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",