HiAPI
블로그

튜토리얼

Python의 Kling 3.0 Turbo 이미지-투-비디오 API: 스키마, 전체 스크립트 및 오류 처리

Turbo 단일 이미지 스키마, 3–15초 제한, 720p/1080p 등급 및 실패 모드에 대한 버전 전용 레퍼런스.

Jul 11, 2026
Python의 Kling 3.0 Turbo 이미지-투-비디오 API: 스키마, 전체 스크립트 및 오류 처리

kling-3.0-turbo/image-to-video의 스키마는 작고 엄격합니다: 공개 이미지 URL 하나, 필수 모션 프롬프트, 3~15초의 정수 길이, 그리고 720p 또는 1080p 출력입니다. 이 페이지는 해당 버전 전용 레퍼런스로, 요청 본문을 검증하고 HTTP 400 오류와 비동기 TASK_FAILED 결과를 구분하는 데 사용됩니다.

생성, 폴링, 콜백, 다운로드의 일반적인 흐름은 Kling Python 작업 러너 및 Omni/Turbo 선택 가이드를 참조하세요.

Turbo 입력 스키마

필드 타입 필수 여부 허용 값
prompt string 예 동작과 카메라 움직임을 설명
image_urls 문자열 배열 예 공개 접근 가능한 이미지 URL 정확히 하나
duration integer 아니오 3~15초
resolution string 아니오 720p 또는 1080p

Turbo는 sound, aspect_ratio, negative_prompt, seed, mode를 허용하지 않으며 두 번째 이미지 URL도 받지 않습니다. 엄격한 스키마는 추가 속성을 조용히 무시하지 않고 거부합니다.

입력 이미지가 화면 형태를 결정합니다. 작업을 만들기 전에 공개 버킷이나 CDN에 업로드하세요. 렌더러는 localhost, 비공개 대시보드, 만료된 서명 URL을 가져올 수 없습니다.

최소 동작 요청

curl -X POST https://api.hiapi.ai/v1/tasks \
  -H "Authorization: Bearer $HIAPI_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "kling-3.0-turbo/image-to-video",
    "input": {
      "prompt": "The runner accelerates as the camera tracks from the side",
      "image_urls": ["https://cdn.example.com/first-frame.jpg"],
      "duration": 6,
      "resolution": "1080p"
    }
  }'

성공 응답에는 data.taskId가 포함됩니다. HTTP 200은 생성 성공만을 의미하며 완료를 뜻하지 않습니다. 비디오 렌더링은 여전히 비동기로 진행됩니다.

Python 사전 검증

네트워크 호출 전에 제약을 먼저 검증하여 명백한 오류가 작업을 생성하지 않도록 하세요:

from urllib.parse import urlparse

import requests


def turbo_input(prompt: str, image_url: str, duration: int, resolution: str) -> dict:
    if not prompt.strip():
        raise ValueError("prompt is required")
    if type(duration) is not int or not 3 <= duration <= 15:
        raise ValueError("duration must be an integer from 3 to 15")
    if resolution not in {"720p", "1080p"}:
        raise ValueError("resolution must be 720p or 1080p")
    parsed = urlparse(image_url)
    if parsed.scheme not in {"http", "https"} or not parsed.netloc:
        raise ValueError("image_url must be a public HTTP(S) URL")

    return {
        "prompt": prompt,
        "image_urls": [image_url],
        "duration": duration,
        "resolution": resolution,
    }


payload = {
    "model": "kling-3.0-turbo/image-to-video",
    "input": turbo_input(
        prompt="The runner accelerates as the camera tracks from the side",
        image_url="https://cdn.example.com/first-frame.jpg",
        duration=6,
        resolution="1080p",
    ),
}

response = requests.post(
    "https://api.hiapi.ai/v1/tasks",
    headers={"Authorization": "Bearer sk-your-key"},
    json=payload,
    timeout=30,
)
response.raise_for_status()
task_id = response.json()["data"]["taskId"]
print(task_id)

이 로컬 검사는 값의 형태 문제를 찾아내지만 원격 이미지가 공개적으로 다운로드될 수 있는지는 증명하지 못합니다. 렌더러는 작업을 생성한 후에 해당 가져오기를 수행합니다.

전체 Python 스크립트: 제출, 폴링, 다운로드

위 코드 조각은 작업 ID에서 끝납니다. 이 버전은 전체 작업을 실행하고 MP4를 저장합니다. Idempotency-Key 헤더를 전송하므로 타임아웃 후 동일한 제출을 재시도하면 두 번째 작업을 생성하고 과금하는 대신 원래 작업을 반환합니다:

import os
import time
import uuid

import requests

API = "https://api.hiapi.ai/v1/tasks"
HEADERS = {"Authorization": f"Bearer {os.environ['HIAPI_API_KEY']}"}


def run_turbo(prompt: str, image_url: str, duration: int = 5,
              resolution: str = "720p", out_path: str = "turbo.mp4") -> str:
    body = {
        "model": "kling-3.0-turbo/image-to-video",
        "input": turbo_input(prompt, image_url, duration, resolution),
    }
    key = str(uuid.uuid4())  # reuse this key if you retry the same submission
    r = requests.post(API, json=body, headers={**HEADERS, "Idempotency-Key": key}, timeout=30)
    if r.status_code == 400:
        raise ValueError(f"schema error, no task created: {r.text}")
    r.raise_for_status()
    task_id = r.json()["data"]["taskId"]

    deadline = time.time() + 900
    while time.time() < deadline:
        data = requests.get(f"{API}/{task_id}", headers=HEADERS, timeout=30).json()["data"]
        if data["status"] == "success":
            video = requests.get(data["output"][0]["url"], timeout=120)
            video.raise_for_status()
            with open(out_path, "wb") as f:
                f.write(video.content)  # the output URL is temporary, so save it now
            return out_path
        if data["status"] == "fail":
            raise RuntimeError(f"TASK_FAILED {task_id}: {data.get('error')}")
        time.sleep(10)
    raise TimeoutError(task_id)


print(run_turbo(
    "The runner accelerates as the camera tracks from the side",
    "https://cdn.example.com/first-frame.jpg",
))

이렇게 5초 720p 클립의 비용은 $0.65입니다. 프로덕션 환경에서는 폴링 루프 대신 최상위 "callback": {"url": "https://your-app.example.com/hiapi/callback"}를 사용하고 작업 ID별로 알림을 중복 제거하세요.

HTTP 400: 작업이 생성되지 않음

HTTP 400 응답은 동기 스키마 검증의 결과입니다. 일반적인 원인은 다음과 같습니다:

잘못된 입력 실패 이유 수정 방법
"duration": "5" 정수가 아닌 문자열을 전송함 5를 전송하도록 변경
"duration": 20 최대값은 15 3–15 선택
image_urls 두 개 Turbo는 하나만 허용 시작 프레임만 유지
"resolution": "4K" Turbo는 720p와 1080p 지원 720p 또는 1080p 사용, 또는 Omni 선택
"sound": true sound는 Turbo 스키마에 없음 해당 필드 제거 또는 Omni 선택
prompt 누락 Turbo는 프롬프트 필요 비어 있지 않은 모션 프롬프트 추가

검증이 생성 전에 실패하므로 폴링할 작업 ID가 없습니다. 응답 본문과 요청 ID를 기록하고, 요청 본문을 수정한 후 새 요청으로 다시 제출하세요.

TASK_FAILED: 생성 성공, 렌더링 실패

POST /v1/tasks가 HTTP 200과 작업 ID를 반환했다면, 이후 실패는 비동기 작업 수명 주기 문제이며 400과 구분해서 다루어야 합니다.

일반적인 원인은 다음과 같습니다:

  • 이미지 URL에 Cookie 또는 인증 헤더가 필요함;
  • 서명된 이미지 URL이 렌더러의 가져오기 전에 만료됨;
  • 호스트가 서버 측 가져오기를 차단하거나 HTML 페이지로 리디렉션함;
  • 파일이 손상되었거나 미디어 타입이 내용과 일치하지 않음;
  • 서비스 제공자가 해당 렌더링을 완료하지 못함.

작업 ID, 최종 오류 코드와 메시지, 원본 입력 URL 및 요청 시간을 기록하세요. 재시도 전에 인증 없는 서버가 2xx 응답과 이미지 콘텐츠 타입으로 해당 이미지를 가져올 수 있는지 확인하세요. 접근 불가능한 동일 URL을 무작정 재시도하면 실패 작업만 하나 더 생성됩니다.

일반 Python 가이드에는 공용 최종 상태 폴링 루프와 출력 다운로드 코드가 포함되어 있습니다. 이를 그곳에 두면 이 버전 레퍼런스 페이지에서 수명 주기 로직이 중복되는 것을 피할 수 있습니다.

Turbo 요금 및 모델 선택

현재 프로덕션 요율은 다음과 같습니다:

Turbo 등급 초당 가격 5초 작업
720p $0.130 $0.65
1080p $0.160 $0.80

대량 사용 전에 실시간 가격 페이지를 확인하세요. Turbo라는 이름은 모델 변형을 설명할 뿐, 모든 해상도에서 더 저렴하다거나 작업이 고정된 렌더링 시간 SLA를 충족한다고 보장하지 않습니다.

끝 프레임, 오디오 또는 4K가 필요할 때는 표준 Kling 3.0(kling-3.0/image-to-video)을 선택하세요. 이 모델은 한 장 또는 두 장의 이미지(시작 프레임과 종료 프레임)를 받고, sound 스위치가 있으며, 720p 무음 기준 $0.10/s, 1080p 무음 기준 $0.129/s입니다. 참조 이미지나 참조 비디오가 필요할 때는 Omni를 선택하세요. 720p 또는 1080p 단일 입력 프레임의 경우, 자체 모션 프롬프트로 이러한 변형들을 벤치마크하고 출력 품질, 대기 시간 및 총비용을 평가하세요.

자주 묻는 질문

Kling 3.0 Turbo 이미지-투-비디오는 이미지를 몇 장 받나요?

공개 이미지 URL 정확히 하나입니다. 두 번째 이미지는 스키마 오류(image_urls: maxItems: got 2, want 1)를 발생시킵니다. 시작/종료 프레임 제어가 필요하면 표준 Kling 3.0 이미지-투-비디오를 사용하세요.

유효한 길이 값은 무엇인가요?

3에서 15 사이의 정수를 전송하세요. "5"와 같이 따옴표로 감싼 숫자는 문자열이므로 검증에 실패합니다.

Turbo는 4K 또는 오디오를 지원하나요?

4K는 지원하지 않습니다. 이 엔드포인트는 720p 또는 1080p를 받습니다. sound 필드는 없지만 Turbo 클립에는 오디오가 내장되어 있으며 끌 수 없습니다. 4K 또는 무음 출력이 필요하면 표준 Kling 3.0 또는 Omni를 사용하세요.

HTTP 400과 TASK_FAILED의 차이는 무엇인가요?

HTTP 400은 요청이 스키마를 위반하여 작업이 생성되지 않았음을 의미합니다. TASK_FAILED는 유효한 생성 응답 이후 입력 가져오기 또는 생성 단계에서 발생합니다.

공개된 것처럼 보이는 이미지 URL이 TASK_FAILED를 유발하는 이유는 무엇인가요?

해당 URL이 Cookie에 의존하거나, 서명이 만료되었거나, 서버 측 가져오기를 차단하거나, 이미지 바이트 대신 HTML을 반환할 수 있습니다. 재시도 전에 브라우저 인증 없이 테스트하세요.

영구 AI 아티팩트로 빌드 시작하기

API 키를 받아 태스크 기반의 하나의 API로 이미지, 비디오, 오디오 모델을 호출하세요.

API 문서 보기