@vuevox/sdk 0.8.0 → 0.9.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
@@ -35,6 +35,8 @@ calls:write
35
35
  leads:read
36
36
  leads:write
37
37
  lead_custom_fields:manage
38
+ webhooks:read
39
+ webhooks:write
38
40
  ```
39
41
 
40
42
  The token request can only request scopes that were granted to that API client.
@@ -117,6 +119,12 @@ vuevox.leads.paginate();
117
119
  vuevox.leadCustomFields.list();
118
120
  vuevox.leadCustomFields.create({ key: "crm_stage", label: "CRM Stage", type: "select", options: ["new", "qualified"] });
119
121
  vuevox.leadCustomFields.update("crm_stage", { label: "CRM Stage" });
122
+ vuevox.webhooks.endpoints.list();
123
+ vuevox.webhooks.endpoints.create({ url: "https://example.com/vuevox/webhooks", events: ["analysis.completed", "analysis.failed"] });
124
+ vuevox.webhooks.endpoints.update("endpoint-id", { isActive: false });
125
+ vuevox.webhooks.endpoints.rotateSecret("endpoint-id");
126
+ vuevox.webhooks.endpoints.test("endpoint-id");
127
+ vuevox.webhooks.endpoints.delete("endpoint-id");
120
128
  vuevox.raw.GET("/v1/hello", { headers: { Authorization: `Bearer ${await vuevox.getAccessToken()}` } });
121
129
  ```
122
130
 
@@ -164,7 +172,7 @@ for await (const call of vuevox.calls.paginate({ limit: 50 })) {
164
172
  }
165
173
  ```
166
174
 
167
- Pagination helpers are available for `spaces`, `agents`, `calls`, and `leads`.
175
+ Pagination helpers are available for `spaces`, `agents`, `calls`, `leads`, and `webhooks.endpoints`.
168
176
 
169
177
  ## Methods
170
178
 
@@ -601,6 +609,126 @@ await vuevox.leadCustomFields.update("crm_stage", {
601
609
 
602
610
  Returns: `Promise<VueVoxApiResponse<LeadCustomFieldResponse>>`.
603
611
 
612
+ ### `vuevox.webhooks.endpoints.list(options?)`
613
+
614
+ Lists webhook endpoints for the authenticated API client.
615
+
616
+ Required scope: `webhooks:read`.
617
+
618
+ Options: `ListWebhookEndpointsOptions`
619
+
620
+ ```ts
621
+ const response = await vuevox.webhooks.endpoints.list({ limit: 50 });
622
+ console.log(response.data.data);
623
+ ```
624
+
625
+ Returns: `Promise<VueVoxApiResponse<WebhookEndpointsListResponse>>`.
626
+
627
+ ### `vuevox.webhooks.endpoints.create(input)`
628
+
629
+ Creates a webhook endpoint. The signing secret is returned only once in this response.
630
+
631
+ Required scope: `webhooks:write`.
632
+
633
+ Input: `WebhookEndpointCreateRequest`
634
+
635
+ ```ts
636
+ const response = await vuevox.webhooks.endpoints.create({
637
+ url: "https://example.com/vuevox/webhooks",
638
+ events: ["analysis.completed", "analysis.failed"],
639
+ });
640
+
641
+ console.log(response.data.data.id, response.data.data.secret);
642
+ ```
643
+
644
+ Returns: `Promise<VueVoxApiResponse<WebhookEndpointSecretResponse>>`.
645
+
646
+ ### `vuevox.webhooks.endpoints.update(endpointId, input)`
647
+
648
+ Updates a webhook endpoint URL, event subscriptions, or active state.
649
+
650
+ Required scope: `webhooks:write`.
651
+
652
+ Input: `WebhookEndpointUpdateRequest`
653
+
654
+ ```ts
655
+ const response = await vuevox.webhooks.endpoints.update("endpoint-id", {
656
+ events: ["analysis.completed"],
657
+ isActive: true,
658
+ });
659
+ ```
660
+
661
+ Returns: `Promise<VueVoxApiResponse<WebhookEndpointResponse>>`.
662
+
663
+ ### `vuevox.webhooks.endpoints.delete(endpointId)`
664
+
665
+ Deletes a webhook endpoint.
666
+
667
+ Required scope: `webhooks:write`.
668
+
669
+ ```ts
670
+ await vuevox.webhooks.endpoints.delete("endpoint-id");
671
+ ```
672
+
673
+ Returns: `Promise<VueVoxApiResponse<null>>`.
674
+
675
+ ### `vuevox.webhooks.endpoints.rotateSecret(endpointId)`
676
+
677
+ Rotates the endpoint signing secret. The new secret is returned only once.
678
+
679
+ Required scope: `webhooks:write`.
680
+
681
+ ```ts
682
+ const response = await vuevox.webhooks.endpoints.rotateSecret("endpoint-id");
683
+ console.log(response.data.data.secret);
684
+ ```
685
+
686
+ Returns: `Promise<VueVoxApiResponse<WebhookEndpointSecretResponse>>`.
687
+
688
+ ### `vuevox.webhooks.endpoints.test(endpointId)`
689
+
690
+ Queues a `webhook.test` delivery to validate endpoint reachability and signature verification.
691
+
692
+ Required scope: `webhooks:write`.
693
+
694
+ ```ts
695
+ const response = await vuevox.webhooks.endpoints.test("endpoint-id");
696
+ console.log(response.data.data.eventType, response.data.data.status);
697
+ ```
698
+
699
+ Returns: `Promise<VueVoxApiResponse<WebhookTestResponse>>`.
700
+
701
+ ### `vuevox.webhooks.endpoints.paginate(options?)`
702
+
703
+ Iterates webhook endpoints across all pages.
704
+
705
+ Required scope: `webhooks:read`.
706
+
707
+ ```ts
708
+ for await (const endpoint of vuevox.webhooks.endpoints.paginate({ limit: 50 })) {
709
+ console.log(endpoint.id, endpoint.events);
710
+ }
711
+ ```
712
+
713
+ Returns: `AsyncGenerator<WebhookEndpoint>`.
714
+
715
+ ### `verifyVueVoxWebhookSignature(input)`
716
+
717
+ Verifies a webhook HMAC signature. Pass the raw request body string exactly as received.
718
+
719
+ ```ts
720
+ import { verifyVueVoxWebhookSignature } from "@vuevox/sdk";
721
+
722
+ const valid = await verifyVueVoxWebhookSignature({
723
+ body: rawBody,
724
+ secret: process.env.VUEVOX_WEBHOOK_SECRET!,
725
+ signature: request.headers.get("VueVox-Signature") ?? "",
726
+ timestamp: request.headers.get("VueVox-Timestamp") ?? "",
727
+ });
728
+ ```
729
+
730
+ Returns: `Promise<boolean>`.
731
+
604
732
  ## Lower-Level Calls
605
733
 
606
734
  For advanced integrations, `raw` exposes a typed lower-level OpenAPI client. You must attach authorization yourself.
@@ -742,15 +870,25 @@ import type {
742
870
  ListLeadCustomFieldsOptions,
743
871
  ListLeadsOptions,
744
872
  ListSpacesOptions,
873
+ ListWebhookEndpointsOptions,
745
874
  Space,
746
875
  SpacesListResponse,
747
876
  UploadCallInput,
877
+ VerifyWebhookSignatureInput,
748
878
  VueVoxApiResponse,
749
879
  VueVoxClientOptions,
750
880
  VueVoxErrorResponse,
751
881
  VueVoxResponseEvent,
752
882
  VueVoxResponseMetadata,
753
883
  WaitForAnalysisOptions,
884
+ WebhookEndpoint,
885
+ WebhookEndpointCreateRequest,
886
+ WebhookEndpointResponse,
887
+ WebhookEndpointSecretResponse,
888
+ WebhookEndpointUpdateRequest,
889
+ WebhookEndpointsListResponse,
890
+ WebhookEventPayload,
891
+ WebhookTestResponse,
754
892
  } from "@vuevox/sdk";
755
893
  ```
756
894
 
package/dist/client.d.ts CHANGED
@@ -12,6 +12,14 @@ export type LeadCustomFieldsListResponse = components["schemas"]["LeadCustomFiel
12
12
  export type LeadCustomFieldResponse = components["schemas"]["LeadCustomFieldResponse"];
13
13
  export type LeadCustomFieldCreateRequest = components["schemas"]["LeadCustomFieldCreateRequest"];
14
14
  export type LeadCustomFieldUpdateRequest = components["schemas"]["LeadCustomFieldUpdateRequest"];
15
+ export type WebhookEndpoint = components["schemas"]["WebhookEndpoint"];
16
+ export type WebhookEndpointCreateRequest = components["schemas"]["WebhookEndpointCreateRequest"];
17
+ export type WebhookEndpointUpdateRequest = components["schemas"]["WebhookEndpointUpdateRequest"];
18
+ export type WebhookEndpointResponse = components["schemas"]["WebhookEndpointResponse"];
19
+ export type WebhookEndpointSecretResponse = components["schemas"]["WebhookEndpointSecretResponse"];
20
+ export type WebhookEndpointsListResponse = components["schemas"]["WebhookEndpointsListResponse"];
21
+ export type WebhookTestResponse = components["schemas"]["WebhookTestResponse"];
22
+ export type WebhookEventPayload = components["schemas"]["WebhookEventPayload"];
15
23
  export type LeadUpsertRequest = components["schemas"]["LeadUpsertRequest"];
16
24
  export type LeadUpdateRequest = components["schemas"]["LeadUpdateRequest"];
17
25
  export type Space = components["schemas"]["Space"];
@@ -65,6 +73,16 @@ export interface ListLeadsOptions extends ListSpacesOptions {
65
73
  export interface ListLeadCustomFieldsOptions {
66
74
  includeArchived?: boolean;
67
75
  }
76
+ export interface ListWebhookEndpointsOptions extends ListSpacesOptions {
77
+ }
78
+ export interface VerifyWebhookSignatureInput {
79
+ body: string;
80
+ secret: string;
81
+ signature: string;
82
+ timestamp: string;
83
+ toleranceSeconds?: number;
84
+ now?: number;
85
+ }
68
86
  export interface VueVoxResponseMetadata {
69
87
  requestId?: string;
70
88
  status: number;
@@ -158,5 +176,25 @@ export declare function createVueVoxClient(options: VueVoxClientOptions): {
158
176
  create: (input: LeadCustomFieldCreateRequest) => Promise<VueVoxApiResponse<LeadCustomFieldResponse>>;
159
177
  update: (key: string, input: LeadCustomFieldUpdateRequest) => Promise<VueVoxApiResponse<LeadCustomFieldResponse>>;
160
178
  };
179
+ webhooks: {
180
+ endpoints: {
181
+ list: (listOptions?: ListWebhookEndpointsOptions) => Promise<VueVoxApiResponse<WebhookEndpointsListResponse>>;
182
+ create: (input: WebhookEndpointCreateRequest) => Promise<VueVoxApiResponse<WebhookEndpointSecretResponse>>;
183
+ update: (endpointId: string, input: WebhookEndpointUpdateRequest) => Promise<VueVoxApiResponse<WebhookEndpointResponse>>;
184
+ delete: (endpointId: string) => Promise<VueVoxApiResponse<null>>;
185
+ rotateSecret: (endpointId: string) => Promise<VueVoxApiResponse<WebhookEndpointSecretResponse>>;
186
+ test: (endpointId: string) => Promise<VueVoxApiResponse<WebhookTestResponse>>;
187
+ paginate: (listOptions?: ListWebhookEndpointsOptions) => AsyncGenerator<{
188
+ id: string;
189
+ url: string;
190
+ events: components["schemas"]["WebhookEventType"][];
191
+ isActive: boolean;
192
+ lastDeliveredAt: string | null;
193
+ createdAt: string;
194
+ updatedAt: string;
195
+ }, any, any>;
196
+ };
197
+ };
161
198
  raw: import("openapi-fetch").Client<paths, `${string}/${string}`>;
162
199
  };
200
+ export declare function verifyVueVoxWebhookSignature(input: VerifyWebhookSignatureInput): Promise<boolean>;
package/dist/client.js CHANGED
@@ -95,6 +95,24 @@ export function createVueVoxClient(options) {
95
95
  async function updateLeadCustomField(key, input) {
96
96
  return apiJson("PATCH", `/v1/lead-custom-fields/${encodeURIComponent(key)}`, input);
97
97
  }
98
+ async function listWebhookEndpoints(listOptions = {}) {
99
+ return apiGet("/v1/webhooks/endpoints", listOptions);
100
+ }
101
+ async function createWebhookEndpoint(input) {
102
+ return apiJson("POST", "/v1/webhooks/endpoints", input);
103
+ }
104
+ async function updateWebhookEndpoint(endpointId, input) {
105
+ return apiJson("PATCH", `/v1/webhooks/endpoints/${encodeURIComponent(endpointId)}`, input);
106
+ }
107
+ async function deleteWebhookEndpoint(endpointId) {
108
+ return apiDelete(`/v1/webhooks/endpoints/${encodeURIComponent(endpointId)}`);
109
+ }
110
+ async function rotateWebhookEndpointSecret(endpointId) {
111
+ return apiJson("POST", `/v1/webhooks/endpoints/${encodeURIComponent(endpointId)}/rotate-secret`, {});
112
+ }
113
+ async function testWebhookEndpoint(endpointId) {
114
+ return apiJson("POST", `/v1/webhooks/endpoints/${encodeURIComponent(endpointId)}/test`, {});
115
+ }
98
116
  async function apiGet(path, query) {
99
117
  const accessToken = await getAccessToken();
100
118
  const result = await requestJson("GET", path, {
@@ -118,6 +136,24 @@ export function createVueVoxClient(options) {
118
136
  });
119
137
  return withMetadata(result.data, result.response, result.requestId);
120
138
  }
139
+ async function apiDelete(path) {
140
+ const accessToken = await getAccessToken();
141
+ const response = await fetchFn(buildUrl(baseUrl, path, undefined), {
142
+ method: "DELETE",
143
+ headers: {
144
+ Authorization: `Bearer ${accessToken}`,
145
+ },
146
+ });
147
+ const body = await parseJson(response);
148
+ const requestId = getRequestId(response, body);
149
+ const retryAfter = retryAfterSeconds(response);
150
+ notifyResponse(options, "DELETE", path, response, requestId, retryAfter);
151
+ if (response.ok) {
152
+ return withMetadata(null, response, requestId);
153
+ }
154
+ const error = isErrorResponse(body) ? body.error : null;
155
+ throw new VueVoxApiError(response.status, error?.code ?? "api_request_failed", error?.message ?? "VueVox API request failed.", isErrorResponse(body) ? body : undefined, requestId, retryAfter);
156
+ }
121
157
  async function apiMultipart(method, path, body, headers) {
122
158
  const accessToken = await getAccessToken();
123
159
  const result = await requestJson(method, path, {
@@ -190,9 +226,34 @@ export function createVueVoxClient(options) {
190
226
  create: createLeadCustomField,
191
227
  update: updateLeadCustomField,
192
228
  },
229
+ webhooks: {
230
+ endpoints: {
231
+ list: listWebhookEndpoints,
232
+ create: createWebhookEndpoint,
233
+ update: updateWebhookEndpoint,
234
+ delete: deleteWebhookEndpoint,
235
+ rotateSecret: rotateWebhookEndpointSecret,
236
+ test: testWebhookEndpoint,
237
+ paginate: (listOptions = {}) => paginate(listWebhookEndpoints, listOptions),
238
+ },
239
+ },
193
240
  raw,
194
241
  };
195
242
  }
243
+ export async function verifyVueVoxWebhookSignature(input) {
244
+ const toleranceSeconds = input.toleranceSeconds ?? 300;
245
+ const now = input.now ?? Date.now();
246
+ const timestampSeconds = Number(input.timestamp);
247
+ if (!Number.isFinite(timestampSeconds)) {
248
+ return false;
249
+ }
250
+ if (Math.abs(Math.floor(now / 1000) - timestampSeconds) > toleranceSeconds) {
251
+ return false;
252
+ }
253
+ const expected = await hmacSha256Hex(input.secret, `${input.timestamp}.${input.body}`);
254
+ const provided = input.signature.startsWith("v1=") ? input.signature.slice(3) : input.signature;
255
+ return constantTimeEqual(expected, provided);
256
+ }
196
257
  function formatScope(scope) {
197
258
  if (Array.isArray(scope)) {
198
259
  return scope.join(" ");
@@ -293,3 +354,18 @@ function retryAfterSeconds(response) {
293
354
  function sleep(ms) {
294
355
  return new Promise((resolve) => setTimeout(resolve, ms));
295
356
  }
357
+ async function hmacSha256Hex(secret, value) {
358
+ const key = await crypto.subtle.importKey("raw", new TextEncoder().encode(secret), { name: "HMAC", hash: "SHA-256" }, false, ["sign"]);
359
+ const signature = await crypto.subtle.sign("HMAC", key, new TextEncoder().encode(value));
360
+ return [...new Uint8Array(signature)].map((byte) => byte.toString(16).padStart(2, "0")).join("");
361
+ }
362
+ function constantTimeEqual(left, right) {
363
+ if (left.length !== right.length) {
364
+ return false;
365
+ }
366
+ let result = 0;
367
+ for (let index = 0; index < left.length; index++) {
368
+ result |= left.charCodeAt(index) ^ right.charCodeAt(index);
369
+ }
370
+ return result === 0;
371
+ }
@@ -148,6 +148,88 @@ export interface paths {
148
148
  patch?: never;
149
149
  trace?: never;
150
150
  };
151
+ "/v1/webhooks/endpoints": {
152
+ parameters: {
153
+ query?: never;
154
+ header?: never;
155
+ path?: never;
156
+ cookie?: never;
157
+ };
158
+ /**
159
+ * List webhook endpoints
160
+ * @description Returns webhook endpoints for the authenticated API client using cursor pagination.
161
+ */
162
+ get: operations["listWebhookEndpoints"];
163
+ put?: never;
164
+ /**
165
+ * Create a webhook endpoint
166
+ * @description Creates a webhook endpoint for the authenticated API client. The signing secret is returned only once.
167
+ */
168
+ post: operations["createWebhookEndpoint"];
169
+ delete?: never;
170
+ options?: never;
171
+ head?: never;
172
+ patch?: never;
173
+ trace?: never;
174
+ };
175
+ "/v1/webhooks/endpoints/{endpointId}": {
176
+ parameters: {
177
+ query?: never;
178
+ header?: never;
179
+ path?: never;
180
+ cookie?: never;
181
+ };
182
+ get?: never;
183
+ put?: never;
184
+ post?: never;
185
+ /** Delete a webhook endpoint */
186
+ delete: operations["deleteWebhookEndpoint"];
187
+ options?: never;
188
+ head?: never;
189
+ /** Update a webhook endpoint */
190
+ patch: operations["updateWebhookEndpoint"];
191
+ trace?: never;
192
+ };
193
+ "/v1/webhooks/endpoints/{endpointId}/rotate-secret": {
194
+ parameters: {
195
+ query?: never;
196
+ header?: never;
197
+ path?: never;
198
+ cookie?: never;
199
+ };
200
+ get?: never;
201
+ put?: never;
202
+ /**
203
+ * Rotate a webhook endpoint signing secret
204
+ * @description Replaces the endpoint signing secret. The new secret is returned only once.
205
+ */
206
+ post: operations["rotateWebhookEndpointSecret"];
207
+ delete?: never;
208
+ options?: never;
209
+ head?: never;
210
+ patch?: never;
211
+ trace?: never;
212
+ };
213
+ "/v1/webhooks/endpoints/{endpointId}/test": {
214
+ parameters: {
215
+ query?: never;
216
+ header?: never;
217
+ path?: never;
218
+ cookie?: never;
219
+ };
220
+ get?: never;
221
+ put?: never;
222
+ /**
223
+ * Send a test webhook event
224
+ * @description Queues a webhook.test delivery to validate endpoint reachability and signature verification.
225
+ */
226
+ post: operations["testWebhookEndpoint"];
227
+ delete?: never;
228
+ options?: never;
229
+ head?: never;
230
+ patch?: never;
231
+ trace?: never;
232
+ };
151
233
  "/v1/leads": {
152
234
  parameters: {
153
235
  query?: never;
@@ -267,7 +349,7 @@ export interface components {
267
349
  client_secret: string;
268
350
  /**
269
351
  * @description Space-separated scopes requested for the access token.
270
- * @example hello:read spaces:read agents:read calls:read calls:write leads:read leads:write lead_custom_fields:manage
352
+ * @example hello:read spaces:read agents:read calls:read calls:write leads:read leads:write lead_custom_fields:manage webhooks:read webhooks:write
271
353
  */
272
354
  scope?: string;
273
355
  };
@@ -277,7 +359,7 @@ export interface components {
277
359
  token_type: "Bearer";
278
360
  /** @example 3600 */
279
361
  expires_in: number;
280
- /** @example hello:read spaces:read agents:read calls:read calls:write leads:read leads:write lead_custom_fields:manage */
362
+ /** @example hello:read spaces:read agents:read calls:read calls:write leads:read leads:write lead_custom_fields:manage webhooks:read webhooks:write */
281
363
  scope: string;
282
364
  };
283
365
  HelloResponse: {
@@ -511,6 +593,79 @@ export interface components {
511
593
  isFilterable?: boolean;
512
594
  archived?: boolean;
513
595
  };
596
+ /**
597
+ * @description Subscribable webhook event type.
598
+ * @enum {string}
599
+ */
600
+ WebhookEventType: "analysis.completed" | "analysis.failed";
601
+ WebhookEndpoint: {
602
+ /** Format: uuid */
603
+ id: string;
604
+ /** Format: uri */
605
+ url: string;
606
+ events: components["schemas"]["WebhookEventType"][];
607
+ isActive: boolean;
608
+ /** Format: date-time */
609
+ lastDeliveredAt: string | null;
610
+ /** Format: date-time */
611
+ createdAt: string;
612
+ /** Format: date-time */
613
+ updatedAt: string;
614
+ };
615
+ WebhookEndpointWithSecret: components["schemas"]["WebhookEndpoint"] & {
616
+ /** @description Signing secret shown only when creating or rotating the endpoint. */
617
+ secret: string;
618
+ };
619
+ WebhookEndpointsListResponse: {
620
+ data: components["schemas"]["WebhookEndpoint"][];
621
+ pagination: components["schemas"]["CursorPagination"];
622
+ };
623
+ WebhookEndpointResponse: {
624
+ data: components["schemas"]["WebhookEndpoint"];
625
+ };
626
+ WebhookEndpointSecretResponse: {
627
+ data: components["schemas"]["WebhookEndpointWithSecret"];
628
+ };
629
+ WebhookEndpointCreateRequest: {
630
+ /**
631
+ * Format: uri
632
+ * @description Public HTTPS URL that will receive webhook POST requests.
633
+ */
634
+ url: string;
635
+ events: components["schemas"]["WebhookEventType"][];
636
+ /** @default true */
637
+ isActive: boolean;
638
+ };
639
+ WebhookEndpointUpdateRequest: {
640
+ /** Format: uri */
641
+ url?: string;
642
+ events?: components["schemas"]["WebhookEventType"][];
643
+ isActive?: boolean;
644
+ };
645
+ WebhookTestResponse: {
646
+ data: {
647
+ /**
648
+ * Format: uuid
649
+ * @description Delivery ID.
650
+ */
651
+ id: string;
652
+ /** @enum {string} */
653
+ status: "pending" | "retrying" | "delivered" | "failed" | "skipped";
654
+ /** @enum {string} */
655
+ eventType: "webhook.test";
656
+ };
657
+ };
658
+ WebhookEventPayload: {
659
+ /** Format: uuid */
660
+ id: string;
661
+ /** @enum {string} */
662
+ type: "analysis.completed" | "analysis.failed" | "webhook.test";
663
+ /** Format: date-time */
664
+ createdAt: string;
665
+ data: {
666
+ [key: string]: unknown;
667
+ };
668
+ };
514
669
  CursorPagination: {
515
670
  /** @example 50 */
516
671
  limit: number;
@@ -535,7 +690,10 @@ export interface components {
535
690
  };
536
691
  };
537
692
  responses: never;
538
- parameters: never;
693
+ parameters: {
694
+ /** @description Webhook endpoint ID. */
695
+ WebhookEndpointId: string;
696
+ };
539
697
  requestBodies: never;
540
698
  headers: never;
541
699
  pathItems: never;
@@ -1055,6 +1213,320 @@ export interface operations {
1055
1213
  };
1056
1214
  };
1057
1215
  };
1216
+ listWebhookEndpoints: {
1217
+ parameters: {
1218
+ query?: {
1219
+ /** @description Number of endpoints to return. Defaults to 50. Maximum is 100. */
1220
+ limit?: number;
1221
+ /** @description Opaque cursor from the previous response's pagination.nextCursor value. */
1222
+ cursor?: string;
1223
+ };
1224
+ header?: never;
1225
+ path?: never;
1226
+ cookie?: never;
1227
+ };
1228
+ requestBody?: never;
1229
+ responses: {
1230
+ /** @description Paginated webhook endpoints response. */
1231
+ 200: {
1232
+ headers: {
1233
+ [name: string]: unknown;
1234
+ };
1235
+ content: {
1236
+ "application/json": components["schemas"]["WebhookEndpointsListResponse"];
1237
+ };
1238
+ };
1239
+ /** @description Bearer token is missing, invalid, or expired. */
1240
+ 401: {
1241
+ headers: {
1242
+ [name: string]: unknown;
1243
+ };
1244
+ content: {
1245
+ "application/json": components["schemas"]["ErrorResponse"];
1246
+ };
1247
+ };
1248
+ /** @description Bearer token does not include the required scope. */
1249
+ 403: {
1250
+ headers: {
1251
+ [name: string]: unknown;
1252
+ };
1253
+ content: {
1254
+ "application/json": components["schemas"]["ErrorResponse"];
1255
+ };
1256
+ };
1257
+ /** @description Query parameters failed validation. */
1258
+ 422: {
1259
+ headers: {
1260
+ [name: string]: unknown;
1261
+ };
1262
+ content: {
1263
+ "application/json": components["schemas"]["ErrorResponse"];
1264
+ };
1265
+ };
1266
+ };
1267
+ };
1268
+ createWebhookEndpoint: {
1269
+ parameters: {
1270
+ query?: never;
1271
+ header?: never;
1272
+ path?: never;
1273
+ cookie?: never;
1274
+ };
1275
+ requestBody: {
1276
+ content: {
1277
+ "application/json": components["schemas"]["WebhookEndpointCreateRequest"];
1278
+ };
1279
+ };
1280
+ responses: {
1281
+ /** @description Webhook endpoint created. */
1282
+ 201: {
1283
+ headers: {
1284
+ [name: string]: unknown;
1285
+ };
1286
+ content: {
1287
+ "application/json": components["schemas"]["WebhookEndpointSecretResponse"];
1288
+ };
1289
+ };
1290
+ /** @description Bearer token is missing, invalid, or expired. */
1291
+ 401: {
1292
+ headers: {
1293
+ [name: string]: unknown;
1294
+ };
1295
+ content: {
1296
+ "application/json": components["schemas"]["ErrorResponse"];
1297
+ };
1298
+ };
1299
+ /** @description Bearer token does not include the required scope. */
1300
+ 403: {
1301
+ headers: {
1302
+ [name: string]: unknown;
1303
+ };
1304
+ content: {
1305
+ "application/json": components["schemas"]["ErrorResponse"];
1306
+ };
1307
+ };
1308
+ /** @description Request body failed validation. */
1309
+ 422: {
1310
+ headers: {
1311
+ [name: string]: unknown;
1312
+ };
1313
+ content: {
1314
+ "application/json": components["schemas"]["ErrorResponse"];
1315
+ };
1316
+ };
1317
+ };
1318
+ };
1319
+ deleteWebhookEndpoint: {
1320
+ parameters: {
1321
+ query?: never;
1322
+ header?: never;
1323
+ path: {
1324
+ /** @description Webhook endpoint ID. */
1325
+ endpointId: components["parameters"]["WebhookEndpointId"];
1326
+ };
1327
+ cookie?: never;
1328
+ };
1329
+ requestBody?: never;
1330
+ responses: {
1331
+ /** @description Webhook endpoint deleted. */
1332
+ 204: {
1333
+ headers: {
1334
+ [name: string]: unknown;
1335
+ };
1336
+ content?: never;
1337
+ };
1338
+ /** @description Bearer token is missing, invalid, or expired. */
1339
+ 401: {
1340
+ headers: {
1341
+ [name: string]: unknown;
1342
+ };
1343
+ content: {
1344
+ "application/json": components["schemas"]["ErrorResponse"];
1345
+ };
1346
+ };
1347
+ /** @description Bearer token does not include the required scope. */
1348
+ 403: {
1349
+ headers: {
1350
+ [name: string]: unknown;
1351
+ };
1352
+ content: {
1353
+ "application/json": components["schemas"]["ErrorResponse"];
1354
+ };
1355
+ };
1356
+ /** @description Webhook endpoint was not found for this API client. */
1357
+ 404: {
1358
+ headers: {
1359
+ [name: string]: unknown;
1360
+ };
1361
+ content: {
1362
+ "application/json": components["schemas"]["ErrorResponse"];
1363
+ };
1364
+ };
1365
+ };
1366
+ };
1367
+ updateWebhookEndpoint: {
1368
+ parameters: {
1369
+ query?: never;
1370
+ header?: never;
1371
+ path: {
1372
+ /** @description Webhook endpoint ID. */
1373
+ endpointId: components["parameters"]["WebhookEndpointId"];
1374
+ };
1375
+ cookie?: never;
1376
+ };
1377
+ requestBody: {
1378
+ content: {
1379
+ "application/json": components["schemas"]["WebhookEndpointUpdateRequest"];
1380
+ };
1381
+ };
1382
+ responses: {
1383
+ /** @description Webhook endpoint updated. */
1384
+ 200: {
1385
+ headers: {
1386
+ [name: string]: unknown;
1387
+ };
1388
+ content: {
1389
+ "application/json": components["schemas"]["WebhookEndpointResponse"];
1390
+ };
1391
+ };
1392
+ /** @description Bearer token is missing, invalid, or expired. */
1393
+ 401: {
1394
+ headers: {
1395
+ [name: string]: unknown;
1396
+ };
1397
+ content: {
1398
+ "application/json": components["schemas"]["ErrorResponse"];
1399
+ };
1400
+ };
1401
+ /** @description Bearer token does not include the required scope. */
1402
+ 403: {
1403
+ headers: {
1404
+ [name: string]: unknown;
1405
+ };
1406
+ content: {
1407
+ "application/json": components["schemas"]["ErrorResponse"];
1408
+ };
1409
+ };
1410
+ /** @description Webhook endpoint was not found for this API client. */
1411
+ 404: {
1412
+ headers: {
1413
+ [name: string]: unknown;
1414
+ };
1415
+ content: {
1416
+ "application/json": components["schemas"]["ErrorResponse"];
1417
+ };
1418
+ };
1419
+ /** @description Request body failed validation. */
1420
+ 422: {
1421
+ headers: {
1422
+ [name: string]: unknown;
1423
+ };
1424
+ content: {
1425
+ "application/json": components["schemas"]["ErrorResponse"];
1426
+ };
1427
+ };
1428
+ };
1429
+ };
1430
+ rotateWebhookEndpointSecret: {
1431
+ parameters: {
1432
+ query?: never;
1433
+ header?: never;
1434
+ path: {
1435
+ /** @description Webhook endpoint ID. */
1436
+ endpointId: components["parameters"]["WebhookEndpointId"];
1437
+ };
1438
+ cookie?: never;
1439
+ };
1440
+ requestBody?: never;
1441
+ responses: {
1442
+ /** @description Webhook endpoint secret rotated. */
1443
+ 200: {
1444
+ headers: {
1445
+ [name: string]: unknown;
1446
+ };
1447
+ content: {
1448
+ "application/json": components["schemas"]["WebhookEndpointSecretResponse"];
1449
+ };
1450
+ };
1451
+ /** @description Bearer token is missing, invalid, or expired. */
1452
+ 401: {
1453
+ headers: {
1454
+ [name: string]: unknown;
1455
+ };
1456
+ content: {
1457
+ "application/json": components["schemas"]["ErrorResponse"];
1458
+ };
1459
+ };
1460
+ /** @description Bearer token does not include the required scope. */
1461
+ 403: {
1462
+ headers: {
1463
+ [name: string]: unknown;
1464
+ };
1465
+ content: {
1466
+ "application/json": components["schemas"]["ErrorResponse"];
1467
+ };
1468
+ };
1469
+ /** @description Webhook endpoint was not found for this API client. */
1470
+ 404: {
1471
+ headers: {
1472
+ [name: string]: unknown;
1473
+ };
1474
+ content: {
1475
+ "application/json": components["schemas"]["ErrorResponse"];
1476
+ };
1477
+ };
1478
+ };
1479
+ };
1480
+ testWebhookEndpoint: {
1481
+ parameters: {
1482
+ query?: never;
1483
+ header?: never;
1484
+ path: {
1485
+ /** @description Webhook endpoint ID. */
1486
+ endpointId: components["parameters"]["WebhookEndpointId"];
1487
+ };
1488
+ cookie?: never;
1489
+ };
1490
+ requestBody?: never;
1491
+ responses: {
1492
+ /** @description Test delivery queued. */
1493
+ 202: {
1494
+ headers: {
1495
+ [name: string]: unknown;
1496
+ };
1497
+ content: {
1498
+ "application/json": components["schemas"]["WebhookTestResponse"];
1499
+ };
1500
+ };
1501
+ /** @description Bearer token is missing, invalid, or expired. */
1502
+ 401: {
1503
+ headers: {
1504
+ [name: string]: unknown;
1505
+ };
1506
+ content: {
1507
+ "application/json": components["schemas"]["ErrorResponse"];
1508
+ };
1509
+ };
1510
+ /** @description Bearer token does not include the required scope. */
1511
+ 403: {
1512
+ headers: {
1513
+ [name: string]: unknown;
1514
+ };
1515
+ content: {
1516
+ "application/json": components["schemas"]["ErrorResponse"];
1517
+ };
1518
+ };
1519
+ /** @description Webhook endpoint was not found for this API client. */
1520
+ 404: {
1521
+ headers: {
1522
+ [name: string]: unknown;
1523
+ };
1524
+ content: {
1525
+ "application/json": components["schemas"]["ErrorResponse"];
1526
+ };
1527
+ };
1528
+ };
1529
+ };
1058
1530
  listLeads: {
1059
1531
  parameters: {
1060
1532
  query?: {
package/dist/index.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- export { createVueVoxClient } from "./client.js";
2
- export type { Agent, AgentsListResponse, CallDetailResponse, CallResponse, CallsListResponse, CallSummary, CallUploadMetadata, CustomFieldFilters, CustomFieldFilterValue, HelloResponse, Lead, LeadCustomField, LeadCustomFieldCreateRequest, LeadCustomFieldResponse, LeadCustomFieldUpdateRequest, LeadCustomFieldsListResponse, LeadDetailResponse, LeadUpdateRequest, LeadUpsertRequest, LeadsListResponse, ListAgentsOptions, ListCallsOptions, ListLeadCustomFieldsOptions, ListLeadsOptions, ListSpacesOptions, Space, SpacesListResponse, UploadCallInput, VueVoxApiResponse, VueVoxClientOptions, VueVoxResponseEvent, VueVoxResponseMetadata, WaitForAnalysisOptions, } from "./client.js";
1
+ export { createVueVoxClient, verifyVueVoxWebhookSignature } from "./client.js";
2
+ export type { Agent, AgentsListResponse, CallDetailResponse, CallResponse, CallsListResponse, CallSummary, CallUploadMetadata, CustomFieldFilters, CustomFieldFilterValue, HelloResponse, Lead, LeadCustomField, LeadCustomFieldCreateRequest, LeadCustomFieldResponse, LeadCustomFieldUpdateRequest, LeadCustomFieldsListResponse, LeadDetailResponse, LeadUpdateRequest, LeadUpsertRequest, LeadsListResponse, ListAgentsOptions, ListCallsOptions, ListLeadCustomFieldsOptions, ListLeadsOptions, ListSpacesOptions, ListWebhookEndpointsOptions, Space, SpacesListResponse, UploadCallInput, VerifyWebhookSignatureInput, VueVoxApiResponse, VueVoxClientOptions, VueVoxResponseEvent, VueVoxResponseMetadata, WaitForAnalysisOptions, WebhookEndpoint, WebhookEndpointCreateRequest, WebhookEndpointResponse, WebhookEndpointSecretResponse, WebhookEndpointUpdateRequest, WebhookEndpointsListResponse, WebhookEventPayload, WebhookTestResponse, } from "./client.js";
3
3
  export { VueVoxApiError } from "./errors.js";
4
4
  export type { VueVoxErrorResponse } from "./errors.js";
package/dist/index.js CHANGED
@@ -1,2 +1,2 @@
1
- export { createVueVoxClient } from "./client.js";
1
+ export { createVueVoxClient, verifyVueVoxWebhookSignature } from "./client.js";
2
2
  export { VueVoxApiError } from "./errors.js";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vuevox/sdk",
3
- "version": "0.8.0",
3
+ "version": "0.9.0",
4
4
  "description": "TypeScript SDK for the VueVox Developer API.",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",