Seedance 2.0 FastAPI 레퍼런스
코드에서 Seedance 2.0 Fast 모델을 호출하는 데 필요한 모든 것: 세 단계 빠른 시작, 모든 필드와 한도, 가격 공식, 웹훅과 멱등성. MCP 도구도 같은 /v1 API로 실행됩니다. MCP로 로그인하면 크리에이티브 잔액을, API 키로는 개발자 API 잔액을 씁니다.
개발자 API는 신청제입니다.
빠른 시작호출 세 번이면 됩니다
키를 설정하고, 가격 상한을 걸어 작업을 보낸 다음, 결과를 읽으세요.
- 01
키 설정
개발자 API는 신청제입니다. 스튜디오의 API 키 메뉴에서 신청하세요. 키는 한 번만 표시되므로 환경 변수에 보관하세요.
export API_KEY="sk_test_…" - 02
작업 보내기
Idempotency-Key와 max_credits 상한(또는 quote_id)을 넣어 클립을 POST 요청으로 보내세요. 곧바로 202와 대기 중인 작업을 받으며, 크레딧이 보류됩니다.
curl https://api.pershot.app/v1/videos/generations \ -H "Authorization: Bearer $API_KEY" \ -H "Idempotency-Key: $(uuidgen)" \ -H "Content-Type: application/json" \ -d '{ "model": "seedance-2.0-fast", "prompt": "Perfume mist in hard side light. Slow push-in, black background, grain.", "duration": 5, "resolution": "720p", "aspect_ratio": "16:9", "generate_audio": true, "max_credits": 34 }'{ "id": "job_01J9ZK4T8W", "object": "job", "kind": "video", "status": "queued", "money_status": "reserved", "queue_position": 2, "requested_model": "seedance-2.0-fast", "credits_quoted": 34, "credits_charged": null } - 03
결과 읽기
status가 succeeded가 될 때까지 작업을 GET으로 조회하세요. outputs[].url은 서명된 링크이며 24시간 후 만료되므로, 보관할 파일은 다운로드하세요.
curl https://api.pershot.app/v1/jobs/job_01J9ZK4T8W \ -H "Authorization: Bearer $API_KEY"
파라미터와한도
API가 검증에 사용하는 것과 같은 스키마로 생성된 OpenAPI 문서에서 읽어 옵니다. 알 수 없는 필드는 거부됩니다.
| 필드 | 유형 | 허용 값 | 참고 |
|---|---|---|---|
model필수 | string | seedance-2.0-fast · seedance-2.0-mini · auto | 모델 ID. |
prompt필수 | string | 2–2,000자 | 생성할 내용: 피사체, 카메라, 조명. |
duration기본값 5 | integer | 4–15 | 출력 길이(초 단위 정수), 최대 15초. |
resolution기본값 "720p" | string | 480p · 720p | 출력 해상도. 초안은 480p, 납품은 720p로 만듭니다. 해상도마다 따로 생성됩니다. |
aspect_ratio기본값 "16:9" | string | 16:9 · 9:16 · 1:1 | 프레임 형태. |
generate_audio기본값 true | boolean | – | 네이티브 오디오. 켜든 끄든 가격은 같습니다. |
image_url선택 | string | https URL | 동영상의 첫 프레임, 편집 모델의 원본 이미지. 공개 https URL 또는 업로드 URL. |
reference_image_urls선택 | string[] | 최대 9 · https URL | 피사체와 스타일을 위한 참조 이미지. 프롬프트에서 @image1, @image2로 지칭하세요. |
seed선택 | integer | 0–2,147,483,647 | 허용되지만 무시됩니다. Seedance 2.0은 시드를 받지 않습니다. |
quote_id선택 | string | qt_… | POST /v1/quotes에서 받은 견적으로 실행하며, 견적은 10분 동안 유효합니다. |
max_credits선택 | number | > 0 | 이 작업에 들 수 있는 최대 비용. 이를 넘으면 작업은 거부되며, 절대 청구되지 않습니다. |
webhook_url선택 | string | https URL | 작업 이벤트를 받는 https URL. |
end_user_id선택 | string | 1–128자 | 승인된 개발자 계정용(신청제): 이 요청에 붙이는 내 사용자 ID로, 사용량에 표시됩니다. |
project_id선택 | string | prj_… | |
shot_id선택 | string | sht_… | |
routing_preference선택 | string | stability · speed | |
enhance선택 | object | – |
quote_id와 max_credits 중 정확히 하나만 보내세요. 이 엔드포인트는 model "auto"를 받지 않습니다. 동영상은 먼저 POST /v1/auto/plan을 호출한 뒤, 선택된 모델을 max_credits와 함께 보내세요.
- 요청 속도와 동시 실행
- 키당 분당 60회 요청, 계정당 기본 동시 작업 3개. 키를 늘려도 동시 실행 수는 늘어나지 않습니다.
한도
API가 검사하는 것과 같은 표에서 읽어 옵니다. 각 행에는 누가 한도를 검사하는지, 한도를 넘으면 어떻게 되는지가 나와 있습니다.
- 강제 적용당사가 검사하며, 견적이나 보류 전에 400으로 응답합니다.
- 공급사공급업체가 검사합니다. 공급업체가 거부한 작업은 실패하며, 비용은 청구되지 않습니다.
- 권장아무도 검사하지 않습니다. 범위 안에 머물면 더 좋은 결과를 얻을 수 있습니다.
| 한도 | 값 | 단위 | 검사 주체 | 한도 초과 시 |
|---|---|---|---|---|
| 요청 | ||||
프롬프트 길이prompt | 2~2,000 | 문자 | 강제 적용 | 견적이나 보류 전에 prompt에 대해 400 invalid_request를 반환합니다. |
영어 프롬프트prompt | 최대 1,000 | 단어 | 권장 | 허용됩니다. 프롬프트가 길수록 모델이 덜 정확하게 따를 수 있습니다. |
중국어 프롬프트prompt | 최대 500 | 중국어 문자 | 권장 | 허용됩니다. 프롬프트가 길수록 모델이 덜 정확하게 따를 수 있습니다. |
길이duration | 4~15기본값 5 | 초 | 강제 적용 | duration에 대해 400 invalid_request를 반환합니다. 초 단위 정수만 가능합니다. |
해상도resolution | 480p, 720p기본값 720p | – | 강제 적용 | resolution에 대해 400 invalid_request를 반환합니다. |
화면 비율aspect_ratio | 16:9, 9:16, 1:1기본값 16:9 | – | 강제 적용 | aspect_ratio에 대해 400 invalid_request를 반환합니다. |
시드seed | 무시됨 | – | 공급사 | 허용되지만 전송되지 않습니다. Seedance 2.0은 시드를 받지 않으므로 시드로 결과를 재현할 수 없습니다. |
입력 동영상 길이input_video_seconds | 2~15 | 초 | 강제 적용 | POST /v1/quotes에서 400 invalid_request를 반환합니다. API 생성 요청은 입력 동영상을 받지 않습니다. |
| 보내는 이미지 | ||||
참조 이미지reference_image_urls | 최대 9 | 장 | 강제 적용 | reference_image_urls에 대해 400 invalid_request를 반환합니다. |
첫 프레임 또는 참조reference_image_urls | image_url 또는 reference_image_urls 중 하나만 | – | 강제 적용 | reference_image_urls에 대해 400 invalid_request를 반환합니다. Seedance 2.0은 작업마다 두 모드 중 하나만 실행합니다. |
이미지 변 길이image_urlreference_image_urls | 300~6,000 | 변당 px | 업로드에 강제 적용 | 업로드: 견적이나 보류 전에 image_url 또는 reference_image_urls.N에 대해 400 invalid_request를 반환합니다. 다른 링크: 공급업체가 작업을 거부하며, 비용은 청구되지 않습니다. |
이미지 형태image_urlreference_image_urls | 0.4~2.5 | 너비 ÷ 높이 | 업로드에 강제 적용 | 업로드: 견적이나 보류 전에 image_url 또는 reference_image_urls.N에 대해 400 invalid_request를 반환합니다. 다른 링크: 공급업체가 작업을 거부하며, 비용은 청구되지 않습니다. |
업로드 크기file | 최대 10 | MB | 강제 적용 | POST /v1/uploads가 file에 대해 400 invalid_request로 응답합니다. |
업로드 형식file | JPEG, PNG, WebP | – | 강제 적용 | 파일 이름이 아니라 파일 자체에서 형식을 읽습니다. 그 밖의 형식은 file에 대해 400 invalid_request를 반환합니다. |
링크된 이미지 크기image_urlreference_image_urls | 최대 30 | MB | 공급사 | 다른 호스트에서 링크한 이미지에 해당합니다. 공급업체가 작업을 거부하며, 비용은 청구되지 않습니다. |
링크된 이미지 형식image_urlreference_image_urls | JPEG, PNG, WebP, BMP, TIFF, GIF, HEIC, HEIF | – | 공급사 | 다른 호스트에서 링크한 이미지에 해당합니다. 공급업체가 작업을 거부하며, 비용은 청구되지 않습니다. |
| 출력 | ||||
| 출력 픽셀 | 480p16:9864×4969:16496×8641:1640×640720p16:91280×7209:16720×12801:1960×960 | px | 공급사 | 해상도와 화면 비율마다 모델이 정합니다. |
| 프레임 레이트 | 24 | fps | 공급사 | 모든 동영상에 동일합니다. |
| 출력 형식 | MP4 | – | 공급사 | 모든 동영상은 MP4이며, generate_audio가 켜져 있으면 소리가 포함됩니다. |
| 링크 | ||||
| 업로드 링크 | 7 | 일 | 강제 적용 | 그 이후에는 링크가 403으로 응답합니다. 파일을 다시 업로드하세요. |
| 출력 링크 | 24 | 시간 | 강제 적용 | 그 이후에는 링크가 403으로 응답합니다. 작업을 다시 GET하면 새 링크를 받을 수 있습니다. 파일 자체는 12개월 동안 보관되며(날짜는 작업의 outputs_expire_at), 에셋에 저장했거나 프로젝트에 사용 중인 결과물은 더 오래 보관됩니다. |
당사는 다른 호스트의 이미지를 가져오지 않으므로, 그런 링크의 크기는 공급업체가 검사합니다. 공급업체가 거부한 작업에는 비용이 청구되지 않습니다. 같은 한도가 JSON으로도 반환됩니다. GET /v1/models는 모든 모델에 대해 limits 객체를 반환합니다.
요금계산 과정까지 공개합니다
모든 작업은 실행 전에 크레딧으로 견적이 제공됩니다(US$1 = 100 크레딧). 초당 요율은 예산 수립용이며, 정확한 금액은 POST /v1/quotes가 반환합니다.
크레딧 = ceil(BytePlus 정가 × 0.55 × 100), 여기서 정가 = (입력 초 + 출력 초) × 너비 × 높이 × 24 ÷ 1024 × 정가 요율| 사양 | 초당(API) | 5초 | 10초 | 15초 |
|---|---|---|---|---|
| 480p동영상 입력 없음 | $0.031입력 동영상 포함 시: $0.019/초$10당 약 322초 | 16 크레딧≈ $0.16 | 31 크레딧≈ $0.31 | 47 크레딧≈ $0.47 |
| 720p동영상 입력 없음 | $0.067입력 동영상 포함 시: $0.040/초$10당 약 149초 | 34 크레딧≈ $0.34 | 67 크레딧≈ $0.67 | 100 크레딧≈ $1.00 |
거부되거나 실패한 작업은 청구되지 않습니다.
웹훅과멱등성
재시도해도 두 번 청구되지 않으며, 폴링할 필요가 없습니다.
- 멱등성
- 모든 생성 POST 요청에는 Idempotency-Key(눈에 보이는 ASCII 문자 1~255자)가 필요합니다. 24시간 이내에 같은 키로 요청하면 HTTP 200과 함께 같은 작업이 반환되므로, 시간 초과 후 재시도해도 두 번째 작업이 생성되거나 청구되지 않습니다.
- 거부된 프롬프트
- 사전 검사에서 거부된 프롬프트(422 content_rejected)는 아무것도 생성하지 않으므로, 같은 키를 새 프롬프트와 함께 다시 사용할 수 있습니다.
- 이벤트
job.queuedjob.processingjob.succeededjob.failedjob.cancelled- 서명
- X-Signature에는 유닉스 시간인 t와, t, 마침표, 원본 본문을 이어 붙인 값을 whsec_ 시크릿으로 계산한 HMAC-SHA256인 v1이 담깁니다. 5분보다 오래된 타임스탬프는 거부하고, X-Event-Id로 중복을 제거하세요.
- 전송
- 10초 이내에 2xx로 응답하면 전송된 것으로 간주합니다. 전송에 실패하면 1분, 5분, 30분, 2시간, 6시간 후에 재시도합니다. 리디렉션은 따르지 않습니다.
{
"id": "evt_01J9ZKB1QX",
"type": "job.succeeded",
"created_at": "2026-09-29T14:02:31Z",
"data": {
"job": {
"id": "job_01J9ZK4T8W",
"object": "job",
"kind": "video",
"status": "succeeded",
"money_status": "settled",
"requested_model": "seedance-2.0-fast",
"credits_charged": 34,
"outputs": [
{
"kind": "video",
"url": "https://…/job_01J9ZK4T8W.mp4?sig=…"
}
]
}
}
}import { createHmac, timingSafeEqual } from "node:crypto";
// rawBody: the request body exactly as received, before any JSON parsing.
export function verifyWebhook(header, rawBody, secret, toleranceSec = 300) {
let t = null;
const signatures = [];
for (const item of (header ?? "").split(",")) {
const [key, value] = item.split("=", 2);
if (key === "t") t = Number(value);
if (key === "v1") signatures.push(Buffer.from(value, "hex"));
}
if (!t || Math.abs(Date.now() / 1000 - t) > toleranceSec) return false;
const expected = createHmac("sha256", secret).update(`${t}.${rawBody}`).digest();
return signatures.some((s) => s.length === expected.length && timingSafeEqual(s, expected));
}
// verifyWebhook(req.headers["x-signature"], rawBody, process.env.WEBHOOK_SECRET)
// Answer 2xx quickly, and skip an X-Event-Id you have already handled.오류와대처 방법
모든 오류는 code, message, param, request_id가 담긴 error 객체라는 같은 형태를 가집니다. 가장 자주 만나게 될 오류는 다음과 같습니다:
| 코드 | HTTP | 대처 방법 |
|---|---|---|
invalid_request | 400 | param에 표시된 필드를 수정하세요. |
unauthorized | 401 | 키와 Bearer 헤더를 확인하세요. |
insufficient_credits | 402 | 충전한 뒤 같은 Idempotency-Key로 재시도하세요. |
forbidden_model | 403 | 스튜디오에서 키의 허용 목록에 모델이나 도구를 추가하거나, 다른 키를 사용하세요. 화질 향상 같은 도구는 별도로 추가해야 합니다. |
quote_expired | 409 | 새 견적을 받으세요. 견적은 10분 동안 유효합니다. |
price_changed | 409 | 가격이 상한보다 올랐습니다. 다시 견적을 받거나 max_credits를 높이세요. |
content_rejected | 422 | 청구된 금액은 없습니다. 프롬프트나 이미지를 바꾸세요. |
rate_limited | 429 | Retry-After만큼 기다린 뒤 재시도하세요. |
upstream_unavailable | 503 | 모델을 이용할 수 없습니다. 나중에 다시 시도하세요. 시작되지 않은 작업은 청구되지 않습니다. |