@remotion-studio/sdk 0.1.0 → 0.1.2

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.
Files changed (2) hide show
  1. package/README.md +214 -207
  2. package/package.json +20 -4
package/README.md CHANGED
@@ -1,56 +1,13 @@
1
- # Remotion Studio
1
+ # @remotion-studio/sdk
2
2
 
3
- Generate, edit, play, and render AI-created Remotion compositions from your own apps.
3
+ Official SDK for the hosted Remotion Studio API.
4
4
 
5
- `@remotion-studio/sdk` is the official package for [Remotion Studio](https://remotionstudio.io). It gives you:
5
+ This package includes:
6
6
 
7
- - `@remotion-studio/sdk` to call the Remotion Studio API
8
- - `@remotion-studio/sdk/runtime` to render returned artifacts inside a Remotion project
7
+ - `@remotion-studio/sdk` for calling the API
8
+ - `@remotion-studio/sdk/runtime` for rendering returned artifacts inside Remotion or `@remotion/player`
9
9
 
10
- If you want a visual workflow, use the Remotion Studio UI. If you want to automate generation, build editors, run async jobs, or embed generated scenes in your own product, use the SDK.
11
-
12
- With this package you can:
13
-
14
- - generate new Remotion compositions from prompts
15
- - edit compositions through follow-up instructions
16
- - play returned artifacts directly inside a Remotion app
17
- - queue long-running async generation or edit jobs
18
- - start Remotion Lambda renders and track render progress
19
- - embed the returned artifact directly inside your own Remotion app
20
-
21
- ## Why Use It
22
-
23
- - Generate motion graphics from prompts
24
- - Edit existing compositions iteratively
25
- - Play returned artifacts immediately in Remotion
26
- - Stream generation output
27
- - Queue long-running jobs and use polling or webhooks
28
- - Start cloud renders and poll for the final video output
29
- - Render the returned artifact directly inside Remotion
30
-
31
- ## Use It Two Ways
32
-
33
- ### 1. Use the UI
34
-
35
- Use [Remotion Studio](https://remotionstudio.io) when you want a visual workflow:
36
-
37
- - create and refine compositions in the browser
38
- - manage prompts, edits, and threads
39
- - create API tokens for external apps
40
-
41
- ### 2. Use the API and SDK
42
-
43
- Use `@remotion-studio/sdk` when you want to:
44
-
45
- - generate compositions from your own app
46
- - build internal tools or automations
47
- - trigger async jobs from servers or background workers
48
- - start Remotion Lambda renders programmatically
49
- - embed generated artifacts in a Remotion pipeline
50
-
51
- ## Quick Start
52
-
53
- Install:
10
+ ## Install
54
11
 
55
12
  ```bash
56
13
  npm install @remotion-studio/sdk
@@ -64,137 +21,91 @@ pnpm add @remotion-studio/sdk
64
21
  bun add @remotion-studio/sdk
65
22
  ```
66
23
 
67
- Create a client:
24
+ ## Authentication
25
+
26
+ Create a personal API token in the Remotion Studio web app, then use it as a bearer token.
68
27
 
69
28
  ```ts
70
29
  import { createRemotionStudioClient } from "@remotion-studio/sdk";
71
30
 
72
31
  const client = createRemotionStudioClient({
73
- baseUrl: "https://your-remotionstudio-domain.com",
32
+ baseUrl: "https://remotionstudio.io",
74
33
  headers: {
75
34
  Authorization: `Bearer ${process.env.REMOTIONSTUDIO_API_TOKEN}`,
76
35
  },
77
36
  });
78
37
  ```
79
38
 
80
- Generate a composition:
39
+ The plaintext token is shown only once when it is created.
81
40
 
82
- ```ts
83
- const generated = await client.generate({
84
- prompt: "A cinematic product hero reveal with dramatic lighting",
85
- reasoningEffort: "none",
86
- });
87
- ```
41
+ ## Client Options
88
42
 
89
- Edit it:
43
+ `createRemotionStudioClient()` accepts:
90
44
 
91
- ```ts
92
- const edited = await client.edit({
93
- prompt: "Make it faster, cleaner, and more typography-driven",
94
- currentCode: generated.code,
95
- threadId: generated.thread?.id,
96
- });
97
- ```
45
+ - `baseUrl?: string`
46
+ - `headers?: HeadersInit`
47
+ - `fetch?: typeof fetch`
98
48
 
99
- Use the artifact in Remotion:
49
+ `baseUrl` should be the Remotion Studio origin, for example `https://remotionstudio.io`, not `https://remotionstudio.io/api`.
100
50
 
101
- ```tsx
102
- import { MotionGraphicsSlot } from "@remotion-studio/sdk/runtime";
51
+ ## SDK Methods
103
52
 
104
- export const MyComposition = ({ artifact }: { artifact: any }) => {
105
- return <MotionGraphicsSlot artifact={artifact} />;
106
- };
107
- ```
53
+ | Method | HTTP | Endpoint | Purpose |
54
+ | ---------------------- | ------ | ---------------------------- | ----------------------------------------------- |
55
+ | `generate()` | `POST` | `/api/generate` | Generate a composition |
56
+ | `generateStream()` | `POST` | `/api/generate` | Stream generation output with `streaming: true` |
57
+ | `edit()` | `POST` | `/api/edit` | Edit existing code |
58
+ | `generateAsync()` | `POST` | `/api/generate/async` | Queue a generation job |
59
+ | `getGenerationJob()` | `GET` | `/api/generate/async/:jobId` | Read generation job state |
60
+ | `pollGenerationJob()` | `GET` | `/api/generate/async/:jobId` | Wait for generation completion |
61
+ | `editAsync()` | `POST` | `/api/edit/async` | Queue an edit job |
62
+ | `getEditJob()` | `GET` | `/api/edit/async/:jobId` | Read edit job state |
63
+ | `pollEditJob()` | `GET` | `/api/edit/async/:jobId` | Wait for edit completion |
64
+ | `render()` | `POST` | `/api/render/render` | Start a Remotion Lambda render |
65
+ | `getRenderProgress()` | `POST` | `/api/render/progress` | Fetch render progress |
66
+ | `pollRenderProgress()` | `POST` | `/api/render/progress` | Wait for render completion |
108
67
 
109
- Start a Remotion Lambda render:
110
-
111
- ```ts
112
- const render = await client.render({
113
- inputProps: {
114
- code: generated.code,
115
- durationInFrames: generated.artifact.composition.durationInFrames,
116
- fps: generated.artifact.composition.fps,
117
- },
118
- threadId: generated.thread?.id,
119
- });
120
-
121
- const progress = await client.pollRenderProgress({
122
- id: render.renderId,
123
- bucketName: render.bucketName,
124
- });
125
- ```
126
-
127
- Successful renders consume `0.1` credit when the final video is returned.
128
-
129
- ## Getting Access
130
-
131
- To use the hosted product, create an account in [Remotion Studio](https://remotionstudio.io).
132
-
133
- To generate, edit, or render compositions through the hosted product, you also need active access to Remotion Studio credits or a subscription plan.
134
-
135
- For programmatic usage:
136
-
137
- 1. Sign in to Remotion Studio
138
- 2. Open `Settings -> API Tokens`
139
- 3. Create a token
140
- 4. Use it as a bearer token in the SDK client
141
-
142
- The plaintext token is shown only once.
143
-
144
- ## What The SDK Returns
145
-
146
- You do not import generated files directly.
147
-
148
- Instead:
149
-
150
- 1. Call the API with `@remotion-studio/sdk`
151
- 2. Receive a JSON payload containing `artifact`
152
- 3. Pass `artifact` into `@remotion-studio/sdk/runtime`
153
-
154
- The artifact is the stable contract between generation and playback.
155
-
156
- ## Core API
157
-
158
- ### Generate
159
-
160
- ```ts
161
- const generated = await client.generate({
162
- prompt: "A clean fintech dashboard animation with sliding cards",
163
- reasoningEffort: "high",
164
- });
165
- ```
166
-
167
- #### Presets
168
-
169
- Pass a `presetId` to generate compositions using a predefined style template:
68
+ ## Generate
170
69
 
171
70
  ```ts
172
71
  const generated = await client.generate({
173
- prompt: "A product showcase with smooth transitions",
174
- presetId: "preset-abc123",
72
+ prompt: "A cinematic product hero reveal with dramatic lighting",
73
+ reasoningEffort: "none",
175
74
  });
176
75
  ```
177
76
 
178
- The response includes preset information in the metadata:
77
+ Request fields:
179
78
 
180
- ```ts
181
- console.log(generated.metadata.preset);
182
- // { id: "preset-abc123", name: "Corporate Minimal", source: "builtin" | "custom" }
183
- ```
79
+ - `prompt: string`
80
+ - `presetId?: string`
81
+ - `model?: string`
82
+ - `reasoningEffort?: "none" | "low" | "medium" | "high" | "xhigh"`
83
+ - `frameImages?: string[]`
184
84
 
185
- Presets are created and managed in the Remotion Studio UI. Builtin presets are provided by Remotion Studio. Custom presets are user-created templates that encode style preferences, animation patterns, and design choices.
186
-
187
- ### Edit
85
+ ## Edit
188
86
 
189
87
  ```ts
190
88
  const edited = await client.edit({
191
- prompt: "Use a brighter palette and add more depth",
89
+ prompt: "Make it faster, cleaner, and more typography-driven",
192
90
  currentCode: generated.code,
193
91
  threadId: generated.thread?.id,
194
92
  });
195
93
  ```
196
94
 
197
- ### Stream
95
+ Common request fields:
96
+
97
+ - `prompt: string`
98
+ - `currentCode: string`
99
+ - `threadId?: string`
100
+ - `conversationHistory?: { role: "user" | "assistant"; content: string; attachedImages?: string[] }[]`
101
+ - `hasManualEdits?: boolean`
102
+ - `errorCorrection?: { error: string; source?: "compilation" | "runtime" | "generation"; attemptNumber: number; maxAttempts: number; failedEdit?: { description: string; old_string: string; new_string: string; lineNumber?: number } }`
103
+ - `previouslyUsedSkills?: string[]`
104
+ - `frameImages?: string[]`
105
+ - `model?: string`
106
+ - `reasoningEffort?: "none" | "low" | "medium" | "high" | "xhigh"`
107
+
108
+ ## Stream Generation
198
109
 
199
110
  ```ts
200
111
  const result = await client.generateStream(
@@ -205,9 +116,15 @@ const result = await client.generateStream(
205
116
  onMetadata: (metadata) => {
206
117
  console.log(metadata);
207
118
  },
119
+ onReasoningStart: () => {
120
+ console.log("reasoning started");
121
+ },
208
122
  onReasoning: (reasoning) => {
209
123
  console.log(reasoning);
210
124
  },
125
+ onTextStart: () => {
126
+ console.log("code started");
127
+ },
211
128
  onCode: (partialCode) => {
212
129
  console.log(partialCode);
213
130
  },
@@ -217,14 +134,9 @@ const result = await client.generateStream(
217
134
 
218
135
  ## Async Jobs
219
136
 
220
- Use async jobs for:
221
-
222
- - high-reasoning generations
223
- - server-to-server automation
224
- - long-running edits
225
- - webhook-driven integrations
137
+ Use async methods for long-running generations or edits.
226
138
 
227
- Queue a generation:
139
+ ### Queue A Generation
228
140
 
229
141
  ```ts
230
142
  const job = await client.generateAsync({
@@ -244,56 +156,151 @@ const generated = await client.pollGenerationJob(job.id, {
244
156
  });
245
157
  ```
246
158
 
247
- Queue an edit:
159
+ ### Read A Generation Job
160
+
161
+ ```ts
162
+ const jobState = await client.getGenerationJob(job.id);
163
+ ```
164
+
165
+ ### Queue An Edit
248
166
 
249
167
  ```ts
250
- const job = await client.editAsync({
168
+ const editJob = await client.editAsync({
251
169
  prompt: "Add more contrast and speed up the transitions",
252
170
  currentCode: generated.code,
253
171
  threadId: generated.thread?.id,
254
172
  });
255
173
 
256
- const edited = await client.pollEditJob(job.id);
174
+ const edited = await client.pollEditJob(editJob.id);
257
175
  ```
258
176
 
259
- If you provide a webhook, Remotion Studio sends the terminal job payload to your callback URL after completion or failure.
177
+ ### Read An Edit Job
178
+
179
+ ```ts
180
+ const editJobState = await client.getEditJob(editJob.id);
181
+ ```
260
182
 
261
- Webhook authentication is handled by caller-provided headers. Remotion Studio forwards those headers when delivering the callback.
183
+ Webhook headers are caller-owned. Remotion Studio forwards them when delivering the callback.
262
184
 
263
- There is no built-in webhook signature mechanism.
185
+ ## Render
264
186
 
265
- The recommended pattern is:
187
+ Start a render:
266
188
 
267
189
  ```ts
268
- await client.generateAsync({
269
- prompt: "...",
270
- webhook: {
271
- url: "https://your-app.example.com/remotionstudio/webhook",
272
- headers: {
273
- Authorization: "Bearer your-app-owned-callback-token",
274
- },
190
+ const render = await client.render({
191
+ inputProps: {
192
+ code: generated.code,
193
+ durationInFrames: generated.artifact.composition.durationInFrames,
194
+ fps: generated.artifact.composition.fps,
275
195
  },
196
+ threadId: generated.thread?.id,
197
+ });
198
+ ```
199
+
200
+ Check progress once:
201
+
202
+ ```ts
203
+ const progress = await client.getRenderProgress({
204
+ id: render.renderId,
205
+ bucketName: render.bucketName,
276
206
  });
277
207
  ```
278
208
 
279
- Remotion Studio may include neutral metadata headers such as `X-RemotionStudio-Job-Id` and `X-RemotionStudio-Job-Type`, but it does not sign, mutate, wrap, or replace caller-provided webhook headers.
209
+ Poll until done:
280
210
 
281
- ## Local Dev And Production
211
+ ```ts
212
+ const completed = await client.pollRenderProgress(
213
+ {
214
+ id: render.renderId,
215
+ bucketName: render.bucketName,
216
+ },
217
+ {
218
+ intervalMs: 2000,
219
+ timeoutMs: 10 * 60 * 1000,
220
+ },
221
+ );
222
+
223
+ console.log(completed.url);
224
+ ```
282
225
 
283
- The async API contract stays the same across environments:
226
+ ## Responses
284
227
 
285
- - local `next dev`: jobs are stored in the database and processed by a local runner
286
- - Vercel preview/production: jobs are stored in the database and executed through Vercel Workflow
228
+ `generate()` and `edit()` return:
287
229
 
288
- In both cases:
230
+ - `code`
231
+ - `summary`
232
+ - `metadata`
233
+ - `artifact`
234
+ - `thread?`
289
235
 
290
- - polling endpoints remain the source of truth
291
- - webhooks receive the same terminal payload shape
292
- - transient webhook failures are retried
236
+ The `artifact` is the stable runtime contract for playback and rendering.
293
237
 
294
238
  ## Runtime
295
239
 
296
- Use `@remotion-studio/sdk/runtime` when you want to render returned artifacts inside a Remotion project.
240
+ `@remotion-studio/sdk/runtime` exports:
241
+
242
+ - `MotionGraphicsSlot`
243
+ - `MotionGraphicsComposition`
244
+ - `calculateMotionGraphicsMetadata`
245
+ - `compileMotionGraphicsArtifact`
246
+
247
+ The runtime executes generated code inside your app process. Treat returned artifacts as trusted code only.
248
+
249
+ ### Render Inside An Existing Composition
250
+
251
+ Use `MotionGraphicsSlot` when you want to place a generated artifact inside your own composition tree.
252
+
253
+ ```tsx
254
+ import { AbsoluteFill } from "remotion";
255
+ import {
256
+ MotionGraphicsSlot,
257
+ type MotionGraphicsArtifact,
258
+ } from "@remotion-studio/sdk/runtime";
259
+
260
+ export const MyComposition = ({
261
+ artifact,
262
+ }: {
263
+ artifact: MotionGraphicsArtifact;
264
+ }) => {
265
+ return (
266
+ <AbsoluteFill>
267
+ <MotionGraphicsSlot artifact={artifact} />
268
+ </AbsoluteFill>
269
+ );
270
+ };
271
+ ```
272
+
273
+ ### Render In `@remotion/player`
274
+
275
+ ```tsx
276
+ import { Player } from "@remotion/player";
277
+ import {
278
+ MotionGraphicsComposition,
279
+ type MotionGraphicsArtifact,
280
+ } from "@remotion-studio/sdk/runtime";
281
+
282
+ export const ArtifactPlayer = ({
283
+ artifact,
284
+ }: {
285
+ artifact: MotionGraphicsArtifact;
286
+ }) => {
287
+ return (
288
+ <Player
289
+ component={MotionGraphicsComposition}
290
+ inputProps={{ artifact }}
291
+ durationInFrames={artifact.composition.durationInFrames}
292
+ fps={artifact.composition.fps}
293
+ compositionWidth={artifact.composition.width}
294
+ compositionHeight={artifact.composition.height}
295
+ controls
296
+ />
297
+ );
298
+ };
299
+ ```
300
+
301
+ ### Register As A Remotion Composition
302
+
303
+ Use `MotionGraphicsComposition` with `calculateMotionGraphicsMetadata` when the artifact should define the composition dimensions and timing.
297
304
 
298
305
  ```tsx
299
306
  import { Composition } from "remotion";
@@ -319,51 +326,51 @@ export const RemotionRoot = ({ artifact }: MotionGraphicsCompositionProps) => {
319
326
  };
320
327
  ```
321
328
 
322
- The runtime expects a normal Remotion project with the peer dependencies installed, including `react`, `remotion`, `three`, `@babel/standalone`, `@remotion/lottie`, `@remotion/shapes`, `@remotion/three`, and `@remotion/transitions`.
323
-
324
- ## Render API
329
+ ### Runtime Props
325
330
 
326
- If your Remotion Studio instance is configured with Remotion Lambda, the SDK also supports:
331
+ Both `MotionGraphicsSlot` and `MotionGraphicsComposition` accept:
327
332
 
328
- - `client.render()` to queue a render
329
- - `client.getRenderProgress()` to fetch the latest render state
330
- - `client.pollRenderProgress()` to wait until the render completes
333
+ - `artifact: MotionGraphicsArtifact`
334
+ - `componentProps?: Record<string, unknown>`
331
335
 
332
- The render endpoints return the Remotion Lambda render identifiers and progress state, including the final output URL when rendering is done.
336
+ `componentProps` is forwarded to the generated component at runtime.
333
337
 
334
- ## Model And Credit Notes
338
+ ## Runtime Dependencies
335
339
 
336
- The base model is controlled by the Remotion Studio admin. External clients should usually send only `reasoningEffort`.
337
- Supported `reasoningEffort` values are `none`, `low`, `medium`, `high`, and `xhigh`. Use `none` to explicitly disable reasoning.
340
+ If you only use the API client from `@remotion-studio/sdk`, you do not need any runtime dependencies.
338
341
 
339
- Current credit usage is:
342
+ If you use `@remotion-studio/sdk/runtime`, the package installs its runtime helper dependencies for you.
340
343
 
341
- - default request or `reasoningEffort: "none"`: 1 credit
342
- - successful render completion: 0.1 credit
343
- - `low`: 2 credits
344
- - `medium`: 3 credits
345
- - `high`: 4 credits
346
- - `xhigh`: 5 credits
344
+ You still need to use it inside a normal React + Remotion app, and install `@remotion/player` separately if you want to use the player example above.
347
345
 
348
- Legacy clients may still send `model: "provider/model:medium"`, but only the reasoning suffix is used.
346
+ ## Errors
349
347
 
350
- ## API Docs
348
+ API failures throw `RemotionStudioError`.
351
349
 
352
- If you run your own Remotion Studio instance, the generated API reference is available at:
350
+ Useful fields:
353
351
 
354
- ```text
355
- https://your-remotionstudio-domain.com/api-docs
356
- ```
352
+ - `message`
353
+ - `type`
354
+ - `status?`
355
+ - `failedEdit?`
356
+ - `availableCredits?`
357
+ - `requiredCredits?`
357
358
 
358
- ## Links
359
+ ## API Docs
359
360
 
360
- - Website: [remotionstudio.io](https://remotionstudio.io)
361
- - Product: [Remotion Studio](https://remotionstudio.io)
362
- - Repository: [github.com/prismosoft/remotionstudio](https://github.com/prismosoft/remotionstudio)
361
+ - Hosted API reference: [remotionstudio.io/api-docs](https://remotionstudio.io/api-docs)
363
362
 
364
363
  ## Package Exports
365
364
 
366
365
  ```ts
367
- import { createRemotionStudioClient } from "@remotion-studio/sdk";
368
- import { MotionGraphicsSlot } from "@remotion-studio/sdk/runtime";
366
+ import {
367
+ createRemotionStudioClient,
368
+ RemotionStudioError,
369
+ } from "@remotion-studio/sdk";
370
+ import {
371
+ MotionGraphicsSlot,
372
+ MotionGraphicsComposition,
373
+ calculateMotionGraphicsMetadata,
374
+ compileMotionGraphicsArtifact,
375
+ } from "@remotion-studio/sdk/runtime";
369
376
  ```
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@remotion-studio/sdk",
3
- "version": "0.1.0",
3
+ "version": "0.1.2",
4
4
  "private": false,
5
5
  "description": "Official Remotion Studio package for generating, editing, playing, and rendering AI-powered Remotion compositions.",
6
6
  "packageManager": "bun@1.3.3",
@@ -39,16 +39,32 @@
39
39
  "publishConfig": {
40
40
  "access": "public"
41
41
  },
42
- "peerDependencies": {
42
+ "dependencies": {
43
43
  "@babel/standalone": "^7.28.5",
44
+ "@react-three/fiber": "^9.1.0",
44
45
  "@remotion/lottie": "^4.0.429",
45
46
  "@remotion/shapes": "^4.0.429",
46
47
  "@remotion/three": "^4.0.429",
47
48
  "@remotion/transitions": "^4.0.429",
48
- "react": "^19.2.1",
49
- "remotion": "^4.0.429",
49
+ "lottie-web": "^5.13.0",
50
50
  "three": "^0.178.0"
51
51
  },
52
+ "peerDependencies": {
53
+ "react": "^19.2.1",
54
+ "react-dom": "^19.2.1",
55
+ "remotion": "^4.0.429"
56
+ },
57
+ "peerDependenciesMeta": {
58
+ "react": {
59
+ "optional": true
60
+ },
61
+ "react-dom": {
62
+ "optional": true
63
+ },
64
+ "remotion": {
65
+ "optional": true
66
+ }
67
+ },
52
68
  "scripts": {
53
69
  "build": "rm -rf dist && tsc -p tsconfig.build.json",
54
70
  "test": "bun test ./test",