@convertrilo/sdk 0.0.10 → 0.0.11

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
@@ -41,6 +41,38 @@ For a complete server-to-server walkthrough covering URL, S3, folder ingest, Goo
41
41
  OAuth tokens, polling, and webhooks, see
42
42
  [`docs/API-INTEGRATION-GUIDE.md`](docs/API-INTEGRATION-GUIDE.md).
43
43
 
44
+ ## Idempotent Job Creation
45
+
46
+ Use an idempotency key when retrying create calls from your backend. Reusing the same key with the
47
+ same body returns the original response instead of creating duplicate jobs.
48
+
49
+ ```ts
50
+ const job = await client.createJob({
51
+ externalId: "upload-123",
52
+ metadata: { customerId: "cus_123" },
53
+ codec: "h264",
54
+ resolution: "1080p",
55
+ fps: 30,
56
+ }, {
57
+ idempotencyKey: "job-upload-123",
58
+ });
59
+
60
+ const batch = await client.createJobsBulk({
61
+ jobs: [
62
+ {
63
+ externalId: "batch-42:clip-1",
64
+ codec: "h264",
65
+ resolution: "1080p",
66
+ fps: 30,
67
+ sourceS3: { bucket: "source", key: "clip-1.mp4" },
68
+ },
69
+ ],
70
+ settings: { confirm: true },
71
+ }, {
72
+ idempotencyKey: "bulk-batch-42",
73
+ });
74
+ ```
75
+
44
76
  ## URL Source To CDN Output
45
77
 
46
78
  ```ts
@@ -35,8 +35,13 @@ export declare class ConvertriloClient {
35
35
  reserveTokens(body: paths["/tokens/reserve"]["post"]["requestBody"]["content"]["application/json"]): Promise<unknown>;
36
36
  releaseTokens(body: paths["/tokens/release"]["post"]["requestBody"]["content"]["application/json"]): Promise<unknown>;
37
37
  deductTokens(body: paths["/tokens/deduct"]["post"]["requestBody"]["content"]["application/json"]): Promise<unknown>;
38
- createJob(body: paths["/jobs"]["post"]["requestBody"]["content"]["application/json"]): Promise<{
38
+ createJob(body: paths["/jobs"]["post"]["requestBody"]["content"]["application/json"], options?: RequestOptions): Promise<{
39
39
  jobId: string;
40
+ externalId?: string | null;
41
+ metadata?: {
42
+ [key: string]: unknown;
43
+ } | null;
44
+ status?: string;
40
45
  upload: {
41
46
  url?: string;
42
47
  key?: string;
@@ -47,6 +52,8 @@ export declare class ConvertriloClient {
47
52
  };
48
53
  estimate?: {
49
54
  neu?: number;
55
+ totalNeu?: number;
56
+ reserved?: number;
50
57
  };
51
58
  }>;
52
59
  probeDuration(id: string): Promise<{
@@ -73,14 +80,22 @@ export declare class ConvertriloClient {
73
80
  encoder?: string | null;
74
81
  pct?: number | null;
75
82
  }>;
76
- createJobsBulk(body: paths["/jobs/bulk"]["post"]["requestBody"]["content"]["application/json"]): Promise<{
83
+ createJobsBulk(body: paths["/jobs/bulk"]["post"]["requestBody"]["content"]["application/json"], options?: RequestOptions): Promise<{
77
84
  totalJobs?: number;
78
85
  totalEstimatedNeu?: number;
86
+ reserved?: number;
79
87
  jobs?: {
80
88
  index?: number;
81
89
  jobId?: string;
90
+ externalId?: string | null;
91
+ metadata?: {
92
+ [key: string]: unknown;
93
+ } | null;
82
94
  status?: string;
83
95
  error?: string;
96
+ estimate?: {
97
+ neu?: number;
98
+ };
84
99
  }[];
85
100
  }>;
86
101
  bulkStatus(ids: string[]): Promise<{
package/dist/src/index.js CHANGED
@@ -68,10 +68,13 @@ export class ConvertriloClient {
68
68
  });
69
69
  }
70
70
  // Jobs
71
- async createJob(body) {
71
+ async createJob(body, options = {}) {
72
72
  return this.request(`/jobs`, {
73
73
  method: "POST",
74
74
  body: JSON.stringify(body),
75
+ headers: options.idempotencyKey
76
+ ? { "Idempotency-Key": options.idempotencyKey }
77
+ : undefined,
75
78
  });
76
79
  }
77
80
  async probeDuration(id) {
@@ -96,10 +99,13 @@ export class ConvertriloClient {
96
99
  return this.request(`/jobs/${id}/status`);
97
100
  }
98
101
  // Bulk Jobs
99
- async createJobsBulk(body) {
102
+ async createJobsBulk(body, options = {}) {
100
103
  return this.request(`/jobs/bulk`, {
101
104
  method: "POST",
102
105
  body: JSON.stringify(body),
106
+ headers: options.idempotencyKey
107
+ ? { "Idempotency-Key": options.idempotencyKey }
108
+ : undefined,
103
109
  });
104
110
  }
105
111
  async bulkStatus(ids) {
@@ -204,12 +204,15 @@ export interface paths {
204
204
  put?: never;
205
205
  /**
206
206
  * Create a new encode job
207
- * @description Create a job for upload ingest (returns a presigned PUT) or direct URL/S3 ingest.
207
+ * @description Create a job for upload ingest (returns a presigned PUT) or direct URL/S3 ingest. Send `Idempotency-Key` when retrying from your backend to avoid duplicate jobs.
208
208
  */
209
209
  post: {
210
210
  parameters: {
211
211
  query?: never;
212
- header?: never;
212
+ header?: {
213
+ /** @description Optional key for safely retrying job creation requests. Reusing the same key with the same request body replays the original response; reusing it with a different body returns 409. */
214
+ "Idempotency-Key"?: components["parameters"]["IdempotencyKey"];
215
+ };
213
216
  path?: never;
214
217
  cookie?: never;
215
218
  };
@@ -773,11 +776,17 @@ export interface paths {
773
776
  };
774
777
  get?: never;
775
778
  put?: never;
776
- /** Bulk create jobs */
779
+ /**
780
+ * Bulk create jobs
781
+ * @description Send `Idempotency-Key` when retrying from your backend to avoid duplicate bulk batches, duplicate token reservations, or duplicate queue entries.
782
+ */
777
783
  post: {
778
784
  parameters: {
779
785
  query?: never;
780
- header?: never;
786
+ header?: {
787
+ /** @description Optional key for safely retrying job creation requests. Reusing the same key with the same request body replays the original response; reusing it with a different body returns 409. */
788
+ "Idempotency-Key"?: components["parameters"]["IdempotencyKey"];
789
+ };
781
790
  path?: never;
782
791
  cookie?: never;
783
792
  };
@@ -1505,6 +1514,12 @@ export interface components {
1505
1514
  amount: number;
1506
1515
  };
1507
1516
  JobCreateRequest: {
1517
+ /** @description Your stable job identifier for reconciliation in status responses and webhooks. */
1518
+ externalId?: string;
1519
+ /** @description Integration-owned JSON object returned in status responses and webhooks. */
1520
+ metadata?: {
1521
+ [key: string]: unknown;
1522
+ };
1508
1523
  /** @enum {string} */
1509
1524
  codec: "h264" | "h265" | "av1";
1510
1525
  /** @enum {string} */
@@ -1559,6 +1574,12 @@ export interface components {
1559
1574
  };
1560
1575
  JobCreateResponse: {
1561
1576
  jobId: string;
1577
+ externalId?: string | null;
1578
+ metadata?: {
1579
+ [key: string]: unknown;
1580
+ } | null;
1581
+ /** @description Present when the job is auto-confirmed and queued. */
1582
+ status?: string;
1562
1583
  upload: {
1563
1584
  url?: string;
1564
1585
  key?: string;
@@ -1569,6 +1590,8 @@ export interface components {
1569
1590
  };
1570
1591
  estimate?: {
1571
1592
  neu?: number;
1593
+ totalNeu?: number;
1594
+ reserved?: number;
1572
1595
  };
1573
1596
  };
1574
1597
  ProbeDurationResponse: {
@@ -1648,12 +1671,20 @@ export interface components {
1648
1671
  BulkCreateResponse: {
1649
1672
  totalJobs?: number;
1650
1673
  totalEstimatedNeu?: number;
1674
+ reserved?: number;
1651
1675
  jobs?: {
1652
1676
  index?: number;
1653
1677
  /** Format: uuid */
1654
1678
  jobId?: string;
1679
+ externalId?: string | null;
1680
+ metadata?: {
1681
+ [key: string]: unknown;
1682
+ } | null;
1655
1683
  status?: string;
1656
1684
  error?: string;
1685
+ estimate?: {
1686
+ neu?: number;
1687
+ };
1657
1688
  }[];
1658
1689
  };
1659
1690
  BulkStatusResponse: {
@@ -46,6 +46,39 @@ const client = new ConvertriloClient({
46
46
 
47
47
  SDK source and examples: https://github.com/serkandrgn/convertrilo-js
48
48
 
49
+ ## Idempotency
50
+
51
+ When your backend retries `POST /jobs`, `POST /jobs/bulk`, `POST /ondemand/encode`, or
52
+ `POST /ondemand/ingest/folder`, send an idempotency key. The API replays the original response for
53
+ the same key and body, and returns `409` if the key is reused with a different body.
54
+
55
+ ```ts
56
+ const job = await client.createJob({
57
+ externalId: "upload-123",
58
+ metadata: { customerId: "cus_123" },
59
+ codec: "h264",
60
+ resolution: "1080p",
61
+ fps: 30,
62
+ }, {
63
+ idempotencyKey: "job-upload-123",
64
+ });
65
+
66
+ const batch = await client.createJobsBulk({
67
+ jobs: [
68
+ {
69
+ externalId: "batch-42:clip-1",
70
+ codec: "h264",
71
+ resolution: "1080p",
72
+ fps: 30,
73
+ sourceS3: { bucket: "source", key: "clip-1.mp4" },
74
+ },
75
+ ],
76
+ settings: { confirm: true },
77
+ }, {
78
+ idempotencyKey: "bulk-batch-42",
79
+ });
80
+ ```
81
+
49
82
  ## Flow 1: URL Source To CDN Output
50
83
 
51
84
  Use this when the source video is already available over HTTP(S), and you want Convertrilo to return a signed CDN download URL.
package/openapi.yaml CHANGED
@@ -81,6 +81,14 @@ components:
81
81
  type: object
82
82
  required: [codec, resolution, fps]
83
83
  properties:
84
+ externalId:
85
+ type: string
86
+ maxLength: 255
87
+ description: Your stable job identifier for reconciliation in status responses and webhooks.
88
+ metadata:
89
+ type: object
90
+ additionalProperties: true
91
+ description: Integration-owned JSON object returned in status responses and webhooks.
84
92
  codec:
85
93
  type: string
86
94
  enum: [h264, h265, av1]
@@ -136,6 +144,14 @@ components:
136
144
  required: [jobId, upload, output]
137
145
  properties:
138
146
  jobId: { type: string }
147
+ externalId: { type: string, nullable: true }
148
+ metadata:
149
+ type: object
150
+ additionalProperties: true
151
+ nullable: true
152
+ status:
153
+ type: string
154
+ description: Present when the job is auto-confirmed and queued.
139
155
  upload:
140
156
  nullable: true
141
157
  type: object
@@ -151,6 +167,8 @@ components:
151
167
  type: object
152
168
  properties:
153
169
  neu: { type: number }
170
+ totalNeu: { type: number }
171
+ reserved: { type: number }
154
172
  ProbeDurationResponse:
155
173
  type: object
156
174
  properties:
@@ -230,6 +248,7 @@ components:
230
248
  properties:
231
249
  totalJobs: { type: integer }
232
250
  totalEstimatedNeu: { type: number }
251
+ reserved: { type: number }
233
252
  jobs:
234
253
  type: array
235
254
  items:
@@ -237,8 +256,17 @@ components:
237
256
  properties:
238
257
  index: { type: integer }
239
258
  jobId: { type: string, format: uuid }
259
+ externalId: { type: string, nullable: true }
260
+ metadata:
261
+ type: object
262
+ additionalProperties: true
263
+ nullable: true
240
264
  status: { type: string }
241
265
  error: { type: string }
266
+ estimate:
267
+ type: object
268
+ properties:
269
+ neu: { type: number }
242
270
  BulkStatusResponse:
243
271
  type: object
244
272
  properties:
@@ -714,7 +742,9 @@ paths:
714
742
  post:
715
743
  security: [{ BearerAuth: [] }, { ApiKeyAuth: [] }]
716
744
  summary: Create a new encode job
717
- description: Create a job for upload ingest (returns a presigned PUT) or direct URL/S3 ingest.
745
+ description: Create a job for upload ingest (returns a presigned PUT) or direct URL/S3 ingest. Send `Idempotency-Key` when retrying from your backend to avoid duplicate jobs.
746
+ parameters:
747
+ - $ref: "#/components/parameters/IdempotencyKey"
718
748
  requestBody:
719
749
  required: true
720
750
  content:
@@ -993,6 +1023,9 @@ paths:
993
1023
  post:
994
1024
  security: [{ BearerAuth: [] }, { ApiKeyAuth: [] }]
995
1025
  summary: Bulk create jobs
1026
+ description: Send `Idempotency-Key` when retrying from your backend to avoid duplicate bulk batches, duplicate token reservations, or duplicate queue entries.
1027
+ parameters:
1028
+ - $ref: "#/components/parameters/IdempotencyKey"
996
1029
  requestBody:
997
1030
  required: true
998
1031
  content:
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@convertrilo/sdk",
3
- "version": "0.0.10",
3
+ "version": "0.0.11",
4
4
  "description": "TypeScript client for the Convertrilo video encoding API",
5
5
  "private": false,
6
6
  "license": "MIT",