@runapi.ai/seedance 0.2.4 → 0.2.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
@@ -1,6 +1,6 @@
1
1
  # Seedance API JavaScript SDK for RunAPI
2
2
 
3
- The seedance api JavaScript SDK is the language-specific package for Seedance on RunAPI. Use this seedance api package for text-to-video, image-to-video, video-to-video, animation, and edit flows when your application needs JSON request bodies, task status lookup, and consistent RunAPI errors in JavaScript.
3
+ The seedance api JavaScript SDK is the language-specific package for Seedance on RunAPI. Use this seedance api package for text-to-video, image-to-video, video editing, and animation flows when your application needs JSON request bodies, task status lookup, and consistent RunAPI errors in JavaScript.
4
4
 
5
5
  This seedance api README is the JavaScript package guide inside the public `seedance-sdk` repository. For the repository overview, start at `../README.md`; for model details, use https://runapi.ai/models/seedance; for API reference, use https://runapi.ai/docs#seedance; for SDK docs, use https://runapi.ai/docs#sdk-seedance.
6
6
 
@@ -24,6 +24,8 @@ const status = await client.generations.get(task.id);
24
24
 
25
25
  Use `create` when you want to submit a task and return quickly, `get` when you need the latest task state, and `run` when a script should create and poll until completion. In web request handlers, prefer `create` plus webhook or later `get` polling so a worker is not held open.
26
26
 
27
+ RunAPI-generated file URLs are temporary. Download and store generated images, videos, audio, or other files in your own durable storage within 7 days; do not treat returned URLs as long-term assets.
28
+
27
29
  ## Language notes
28
30
 
29
31
  Use the TypeScript types in `src/types.ts` and the resource classes under `src/resources` when building video applications. The available resources include generations. Keep `RUNAPI_API_KEY` in the environment or your secret manager; never commit API keys or callback secrets.
package/dist/index.d.mts CHANGED
@@ -1,4 +1,4 @@
1
- import { AsyncTaskStatus, HttpClient, RequestOptions, PollingOptions, ClientOptions } from '@runapi.ai/core';
1
+ import { AsyncTaskStatus, HttpClient, RequestOptions, PollingOptions, BaseClient, ClientOptions } from '@runapi.ai/core';
2
2
  export { AuthenticationError, InsufficientCreditsError, NetworkError, NotFoundError, RateLimitError, RunApiError, ServiceUnavailableError, TaskFailedError, TaskTimeoutError, TimeoutError, ValidationError } from '@runapi.ai/core';
3
3
 
4
4
  type SeedanceModel = 'seedance-1.5-pro' | 'seedance-2.0' | 'seedance-2.0-fast' | 'seedance-v1-lite' | 'seedance-v1-pro' | 'seedance-v1-pro-fast';
@@ -12,7 +12,7 @@ type Resolution15Pro = '480p' | '720p' | '1080p';
12
12
  type Resolution2 = '480p' | '720p' | '1080p';
13
13
  type ResolutionV1 = '480p' | '720p' | '1080p';
14
14
  type ResolutionV1ProFast = '720p' | '1080p';
15
- type DurationV1 = '5' | '10';
15
+ type DurationV1 = 5 | 10;
16
16
  interface GenerationCommonParams {
17
17
  /** Text description of desired video content */
18
18
  prompt: string;
@@ -20,8 +20,8 @@ interface GenerationCommonParams {
20
20
  callback_url?: string;
21
21
  /** Generate audio track for the video */
22
22
  generate_audio?: boolean;
23
- /** Enable NSFW content check */
24
- nsfw_checker?: boolean;
23
+ /** Content safety check toggle */
24
+ enable_safety_checker?: boolean;
25
25
  }
26
26
  /**
27
27
  * seedance-1.5-pro generation parameters.
@@ -31,11 +31,11 @@ interface Generation15ProParams extends GenerationCommonParams {
31
31
  model: 'seedance-1.5-pro';
32
32
  /** Required for seedance-1.5-pro */
33
33
  aspect_ratio: AspectRatio15Pro;
34
- resolution?: Resolution15Pro;
34
+ output_resolution?: Resolution15Pro;
35
35
  /** Fixed values: 4, 8, or 12 seconds */
36
- duration?: 4 | 8 | 12;
37
- /** Up to 2 image URLs for image-to-video */
38
- input_urls?: string[];
36
+ duration_seconds: 4 | 8 | 12;
37
+ /** Up to 2 source image URLs for image-to-video */
38
+ source_image_urls?: string[];
39
39
  /** Lock camera movement */
40
40
  lock_camera?: boolean;
41
41
  }
@@ -43,9 +43,9 @@ interface Generation15ProParams extends GenerationCommonParams {
43
43
  interface Generation2BaseParams extends GenerationCommonParams {
44
44
  model: SeedanceModel2;
45
45
  aspect_ratio?: AspectRatio2;
46
- resolution?: Resolution2;
46
+ output_resolution?: Resolution2;
47
47
  /** Integer 4-15 */
48
- duration?: number;
48
+ duration_seconds?: number;
49
49
  /** Enable web search for prompt enrichment. */
50
50
  web_search?: boolean;
51
51
  }
@@ -62,9 +62,9 @@ interface Generation2TextParams extends Generation2BaseParams {
62
62
  */
63
63
  interface Generation2FrameParams extends Generation2BaseParams {
64
64
  /** First frame image URL (required for frame mode) */
65
- first_frame_url: string;
65
+ first_frame_image_url: string;
66
66
  /** Last frame image URL */
67
- last_frame_url?: string;
67
+ last_frame_image_url?: string;
68
68
  }
69
69
  /**
70
70
  * seedance-2.0/2-fast reference mode.
@@ -81,50 +81,48 @@ interface Generation2ReferenceParams extends Generation2BaseParams {
81
81
  }
82
82
  /** Common fields for v1-lite and v1-pro (not v1-pro-fast). */
83
83
  interface GenerationV1SharedParams extends GenerationCommonParams {
84
- /** `'5'` or `'10'`. Required. */
85
- duration: DurationV1;
86
- resolution?: ResolutionV1;
84
+ /** `5` or `10`. Required. */
85
+ duration_seconds: DurationV1;
86
+ output_resolution?: ResolutionV1;
87
87
  /** Lock camera movement */
88
88
  lock_camera?: boolean;
89
89
  /** Random seed; `-1` for random. Integer in [-1, 2147483647]. */
90
90
  seed?: number;
91
- /** Safety checker toggle */
92
- enable_safety_checker?: boolean;
93
91
  }
94
92
  /**
95
93
  * seedance-v1-lite text-to-video or image-to-video. Mode is auto-detected by
96
- * `input_urls` presence. `last_frame_url` is only valid in image-to-video mode.
94
+ * `first_frame_image_url` presence. `last_frame_image_url` is only valid in image-to-video mode.
97
95
  */
98
96
  interface GenerationV1LiteParams extends GenerationV1SharedParams {
99
97
  model: 'seedance-v1-lite';
100
- /** Required in text-to-video mode. Omit when `input_urls` is set. */
98
+ /** Required in text-to-video mode. Omit when `first_frame_image_url` is set. */
101
99
  aspect_ratio?: AspectRatioV1Lite;
102
- /** Up to 1 image URL. Triggers image-to-video mode when set. */
103
- input_urls?: string[];
100
+ /** First frame image URL. Triggers image-to-video mode when set. */
101
+ first_frame_image_url?: string;
104
102
  /** Ending frame image URL; image-to-video mode only. */
105
- last_frame_url?: string;
103
+ last_frame_image_url?: string;
106
104
  }
107
105
  /**
108
106
  * seedance-v1-pro text-to-video or image-to-video. Mode is auto-detected by
109
- * `input_urls` presence.
107
+ * `first_frame_image_url` presence.
110
108
  */
111
109
  interface GenerationV1ProParams extends GenerationV1SharedParams {
112
110
  model: 'seedance-v1-pro';
113
- /** Required in text-to-video mode. Omit when `input_urls` is set. */
111
+ /** Required in text-to-video mode. Omit when `first_frame_image_url` is set. */
114
112
  aspect_ratio?: AspectRatioV1Pro;
115
- /** Up to 1 image URL. Triggers image-to-video mode when set. */
116
- input_urls?: string[];
113
+ /** First frame image URL. Triggers image-to-video mode when set. */
114
+ first_frame_image_url?: string;
117
115
  }
118
116
  /**
119
117
  * seedance-v1-pro-fast image-to-video only. Smaller parameter surface —
120
- * no `aspect_ratio`, `lock_camera`, `seed`, or `enable_safety_checker`.
118
+ * no `aspect_ratio`, `lock_camera`, or `seed`.
121
119
  */
122
120
  interface GenerationV1ProFastParams extends GenerationCommonParams {
123
121
  model: 'seedance-v1-pro-fast';
124
- /** Required at least one image URL. */
125
- input_urls: [string] | [string, ...string[]];
126
- resolution?: ResolutionV1ProFast;
127
- duration: DurationV1;
122
+ /** Required first frame image URL. */
123
+ first_frame_image_url: string;
124
+ output_resolution?: ResolutionV1ProFast;
125
+ duration_seconds: DurationV1;
128
126
  }
129
127
  /** Discriminated union of all generation parameter variants */
130
128
  type TextToVideoParams = Generation15ProParams | Generation2TextParams | Generation2FrameParams | Generation2ReferenceParams | GenerationV1LiteParams | GenerationV1ProParams | GenerationV1ProFastParams;
@@ -138,13 +136,13 @@ interface TextToVideoResponse {
138
136
  id: string;
139
137
  status: AsyncTaskStatus;
140
138
  videos?: VideoMetadata[];
141
- last_frame_url?: string;
139
+ last_frame_image_url?: string;
142
140
  error?: string;
143
141
  [key: string]: unknown;
144
142
  }
145
143
  /**
146
144
  * Resolved response returned by the `run()` method after polling sees
147
- * `status: 'completed'`. Narrows `videos` to non-optional; `last_frame_url`
145
+ * `status: 'completed'`. Narrows `videos` to non-optional; `last_frame_image_url`
148
146
  * stays optional because it may be absent.
149
147
  */
150
148
  type CompletedTextToVideoResponse = TextToVideoResponse & {
@@ -152,11 +150,30 @@ type CompletedTextToVideoResponse = TextToVideoResponse & {
152
150
  videos: VideoMetadata[];
153
151
  };
154
152
 
153
+ /** Generate video from text prompts, optionally conditioned on reference images, frame images, reference videos, or audio. */
155
154
  declare class TextToVideo {
156
155
  private readonly http;
157
156
  constructor(http: HttpClient);
157
+ /**
158
+ * Create a text to video task and wait until complete.
159
+ * @param params Text to video parameters.
160
+ * @param options Per-request and polling overrides.
161
+ * @returns The completed text to video response.
162
+ */
158
163
  run(params: TextToVideoParams, options?: RequestOptions & PollingOptions): Promise<CompletedTextToVideoResponse>;
164
+ /**
165
+ * Create a text to video task; returns immediately with a task id.
166
+ * @param params Text to video parameters.
167
+ * @param options Per-request overrides.
168
+ * @returns The task creation result.
169
+ */
159
170
  create(params: TextToVideoParams, options?: RequestOptions): Promise<TaskCreateResponse>;
171
+ /**
172
+ * Fetch the current status of a text to video task.
173
+ * @param id The task id.
174
+ * @param options Per-request overrides.
175
+ * @returns The current text to video task status.
176
+ */
160
177
  get(id: string, options?: RequestOptions): Promise<TextToVideoResponse>;
161
178
  }
162
179
 
@@ -176,7 +193,7 @@ declare class TextToVideo {
176
193
  * });
177
194
  * ```
178
195
  */
179
- declare class SeedanceClient {
196
+ declare class SeedanceClient extends BaseClient {
180
197
  /** Video generation operations. */
181
198
  readonly textToVideo: TextToVideo;
182
199
  constructor(options?: ClientOptions);
package/dist/index.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { AsyncTaskStatus, HttpClient, RequestOptions, PollingOptions, ClientOptions } from '@runapi.ai/core';
1
+ import { AsyncTaskStatus, HttpClient, RequestOptions, PollingOptions, BaseClient, ClientOptions } from '@runapi.ai/core';
2
2
  export { AuthenticationError, InsufficientCreditsError, NetworkError, NotFoundError, RateLimitError, RunApiError, ServiceUnavailableError, TaskFailedError, TaskTimeoutError, TimeoutError, ValidationError } from '@runapi.ai/core';
3
3
 
4
4
  type SeedanceModel = 'seedance-1.5-pro' | 'seedance-2.0' | 'seedance-2.0-fast' | 'seedance-v1-lite' | 'seedance-v1-pro' | 'seedance-v1-pro-fast';
@@ -12,7 +12,7 @@ type Resolution15Pro = '480p' | '720p' | '1080p';
12
12
  type Resolution2 = '480p' | '720p' | '1080p';
13
13
  type ResolutionV1 = '480p' | '720p' | '1080p';
14
14
  type ResolutionV1ProFast = '720p' | '1080p';
15
- type DurationV1 = '5' | '10';
15
+ type DurationV1 = 5 | 10;
16
16
  interface GenerationCommonParams {
17
17
  /** Text description of desired video content */
18
18
  prompt: string;
@@ -20,8 +20,8 @@ interface GenerationCommonParams {
20
20
  callback_url?: string;
21
21
  /** Generate audio track for the video */
22
22
  generate_audio?: boolean;
23
- /** Enable NSFW content check */
24
- nsfw_checker?: boolean;
23
+ /** Content safety check toggle */
24
+ enable_safety_checker?: boolean;
25
25
  }
26
26
  /**
27
27
  * seedance-1.5-pro generation parameters.
@@ -31,11 +31,11 @@ interface Generation15ProParams extends GenerationCommonParams {
31
31
  model: 'seedance-1.5-pro';
32
32
  /** Required for seedance-1.5-pro */
33
33
  aspect_ratio: AspectRatio15Pro;
34
- resolution?: Resolution15Pro;
34
+ output_resolution?: Resolution15Pro;
35
35
  /** Fixed values: 4, 8, or 12 seconds */
36
- duration?: 4 | 8 | 12;
37
- /** Up to 2 image URLs for image-to-video */
38
- input_urls?: string[];
36
+ duration_seconds: 4 | 8 | 12;
37
+ /** Up to 2 source image URLs for image-to-video */
38
+ source_image_urls?: string[];
39
39
  /** Lock camera movement */
40
40
  lock_camera?: boolean;
41
41
  }
@@ -43,9 +43,9 @@ interface Generation15ProParams extends GenerationCommonParams {
43
43
  interface Generation2BaseParams extends GenerationCommonParams {
44
44
  model: SeedanceModel2;
45
45
  aspect_ratio?: AspectRatio2;
46
- resolution?: Resolution2;
46
+ output_resolution?: Resolution2;
47
47
  /** Integer 4-15 */
48
- duration?: number;
48
+ duration_seconds?: number;
49
49
  /** Enable web search for prompt enrichment. */
50
50
  web_search?: boolean;
51
51
  }
@@ -62,9 +62,9 @@ interface Generation2TextParams extends Generation2BaseParams {
62
62
  */
63
63
  interface Generation2FrameParams extends Generation2BaseParams {
64
64
  /** First frame image URL (required for frame mode) */
65
- first_frame_url: string;
65
+ first_frame_image_url: string;
66
66
  /** Last frame image URL */
67
- last_frame_url?: string;
67
+ last_frame_image_url?: string;
68
68
  }
69
69
  /**
70
70
  * seedance-2.0/2-fast reference mode.
@@ -81,50 +81,48 @@ interface Generation2ReferenceParams extends Generation2BaseParams {
81
81
  }
82
82
  /** Common fields for v1-lite and v1-pro (not v1-pro-fast). */
83
83
  interface GenerationV1SharedParams extends GenerationCommonParams {
84
- /** `'5'` or `'10'`. Required. */
85
- duration: DurationV1;
86
- resolution?: ResolutionV1;
84
+ /** `5` or `10`. Required. */
85
+ duration_seconds: DurationV1;
86
+ output_resolution?: ResolutionV1;
87
87
  /** Lock camera movement */
88
88
  lock_camera?: boolean;
89
89
  /** Random seed; `-1` for random. Integer in [-1, 2147483647]. */
90
90
  seed?: number;
91
- /** Safety checker toggle */
92
- enable_safety_checker?: boolean;
93
91
  }
94
92
  /**
95
93
  * seedance-v1-lite text-to-video or image-to-video. Mode is auto-detected by
96
- * `input_urls` presence. `last_frame_url` is only valid in image-to-video mode.
94
+ * `first_frame_image_url` presence. `last_frame_image_url` is only valid in image-to-video mode.
97
95
  */
98
96
  interface GenerationV1LiteParams extends GenerationV1SharedParams {
99
97
  model: 'seedance-v1-lite';
100
- /** Required in text-to-video mode. Omit when `input_urls` is set. */
98
+ /** Required in text-to-video mode. Omit when `first_frame_image_url` is set. */
101
99
  aspect_ratio?: AspectRatioV1Lite;
102
- /** Up to 1 image URL. Triggers image-to-video mode when set. */
103
- input_urls?: string[];
100
+ /** First frame image URL. Triggers image-to-video mode when set. */
101
+ first_frame_image_url?: string;
104
102
  /** Ending frame image URL; image-to-video mode only. */
105
- last_frame_url?: string;
103
+ last_frame_image_url?: string;
106
104
  }
107
105
  /**
108
106
  * seedance-v1-pro text-to-video or image-to-video. Mode is auto-detected by
109
- * `input_urls` presence.
107
+ * `first_frame_image_url` presence.
110
108
  */
111
109
  interface GenerationV1ProParams extends GenerationV1SharedParams {
112
110
  model: 'seedance-v1-pro';
113
- /** Required in text-to-video mode. Omit when `input_urls` is set. */
111
+ /** Required in text-to-video mode. Omit when `first_frame_image_url` is set. */
114
112
  aspect_ratio?: AspectRatioV1Pro;
115
- /** Up to 1 image URL. Triggers image-to-video mode when set. */
116
- input_urls?: string[];
113
+ /** First frame image URL. Triggers image-to-video mode when set. */
114
+ first_frame_image_url?: string;
117
115
  }
118
116
  /**
119
117
  * seedance-v1-pro-fast image-to-video only. Smaller parameter surface —
120
- * no `aspect_ratio`, `lock_camera`, `seed`, or `enable_safety_checker`.
118
+ * no `aspect_ratio`, `lock_camera`, or `seed`.
121
119
  */
122
120
  interface GenerationV1ProFastParams extends GenerationCommonParams {
123
121
  model: 'seedance-v1-pro-fast';
124
- /** Required at least one image URL. */
125
- input_urls: [string] | [string, ...string[]];
126
- resolution?: ResolutionV1ProFast;
127
- duration: DurationV1;
122
+ /** Required first frame image URL. */
123
+ first_frame_image_url: string;
124
+ output_resolution?: ResolutionV1ProFast;
125
+ duration_seconds: DurationV1;
128
126
  }
129
127
  /** Discriminated union of all generation parameter variants */
130
128
  type TextToVideoParams = Generation15ProParams | Generation2TextParams | Generation2FrameParams | Generation2ReferenceParams | GenerationV1LiteParams | GenerationV1ProParams | GenerationV1ProFastParams;
@@ -138,13 +136,13 @@ interface TextToVideoResponse {
138
136
  id: string;
139
137
  status: AsyncTaskStatus;
140
138
  videos?: VideoMetadata[];
141
- last_frame_url?: string;
139
+ last_frame_image_url?: string;
142
140
  error?: string;
143
141
  [key: string]: unknown;
144
142
  }
145
143
  /**
146
144
  * Resolved response returned by the `run()` method after polling sees
147
- * `status: 'completed'`. Narrows `videos` to non-optional; `last_frame_url`
145
+ * `status: 'completed'`. Narrows `videos` to non-optional; `last_frame_image_url`
148
146
  * stays optional because it may be absent.
149
147
  */
150
148
  type CompletedTextToVideoResponse = TextToVideoResponse & {
@@ -152,11 +150,30 @@ type CompletedTextToVideoResponse = TextToVideoResponse & {
152
150
  videos: VideoMetadata[];
153
151
  };
154
152
 
153
+ /** Generate video from text prompts, optionally conditioned on reference images, frame images, reference videos, or audio. */
155
154
  declare class TextToVideo {
156
155
  private readonly http;
157
156
  constructor(http: HttpClient);
157
+ /**
158
+ * Create a text to video task and wait until complete.
159
+ * @param params Text to video parameters.
160
+ * @param options Per-request and polling overrides.
161
+ * @returns The completed text to video response.
162
+ */
158
163
  run(params: TextToVideoParams, options?: RequestOptions & PollingOptions): Promise<CompletedTextToVideoResponse>;
164
+ /**
165
+ * Create a text to video task; returns immediately with a task id.
166
+ * @param params Text to video parameters.
167
+ * @param options Per-request overrides.
168
+ * @returns The task creation result.
169
+ */
159
170
  create(params: TextToVideoParams, options?: RequestOptions): Promise<TaskCreateResponse>;
171
+ /**
172
+ * Fetch the current status of a text to video task.
173
+ * @param id The task id.
174
+ * @param options Per-request overrides.
175
+ * @returns The current text to video task status.
176
+ */
160
177
  get(id: string, options?: RequestOptions): Promise<TextToVideoResponse>;
161
178
  }
162
179
 
@@ -176,7 +193,7 @@ declare class TextToVideo {
176
193
  * });
177
194
  * ```
178
195
  */
179
- declare class SeedanceClient {
196
+ declare class SeedanceClient extends BaseClient {
180
197
  /** Video generation operations. */
181
198
  readonly textToVideo: TextToVideo;
182
199
  constructor(options?: ClientOptions);
package/dist/index.js CHANGED
@@ -47,6 +47,12 @@ var TextToVideo = class {
47
47
  this.http = http;
48
48
  }
49
49
  http;
50
+ /**
51
+ * Create a text to video task and wait until complete.
52
+ * @param params Text to video parameters.
53
+ * @param options Per-request and polling overrides.
54
+ * @returns The completed text to video response.
55
+ */
50
56
  async run(params, options) {
51
57
  const { id } = await this.create(params, options);
52
58
  const response = await (0, import_internal.pollUntilComplete)(() => this.get(id, options), {
@@ -55,12 +61,24 @@ var TextToVideo = class {
55
61
  });
56
62
  return response;
57
63
  }
64
+ /**
65
+ * Create a text to video task; returns immediately with a task id.
66
+ * @param params Text to video parameters.
67
+ * @param options Per-request overrides.
68
+ * @returns The task creation result.
69
+ */
58
70
  async create(params, options) {
59
71
  return this.http.request("POST", ENDPOINT, {
60
72
  body: (0, import_core.compactParams)(params),
61
73
  ...options
62
74
  });
63
75
  }
76
+ /**
77
+ * Fetch the current status of a text to video task.
78
+ * @param id The task id.
79
+ * @param options Per-request overrides.
80
+ * @returns The current text to video task status.
81
+ */
64
82
  async get(id, options) {
65
83
  return this.http.request("GET", `${ENDPOINT}/${id}`, {
66
84
  ...options
@@ -69,12 +87,12 @@ var TextToVideo = class {
69
87
  };
70
88
 
71
89
  // src/client.ts
72
- var SeedanceClient = class {
90
+ var SeedanceClient = class extends import_core2.BaseClient {
73
91
  /** Video generation operations. */
74
92
  textToVideo;
75
93
  constructor(options = {}) {
76
- const http = (0, import_core2.createHttpClient)(options);
77
- this.textToVideo = new TextToVideo(http);
94
+ super(options);
95
+ this.textToVideo = new TextToVideo(this.http);
78
96
  }
79
97
  };
80
98
 
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/client.ts","../src/resources/text-to-video.ts"],"sourcesContent":["export { SeedanceClient } from './client';\nexport * from './types';\n\nexport {\n RunApiError,\n AuthenticationError,\n InsufficientCreditsError,\n NotFoundError,\n ValidationError,\n RateLimitError,\n ServiceUnavailableError,\n NetworkError,\n TimeoutError,\n TaskTimeoutError,\n TaskFailedError,\n} from '@runapi.ai/core';\n","import { createHttpClient, type ClientOptions } from '@runapi.ai/core';\nimport { TextToVideo } from './resources/text-to-video';\n\n/**\n * Seedance video API client.\n *\n * @example\n * ```typescript\n * const client = new SeedanceClient({\n * apiKey: 'your-api-key',\n * baseUrl: 'https://runapi.ai',\n * });\n *\n * const result = await client.textToVideo.run({\n * model: 'seedance-2.0',\n * prompt: 'A cat walking through a garden',\n * });\n * ```\n */\nexport class SeedanceClient {\n /** Video generation operations. */\n public readonly textToVideo: TextToVideo;\n\n constructor(options: ClientOptions = {}) {\n const http = createHttpClient(options);\n this.textToVideo = new TextToVideo(http);\n }\n}\n","import type { HttpClient, RequestOptions, PollingOptions } from '@runapi.ai/core';\nimport { compactParams } from '@runapi.ai/core';\nimport { pollUntilComplete } from '@runapi.ai/core/internal';\nimport type {\n CompletedTextToVideoResponse,\n TextToVideoParams,\n TextToVideoResponse,\n TaskCreateResponse,\n} from '../types';\n\nconst ENDPOINT = '/api/v1/seedance/text_to_video';\n\nexport class TextToVideo {\n constructor(private readonly http: HttpClient) {}\n\n async run(params: TextToVideoParams, options?: RequestOptions & PollingOptions): Promise<CompletedTextToVideoResponse> {\n const { id } = await this.create(params, options);\n const response = await pollUntilComplete<TextToVideoResponse>(() => this.get(id, options), {\n maxWaitMs: options?.maxWaitMs,\n pollIntervalMs: options?.pollIntervalMs,\n });\n return response as CompletedTextToVideoResponse;\n }\n\n async create(params: TextToVideoParams, options?: RequestOptions): Promise<TaskCreateResponse> {\n return this.http.request<TaskCreateResponse>('POST', ENDPOINT, {\n body: compactParams(params),\n ...options,\n });\n }\n\n async get(id: string, options?: RequestOptions): Promise<TextToVideoResponse> {\n return this.http.request<TextToVideoResponse>('GET', `${ENDPOINT}/${id}`, {\n ...options,\n });\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACAA,IAAAA,eAAqD;;;ACCrD,kBAA8B;AAC9B,sBAAkC;AAQlC,IAAM,WAAW;AAEV,IAAM,cAAN,MAAkB;AAAA,EACvB,YAA6B,MAAkB;AAAlB;AAAA,EAAmB;AAAA,EAAnB;AAAA,EAE7B,MAAM,IAAI,QAA2B,SAAkF;AACrH,UAAM,EAAE,GAAG,IAAI,MAAM,KAAK,OAAO,QAAQ,OAAO;AAChD,UAAM,WAAW,UAAM,mCAAuC,MAAM,KAAK,IAAI,IAAI,OAAO,GAAG;AAAA,MACzF,WAAW,SAAS;AAAA,MACpB,gBAAgB,SAAS;AAAA,IAC3B,CAAC;AACD,WAAO;AAAA,EACT;AAAA,EAEA,MAAM,OAAO,QAA2B,SAAuD;AAC7F,WAAO,KAAK,KAAK,QAA4B,QAAQ,UAAU;AAAA,MAC7D,UAAM,2BAAc,MAAM;AAAA,MAC1B,GAAG;AAAA,IACL,CAAC;AAAA,EACH;AAAA,EAEA,MAAM,IAAI,IAAY,SAAwD;AAC5E,WAAO,KAAK,KAAK,QAA6B,OAAO,GAAG,QAAQ,IAAI,EAAE,IAAI;AAAA,MACxE,GAAG;AAAA,IACL,CAAC;AAAA,EACH;AACF;;;ADjBO,IAAM,iBAAN,MAAqB;AAAA;AAAA,EAEV;AAAA,EAEhB,YAAY,UAAyB,CAAC,GAAG;AACvC,UAAM,WAAO,+BAAiB,OAAO;AACrC,SAAK,cAAc,IAAI,YAAY,IAAI;AAAA,EACzC;AACF;;;ADxBA,IAAAC,eAYO;","names":["import_core","import_core"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/client.ts","../src/resources/text-to-video.ts"],"sourcesContent":["export { SeedanceClient } from './client';\nexport * from './types';\n\nexport {\n RunApiError,\n AuthenticationError,\n InsufficientCreditsError,\n NotFoundError,\n ValidationError,\n RateLimitError,\n ServiceUnavailableError,\n NetworkError,\n TimeoutError,\n TaskTimeoutError,\n TaskFailedError,\n} from '@runapi.ai/core';\n","import { BaseClient, type ClientOptions } from '@runapi.ai/core';\nimport { TextToVideo } from './resources/text-to-video';\n\n/**\n * Seedance video API client.\n *\n * @example\n * ```typescript\n * const client = new SeedanceClient({\n * apiKey: 'your-api-key',\n * baseUrl: 'https://runapi.ai',\n * });\n *\n * const result = await client.textToVideo.run({\n * model: 'seedance-2.0',\n * prompt: 'A cat walking through a garden',\n * });\n * ```\n */\nexport class SeedanceClient extends BaseClient {\n /** Video generation operations. */\n public readonly textToVideo: TextToVideo;\n\n constructor(options: ClientOptions = {}) {\n super(options);\n this.textToVideo = new TextToVideo(this.http);\n }\n}\n","import type { HttpClient, RequestOptions, PollingOptions } from '@runapi.ai/core';\nimport { compactParams } from '@runapi.ai/core';\nimport { pollUntilComplete } from '@runapi.ai/core/internal';\nimport type {\n CompletedTextToVideoResponse,\n TextToVideoParams,\n TextToVideoResponse,\n TaskCreateResponse,\n} from '../types';\n\nconst ENDPOINT = '/api/v1/seedance/text_to_video';\n\n/** Generate video from text prompts, optionally conditioned on reference images, frame images, reference videos, or audio. */\nexport class TextToVideo {\n constructor(private readonly http: HttpClient) {}\n\n /**\n * Create a text to video task and wait until complete.\n * @param params Text to video parameters.\n * @param options Per-request and polling overrides.\n * @returns The completed text to video response.\n */\n async run(params: TextToVideoParams, options?: RequestOptions & PollingOptions): Promise<CompletedTextToVideoResponse> {\n const { id } = await this.create(params, options);\n const response = await pollUntilComplete<TextToVideoResponse>(() => this.get(id, options), {\n maxWaitMs: options?.maxWaitMs,\n pollIntervalMs: options?.pollIntervalMs,\n });\n return response as CompletedTextToVideoResponse;\n }\n\n /**\n * Create a text to video task; returns immediately with a task id.\n * @param params Text to video parameters.\n * @param options Per-request overrides.\n * @returns The task creation result.\n */\n async create(params: TextToVideoParams, options?: RequestOptions): Promise<TaskCreateResponse> {\n return this.http.request<TaskCreateResponse>('POST', ENDPOINT, {\n body: compactParams(params),\n ...options,\n });\n }\n\n /**\n * Fetch the current status of a text to video task.\n * @param id The task id.\n * @param options Per-request overrides.\n * @returns The current text to video task status.\n */\n async get(id: string, options?: RequestOptions): Promise<TextToVideoResponse> {\n return this.http.request<TextToVideoResponse>('GET', `${ENDPOINT}/${id}`, {\n ...options,\n });\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACAA,IAAAA,eAA+C;;;ACC/C,kBAA8B;AAC9B,sBAAkC;AAQlC,IAAM,WAAW;AAGV,IAAM,cAAN,MAAkB;AAAA,EACvB,YAA6B,MAAkB;AAAlB;AAAA,EAAmB;AAAA,EAAnB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQ7B,MAAM,IAAI,QAA2B,SAAkF;AACrH,UAAM,EAAE,GAAG,IAAI,MAAM,KAAK,OAAO,QAAQ,OAAO;AAChD,UAAM,WAAW,UAAM,mCAAuC,MAAM,KAAK,IAAI,IAAI,OAAO,GAAG;AAAA,MACzF,WAAW,SAAS;AAAA,MACpB,gBAAgB,SAAS;AAAA,IAC3B,CAAC;AACD,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,MAAM,OAAO,QAA2B,SAAuD;AAC7F,WAAO,KAAK,KAAK,QAA4B,QAAQ,UAAU;AAAA,MAC7D,UAAM,2BAAc,MAAM;AAAA,MAC1B,GAAG;AAAA,IACL,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,MAAM,IAAI,IAAY,SAAwD;AAC5E,WAAO,KAAK,KAAK,QAA6B,OAAO,GAAG,QAAQ,IAAI,EAAE,IAAI;AAAA,MACxE,GAAG;AAAA,IACL,CAAC;AAAA,EACH;AACF;;;ADpCO,IAAM,iBAAN,cAA6B,wBAAW;AAAA;AAAA,EAE7B;AAAA,EAEhB,YAAY,UAAyB,CAAC,GAAG;AACvC,UAAM,OAAO;AACb,SAAK,cAAc,IAAI,YAAY,KAAK,IAAI;AAAA,EAC9C;AACF;;;ADxBA,IAAAC,eAYO;","names":["import_core","import_core"]}
package/dist/index.mjs CHANGED
@@ -1,5 +1,5 @@
1
1
  // src/client.ts
2
- import { createHttpClient } from "@runapi.ai/core";
2
+ import { BaseClient } from "@runapi.ai/core";
3
3
 
4
4
  // src/resources/text-to-video.ts
5
5
  import { compactParams } from "@runapi.ai/core";
@@ -10,6 +10,12 @@ var TextToVideo = class {
10
10
  this.http = http;
11
11
  }
12
12
  http;
13
+ /**
14
+ * Create a text to video task and wait until complete.
15
+ * @param params Text to video parameters.
16
+ * @param options Per-request and polling overrides.
17
+ * @returns The completed text to video response.
18
+ */
13
19
  async run(params, options) {
14
20
  const { id } = await this.create(params, options);
15
21
  const response = await pollUntilComplete(() => this.get(id, options), {
@@ -18,12 +24,24 @@ var TextToVideo = class {
18
24
  });
19
25
  return response;
20
26
  }
27
+ /**
28
+ * Create a text to video task; returns immediately with a task id.
29
+ * @param params Text to video parameters.
30
+ * @param options Per-request overrides.
31
+ * @returns The task creation result.
32
+ */
21
33
  async create(params, options) {
22
34
  return this.http.request("POST", ENDPOINT, {
23
35
  body: compactParams(params),
24
36
  ...options
25
37
  });
26
38
  }
39
+ /**
40
+ * Fetch the current status of a text to video task.
41
+ * @param id The task id.
42
+ * @param options Per-request overrides.
43
+ * @returns The current text to video task status.
44
+ */
27
45
  async get(id, options) {
28
46
  return this.http.request("GET", `${ENDPOINT}/${id}`, {
29
47
  ...options
@@ -32,12 +50,12 @@ var TextToVideo = class {
32
50
  };
33
51
 
34
52
  // src/client.ts
35
- var SeedanceClient = class {
53
+ var SeedanceClient = class extends BaseClient {
36
54
  /** Video generation operations. */
37
55
  textToVideo;
38
56
  constructor(options = {}) {
39
- const http = createHttpClient(options);
40
- this.textToVideo = new TextToVideo(http);
57
+ super(options);
58
+ this.textToVideo = new TextToVideo(this.http);
41
59
  }
42
60
  };
43
61
 
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/client.ts","../src/resources/text-to-video.ts","../src/index.ts"],"sourcesContent":["import { createHttpClient, type ClientOptions } from '@runapi.ai/core';\nimport { TextToVideo } from './resources/text-to-video';\n\n/**\n * Seedance video API client.\n *\n * @example\n * ```typescript\n * const client = new SeedanceClient({\n * apiKey: 'your-api-key',\n * baseUrl: 'https://runapi.ai',\n * });\n *\n * const result = await client.textToVideo.run({\n * model: 'seedance-2.0',\n * prompt: 'A cat walking through a garden',\n * });\n * ```\n */\nexport class SeedanceClient {\n /** Video generation operations. */\n public readonly textToVideo: TextToVideo;\n\n constructor(options: ClientOptions = {}) {\n const http = createHttpClient(options);\n this.textToVideo = new TextToVideo(http);\n }\n}\n","import type { HttpClient, RequestOptions, PollingOptions } from '@runapi.ai/core';\nimport { compactParams } from '@runapi.ai/core';\nimport { pollUntilComplete } from '@runapi.ai/core/internal';\nimport type {\n CompletedTextToVideoResponse,\n TextToVideoParams,\n TextToVideoResponse,\n TaskCreateResponse,\n} from '../types';\n\nconst ENDPOINT = '/api/v1/seedance/text_to_video';\n\nexport class TextToVideo {\n constructor(private readonly http: HttpClient) {}\n\n async run(params: TextToVideoParams, options?: RequestOptions & PollingOptions): Promise<CompletedTextToVideoResponse> {\n const { id } = await this.create(params, options);\n const response = await pollUntilComplete<TextToVideoResponse>(() => this.get(id, options), {\n maxWaitMs: options?.maxWaitMs,\n pollIntervalMs: options?.pollIntervalMs,\n });\n return response as CompletedTextToVideoResponse;\n }\n\n async create(params: TextToVideoParams, options?: RequestOptions): Promise<TaskCreateResponse> {\n return this.http.request<TaskCreateResponse>('POST', ENDPOINT, {\n body: compactParams(params),\n ...options,\n });\n }\n\n async get(id: string, options?: RequestOptions): Promise<TextToVideoResponse> {\n return this.http.request<TextToVideoResponse>('GET', `${ENDPOINT}/${id}`, {\n ...options,\n });\n }\n}\n","export { SeedanceClient } from './client';\nexport * from './types';\n\nexport {\n RunApiError,\n AuthenticationError,\n InsufficientCreditsError,\n NotFoundError,\n ValidationError,\n RateLimitError,\n ServiceUnavailableError,\n NetworkError,\n TimeoutError,\n TaskTimeoutError,\n TaskFailedError,\n} from '@runapi.ai/core';\n"],"mappings":";AAAA,SAAS,wBAA4C;;;ACCrD,SAAS,qBAAqB;AAC9B,SAAS,yBAAyB;AAQlC,IAAM,WAAW;AAEV,IAAM,cAAN,MAAkB;AAAA,EACvB,YAA6B,MAAkB;AAAlB;AAAA,EAAmB;AAAA,EAAnB;AAAA,EAE7B,MAAM,IAAI,QAA2B,SAAkF;AACrH,UAAM,EAAE,GAAG,IAAI,MAAM,KAAK,OAAO,QAAQ,OAAO;AAChD,UAAM,WAAW,MAAM,kBAAuC,MAAM,KAAK,IAAI,IAAI,OAAO,GAAG;AAAA,MACzF,WAAW,SAAS;AAAA,MACpB,gBAAgB,SAAS;AAAA,IAC3B,CAAC;AACD,WAAO;AAAA,EACT;AAAA,EAEA,MAAM,OAAO,QAA2B,SAAuD;AAC7F,WAAO,KAAK,KAAK,QAA4B,QAAQ,UAAU;AAAA,MAC7D,MAAM,cAAc,MAAM;AAAA,MAC1B,GAAG;AAAA,IACL,CAAC;AAAA,EACH;AAAA,EAEA,MAAM,IAAI,IAAY,SAAwD;AAC5E,WAAO,KAAK,KAAK,QAA6B,OAAO,GAAG,QAAQ,IAAI,EAAE,IAAI;AAAA,MACxE,GAAG;AAAA,IACL,CAAC;AAAA,EACH;AACF;;;ADjBO,IAAM,iBAAN,MAAqB;AAAA;AAAA,EAEV;AAAA,EAEhB,YAAY,UAAyB,CAAC,GAAG;AACvC,UAAM,OAAO,iBAAiB,OAAO;AACrC,SAAK,cAAc,IAAI,YAAY,IAAI;AAAA,EACzC;AACF;;;AExBA;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;","names":[]}
1
+ {"version":3,"sources":["../src/client.ts","../src/resources/text-to-video.ts","../src/index.ts"],"sourcesContent":["import { BaseClient, type ClientOptions } from '@runapi.ai/core';\nimport { TextToVideo } from './resources/text-to-video';\n\n/**\n * Seedance video API client.\n *\n * @example\n * ```typescript\n * const client = new SeedanceClient({\n * apiKey: 'your-api-key',\n * baseUrl: 'https://runapi.ai',\n * });\n *\n * const result = await client.textToVideo.run({\n * model: 'seedance-2.0',\n * prompt: 'A cat walking through a garden',\n * });\n * ```\n */\nexport class SeedanceClient extends BaseClient {\n /** Video generation operations. */\n public readonly textToVideo: TextToVideo;\n\n constructor(options: ClientOptions = {}) {\n super(options);\n this.textToVideo = new TextToVideo(this.http);\n }\n}\n","import type { HttpClient, RequestOptions, PollingOptions } from '@runapi.ai/core';\nimport { compactParams } from '@runapi.ai/core';\nimport { pollUntilComplete } from '@runapi.ai/core/internal';\nimport type {\n CompletedTextToVideoResponse,\n TextToVideoParams,\n TextToVideoResponse,\n TaskCreateResponse,\n} from '../types';\n\nconst ENDPOINT = '/api/v1/seedance/text_to_video';\n\n/** Generate video from text prompts, optionally conditioned on reference images, frame images, reference videos, or audio. */\nexport class TextToVideo {\n constructor(private readonly http: HttpClient) {}\n\n /**\n * Create a text to video task and wait until complete.\n * @param params Text to video parameters.\n * @param options Per-request and polling overrides.\n * @returns The completed text to video response.\n */\n async run(params: TextToVideoParams, options?: RequestOptions & PollingOptions): Promise<CompletedTextToVideoResponse> {\n const { id } = await this.create(params, options);\n const response = await pollUntilComplete<TextToVideoResponse>(() => this.get(id, options), {\n maxWaitMs: options?.maxWaitMs,\n pollIntervalMs: options?.pollIntervalMs,\n });\n return response as CompletedTextToVideoResponse;\n }\n\n /**\n * Create a text to video task; returns immediately with a task id.\n * @param params Text to video parameters.\n * @param options Per-request overrides.\n * @returns The task creation result.\n */\n async create(params: TextToVideoParams, options?: RequestOptions): Promise<TaskCreateResponse> {\n return this.http.request<TaskCreateResponse>('POST', ENDPOINT, {\n body: compactParams(params),\n ...options,\n });\n }\n\n /**\n * Fetch the current status of a text to video task.\n * @param id The task id.\n * @param options Per-request overrides.\n * @returns The current text to video task status.\n */\n async get(id: string, options?: RequestOptions): Promise<TextToVideoResponse> {\n return this.http.request<TextToVideoResponse>('GET', `${ENDPOINT}/${id}`, {\n ...options,\n });\n }\n}\n","export { SeedanceClient } from './client';\nexport * from './types';\n\nexport {\n RunApiError,\n AuthenticationError,\n InsufficientCreditsError,\n NotFoundError,\n ValidationError,\n RateLimitError,\n ServiceUnavailableError,\n NetworkError,\n TimeoutError,\n TaskTimeoutError,\n TaskFailedError,\n} from '@runapi.ai/core';\n"],"mappings":";AAAA,SAAS,kBAAsC;;;ACC/C,SAAS,qBAAqB;AAC9B,SAAS,yBAAyB;AAQlC,IAAM,WAAW;AAGV,IAAM,cAAN,MAAkB;AAAA,EACvB,YAA6B,MAAkB;AAAlB;AAAA,EAAmB;AAAA,EAAnB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQ7B,MAAM,IAAI,QAA2B,SAAkF;AACrH,UAAM,EAAE,GAAG,IAAI,MAAM,KAAK,OAAO,QAAQ,OAAO;AAChD,UAAM,WAAW,MAAM,kBAAuC,MAAM,KAAK,IAAI,IAAI,OAAO,GAAG;AAAA,MACzF,WAAW,SAAS;AAAA,MACpB,gBAAgB,SAAS;AAAA,IAC3B,CAAC;AACD,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,MAAM,OAAO,QAA2B,SAAuD;AAC7F,WAAO,KAAK,KAAK,QAA4B,QAAQ,UAAU;AAAA,MAC7D,MAAM,cAAc,MAAM;AAAA,MAC1B,GAAG;AAAA,IACL,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,MAAM,IAAI,IAAY,SAAwD;AAC5E,WAAO,KAAK,KAAK,QAA6B,OAAO,GAAG,QAAQ,IAAI,EAAE,IAAI;AAAA,MACxE,GAAG;AAAA,IACL,CAAC;AAAA,EACH;AACF;;;ADpCO,IAAM,iBAAN,cAA6B,WAAW;AAAA;AAAA,EAE7B;AAAA,EAEhB,YAAY,UAAyB,CAAC,GAAG;AACvC,UAAM,OAAO;AACb,SAAK,cAAc,IAAI,YAAY,KAAK,IAAI;AAAA,EAC9C;AACF;;;AExBA;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;","names":[]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@runapi.ai/seedance",
3
- "version": "0.2.4",
3
+ "version": "0.2.7",
4
4
  "description": "RunAPI Seedance SDK for JavaScript, Ruby, and Go",
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/index.mjs",
@@ -25,12 +25,10 @@
25
25
  "build": "tsup",
26
26
  "test": "vitest run",
27
27
  "typecheck": "tsc --noEmit",
28
- "clean": "rm -rf dist",
29
- "test:text2video": "dotenv -e manual-tests/.env -- tsx manual-tests/test-text-to-video.ts",
30
- "test:manual": "pnpm run test:text2video"
28
+ "clean": "rm -rf dist"
31
29
  },
32
30
  "dependencies": {
33
- "@runapi.ai/core": "^0.2.4"
31
+ "@runapi.ai/core": "^0.2.6"
34
32
  },
35
33
  "devDependencies": {
36
34
  "@types/node": "^20.0.0",
@@ -79,6 +79,8 @@ const url = result.videos[0].url;
79
79
 
80
80
  ## Agent rules
81
81
 
82
+ - Integration work uses the target language SDK; one-off generation, manual smoke tests, debugging, or user-requested CLI runs use the RunAPI CLI skill: https://github.com/runapi-ai/cli-skill
83
+ - RunAPI-generated file URLs are temporary. Download and store generated images, videos, audio, or other files in your own durable storage within 7 days; do not treat returned URLs as long-term assets.
82
84
  - Keep API keys in `RUNAPI_API_KEY` or RunAPI CLI config; never commit secrets.
83
85
  - Prefer `create`, `get`, and `run` JSON passthrough patterns instead of inventing flags for every model parameter.
84
86
  - For seedance api pricing, rate-limit, and commercial-usage answers, link to the variant page rather than the repository README.
@@ -25,16 +25,25 @@ metadata:
25
25
 
26
26
  Generate and edit video with Seedance through RunAPI. The default path for one-off agent tasks is the `runapi` CLI; SDKs are for application integration.
27
27
 
28
- ## Routing decision
28
+ ## Critical: Integration Runtime
29
29
 
30
- - One-off generation, editing, or transformation for the user use the **CLI path** with the `runapi` binary.
31
- - Building an app, backend, worker, library, or production codebase use the **SDK integration path**.
30
+ - Integration work (app, backend, worker, library, Rails service, Node service, Go service, webhook pipeline, or production codebase) uses the **SDK integration path** for the target language.
31
+ - One-off generation, editing, transformation, manual smoke tests, debugging, or user-requested CLI runs use the **CLI path** with the `runapi` binary. For full CLI-specific agent guidance, see https://github.com/runapi-ai/cli-skill.
32
+ - Never shell out to the `runapi` CLI as the production runtime integration layer.
33
+
34
+ ## SDK integration path
35
+
36
+ When integrating Seedance into an app, backend, worker, library, Rails service, Node service, Go service, webhook pipeline, or production workflow, start by checking the current SDK package and official usage. Confirm install commands, client methods (`create`, `get`, `run`), request fields, response shape, and error classes before using CLI help or raw HTTP examples. Use a RunAPI SDK package:
37
+
38
+ - JavaScript / TypeScript: `@runapi.ai/seedance`
39
+ - Ruby: `runapi-seedance`
40
+ - Go: `github.com/runapi-ai/seedance-sdk/go`
32
41
 
33
42
  ## CLI path
34
43
 
35
- The `runapi` binary is the runtime dependency. Run `runapi auth status` first. For agents and headless runs, prefer `RUNAPI_API_KEY` or import it into saved config with `printf '%s' "$RUNAPI_API_KEY" | runapi auth import-token --token -`. Use `runapi login` only when the user explicitly wants interactive browser auth.
44
+ The `runapi` binary is the one-off and manual testing runtime dependency. For full CLI-specific agent guidance, see https://github.com/runapi-ai/cli-skill. Run `runapi auth status` first. For agents and headless runs, prefer `RUNAPI_API_KEY` or import it into saved config with `printf '%s' "$RUNAPI_API_KEY" | runapi auth import-token --token -`. Use `runapi login` only when the user explicitly wants interactive browser auth.
36
45
 
37
- Inspect the available actions and request fields with CLI help:
46
+ Inspect the available commands and request fields with CLI help:
38
47
 
39
48
  ```shell
40
49
  runapi seedance --help
@@ -54,15 +63,11 @@ runapi seedance text-to-video --async --input-file request.json
54
63
  runapi wait <task-id> --service seedance --action text-to-video
55
64
  ```
56
65
 
57
- Available actions: `text-to-video`.
58
-
59
- ## SDK integration path
66
+ Available commands: `text-to-video`.
60
67
 
61
- When integrating Seedance into an app, backend, worker, or library — not for one-off tasks — use a RunAPI SDK package:
68
+ ## Generated file storage
62
69
 
63
- - JavaScript / TypeScript: `@runapi.ai/seedance`
64
- - Ruby: `runapi-seedance`
65
- - Go: `github.com/runapi-ai/seedance-sdk/go`
70
+ RunAPI-generated file URLs are temporary. Download and store generated images, videos, audio, or other files in your own durable storage within 7 days; do not treat returned URLs as long-term assets.
66
71
 
67
72
  ## References
68
73