@convertrilo/sdk 0.0.5 → 0.0.7

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
@@ -167,6 +167,19 @@ for (const job of batch.jobs || []) {
167
167
 
168
168
  Poll each returned `jobId` with `client.onDemandStatus(jobId)`.
169
169
 
170
+ ## Webhook Delivery History
171
+
172
+ Managed webhooks are HMAC signed. You can test a webhook and inspect recent delivery attempts:
173
+
174
+ ```ts
175
+ await client.testWebhook(webhookId);
176
+
177
+ const history = await client.getWebhookDeliveries(webhookId);
178
+ for (const delivery of history.deliveries || []) {
179
+ console.log(delivery.status, delivery.statusCode, delivery.event);
180
+ }
181
+ ```
182
+
170
183
  ## Regenerate Types
171
184
 
172
185
  The SDK types are generated from `openapi.yaml`.
@@ -115,8 +115,22 @@ export declare class ConvertriloClient {
115
115
  lastFailedAt?: string | null;
116
116
  createdAt?: string;
117
117
  }>;
118
+ updateWebhook(id: string, body: paths["/webhooks/{id}"]["patch"]["requestBody"]["content"]["application/json"]): Promise<{
119
+ id?: string;
120
+ url?: string;
121
+ events?: string[];
122
+ secret?: string;
123
+ isActive?: boolean;
124
+ failureCount?: number;
125
+ lastTriggeredAt?: string | null;
126
+ lastFailedAt?: string | null;
127
+ createdAt?: string;
128
+ }>;
118
129
  deleteWebhook(id: string): Promise<unknown>;
119
130
  testWebhook(id: string): Promise<unknown>;
131
+ getWebhookDeliveries(id: string): Promise<{
132
+ deliveries?: import("./types").components["schemas"]["WebhookDeliveryResponse"][];
133
+ }>;
120
134
  initStream(id: string): Promise<{
121
135
  ok?: boolean;
122
136
  uploadId?: string;
package/dist/src/index.js CHANGED
@@ -134,12 +134,21 @@ export class ConvertriloClient {
134
134
  body: JSON.stringify(body),
135
135
  });
136
136
  }
137
+ async updateWebhook(id, body) {
138
+ return this.request(`/webhooks/${id}`, {
139
+ method: "PATCH",
140
+ body: JSON.stringify(body),
141
+ });
142
+ }
137
143
  async deleteWebhook(id) {
138
144
  return this.request(`/webhooks/${id}`, { method: "DELETE" });
139
145
  }
140
146
  async testWebhook(id) {
141
147
  return this.request(`/webhooks/${id}/test`, { method: "POST" });
142
148
  }
149
+ async getWebhookDeliveries(id) {
150
+ return this.request(`/webhooks/${id}/deliveries`);
151
+ }
143
152
  // Streaming
144
153
  async initStream(id) {
145
154
  return this.request(`/jobs/${id}/stream/init`, { method: "POST" });
@@ -707,6 +707,56 @@ export interface paths {
707
707
  };
708
708
  trace?: never;
709
709
  };
710
+ "/webhooks/{id}/deliveries": {
711
+ parameters: {
712
+ query?: never;
713
+ header?: never;
714
+ path?: never;
715
+ cookie?: never;
716
+ };
717
+ /**
718
+ * List webhook delivery attempts
719
+ * @description Returns the 50 most recent managed or test delivery attempts for this webhook.
720
+ */
721
+ get: {
722
+ parameters: {
723
+ query?: never;
724
+ header?: never;
725
+ path: {
726
+ id: string;
727
+ };
728
+ cookie?: never;
729
+ };
730
+ requestBody?: never;
731
+ responses: {
732
+ /** @description Recent delivery attempts */
733
+ 200: {
734
+ headers: {
735
+ [name: string]: unknown;
736
+ };
737
+ content: {
738
+ "application/json": components["schemas"]["WebhookDeliveryListResponse"];
739
+ };
740
+ };
741
+ /** @description Webhook not found */
742
+ 404: {
743
+ headers: {
744
+ [name: string]: unknown;
745
+ };
746
+ content: {
747
+ "application/json": components["schemas"]["ErrorResponse"];
748
+ };
749
+ };
750
+ };
751
+ };
752
+ put?: never;
753
+ post?: never;
754
+ delete?: never;
755
+ options?: never;
756
+ head?: never;
757
+ patch?: never;
758
+ trace?: never;
759
+ };
710
760
  "/jobs/bulk": {
711
761
  parameters: {
712
762
  query?: never;
@@ -1655,6 +1705,33 @@ export interface components {
1655
1705
  WebhookListResponse: {
1656
1706
  webhooks?: components["schemas"]["WebhookResponse"][];
1657
1707
  };
1708
+ WebhookDeliveryResponse: {
1709
+ /** Format: uuid */
1710
+ id?: string;
1711
+ /** Format: uuid */
1712
+ webhookId?: string;
1713
+ event?: string;
1714
+ /** Format: uuid */
1715
+ jobId?: string | null;
1716
+ /** @enum {string} */
1717
+ status?: "success" | "failed";
1718
+ statusCode?: number | null;
1719
+ durationMs?: number | null;
1720
+ /** @description Response body captured from the receiver, truncated to 2048 characters. */
1721
+ responseBody?: string | null;
1722
+ /** @description Network, timeout, or delivery error, truncated to 2048 characters. */
1723
+ error?: string | null;
1724
+ attempt?: number;
1725
+ /** Format: date-time */
1726
+ nextRetryAt?: string | null;
1727
+ /** Format: date-time */
1728
+ retriedAt?: string | null;
1729
+ /** Format: date-time */
1730
+ createdAt?: string;
1731
+ };
1732
+ WebhookDeliveryListResponse: {
1733
+ deliveries?: components["schemas"]["WebhookDeliveryResponse"][];
1734
+ };
1658
1735
  S3Output: {
1659
1736
  bucket: string;
1660
1737
  key: string;
package/docs/WEBHOOKS.md CHANGED
@@ -127,7 +127,62 @@ export async function POST(req: NextRequest) {
127
127
  - A webhook is automatically disabled after 10 consecutive failures
128
128
  - Re-enable it with `PATCH /webhooks/{id}` and `{ "isActive": true }`
129
129
 
130
- Current deliveries are best-effort. There is not yet a durable retry queue or delivery history API.
130
+ Failed managed deliveries are scheduled for retry when possible.
131
+
132
+ Retry schedule:
133
+
134
+ - Attempt 2: about 1 minute after the failed attempt
135
+ - Attempt 3: about 5 minutes after the failed attempt
136
+ - Attempt 4: about 30 minutes after the failed attempt
137
+
138
+ Run due retries with:
139
+
140
+ ```bash
141
+ pnpm run webhooks:retry
142
+ ```
143
+
144
+ Use `--limit` to cap one run:
145
+
146
+ ```bash
147
+ pnpm run webhooks:retry -- --limit=50
148
+ ```
149
+
150
+ Schedule this command every minute in production. Webhooks are still disabled after
151
+ 10 consecutive failures.
152
+
153
+ ## Delivery History
154
+
155
+ Recent managed and test delivery attempts are available with:
156
+
157
+ ```txt
158
+ GET /webhooks/{id}/deliveries
159
+ ```
160
+
161
+ The response includes the 50 most recent attempts for that webhook:
162
+
163
+ ```json
164
+ {
165
+ "deliveries": [
166
+ {
167
+ "id": "550e8400-e29b-41d4-a716-446655440000",
168
+ "webhookId": "4a5c26a0-7b04-4d37-8bb1-446655440000",
169
+ "event": "job.completed",
170
+ "jobId": "9db109f6-6a88-49d7-89e2-446655440000",
171
+ "status": "success",
172
+ "statusCode": 204,
173
+ "durationMs": 182,
174
+ "responseBody": null,
175
+ "error": null,
176
+ "attempt": 1,
177
+ "nextRetryAt": null,
178
+ "retriedAt": null,
179
+ "createdAt": "2026-06-09T07:30:00.000Z"
180
+ }
181
+ ]
182
+ }
183
+ ```
184
+
185
+ `responseBody` and `error` are capped at 2048 characters.
131
186
 
132
187
  ## One-Off On-Demand Webhook URL
133
188
 
package/openapi.yaml CHANGED
@@ -345,6 +345,35 @@ components:
345
345
  type: array
346
346
  items:
347
347
  $ref: "#/components/schemas/WebhookResponse"
348
+ WebhookDeliveryResponse:
349
+ type: object
350
+ properties:
351
+ id: { type: string, format: uuid }
352
+ webhookId: { type: string, format: uuid }
353
+ event: { type: string }
354
+ jobId: { type: string, format: uuid, nullable: true }
355
+ status: { type: string, enum: [success, failed] }
356
+ statusCode: { type: integer, nullable: true }
357
+ durationMs: { type: integer, nullable: true }
358
+ responseBody:
359
+ type: string
360
+ nullable: true
361
+ description: Response body captured from the receiver, truncated to 2048 characters.
362
+ error:
363
+ type: string
364
+ nullable: true
365
+ description: Network, timeout, or delivery error, truncated to 2048 characters.
366
+ attempt: { type: integer }
367
+ nextRetryAt: { type: string, format: date-time, nullable: true }
368
+ retriedAt: { type: string, format: date-time, nullable: true }
369
+ createdAt: { type: string, format: date-time }
370
+ WebhookDeliveryListResponse:
371
+ type: object
372
+ properties:
373
+ deliveries:
374
+ type: array
375
+ items:
376
+ $ref: "#/components/schemas/WebhookDeliveryResponse"
348
377
 
349
378
  # On-Demand Encoding
350
379
  S3Output:
@@ -897,6 +926,29 @@ paths:
897
926
  schema: { type: string, format: uuid }
898
927
  responses:
899
928
  "200": { description: Test event sent }
929
+ /webhooks/{id}/deliveries:
930
+ get:
931
+ security: [{ BearerAuth: [] }]
932
+ summary: List webhook delivery attempts
933
+ description: Returns the 50 most recent managed or test delivery attempts for this webhook.
934
+ parameters:
935
+ - in: path
936
+ name: id
937
+ required: true
938
+ schema: { type: string, format: uuid }
939
+ responses:
940
+ "200":
941
+ description: Recent delivery attempts
942
+ content:
943
+ application/json:
944
+ schema:
945
+ $ref: "#/components/schemas/WebhookDeliveryListResponse"
946
+ "404":
947
+ description: Webhook not found
948
+ content:
949
+ application/json:
950
+ schema:
951
+ $ref: "#/components/schemas/ErrorResponse"
900
952
 
901
953
  /jobs/bulk:
902
954
  post:
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@convertrilo/sdk",
3
- "version": "0.0.5",
3
+ "version": "0.0.7",
4
4
  "description": "TypeScript client for the Convertrilo video encoding API",
5
5
  "private": false,
6
6
  "license": "MIT",