@rendobar/sdk 5.0.0 → 5.1.1

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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Rendobar
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md CHANGED
@@ -1,110 +1,84 @@
1
- # @rendobar/sdk
1
+ <p align="center">
2
+ <a href="https://rendobar.com">
3
+ <picture>
4
+ <source media="(prefers-color-scheme: dark)" srcset="https://cdn.rendobar.com/assets/brand/logo-mark.svg">
5
+ <img alt="Rendobar" src="https://cdn.rendobar.com/assets/brand/logo-mark-black.svg" width="80">
6
+ </picture>
7
+ </a>
8
+ </p>
2
9
 
3
- TypeScript client for the Rendobar media processing API.
10
+ <h1 align="center">@rendobar/sdk</h1>
4
11
 
5
- ## Install
12
+ <p align="center">
13
+ <strong>TypeScript client for the Rendobar media processing API.</strong>
14
+ </p>
6
15
 
7
- ```bash
8
- npm install @rendobar/sdk
9
- ```
16
+ <p align="center">
17
+ <a href="https://rendobar.com/docs/sdk">Docs</a> &nbsp;·&nbsp;
18
+ <a href="https://rendobar.com/docs/quickstart">Quickstart</a> &nbsp;·&nbsp;
19
+ <a href="https://www.npmjs.com/package/@rendobar/sdk">npm</a> &nbsp;·&nbsp;
20
+ <a href="https://discord.gg/kAGqjBzx8N">Discord</a>
21
+ </p>
10
22
 
11
- ## Quick Start
23
+ <p align="center">
24
+ <a href="https://www.npmjs.com/package/@rendobar/sdk"><img src="https://img.shields.io/npm/v/@rendobar/sdk?style=flat-square&color=059669&label=npm" alt="npm version"></a>
25
+ <a href="https://www.npmjs.com/package/@rendobar/sdk"><img src="https://img.shields.io/npm/dm/@rendobar/sdk?style=flat-square&color=059669" alt="npm downloads"></a>
26
+ <img src="https://img.shields.io/node/v/@rendobar/sdk?style=flat-square&color=059669" alt="Node version">
27
+ </p>
12
28
 
13
- ```typescript
14
- import { createClient } from "@rendobar/sdk";
29
+ `@rendobar/sdk` is the official TypeScript client for [Rendobar](https://rendobar.com), a serverless media processing API. You submit a job, the SDK polls it to completion, and you get back a hosted URL. It ships ESM and CJS builds with full types, retries 429 and 5xx automatically, auto-paginates, and accepts an `AbortSignal` on every method.
15
30
 
16
- const client = createClient({ apiKey: "rb_..." });
31
+ ## Requirements
17
32
 
18
- // Submit a job
19
- const job = await client.jobs.create({
20
- type: "watermark.apply",
21
- inputs: { source: "https://example.com/video.mp4" },
22
- params: { text: "PREVIEW", position: "center", opacity: 0.3 },
23
- });
33
+ Node 18 or later. Works in any runtime with `fetch`, including Cloudflare Workers, Deno, and Bun.
24
34
 
25
- // Wait for completion
26
- import { outputUrl } from "@rendobar/sdk";
35
+ ## Install
27
36
 
28
- const result = await client.jobs.wait(job.id);
29
- console.log(outputUrl(result)); // primary download/playable URL
37
+ ```bash
38
+ npm install @rendobar/sdk
30
39
  ```
31
40
 
32
- ## Authentication
33
-
34
- ```typescript
35
- // API key (external users, CLI, scripts)
36
- const client = createClient({ apiKey: "rb_..." });
37
-
38
- // Session cookie (internal dashboard)
39
- const client = createClient({
40
- baseUrl: "https://api.rendobar.com",
41
- credentials: "include",
42
- });
43
- ```
41
+ ## Quickstart
44
42
 
45
- ## Configuration
43
+ Run an FFmpeg command against a remote file and wait for the result. Put input
44
+ URLs directly in `-i` positions; the SDK stages them before execution.
46
45
 
47
46
  ```typescript
48
- const client = createClient({
49
- apiKey: "rb_...",
50
- baseUrl: "https://api.rendobar.com", // default
51
- timeout: 30_000, // default: 30s
52
- maxRetries: 2, // default: 2 (retries 429, 5xx)
53
- orgId: "org_abc", // X-Org-Id header
54
- debug: false, // log request metadata
55
- fetch: customFetch, // custom fetch for testing
56
- });
57
- ```
47
+ import { createClient, outputUrl } from "@rendobar/sdk";
58
48
 
59
- ## Jobs
49
+ const client = createClient({ apiKey: process.env.RENDOBAR_API_KEY });
60
50
 
61
- ```typescript
62
- // Create
63
51
  const job = await client.jobs.create({
64
- type: "watermark.apply",
65
- inputs: { source: "https://example.com/video.mp4" },
66
- params: { text: "PREVIEW", position: "center" },
67
- idempotencyKey: "unique-key-123",
52
+ type: "ffmpeg",
53
+ params: {
54
+ command:
55
+ "ffmpeg -i https://cdn.example.com/source.mp4 " +
56
+ "-vf scale=1280:720 -c:v libx264 -crf 23 output.mp4",
57
+ },
68
58
  });
69
59
 
70
- // Get
71
- const job = await client.jobs.get("job_abc");
72
-
73
- // List (paginated — works with React Query)
74
- const page = await client.jobs.list({ status: "complete", limit: 20 });
75
- // page.data: Job[], page.meta: { total, page, limit }
60
+ const done = await client.jobs.wait(job.id);
61
+ console.log(outputUrl(done));
62
+ ```
76
63
 
77
- // Auto-paginate all pages
78
- for await (const job of client.jobs.listAll({ status: "complete" })) {
79
- console.log(job.id);
80
- }
64
+ Prefer named inputs? Pass them in `inputs` and reference the keys in the command:
81
65
 
82
- // Wait for completion (polls until terminal status)
83
- const result = await client.jobs.wait("job_abc", {
84
- timeout: 300_000,
85
- interval: 2_000,
86
- onProgress: (job) => console.log(job.status),
87
- signal: abortController.signal,
66
+ ```typescript
67
+ await client.jobs.create({
68
+ type: "ffmpeg",
69
+ inputs: { source: "https://cdn.example.com/source.mp4" },
70
+ params: { command: "ffmpeg -i source -vf scale=1280:720 output.mp4" },
88
71
  });
89
-
90
- // Cancel
91
- await client.jobs.cancel("job_abc");
92
-
93
- // Download output (returns raw Response)
94
- const response = await client.jobs.download("job_abc");
95
- const blob = await response.blob();
96
-
97
- // Execution logs
98
- const logs = await client.jobs.logs("job_abc");
99
-
100
- // Available job types
101
- const types = await client.jobs.types();
102
72
  ```
103
73
 
104
- ### Job output
74
+ `ffmpeg` is one of several job types. Composition, compression to a size budget,
75
+ subtitle burn-in, animated captions, and media inspection each have their own.
76
+ Browse them at [rendobar.com/docs/jobs](https://rendobar.com/docs/jobs), or call
77
+ `client.jobs.types()` to read the live registry.
78
+
79
+ ## Reading a result
105
80
 
106
- Every job type returns the same output shape. A completed job carries an
107
- `output` with four fields:
81
+ Every job type returns the same output shape, so you write this handling once.
108
82
 
109
83
  ```typescript
110
84
  type Output = {
@@ -123,219 +97,177 @@ type OutputFile = {
123
97
  };
124
98
  ```
125
99
 
126
- `output` exists only on a completed job (`status === "complete"`), so narrow on
127
- status before reading it.
100
+ `output` exists only when `status === "complete"`, so narrow on status before
101
+ reading it.
128
102
 
129
103
  ```typescript
130
104
  import { outputUrl, jobData } from "@rendobar/sdk";
131
105
 
132
106
  const job = await client.jobs.wait("job_abc");
133
107
 
134
- // Headline URL: the single file, or a stream manifest (.m3u8/.mpd). Returns
135
- // undefined for data-only jobs and pure file sets (no single headline).
108
+ // Headline URL: the single file, or a stream manifest (.m3u8/.mpd). Undefined
109
+ // for data-only jobs and for pure file sets with no single headline.
136
110
  const url = outputUrl(job);
137
111
 
138
- // Or read it yourself after a status check
139
112
  if (job.status === "complete") {
140
- console.log(job.output.file?.url);
141
-
142
- // Iterate every produced file (frame extraction, HLS segments, sprite sets)
143
113
  for (const f of job.output.files) {
144
114
  console.log(f.type, f.path, f.size, f.url);
145
115
  }
146
116
  }
147
117
 
148
- // A failed job carries a structured error instead
149
118
  if (job.status === "failed") {
150
119
  console.log(job.error.code, job.error.message, job.error.detail);
151
120
  }
152
121
  ```
153
122
 
154
- For data jobs (`extract.metadata`, `caption.extract`, detections), the answer is
155
- in `output.data`. It is `unknown` at the contract level because its shape is
156
- job-type-specific. Use `jobData<T>(job)` to read it with your expected type, or
157
- read `job.output.data` and narrow it yourself:
123
+ Inspection jobs put their answer in `output.data`, which is `unknown` at the
124
+ contract level because its shape depends on the job type. `jobData<T>(job)`
125
+ reads it as your expected type:
158
126
 
159
127
  ```typescript
160
- import { jobData } from "@rendobar/sdk";
161
-
162
- type Metadata = { format: string; durationMs: number; width: number; height: number };
163
-
164
- const job = await client.jobs.wait("job_abc");
165
- const meta = jobData<Metadata>(job); // Metadata | null
128
+ type Probe = { format: string; durationMs: number; width: number; height: number };
166
129
 
167
- if (meta) {
168
- console.log(meta.format, meta.durationMs);
169
- }
130
+ const probe = jobData<Probe>(await client.jobs.wait("job_abc")); // Probe | null
170
131
  ```
171
132
 
172
- `T` is your claim about the shape for the job type you submitted. If the input is
173
- untrusted, validate `output.data` yourself (e.g. with Zod) instead of asserting a
174
- type.
175
-
176
- ## Raw FFmpeg
177
-
178
- Run arbitrary FFmpeg commands in a sandboxed container. Commands are parsed, sanitized (protocol whitelist/blacklist flags blocked), and executed with a clean process environment.
179
-
180
- Put input URLs directly in `-i` positions — they're extracted automatically and staged via presigned R2 URLs before execution:
133
+ `T` is your claim about the shape, not a guarantee. If the input is untrusted,
134
+ validate `output.data` with Zod rather than asserting.
181
135
 
182
- ```ts
183
- import { createClient } from "@rendobar/sdk";
136
+ ## Errors
184
137
 
185
- const client = createClient({ apiKey: process.env.RENDOBAR_API_KEY });
186
-
187
- const job = await client.jobs.create({
188
- type: "ffmpeg",
189
- params: {
190
- command:
191
- "ffmpeg -i https://cdn.example.com/source.mp4 " +
192
- "-vf scale=1280:720 -c:v libx264 -crf 23 output.mp4",
193
- },
194
- });
138
+ ```typescript
139
+ import { isApiError } from "@rendobar/sdk";
195
140
 
196
- const done = await client.jobs.wait(job.id);
197
- console.log(outputUrl(done));
141
+ try {
142
+ await client.jobs.create({ type: "ffmpeg", params: { command } });
143
+ } catch (err) {
144
+ if (isApiError(err)) {
145
+ console.log(err.code); // "INSUFFICIENT_CREDITS"
146
+ console.log(err.statusCode); // 402
147
+ console.log(err.retryAfter); // seconds, on 429s
148
+ }
149
+ }
198
150
  ```
199
151
 
200
- Prefer named inputs? Pass them in the top-level `inputs` map and reference the keys in the command:
152
+ Codes: `UNAUTHORIZED`, `FORBIDDEN`, `VALIDATION_ERROR`, `INSUFFICIENT_CREDITS`,
153
+ `RATE_LIMITED`, `NOT_FOUND`, `CONFLICT`, `INTERNAL_ERROR`. Full reference at
154
+ [rendobar.com/docs/support/errors](https://rendobar.com/docs/support/errors).
201
155
 
202
- ```ts
203
- await client.jobs.create({
204
- type: "ffmpeg",
205
- inputs: { source: "https://cdn.example.com/source.mp4" },
206
- params: { command: "ffmpeg -i source -vf scale=1280:720 output.mp4" },
207
- });
208
- ```
209
-
210
- Need a typed params object? Import `FfmpegParams` — optional fields (`timeout`, `compute`) have server-side defaults. The output format comes from the command's output filename.
156
+ 429 and 5xx retry automatically with exponential backoff (500ms, then 1s), twice
157
+ by default, respecting `Retry-After`. 400, 401, 403 and 404 throw immediately.
211
158
 
212
- See the [FFmpeg guide](https://rendobar.com/docs/guides/ffmpeg) for the full security model and supported flags.
159
+ ## The rest of the API
213
160
 
214
- ## Billing
161
+ <details>
162
+ <summary><strong>Jobs</strong></summary>
215
163
 
216
164
  ```typescript
217
- const state = await client.billing.state();
218
- const usage = await client.billing.usage({ start: "2026-01-01", end: "2026-03-29" });
219
- const txns = await client.billing.transactions({ page: 1, limit: 50 });
220
- ```
165
+ await client.jobs.create({ type, inputs, params, idempotencyKey });
166
+ await client.jobs.get("job_abc");
167
+ await client.jobs.cancel("job_abc");
168
+ await client.jobs.logs("job_abc");
169
+ await client.jobs.getTimings("job_abc");
170
+ await client.jobs.types(); // live job registry
221
171
 
222
- ## Uploads
172
+ const page = await client.jobs.list({ status: "complete", limit: 20 });
173
+ // page.data: Job[], page.meta: { total, page, limit }
223
174
 
224
- ```typescript
225
- // Upload a file, get a URL to use as job input
226
- const { downloadUrl } = await client.uploads.upload(file, { filename: "input.mp4" });
175
+ for await (const job of client.jobs.listAll({ status: "complete" })) { /* ... */ }
227
176
 
228
- const job = await client.jobs.create({
229
- type: "watermark.apply",
230
- inputs: { source: downloadUrl },
231
- params: { text: "PREVIEW" },
177
+ await client.jobs.wait("job_abc", {
178
+ timeout: 300_000,
179
+ interval: 2_000,
180
+ onProgress: (job) => console.log(job.status),
181
+ signal: controller.signal,
232
182
  });
183
+
184
+ const response = await client.jobs.download("job_abc"); // raw Response
233
185
  ```
186
+ </details>
234
187
 
235
- ## Batches
188
+ <details>
189
+ <summary><strong>Uploads, batches, billing</strong></summary>
236
190
 
237
191
  ```typescript
238
- const batch = await client.batches.create({
192
+ const { downloadUrl } = await client.uploads.upload(file, { filename: "input.mp4" });
193
+
194
+ await client.batches.create({
239
195
  jobs: [
240
- { type: "watermark.apply", inputs: { source: url1 }, params: { text: "1" } },
241
- { type: "watermark.apply", inputs: { source: url2 }, params: { text: "2" } },
196
+ { type: "ffmpeg", inputs: { source: url1 }, params: { command } },
197
+ { type: "ffmpeg", inputs: { source: url2 }, params: { command } },
242
198
  ],
243
199
  });
200
+
201
+ await client.billing.state();
202
+ await client.billing.usage({ start: "2026-01-01", end: "2026-03-29" });
203
+ await client.billing.transactions({ page: 1, limit: 50 });
244
204
  ```
205
+ </details>
245
206
 
246
- ## Webhooks
207
+ <details>
208
+ <summary><strong>Webhooks</strong></summary>
247
209
 
248
210
  ```typescript
249
- // Create endpoint
250
- const endpoint = await client.webhooks.create({
211
+ await client.webhooks.create({
251
212
  name: "My Webhook",
252
213
  url: "https://example.com/webhook",
253
214
  subscribedEvents: ["job.completed", "job.failed"],
254
215
  });
216
+ ```
217
+
218
+ Verify a delivery with the **raw body**, not parsed JSON. `verifyWebhook` reads
219
+ the signature and timestamp headers, rebuilds the signed string, checks the
220
+ HMAC, rejects stale deliveries, and handles secret rotation.
255
221
 
256
- // Verify signature in your webhook handler
257
- import { verifyWebhookSignature } from "@rendobar/sdk/webhooks";
222
+ ```typescript
223
+ import { verifyWebhook } from "@rendobar/sdk/webhooks";
258
224
 
259
- const isValid = await verifyWebhookSignature(
260
- requestBody,
261
- request.headers.get("X-Rendobar-Signature"),
262
- signingSecret,
263
- );
225
+ if (!(await verifyWebhook(rawBody, request.headers, signingSecret))) {
226
+ throw new Error("invalid signature");
227
+ }
264
228
  ```
265
229
 
266
- ## Realtime Events (WebSocket)
230
+ See the [webhooks guide](https://rendobar.com/docs/guides/webhooks).
231
+ </details>
232
+
233
+ <details>
234
+ <summary><strong>Realtime and client configuration</strong></summary>
235
+
236
+ Realtime needs session cookie auth. On an API key, use `jobs.wait()` instead.
267
237
 
268
238
  ```typescript
269
- // Org-wide event stream
270
239
  const connection = client.realtime.connect({
271
- onEvent: (event) => console.log(event.type, event),
272
- onLive: () => console.log("Replay complete, now live"),
273
- onResync: () => console.log("Buffer overflow refresh data"),
240
+ onEvent: (e) => console.log(e.type, e),
241
+ onLive: () => console.log("replay complete, now live"),
242
+ onResync: () => console.log("buffer overflow, refresh data"),
274
243
  });
275
244
 
276
- // Per-job subscription
277
245
  const sub = client.realtime.subscribeJob("job_abc", {
278
246
  onProgress: (e) => console.log(`${e.progress}%`),
279
- onStep: (e) => console.log(`Step: ${e.stepName}`),
280
- onComplete: (e) => console.log("Done!", e.status),
247
+ onComplete: (e) => console.log("done", e.status),
281
248
  });
282
249
 
283
- // Cleanup
284
250
  connection.disconnect();
285
251
  sub.unsubscribe();
286
252
  ```
287
253
 
288
- > **Note:** Realtime requires session cookie auth. API key users should use `jobs.wait()` for polling.
289
-
290
- ## Error Handling
291
-
292
254
  ```typescript
293
- import { createClient, ApiError, isApiError } from "@rendobar/sdk";
294
-
295
- try {
296
- await client.jobs.create({ type: "watermark.apply", ... });
297
- } catch (err) {
298
- if (isApiError(err)) {
299
- console.log(err.code); // "INSUFFICIENT_CREDITS"
300
- console.log(err.statusCode); // 402
301
- console.log(err.message); // "Not enough credits"
302
- console.log(err.retryAfter); // seconds (for 429s)
303
- }
304
- }
305
- ```
306
-
307
- Error codes: `UNAUTHORIZED`, `FORBIDDEN`, `VALIDATION_ERROR`, `INSUFFICIENT_CREDITS`, `RATE_LIMITED`, `NOT_FOUND`, `CONFLICT`, `INTERNAL_ERROR`.
308
-
309
- ## Retries
310
-
311
- The SDK automatically retries:
312
- - **429** (rate limited) — respects `Retry-After` header
313
- - **500, 502, 503, 504** — server errors
314
-
315
- Retries use exponential backoff (500ms, 1s). Max 2 retries by default. Non-retryable errors (400, 401, 403, 404) throw immediately.
316
-
317
- ## AbortSignal
318
-
319
- Every method accepts an optional `signal` for cancellation:
320
-
321
- ```typescript
322
- const controller = new AbortController();
323
- const job = await client.jobs.get("job_abc", { signal: controller.signal });
255
+ const client = createClient({
256
+ apiKey: "rb_...",
257
+ baseUrl: "https://api.rendobar.com", // default
258
+ timeout: 30_000, // default 30s
259
+ maxRetries: 2, // default 2
260
+ orgId: "org_abc", // X-Org-Id header
261
+ debug: false, // log request metadata
262
+ fetch: customFetch, // inject a fetch, for tests
263
+ });
324
264
 
325
- // Cancel the request
326
- controller.abort();
265
+ // Browser session cookie instead of a key
266
+ createClient({ baseUrl: "https://api.rendobar.com", credentials: "include" });
327
267
  ```
268
+ </details>
328
269
 
329
- ## Types
330
-
331
- All response types are exported:
332
-
333
- ```typescript
334
- import type {
335
- Job, JobStep, Output, OutputFile, FileType, JobError, Cost, JobType, JobCreatedResponse,
336
- BillingState, Transaction, UsageSummary,
337
- WebhookEndpoint, WebhookDelivery,
338
- Organization, ApiKey, PaginationMeta,
339
- BillingInvoice, PaymentMethod, LogEntryData,
340
- } from "@rendobar/sdk";
341
- ```
270
+ Response types are all exported: `Job`, `JobStep`, `Output`, `OutputFile`,
271
+ `FileType`, `JobError`, `Cost`, `JobType`, `BillingState`, `Transaction`,
272
+ `UsageSummary`, `WebhookEndpoint`, `WebhookDelivery`, `Organization`, `ApiKey`,
273
+ and `PaginationMeta`.
package/dist/index.d.cts CHANGED
@@ -2163,13 +2163,13 @@ declare const jobStepSchema: ZodObject<{
2163
2163
  * treating the file as opaque ("other"). Adding a value here is non-breaking.
2164
2164
  */
2165
2165
  declare const fileTypeSchema: ZodEnum<{
2166
- video: "video";
2167
- image: "image";
2168
2166
  audio: "audio";
2169
2167
  captions: "captions";
2170
- playlist: "playlist";
2171
2168
  data: "data";
2169
+ image: "image";
2172
2170
  other: "other";
2171
+ playlist: "playlist";
2172
+ video: "video";
2173
2173
  }>;
2174
2174
  /**
2175
2175
  * A single produced file. `url` is a ready-to-fetch, time-limited URL (signed
@@ -2181,13 +2181,13 @@ declare const fileSchema: ZodObject<{
2181
2181
  url: ZodString;
2182
2182
  path: ZodString;
2183
2183
  type: ZodEnum<{
2184
- video: "video";
2185
- image: "image";
2186
2184
  audio: "audio";
2187
2185
  captions: "captions";
2188
- playlist: "playlist";
2189
2186
  data: "data";
2187
+ image: "image";
2190
2188
  other: "other";
2189
+ playlist: "playlist";
2190
+ video: "video";
2191
2191
  }>;
2192
2192
  size: ZodNumber;
2193
2193
  meta: ZodOptional<ZodObject<{
@@ -2203,13 +2203,13 @@ declare const jobOutputSchema: ZodObject<{
2203
2203
  url: ZodString;
2204
2204
  path: ZodString;
2205
2205
  type: ZodEnum<{
2206
- video: "video";
2207
- image: "image";
2208
2206
  audio: "audio";
2209
2207
  captions: "captions";
2210
- playlist: "playlist";
2211
2208
  data: "data";
2209
+ image: "image";
2212
2210
  other: "other";
2211
+ playlist: "playlist";
2212
+ video: "video";
2213
2213
  }>;
2214
2214
  size: ZodNumber;
2215
2215
  meta: ZodOptional<ZodObject<{
@@ -2223,13 +2223,13 @@ declare const jobOutputSchema: ZodObject<{
2223
2223
  url: ZodString;
2224
2224
  path: ZodString;
2225
2225
  type: ZodEnum<{
2226
- video: "video";
2227
- image: "image";
2228
2226
  audio: "audio";
2229
2227
  captions: "captions";
2230
- playlist: "playlist";
2231
2228
  data: "data";
2229
+ image: "image";
2232
2230
  other: "other";
2231
+ playlist: "playlist";
2232
+ video: "video";
2233
2233
  }>;
2234
2234
  size: ZodNumber;
2235
2235
  meta: ZodOptional<ZodObject<{
@@ -2247,9 +2247,9 @@ declare const jobErrorSchema: ZodObject<{
2247
2247
  detail: ZodNullable<ZodString>;
2248
2248
  retryable: ZodBoolean;
2249
2249
  failedPhase: ZodOptional<ZodEnum<{
2250
+ finalizing: "finalizing";
2250
2251
  preparing: "preparing";
2251
2252
  processing: "processing";
2252
- finalizing: "finalizing";
2253
2253
  }>>;
2254
2254
  }, $strip>;
2255
2255
  declare const jobCostSchema: ZodObject<{
@@ -2274,12 +2274,12 @@ declare const jobResponseSchema: ZodDiscriminatedUnion<[ZodObject<{
2274
2274
  formatted: ZodString;
2275
2275
  }, $strip>>;
2276
2276
  outputCategory: ZodEnum<{
2277
- video: "video";
2278
- image: "image";
2279
2277
  audio: "audio";
2280
2278
  captions: "captions";
2279
+ image: "image";
2281
2280
  json: "json";
2282
2281
  raw: "raw";
2282
+ video: "video";
2283
2283
  }>;
2284
2284
  steps: ZodArray<ZodObject<{
2285
2285
  id: ZodString;
@@ -2301,6 +2301,13 @@ declare const jobResponseSchema: ZodDiscriminatedUnion<[ZodObject<{
2301
2301
  completedAt: ZodNullable<ZodNumber>;
2302
2302
  settledAt: ZodNullable<ZodNumber>;
2303
2303
  retentionExpiresAt: ZodNullable<ZodNumber>;
2304
+ callback: ZodOptional<ZodNullable<ZodObject<{
2305
+ status: ZodEnum<{
2306
+ delivered: "delivered";
2307
+ failed: "failed";
2308
+ pending: "pending";
2309
+ }>;
2310
+ }, $strip>>>;
2304
2311
  status: ZodLiteral<"waiting">;
2305
2312
  }, $strip>, ZodObject<{
2306
2313
  id: ZodString;
@@ -2319,12 +2326,12 @@ declare const jobResponseSchema: ZodDiscriminatedUnion<[ZodObject<{
2319
2326
  formatted: ZodString;
2320
2327
  }, $strip>>;
2321
2328
  outputCategory: ZodEnum<{
2322
- video: "video";
2323
- image: "image";
2324
2329
  audio: "audio";
2325
2330
  captions: "captions";
2331
+ image: "image";
2326
2332
  json: "json";
2327
2333
  raw: "raw";
2334
+ video: "video";
2328
2335
  }>;
2329
2336
  steps: ZodArray<ZodObject<{
2330
2337
  id: ZodString;
@@ -2346,6 +2353,13 @@ declare const jobResponseSchema: ZodDiscriminatedUnion<[ZodObject<{
2346
2353
  completedAt: ZodNullable<ZodNumber>;
2347
2354
  settledAt: ZodNullable<ZodNumber>;
2348
2355
  retentionExpiresAt: ZodNullable<ZodNumber>;
2356
+ callback: ZodOptional<ZodNullable<ZodObject<{
2357
+ status: ZodEnum<{
2358
+ delivered: "delivered";
2359
+ failed: "failed";
2360
+ pending: "pending";
2361
+ }>;
2362
+ }, $strip>>>;
2349
2363
  status: ZodLiteral<"dispatched">;
2350
2364
  progress: ZodOptional<ZodNullable<ZodNumber>>;
2351
2365
  eta: ZodOptional<ZodNullable<ZodNumber>>;
@@ -2366,12 +2380,12 @@ declare const jobResponseSchema: ZodDiscriminatedUnion<[ZodObject<{
2366
2380
  formatted: ZodString;
2367
2381
  }, $strip>>;
2368
2382
  outputCategory: ZodEnum<{
2369
- video: "video";
2370
- image: "image";
2371
2383
  audio: "audio";
2372
2384
  captions: "captions";
2385
+ image: "image";
2373
2386
  json: "json";
2374
2387
  raw: "raw";
2388
+ video: "video";
2375
2389
  }>;
2376
2390
  steps: ZodArray<ZodObject<{
2377
2391
  id: ZodString;
@@ -2393,6 +2407,13 @@ declare const jobResponseSchema: ZodDiscriminatedUnion<[ZodObject<{
2393
2407
  completedAt: ZodNullable<ZodNumber>;
2394
2408
  settledAt: ZodNullable<ZodNumber>;
2395
2409
  retentionExpiresAt: ZodNullable<ZodNumber>;
2410
+ callback: ZodOptional<ZodNullable<ZodObject<{
2411
+ status: ZodEnum<{
2412
+ delivered: "delivered";
2413
+ failed: "failed";
2414
+ pending: "pending";
2415
+ }>;
2416
+ }, $strip>>>;
2396
2417
  status: ZodLiteral<"running">;
2397
2418
  progress: ZodNullable<ZodNumber>;
2398
2419
  eta: ZodNullable<ZodNumber>;
@@ -2413,12 +2434,12 @@ declare const jobResponseSchema: ZodDiscriminatedUnion<[ZodObject<{
2413
2434
  formatted: ZodString;
2414
2435
  }, $strip>>;
2415
2436
  outputCategory: ZodEnum<{
2416
- video: "video";
2417
- image: "image";
2418
2437
  audio: "audio";
2419
2438
  captions: "captions";
2439
+ image: "image";
2420
2440
  json: "json";
2421
2441
  raw: "raw";
2442
+ video: "video";
2422
2443
  }>;
2423
2444
  steps: ZodArray<ZodObject<{
2424
2445
  id: ZodString;
@@ -2440,6 +2461,13 @@ declare const jobResponseSchema: ZodDiscriminatedUnion<[ZodObject<{
2440
2461
  completedAt: ZodNullable<ZodNumber>;
2441
2462
  settledAt: ZodNullable<ZodNumber>;
2442
2463
  retentionExpiresAt: ZodNullable<ZodNumber>;
2464
+ callback: ZodOptional<ZodNullable<ZodObject<{
2465
+ status: ZodEnum<{
2466
+ delivered: "delivered";
2467
+ failed: "failed";
2468
+ pending: "pending";
2469
+ }>;
2470
+ }, $strip>>>;
2443
2471
  status: ZodLiteral<"complete">;
2444
2472
  output: ZodObject<{
2445
2473
  data: ZodUnknown;
@@ -2447,13 +2475,13 @@ declare const jobResponseSchema: ZodDiscriminatedUnion<[ZodObject<{
2447
2475
  url: ZodString;
2448
2476
  path: ZodString;
2449
2477
  type: ZodEnum<{
2450
- video: "video";
2451
- image: "image";
2452
2478
  audio: "audio";
2453
2479
  captions: "captions";
2454
- playlist: "playlist";
2455
2480
  data: "data";
2481
+ image: "image";
2456
2482
  other: "other";
2483
+ playlist: "playlist";
2484
+ video: "video";
2457
2485
  }>;
2458
2486
  size: ZodNumber;
2459
2487
  meta: ZodOptional<ZodObject<{
@@ -2467,13 +2495,13 @@ declare const jobResponseSchema: ZodDiscriminatedUnion<[ZodObject<{
2467
2495
  url: ZodString;
2468
2496
  path: ZodString;
2469
2497
  type: ZodEnum<{
2470
- video: "video";
2471
- image: "image";
2472
2498
  audio: "audio";
2473
2499
  captions: "captions";
2474
- playlist: "playlist";
2475
2500
  data: "data";
2501
+ image: "image";
2476
2502
  other: "other";
2503
+ playlist: "playlist";
2504
+ video: "video";
2477
2505
  }>;
2478
2506
  size: ZodNumber;
2479
2507
  meta: ZodOptional<ZodObject<{
@@ -2502,12 +2530,12 @@ declare const jobResponseSchema: ZodDiscriminatedUnion<[ZodObject<{
2502
2530
  formatted: ZodString;
2503
2531
  }, $strip>>;
2504
2532
  outputCategory: ZodEnum<{
2505
- video: "video";
2506
- image: "image";
2507
2533
  audio: "audio";
2508
2534
  captions: "captions";
2535
+ image: "image";
2509
2536
  json: "json";
2510
2537
  raw: "raw";
2538
+ video: "video";
2511
2539
  }>;
2512
2540
  steps: ZodArray<ZodObject<{
2513
2541
  id: ZodString;
@@ -2529,6 +2557,13 @@ declare const jobResponseSchema: ZodDiscriminatedUnion<[ZodObject<{
2529
2557
  completedAt: ZodNullable<ZodNumber>;
2530
2558
  settledAt: ZodNullable<ZodNumber>;
2531
2559
  retentionExpiresAt: ZodNullable<ZodNumber>;
2560
+ callback: ZodOptional<ZodNullable<ZodObject<{
2561
+ status: ZodEnum<{
2562
+ delivered: "delivered";
2563
+ failed: "failed";
2564
+ pending: "pending";
2565
+ }>;
2566
+ }, $strip>>>;
2532
2567
  status: ZodLiteral<"failed">;
2533
2568
  error: ZodObject<{
2534
2569
  code: ZodString;
@@ -2536,9 +2571,9 @@ declare const jobResponseSchema: ZodDiscriminatedUnion<[ZodObject<{
2536
2571
  detail: ZodNullable<ZodString>;
2537
2572
  retryable: ZodBoolean;
2538
2573
  failedPhase: ZodOptional<ZodEnum<{
2574
+ finalizing: "finalizing";
2539
2575
  preparing: "preparing";
2540
2576
  processing: "processing";
2541
- finalizing: "finalizing";
2542
2577
  }>>;
2543
2578
  }, $strip>;
2544
2579
  }, $strip>, ZodObject<{
@@ -2558,12 +2593,12 @@ declare const jobResponseSchema: ZodDiscriminatedUnion<[ZodObject<{
2558
2593
  formatted: ZodString;
2559
2594
  }, $strip>>;
2560
2595
  outputCategory: ZodEnum<{
2561
- video: "video";
2562
- image: "image";
2563
2596
  audio: "audio";
2564
2597
  captions: "captions";
2598
+ image: "image";
2565
2599
  json: "json";
2566
2600
  raw: "raw";
2601
+ video: "video";
2567
2602
  }>;
2568
2603
  steps: ZodArray<ZodObject<{
2569
2604
  id: ZodString;
@@ -2585,6 +2620,13 @@ declare const jobResponseSchema: ZodDiscriminatedUnion<[ZodObject<{
2585
2620
  completedAt: ZodNullable<ZodNumber>;
2586
2621
  settledAt: ZodNullable<ZodNumber>;
2587
2622
  retentionExpiresAt: ZodNullable<ZodNumber>;
2623
+ callback: ZodOptional<ZodNullable<ZodObject<{
2624
+ status: ZodEnum<{
2625
+ delivered: "delivered";
2626
+ failed: "failed";
2627
+ pending: "pending";
2628
+ }>;
2629
+ }, $strip>>>;
2588
2630
  status: ZodLiteral<"cancelled">;
2589
2631
  }, $strip>], "status">;
2590
2632
  declare const jobCreatedResponseSchema: ZodObject<{
@@ -2722,10 +2764,10 @@ declare const webhookDeliverySchema: ZodObject<{
2722
2764
  event: ZodString;
2723
2765
  payload: ZodString;
2724
2766
  status: ZodEnum<{
2725
- failed: "failed";
2726
2767
  cancelled: "cancelled";
2727
- pending: "pending";
2728
2768
  delivered: "delivered";
2769
+ failed: "failed";
2770
+ pending: "pending";
2729
2771
  }>;
2730
2772
  statusCode: ZodNullable<ZodNumber>;
2731
2773
  responseBody: ZodNullable<ZodString>;
@@ -2982,9 +3024,9 @@ declare const orgEventSchema: ZodDiscriminatedUnion<[ZodObject<{
2982
3024
  timestamp: ZodNumber;
2983
3025
  progress: ZodNullable<ZodNumber>;
2984
3026
  phase: ZodOptional<ZodEnum<{
3027
+ finalizing: "finalizing";
2985
3028
  preparing: "preparing";
2986
3029
  processing: "processing";
2987
- finalizing: "finalizing";
2988
3030
  }>>;
2989
3031
  step: ZodString;
2990
3032
  stepProgress: ZodOptional<ZodNumber>;
@@ -3041,10 +3083,10 @@ declare const orgEventSchema: ZodDiscriminatedUnion<[ZodObject<{
3041
3083
  jobId: ZodString;
3042
3084
  timestamp: ZodOptional<ZodNumber>;
3043
3085
  level: ZodEnum<{
3086
+ debug: "debug";
3044
3087
  error: "error";
3045
3088
  info: "info";
3046
3089
  warn: "warn";
3047
- debug: "debug";
3048
3090
  }>;
3049
3091
  message: ZodString;
3050
3092
  step: ZodOptional<ZodString>;
@@ -3458,7 +3500,7 @@ declare function createClient(config?: ClientConfig): {
3458
3500
  signal?: AbortSignal;
3459
3501
  }): Promise<void>;
3460
3502
  getSettings(options?: {
3461
- signal? /** Custom fetch function for testing or special runtimes. */ : AbortSignal;
3503
+ signal?: AbortSignal;
3462
3504
  }): Promise<OrgSettings>;
3463
3505
  updateSettings(body: Partial<Pick<OrgSettings, "billingEmailsEnabled" | "defaultRegion" | "regionPinned">>, options?: {
3464
3506
  signal?: AbortSignal;
@@ -3643,6 +3685,31 @@ type CreateJobParams = {
3643
3685
  params?: Record<string, unknown>;
3644
3686
  idempotencyKey?: string;
3645
3687
  forceAsync?: boolean;
3688
+ /**
3689
+ * Per-job completion callback. On a terminal state (complete/failed/cancelled)
3690
+ * Rendobar POSTs the standard job envelope to `url`. HTTPS only. The URL is the
3691
+ * capability — keep it secret, or use the callback as a trigger and re-fetch the
3692
+ * job for authoritative data.
3693
+ *
3694
+ * Optional `headers` (e.g. `{ Authorization: "Bearer …" }`) are sent with the
3695
+ * POST, so the callback can hit an authed target directly — for example
3696
+ * Cloudflare's Workflows events endpoint, with no receiver Worker.
3697
+ *
3698
+ * Set `verify: true` to opt into signing: the POST then carries an
3699
+ * `X-Rendobar-Signature` (same HMAC scheme as webhooks). Fetch your org's
3700
+ * callback signing secret once (`GET /orgs/current/callback-secret`) and verify
3701
+ * with `verifyCallback(rawBody, headers, secret)` from `@rendobar/sdk/webhooks`.
3702
+ *
3703
+ * `events` opts into EXTRA non-terminal events. Terminal events
3704
+ * (complete/failed/cancelled) always fire and can't be filtered out, so a
3705
+ * `waitForEvent` can never hang. Today the only opt-in extra is `job.started`.
3706
+ */
3707
+ callback?: {
3708
+ url: string;
3709
+ headers?: Record<string, string>;
3710
+ verify?: boolean;
3711
+ events?: "job.started"[];
3712
+ };
3646
3713
  };
3647
3714
  type ListJobsParams = {
3648
3715
  status?: string;
package/dist/index.d.mts CHANGED
@@ -2163,13 +2163,13 @@ declare const jobStepSchema: ZodObject<{
2163
2163
  * treating the file as opaque ("other"). Adding a value here is non-breaking.
2164
2164
  */
2165
2165
  declare const fileTypeSchema: ZodEnum<{
2166
- video: "video";
2167
- image: "image";
2168
2166
  audio: "audio";
2169
2167
  captions: "captions";
2170
- playlist: "playlist";
2171
2168
  data: "data";
2169
+ image: "image";
2172
2170
  other: "other";
2171
+ playlist: "playlist";
2172
+ video: "video";
2173
2173
  }>;
2174
2174
  /**
2175
2175
  * A single produced file. `url` is a ready-to-fetch, time-limited URL (signed
@@ -2181,13 +2181,13 @@ declare const fileSchema: ZodObject<{
2181
2181
  url: ZodString;
2182
2182
  path: ZodString;
2183
2183
  type: ZodEnum<{
2184
- video: "video";
2185
- image: "image";
2186
2184
  audio: "audio";
2187
2185
  captions: "captions";
2188
- playlist: "playlist";
2189
2186
  data: "data";
2187
+ image: "image";
2190
2188
  other: "other";
2189
+ playlist: "playlist";
2190
+ video: "video";
2191
2191
  }>;
2192
2192
  size: ZodNumber;
2193
2193
  meta: ZodOptional<ZodObject<{
@@ -2203,13 +2203,13 @@ declare const jobOutputSchema: ZodObject<{
2203
2203
  url: ZodString;
2204
2204
  path: ZodString;
2205
2205
  type: ZodEnum<{
2206
- video: "video";
2207
- image: "image";
2208
2206
  audio: "audio";
2209
2207
  captions: "captions";
2210
- playlist: "playlist";
2211
2208
  data: "data";
2209
+ image: "image";
2212
2210
  other: "other";
2211
+ playlist: "playlist";
2212
+ video: "video";
2213
2213
  }>;
2214
2214
  size: ZodNumber;
2215
2215
  meta: ZodOptional<ZodObject<{
@@ -2223,13 +2223,13 @@ declare const jobOutputSchema: ZodObject<{
2223
2223
  url: ZodString;
2224
2224
  path: ZodString;
2225
2225
  type: ZodEnum<{
2226
- video: "video";
2227
- image: "image";
2228
2226
  audio: "audio";
2229
2227
  captions: "captions";
2230
- playlist: "playlist";
2231
2228
  data: "data";
2229
+ image: "image";
2232
2230
  other: "other";
2231
+ playlist: "playlist";
2232
+ video: "video";
2233
2233
  }>;
2234
2234
  size: ZodNumber;
2235
2235
  meta: ZodOptional<ZodObject<{
@@ -2247,9 +2247,9 @@ declare const jobErrorSchema: ZodObject<{
2247
2247
  detail: ZodNullable<ZodString>;
2248
2248
  retryable: ZodBoolean;
2249
2249
  failedPhase: ZodOptional<ZodEnum<{
2250
+ finalizing: "finalizing";
2250
2251
  preparing: "preparing";
2251
2252
  processing: "processing";
2252
- finalizing: "finalizing";
2253
2253
  }>>;
2254
2254
  }, $strip>;
2255
2255
  declare const jobCostSchema: ZodObject<{
@@ -2274,12 +2274,12 @@ declare const jobResponseSchema: ZodDiscriminatedUnion<[ZodObject<{
2274
2274
  formatted: ZodString;
2275
2275
  }, $strip>>;
2276
2276
  outputCategory: ZodEnum<{
2277
- video: "video";
2278
- image: "image";
2279
2277
  audio: "audio";
2280
2278
  captions: "captions";
2279
+ image: "image";
2281
2280
  json: "json";
2282
2281
  raw: "raw";
2282
+ video: "video";
2283
2283
  }>;
2284
2284
  steps: ZodArray<ZodObject<{
2285
2285
  id: ZodString;
@@ -2301,6 +2301,13 @@ declare const jobResponseSchema: ZodDiscriminatedUnion<[ZodObject<{
2301
2301
  completedAt: ZodNullable<ZodNumber>;
2302
2302
  settledAt: ZodNullable<ZodNumber>;
2303
2303
  retentionExpiresAt: ZodNullable<ZodNumber>;
2304
+ callback: ZodOptional<ZodNullable<ZodObject<{
2305
+ status: ZodEnum<{
2306
+ delivered: "delivered";
2307
+ failed: "failed";
2308
+ pending: "pending";
2309
+ }>;
2310
+ }, $strip>>>;
2304
2311
  status: ZodLiteral<"waiting">;
2305
2312
  }, $strip>, ZodObject<{
2306
2313
  id: ZodString;
@@ -2319,12 +2326,12 @@ declare const jobResponseSchema: ZodDiscriminatedUnion<[ZodObject<{
2319
2326
  formatted: ZodString;
2320
2327
  }, $strip>>;
2321
2328
  outputCategory: ZodEnum<{
2322
- video: "video";
2323
- image: "image";
2324
2329
  audio: "audio";
2325
2330
  captions: "captions";
2331
+ image: "image";
2326
2332
  json: "json";
2327
2333
  raw: "raw";
2334
+ video: "video";
2328
2335
  }>;
2329
2336
  steps: ZodArray<ZodObject<{
2330
2337
  id: ZodString;
@@ -2346,6 +2353,13 @@ declare const jobResponseSchema: ZodDiscriminatedUnion<[ZodObject<{
2346
2353
  completedAt: ZodNullable<ZodNumber>;
2347
2354
  settledAt: ZodNullable<ZodNumber>;
2348
2355
  retentionExpiresAt: ZodNullable<ZodNumber>;
2356
+ callback: ZodOptional<ZodNullable<ZodObject<{
2357
+ status: ZodEnum<{
2358
+ delivered: "delivered";
2359
+ failed: "failed";
2360
+ pending: "pending";
2361
+ }>;
2362
+ }, $strip>>>;
2349
2363
  status: ZodLiteral<"dispatched">;
2350
2364
  progress: ZodOptional<ZodNullable<ZodNumber>>;
2351
2365
  eta: ZodOptional<ZodNullable<ZodNumber>>;
@@ -2366,12 +2380,12 @@ declare const jobResponseSchema: ZodDiscriminatedUnion<[ZodObject<{
2366
2380
  formatted: ZodString;
2367
2381
  }, $strip>>;
2368
2382
  outputCategory: ZodEnum<{
2369
- video: "video";
2370
- image: "image";
2371
2383
  audio: "audio";
2372
2384
  captions: "captions";
2385
+ image: "image";
2373
2386
  json: "json";
2374
2387
  raw: "raw";
2388
+ video: "video";
2375
2389
  }>;
2376
2390
  steps: ZodArray<ZodObject<{
2377
2391
  id: ZodString;
@@ -2393,6 +2407,13 @@ declare const jobResponseSchema: ZodDiscriminatedUnion<[ZodObject<{
2393
2407
  completedAt: ZodNullable<ZodNumber>;
2394
2408
  settledAt: ZodNullable<ZodNumber>;
2395
2409
  retentionExpiresAt: ZodNullable<ZodNumber>;
2410
+ callback: ZodOptional<ZodNullable<ZodObject<{
2411
+ status: ZodEnum<{
2412
+ delivered: "delivered";
2413
+ failed: "failed";
2414
+ pending: "pending";
2415
+ }>;
2416
+ }, $strip>>>;
2396
2417
  status: ZodLiteral<"running">;
2397
2418
  progress: ZodNullable<ZodNumber>;
2398
2419
  eta: ZodNullable<ZodNumber>;
@@ -2413,12 +2434,12 @@ declare const jobResponseSchema: ZodDiscriminatedUnion<[ZodObject<{
2413
2434
  formatted: ZodString;
2414
2435
  }, $strip>>;
2415
2436
  outputCategory: ZodEnum<{
2416
- video: "video";
2417
- image: "image";
2418
2437
  audio: "audio";
2419
2438
  captions: "captions";
2439
+ image: "image";
2420
2440
  json: "json";
2421
2441
  raw: "raw";
2442
+ video: "video";
2422
2443
  }>;
2423
2444
  steps: ZodArray<ZodObject<{
2424
2445
  id: ZodString;
@@ -2440,6 +2461,13 @@ declare const jobResponseSchema: ZodDiscriminatedUnion<[ZodObject<{
2440
2461
  completedAt: ZodNullable<ZodNumber>;
2441
2462
  settledAt: ZodNullable<ZodNumber>;
2442
2463
  retentionExpiresAt: ZodNullable<ZodNumber>;
2464
+ callback: ZodOptional<ZodNullable<ZodObject<{
2465
+ status: ZodEnum<{
2466
+ delivered: "delivered";
2467
+ failed: "failed";
2468
+ pending: "pending";
2469
+ }>;
2470
+ }, $strip>>>;
2443
2471
  status: ZodLiteral<"complete">;
2444
2472
  output: ZodObject<{
2445
2473
  data: ZodUnknown;
@@ -2447,13 +2475,13 @@ declare const jobResponseSchema: ZodDiscriminatedUnion<[ZodObject<{
2447
2475
  url: ZodString;
2448
2476
  path: ZodString;
2449
2477
  type: ZodEnum<{
2450
- video: "video";
2451
- image: "image";
2452
2478
  audio: "audio";
2453
2479
  captions: "captions";
2454
- playlist: "playlist";
2455
2480
  data: "data";
2481
+ image: "image";
2456
2482
  other: "other";
2483
+ playlist: "playlist";
2484
+ video: "video";
2457
2485
  }>;
2458
2486
  size: ZodNumber;
2459
2487
  meta: ZodOptional<ZodObject<{
@@ -2467,13 +2495,13 @@ declare const jobResponseSchema: ZodDiscriminatedUnion<[ZodObject<{
2467
2495
  url: ZodString;
2468
2496
  path: ZodString;
2469
2497
  type: ZodEnum<{
2470
- video: "video";
2471
- image: "image";
2472
2498
  audio: "audio";
2473
2499
  captions: "captions";
2474
- playlist: "playlist";
2475
2500
  data: "data";
2501
+ image: "image";
2476
2502
  other: "other";
2503
+ playlist: "playlist";
2504
+ video: "video";
2477
2505
  }>;
2478
2506
  size: ZodNumber;
2479
2507
  meta: ZodOptional<ZodObject<{
@@ -2502,12 +2530,12 @@ declare const jobResponseSchema: ZodDiscriminatedUnion<[ZodObject<{
2502
2530
  formatted: ZodString;
2503
2531
  }, $strip>>;
2504
2532
  outputCategory: ZodEnum<{
2505
- video: "video";
2506
- image: "image";
2507
2533
  audio: "audio";
2508
2534
  captions: "captions";
2535
+ image: "image";
2509
2536
  json: "json";
2510
2537
  raw: "raw";
2538
+ video: "video";
2511
2539
  }>;
2512
2540
  steps: ZodArray<ZodObject<{
2513
2541
  id: ZodString;
@@ -2529,6 +2557,13 @@ declare const jobResponseSchema: ZodDiscriminatedUnion<[ZodObject<{
2529
2557
  completedAt: ZodNullable<ZodNumber>;
2530
2558
  settledAt: ZodNullable<ZodNumber>;
2531
2559
  retentionExpiresAt: ZodNullable<ZodNumber>;
2560
+ callback: ZodOptional<ZodNullable<ZodObject<{
2561
+ status: ZodEnum<{
2562
+ delivered: "delivered";
2563
+ failed: "failed";
2564
+ pending: "pending";
2565
+ }>;
2566
+ }, $strip>>>;
2532
2567
  status: ZodLiteral<"failed">;
2533
2568
  error: ZodObject<{
2534
2569
  code: ZodString;
@@ -2536,9 +2571,9 @@ declare const jobResponseSchema: ZodDiscriminatedUnion<[ZodObject<{
2536
2571
  detail: ZodNullable<ZodString>;
2537
2572
  retryable: ZodBoolean;
2538
2573
  failedPhase: ZodOptional<ZodEnum<{
2574
+ finalizing: "finalizing";
2539
2575
  preparing: "preparing";
2540
2576
  processing: "processing";
2541
- finalizing: "finalizing";
2542
2577
  }>>;
2543
2578
  }, $strip>;
2544
2579
  }, $strip>, ZodObject<{
@@ -2558,12 +2593,12 @@ declare const jobResponseSchema: ZodDiscriminatedUnion<[ZodObject<{
2558
2593
  formatted: ZodString;
2559
2594
  }, $strip>>;
2560
2595
  outputCategory: ZodEnum<{
2561
- video: "video";
2562
- image: "image";
2563
2596
  audio: "audio";
2564
2597
  captions: "captions";
2598
+ image: "image";
2565
2599
  json: "json";
2566
2600
  raw: "raw";
2601
+ video: "video";
2567
2602
  }>;
2568
2603
  steps: ZodArray<ZodObject<{
2569
2604
  id: ZodString;
@@ -2585,6 +2620,13 @@ declare const jobResponseSchema: ZodDiscriminatedUnion<[ZodObject<{
2585
2620
  completedAt: ZodNullable<ZodNumber>;
2586
2621
  settledAt: ZodNullable<ZodNumber>;
2587
2622
  retentionExpiresAt: ZodNullable<ZodNumber>;
2623
+ callback: ZodOptional<ZodNullable<ZodObject<{
2624
+ status: ZodEnum<{
2625
+ delivered: "delivered";
2626
+ failed: "failed";
2627
+ pending: "pending";
2628
+ }>;
2629
+ }, $strip>>>;
2588
2630
  status: ZodLiteral<"cancelled">;
2589
2631
  }, $strip>], "status">;
2590
2632
  declare const jobCreatedResponseSchema: ZodObject<{
@@ -2722,10 +2764,10 @@ declare const webhookDeliverySchema: ZodObject<{
2722
2764
  event: ZodString;
2723
2765
  payload: ZodString;
2724
2766
  status: ZodEnum<{
2725
- failed: "failed";
2726
2767
  cancelled: "cancelled";
2727
- pending: "pending";
2728
2768
  delivered: "delivered";
2769
+ failed: "failed";
2770
+ pending: "pending";
2729
2771
  }>;
2730
2772
  statusCode: ZodNullable<ZodNumber>;
2731
2773
  responseBody: ZodNullable<ZodString>;
@@ -2982,9 +3024,9 @@ declare const orgEventSchema: ZodDiscriminatedUnion<[ZodObject<{
2982
3024
  timestamp: ZodNumber;
2983
3025
  progress: ZodNullable<ZodNumber>;
2984
3026
  phase: ZodOptional<ZodEnum<{
3027
+ finalizing: "finalizing";
2985
3028
  preparing: "preparing";
2986
3029
  processing: "processing";
2987
- finalizing: "finalizing";
2988
3030
  }>>;
2989
3031
  step: ZodString;
2990
3032
  stepProgress: ZodOptional<ZodNumber>;
@@ -3041,10 +3083,10 @@ declare const orgEventSchema: ZodDiscriminatedUnion<[ZodObject<{
3041
3083
  jobId: ZodString;
3042
3084
  timestamp: ZodOptional<ZodNumber>;
3043
3085
  level: ZodEnum<{
3086
+ debug: "debug";
3044
3087
  error: "error";
3045
3088
  info: "info";
3046
3089
  warn: "warn";
3047
- debug: "debug";
3048
3090
  }>;
3049
3091
  message: ZodString;
3050
3092
  step: ZodOptional<ZodString>;
@@ -3458,7 +3500,7 @@ declare function createClient(config?: ClientConfig): {
3458
3500
  signal?: AbortSignal;
3459
3501
  }): Promise<void>;
3460
3502
  getSettings(options?: {
3461
- signal? /** Custom fetch function for testing or special runtimes. */ : AbortSignal;
3503
+ signal?: AbortSignal;
3462
3504
  }): Promise<OrgSettings>;
3463
3505
  updateSettings(body: Partial<Pick<OrgSettings, "billingEmailsEnabled" | "defaultRegion" | "regionPinned">>, options?: {
3464
3506
  signal?: AbortSignal;
@@ -3643,6 +3685,31 @@ type CreateJobParams = {
3643
3685
  params?: Record<string, unknown>;
3644
3686
  idempotencyKey?: string;
3645
3687
  forceAsync?: boolean;
3688
+ /**
3689
+ * Per-job completion callback. On a terminal state (complete/failed/cancelled)
3690
+ * Rendobar POSTs the standard job envelope to `url`. HTTPS only. The URL is the
3691
+ * capability — keep it secret, or use the callback as a trigger and re-fetch the
3692
+ * job for authoritative data.
3693
+ *
3694
+ * Optional `headers` (e.g. `{ Authorization: "Bearer …" }`) are sent with the
3695
+ * POST, so the callback can hit an authed target directly — for example
3696
+ * Cloudflare's Workflows events endpoint, with no receiver Worker.
3697
+ *
3698
+ * Set `verify: true` to opt into signing: the POST then carries an
3699
+ * `X-Rendobar-Signature` (same HMAC scheme as webhooks). Fetch your org's
3700
+ * callback signing secret once (`GET /orgs/current/callback-secret`) and verify
3701
+ * with `verifyCallback(rawBody, headers, secret)` from `@rendobar/sdk/webhooks`.
3702
+ *
3703
+ * `events` opts into EXTRA non-terminal events. Terminal events
3704
+ * (complete/failed/cancelled) always fire and can't be filtered out, so a
3705
+ * `waitForEvent` can never hang. Today the only opt-in extra is `job.started`.
3706
+ */
3707
+ callback?: {
3708
+ url: string;
3709
+ headers?: Record<string, string>;
3710
+ verify?: boolean;
3711
+ events?: "job.started"[];
3712
+ };
3646
3713
  };
3647
3714
  type ListJobsParams = {
3648
3715
  status?: string;
package/dist/webhooks.cjs CHANGED
@@ -77,5 +77,6 @@ async function verifyWebhookSignature(payload, signature, secret) {
77
77
  return mismatch === 0;
78
78
  }
79
79
  //#endregion
80
+ exports.verifyCallback = verifyWebhook;
80
81
  exports.verifyWebhook = verifyWebhook;
81
82
  exports.verifyWebhookSignature = verifyWebhookSignature;
@@ -40,4 +40,4 @@ declare function verifyWebhook(body: string, headers: WebhookHeaders, secret: st
40
40
  */
41
41
  declare function verifyWebhookSignature(payload: string, signature: string, secret: string): Promise<boolean>;
42
42
  //#endregion
43
- export { type WebhookHeaders, verifyWebhook, verifyWebhookSignature };
43
+ export { type WebhookHeaders, verifyWebhook as verifyCallback, verifyWebhook, verifyWebhookSignature };
@@ -40,4 +40,4 @@ declare function verifyWebhook(body: string, headers: WebhookHeaders, secret: st
40
40
  */
41
41
  declare function verifyWebhookSignature(payload: string, signature: string, secret: string): Promise<boolean>;
42
42
  //#endregion
43
- export { type WebhookHeaders, verifyWebhook, verifyWebhookSignature };
43
+ export { type WebhookHeaders, verifyWebhook as verifyCallback, verifyWebhook, verifyWebhookSignature };
package/dist/webhooks.mjs CHANGED
@@ -76,4 +76,4 @@ async function verifyWebhookSignature(payload, signature, secret) {
76
76
  return mismatch === 0;
77
77
  }
78
78
  //#endregion
79
- export { verifyWebhook, verifyWebhookSignature };
79
+ export { verifyWebhook as verifyCallback, verifyWebhook, verifyWebhookSignature };
package/package.json CHANGED
@@ -1,8 +1,29 @@
1
1
  {
2
2
  "name": "@rendobar/sdk",
3
- "version": "5.0.0",
3
+ "version": "5.1.1",
4
4
  "type": "module",
5
5
  "description": "TypeScript client for the Rendobar media processing API",
6
+ "license": "MIT",
7
+ "homepage": "https://rendobar.com/docs/sdk",
8
+ "repository": {
9
+ "type": "git",
10
+ "url": "https://github.com/rendobar/rendobar.git",
11
+ "directory": "packages/sdk"
12
+ },
13
+ "bugs": {
14
+ "url": "https://github.com/rendobar/rendobar/issues"
15
+ },
16
+ "author": "Rendobar",
17
+ "keywords": [
18
+ "rendobar",
19
+ "ffmpeg",
20
+ "video",
21
+ "media-processing",
22
+ "transcode",
23
+ "api-client",
24
+ "sdk",
25
+ "typescript"
26
+ ],
6
27
  "main": "./dist/index.cjs",
7
28
  "module": "./dist/index.mjs",
8
29
  "types": "./dist/index.d.cts",
@@ -41,9 +62,10 @@
41
62
  "partysocket": "^1.1.16"
42
63
  },
43
64
  "devDependencies": {
65
+ "@types/node": "^25",
44
66
  "@rendobar/shared": "workspace:*",
45
67
  "tsdown": "^0.22.0",
46
- "typescript": "^5.9.3",
68
+ "typescript": "^7.0.2",
47
69
  "vitest": "^4.0.18"
48
70
  }
49
71
  }