본문으로 건너뛰기

문서키 발급부터 첫 클립까지

첫 생성에 필요한 모든 것: 키, 요청 하나, 작업, 그리고 웹훅.

개발자 API는 신청제입니다.

개요

HTTPS 기반 REST이며, JSON으로 주고받습니다. 모든 생성은 비동기로 처리됩니다.

기본 URL
https://api.pershot.app/v1
인증
Authorization: Bearer 뒤에 키를 붙입니다. 키는 sk_test_ 또는 sk_live_로 시작하며 한 번만 표시되고, 당사는 해시만 저장합니다.
키 권한
각 키에는 범위가 있으며, 스튜디오에서 설정한 경우 모델과 도구의 허용 목록도 있습니다. 허용 목록이 있는 키는 목록에 있는 것만 사용할 수 있으며, 여기에는 이미지 업스케일, 배경 제거, 화질 향상, 립싱크, 아웃페인팅, 이미지 편집기 같은 도구도 포함됩니다. 그 밖의 요청은 403 forbidden_model로 응답합니다. 화질 향상으로 1080p나 4K를 만들려면 동영상 모델과 화질 향상이 모두 필요합니다.
오류 형식
{ "error": { "code", "message", "param", "request_id" } }
ID
유형별 접두사가 붙습니다: job_, qt_, key_, up_.
AI 에이전트용
AI 에이전트용 텍스트: 입력, 허용 값, 설정별 가격, 요청 예시seedance-2.0-fastseedance-2.0-miniqwen-image-2512-lightningqwen-image-2512qwen-image-edit-2511-lightningqwen-image-edit-2511

실제 생성은 아직 열리지 않았습니다. 모델 페이지에 이메일을 남겨 주시면 열릴 때 한 번만 연락드리겠습니다.

빠른 시작

네 단계이며, 단계마다 받아야 할 응답을 함께 보여 줍니다.

  1. 01

    키 받기

    개발자 API는 신청제입니다. 스튜디오의 API 키 메뉴에서 신청하세요. 이용이 열리면 그곳에서 키를 만들고 바로 복사하세요. 전체 키는 한 번만 표시됩니다.

    Shell
    export API_KEY="sk_test_…"
  2. 02

    요청 보내기

    Idempotency-Key와 max_credits 상한을 넣어 샷을 POST 요청으로 보내세요. 곧바로 202와 대기 중인 작업을 받으며, 크레딧이 보류됩니다.

    POST /videos/generations
    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
    }
  3. 03

    작업 확인

    status가 succeeded가 될 때까지 작업을 GET으로 조회하세요. 출력 URL은 서명된 링크이며 만료되므로, 보관할 파일은 다운로드하세요.

    GET /jobs/{id}
    curl https://api.pershot.app/v1/jobs/job_01J9ZK4T8W \
      -H "Authorization: Bearer $API_KEY"
    받아야 할 응답
    {
      "id": "job_01J9ZK4T8W",
      "object": "job",
      "kind": "video",
      "status": "succeeded",
      "money_status": "settled",
      "requested_model": "seedance-2.0-fast",
      "resolved_model": "seedance-2.0-fast",
      "credits_quoted": 34,
      "credits_charged": 34,
      "outputs": [
        {
          "kind": "video",
          "url": "https://…/job_01J9ZK4T8W.mp4?sig=…",
          "width": 1280,
          "height": 720,
          "duration_s": 5
        }
      ],
      "error": null
    }
  4. 04

    웹훅 받기

    webhook_url을 전달하면 상태가 바뀔 때마다 타임스탬프로 서명된 POST 요청을 보내 드립니다. 2xx로 응답하세요. 전송에 실패하면 간격을 늘려 가며 재시도합니다.

    POST → webhook_url
    {
      "id": "evt_01J9ZKB1QX",
      "type": "job.succeeded",
      "created_at": "2026-09-29T14:02:31Z",
      "data": {
        "job": {
          "id": "job_01J9ZK4T8W",
          "object": "job",
          "status": "succeeded",
          "money_status": "settled",
          "credits_charged": 34,
          "outputs": [
            {
              "kind": "video",
              "url": "https://…/job_01J9ZK4T8W.mp4?sig=…",
              "width": 1280,
              "height": 720,
              "duration_s": 5
            }
          ]
        }
      }
    }

엔드포인트

모든 경로는 기본 URL을 기준으로 합니다.

메서드경로기능
GET/v1/models내 계정에서 사용할 수 있는 모델, 기능, 상태
GET/v1/pricing공개 가격, 로그인한 경우 내 계정의 가격
POST/v1/quotes계획, 항목별 내역, 최대 청구액, 만료 시각(10분)
POST/v1/videos/generations동영상 생성, 202와 작업 반환
POST/v1/images/generations이미지 생성 또는 편집, 202와 작업 반환
GET/v1/jobs/{id}상태, 서명된 링크로 된 출력물, 실제 비용
GET/v1/jobs내 작업, 최신순
POST/v1/jobs/{id}/cancel취소 요청, 모델이 이미 작업을 수락한 경우가 아니면 보류된 크레딧이 환불됨
GET/v1/balance버킷별 사용 가능 크레딧과 보류된 크레딧
GET/v1/usage일별 또는 모델별 사용량, JSON 또는 CSV
POST/v1/uploads최대 10 MB의 JPEG, PNG 또는 WebP 업로드

견적과 상한

모든 생성 요청에는 quote_id 또는 max_credits 상한 중 하나가 필요하며, 둘을 함께 보낼 수는 없습니다. quote_id를 보내면 작업이 그 견적대로 실행되고, max_credits를 보내면 가격이 상한 이하일 때만 실행됩니다.

model: "auto"에는 항상 max_credits가 필요합니다. 견적은 10분 동안 유효하며, 그 이후에는 quote_expired가 반환됩니다.

멱등성

모든 생성 요청에 Idempotency-Key 헤더(눈에 보이는 ASCII 문자 1~255자)를 보내세요.

24시간 이내에 같은 키로 요청하면 202 대신 HTTP 200과 함께 같은 작업이 반환되므로, 시간 초과 후 재시도해도 두 번째 작업이 생성되거나 청구되지 않습니다.

웹훅

생성 요청(또는 일괄 생성)에 webhook_url을 전달하면 상태 변경을 받을 수 있습니다. 각 이벤트는 id, type, created_at, data가 담긴 JSON 본문의 POST 요청이며, 작업 이벤트는 data.job, batch.completed는 data.batch를 포함합니다.

이벤트

  • job.queued
  • job.processing
  • job.succeeded
  • job.failed
  • job.cancelled
  • batch.completed
  • 각 전송에는 이벤트 ID, 타임스탬프, 서명이 있습니다. 본문을 신뢰하기 전에 서명을 검증하세요.
  • 엔드포인트가 10초 이내에 2xx로 응답하면 전송된 것으로 간주합니다. 그렇지 않으면 1분, 5분, 30분, 2시간, 6시간 후에 재시도한 뒤 실패로 표시하며, 지원팀이 다시 보낼 수 있습니다. 리디렉션은 따르지 않습니다.
  • 웹훅 URL은 https여야 합니다. 사설, 루프백 또는 예약된 주소의 호스트는 제출할 때와 연결할 때 모두 거부됩니다.

헤더

X-Signature
t=<unix>,v1=<hex HMAC-SHA256(secret, "<t>.<raw body>")>
X-Event-Id
이벤트 ID이며 본문에도 들어 있습니다. 재시도와 재전송에도 그대로 유지되므로, 저장해 두고 이미 처리한 ID는 건너뛰세요.
서명 시크릿
계정마다 whsec_… 시크릿이 하나 있으며, 스튜디오의 API 키 메뉴에서 확인할 수 있습니다. HMAC 키는 접두사를 포함한 시크릿 전체입니다.
교체
교체한 후 24시간 동안은 이전 시크릿도 두 번째 v1 항목으로 계속 서명합니다. v1 중 하나라도 일치하면 전송을 수락하세요.

다시 직렬화한 사본이 아니라 원본 본문으로 HMAC을 계산하고, 상수 시간으로 비교하며, 5분보다 오래된 타임스탬프는 거부하세요.

X-Signature 검증
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.

오류

코드와 HTTP 상태는 고정되어 있으며, message는 사람이 읽기 위한 것입니다.

코드HTTP발생 조건
invalid_request400필드가 없거나 범위를 벗어남
unauthorized401키가 없거나, 폐기된 키이거나, 서명이 잘못됨
insufficient_credits402잔액이 보류액을 충당하지 못함
forbidden_model403키의 허용 목록에 이 모델이나 도구가 없음
region_not_supported403현재 지역에서 제공되지 않는 모델
developer_api_closed403개발자 API가 닫혀 있을 때의 개발자 키. 이용은 신청제
member_connections_paused403내 AI 에이전트 연결이 일시 중지된 동안의 회원 로그인(MCP, 연결 코드, 명령줄)
not_found404내 계정에 해당 작업, 견적 또는 업로드가 없음
quote_expired409견적이 10분보다 오래됨
price_changed409가격이 상한보다 올라감
content_rejected422콘텐츠가 거부됨, 청구 없음
rate_limited429이 키의 요청이 너무 많음
concurrency_limited429이 계정에서 실행 중인 작업이 너무 많음
internal_error500당사 쪽에서 문제가 발생함
upstream_unavailable503모델을 이용할 수 없음, 나중에 재시도

모델의 결과가 불확실한 것은 오류가 아닙니다. 작업 상태가 unknown으로 표시되며, 다시 제출하기 전에 확인합니다.

한도

요청
기본적으로 키당 분당 60회.
동시 실행
기본적으로 계정당 동시 작업 3개이며, 요청하면 늘릴 수 있습니다.
최대치
모델의 처리 용량이 절대적인 최대치입니다. 키를 늘려도 동시 실행 수는 늘어나지 않습니다.

이미지

POST /v1/images/generations는 같은 헤더를 사용합니다. 등급과 작업 유형에 따라 모델 ID를 고르세요. 편집 모델은 image_url도 필요하며, 생성 모델은 이를 거부합니다.

등급생성편집
Image Mini이코노미 · 초안qwen-image-2512-lightningqwen-image-edit-2511-lightning
Image Fast추천qwen-image-2512qwen-image-edit-2511

모델별 한도

모든 모델의 API 페이지에 값, 단위, 검사 주체, 한도 초과 시 동작을 담은 전체 표가 있습니다. GET /v1/models도 같은 한도를 JSON으로 반환합니다.

  • 강제 적용당사가 검사하며, 견적이나 보류 전에 400으로 응답합니다.
  • 공급사공급업체가 검사합니다. 공급업체가 거부한 작업은 실패하며, 비용은 청구되지 않습니다.
  • 권장아무도 검사하지 않습니다. 범위 안에 머물면 더 좋은 결과를 얻을 수 있습니다.
모델주요 한도전체 표
seedance-2.0-fastSeedance 2.0 Fast프롬프트 2~2,000자 · 4~15초 · 참조 이미지 최대 9장 · 이미지 변당 300~6,000 px표 열기
seedance-2.0-miniSeedance 2.0 Mini프롬프트 2~2,000자 · 4~15초 · 참조 이미지 최대 9장 · 이미지 변당 300~6,000 px표 열기
qwen-image-2512Qwen-Image-2512프롬프트 2~2,000자 · 1K 또는 2K · 원본 이미지 없음표 열기
qwen-image-2512-lightningQwen-Image-2512 · Lightning 4-step프롬프트 2~2,000자 · 1K 또는 2K · 원본 이미지 없음표 열기
qwen-image-edit-2511Qwen-Image-Edit-2511프롬프트 2~2,000자 · 1K 또는 2K · 원본 이미지 1장, 최대 10 MB의 JPEG, PNG 또는 WebP표 열기
qwen-image-edit-2511-lightningQwen-Image-Edit-2511 · Lightning프롬프트 2~2,000자 · 1K 또는 2K · 원본 이미지 1장, 최대 10 MB의 JPEG, PNG 또는 WebP표 열기

업로드

POST /v1/uploads는 파일 자체에서 형식을 읽습니다. 업로드 링크는 7일 동안 유효합니다.

파일형식최대 파일 크기최대 길이
이미지: 첫 프레임, 참조 또는 편집 원본JPEG, PNG, WebP10 MB–
동영상: 립싱크MP450 MB60초
오디오: 립싱크MP3, WAV, M4A10 MB60초

당사는 다른 호스트의 이미지를 가져오지 않으므로, 그런 링크의 크기는 공급업체가 검사합니다. 공급업체가 거부한 작업에는 비용이 청구되지 않습니다. 같은 한도가 JSON으로도 반환됩니다. GET /v1/models는 모든 모델에 대해 limits 객체를 반환합니다.

fal, Replicate, WaveSpeed에서 옮겨 오는 경우

기본 URL과 키만 바꿔서는 충분하지 않습니다. 모든 요청에는 본문의 모델 ID, Idempotency-Key 헤더, 가격 상한(max_credits 또는 quote_id)도 필요합니다. 마이그레이션 가이드는 Seedance 2.0과 Qwen-Image의 모든 필드를 대응시키고, 그대로 옮겨지지 않는 것을 정리합니다.