튜토리얼
kling-3.0-omni/transformation API 사용법: curl과 Python으로 구현하는 비디오 리스타일링
kling-3.0-omni/transformation은 Kling 3.0 Omni의 비디오-투-비디오 모델입니다. 소스 비디오와 텍스트 프롬프트를 제공하면 원본의 움직임과 타이밍은 유지하면서 장면, 스타일, 피사체 등 비디오의 외형을 다시 작성합니다. hiapi에서는 다른 모든 생성 모델과 동일한 통합 비동기 엔드포인트 POST /v1/tasks를 통해 호출합니다. 이 가이드는 실제로 검증된 파라미터 표, 바로 복사해 붙여넣을 수 있는 curl 요청, 완전한 Python 클라이언트(폴링 및 결과 다운로드 담당), 그리고 실제 애플리케이션에 연결하기 전에 필요한 프로덕션 패턴(콜백, 멱등성, 오류 처리)을 제공합니다.
아래의 모든 필드 이름, 열거형 값, 응답 구조는 실제 API와 대조하여 확인했습니다.
구축할 내용 + 사전 요구 사항
리스타일링 작업을 제출하고, 완료될 때까지 기다린 후, 리스타일링된 .mp4를 다운로드하는 작은 프로그램입니다. 두 가지가 필요합니다:
- hiapi API 키. hiapi 콘솔에서 생성하세요. 형식은
sk-...와 유사합니다. 모든 요청에는Authorization: Bearer sk-<your-key>를 사용합니다. - 공개적으로 접근 가능한 소스 비디오 URL. 모델이 서버 측에서 비디오를 다운로드하므로, 로컬 파일 경로가 아닌 공개
http(s)URL(자체 CDN, 공개 객체가 있는 R2/S3 등)이어야 합니다. URL은 하나만 허용됩니다.
모델 및 파라미터
요청의 외부 구조는 {"model": ..., "input": {...}}입니다. input의 스키마는 엄격합니다. 다음 세 필드만 허용되며, 그 외의 필드가 있으면 400이 반환됩니다.
| 필드 | 유형 | 필수 | 설명 |
|---|---|---|---|
prompt |
string | 예 | 목표 스타일/장면/피사체를 설명합니다. 리스타일링 강도도 여기서 조절합니다. 숫자형 strength/fidelity 파라미터는 없습니다. |
video_urls |
array | 예 | 공개 소스 비디오 URL 정확히 하나(minItems는 1, maxItems는 1). |
resolution |
string 열거형 | 예 | 720p, 1080p, 4k 중 하나. |
실수하기 쉬운 몇 가지:
duration파라미터는 없습니다. 출력 길이와 화면 비율은 소스 비디오를 따르며(3~15.5초), 최종 출력 길이를 기준으로 과금됩니다.- 모델 id 자체에
-omni가 포함되어 있습니다:kling-3.0-omni/transformation(일부 다른 Omni 엔드포인트는kling-3.0/...을 사용합니다). 이 id를 그대로model값으로 사용하세요. - 리스타일링 강도는 프롬프트로 제어됩니다. 약간의 변경을 원하면 "약하게 리스타일링하고 얼굴 특징과 조명을 유지"라고 쓰고, 큰 변경을 원하면 "2D 셀룰로이드 카툰으로 완전히 재상상"이라고 쓰세요.
최소 실행 예제(curl)
# 1) 리스타일링 작업 생성
curl -s https://api.hiapi.ai/v1/tasks \
-H "Authorization: Bearer sk-<your-key>" \
-H "Content-Type: application/json" \
-d '{
"model": "kling-3.0-omni/transformation",
"input": {
"prompt": "이 장면을 부드러운 종이 질감과 따뜻한 황혼 조명이 있는 수채화 애니메이션 스타일로 리스타일링하세요. 원본 카메라 움직임과 피사체는 유지하세요.",
"video_urls": ["https://your-cdn.example.com/source-clip.mp4"],
"resolution": "720p"
}
}'
# -> {"code":200,"data":{"taskId":"tk-hiapi-01..."},"message":"success"}
# 2) 작업이 종료 상태에 도달할 때까지 폴링
curl -s https://api.hiapi.ai/v1/tasks/tk-hiapi-01... \
-H "Authorization: Bearer sk-<your-key>"
# data.status 순서: queued -> handling -> archiving -> success
# 성공 시 data.output[0].url이 리스타일링된 .mp4입니다.
폴링에 사용하는 작업 id는 생성 응답의 data.taskId에서 가져옵니다. 최상위 id가 아닙니다. 상태 문자열은 queued / handling / archiving / success(종료 상태) 또는 fail입니다. succeeded/completed라고 가정하지 마세요.
완전한 Python 클라이언트(생성 → 폴링 → 다운로드)
import os
import time
import requests
API_KEY = os.environ["HIAPI_KEY"] # 당신의 sk-... 키
BASE = "https://api.hiapi.ai"
HEADERS = {
"Authorization": f"Bearer {API_KEY}",
"Content-Type": "application/json",
}
def create_restyle(source_video_url: str, prompt: str, resolution: str = "720p") -> str:
body = {
"model": "kling-3.0-omni/transformation",
"input": {
"prompt": prompt,
"video_urls": [source_video_url], # 정확히 하나의 공개 URL
"resolution": resolution, # "720p" | "1080p" | "4k"
},
}
r = requests.post(f"{BASE}/v1/tasks", json=body, headers=HEADERS, timeout=30)
r.raise_for_status()
data = r.json()
if data.get("code") != 200:
raise RuntimeError(f"제출이 거부됨: {data}")
return data["data"]["taskId"]
def wait_for_video(task_id: str, poll_s: int = 10, timeout_s: int = 900) -> str:
deadline = time.time() + timeout_s
while time.time() < deadline:
r = requests.get(f"{BASE}/v1/tasks/{task_id}", headers=HEADERS, timeout=30)
r.raise_for_status()
data = r.json()["data"]
status = data["status"]
if status == "success":
return data["output"][0]["url"]
if status == "fail":
raise RuntimeError(f"작업 실패: {data.get('error')}")
time.sleep(poll_s) # queued / handling / archiving
raise TimeoutError(f"{task_id}이(가) {timeout_s}초 내에 완료되지 않았습니다")
if __name__ == "__main__":
task_id = create_restyle(
source_video_url="https://your-cdn.example.com/source-clip.mp4",
prompt=(
"이 장면을 부드러운 종이 질감과 따뜻한 황혼 조명이 있는 "
"수채화 애니메이션 스타일로 리스타일링하세요. 원본 카메라 움직임과 피사체는 유지하세요."
),
resolution="720p",
)
print("작업:", task_id)
url = wait_for_video(task_id)
print("비디오 URL:", url)
# 출력 파일은 temp.hiapi.ai에 있으며 만료됩니다(약 7일). 지금 즉시 다운로드하세요.
clip = requests.get(url, timeout=120).content
with open("restyled.mp4", "wb") as f:
f.write(clip)
print("restyled.mp4 저장됨", len(clip), "바이트")
키를 환경 변수에 넣고 실행하세요:
export HIAPI_KEY=sk-<your-key>
python restyle.py
프로덕션 패턴
잦은 폴링 대신 콜백 사용
스크립트 외의 모든 상황에서는 폴링 루프를 유지하지 않도록 webhook을 등록하세요. callback은 최상위 필드로, model 및 input과 같은 레벨이며 절대 input 안에 두면 안 됩니다:
{
"model": "kling-3.0-omni/transformation",
"input": {
"prompt": "이 장면을 굵은 외곽선이 있는 2D 셀룰로이드 카툰 스타일로 리스타일링하세요. 원본 움직임은 유지하세요.",
"video_urls": ["https://your-cdn.example.com/source-clip.mp4"],
"resolution": "1080p"
},
"callback": { "url": "https://your-app.example.com/hooks/hiapi", "when": "final" }
}
callback.when은final(기본값)만 허용합니다. 작업이 종료 상태에 도달하면 한 번 큐에 들어가며, 성공과 실패 모두에서 트리거됩니다. 전달 의미론은 최소 한 번(at-least-once)이므로 동일한 콜백이 여러 번 도착할 수 있습니다(아래 참조).- 전달되는 POST 요청 본문은
GET /v1/tasks/<id>로 얻는data객체와 동일합니다. 따라서 핸들러는 다시 가져오지 않고도status,output[].url,error를 읽을 수 있습니다. callback을input에 넣으면 제출 시additional properties 'callback' not allowed오류로 실패합니다(각 모델의 input 스키마는 엄격합니다).
멱등성과 전달 의미론
콜백은 정확히 한 번이 아니라 최소 한 번입니다. 동일한 taskId가 여러 번 도착할 수 있습니다. 핸들러의 키로 taskId를 사용하고, "완료 표시 + 비디오 저장" 단계를 멱등적으로 만드세요. hiapi는 비 2xx/타임아웃 콜백을 즉시 → +1분 → +5분 → +20분, 최대 4회 시도 리듬으로 재시도합니다. 엔드포인트가 HTTP 2xx를 반환해야 재시도가 중단됩니다.
출력을 즉시 다운로드
data.output[0].url은 temp.hiapi.ai를 가리키며 expireAt(Unix 타임스탬프, 약 7일 TTL)을 가집니다. 만료 후 객체는 삭제되며 해당 URL은 404를 반환합니다. 작업을 다시 폴링하면 동일한 URL이 반환되지만 파일이 재생성되지는 않습니다. 작업이 성공하면 즉시 바이트를 자체 스토리지로 복사하세요.
오류 처리
분기 처리해야 하는 세 가지 실패 형태:
- 요청 오류(HTTP 400) — 평면 구조, 작업이 생성되지 않음:
{"code":400,"data":null,"error_code":"INVALID_REQUEST","message":"invalid input: resolution: value must be one of '720p', '1080p', '4k'"} - 인증 실패(HTTP 401) — 중첩 구조:
{"error":{"code":"permission_denied","type":"hiapi_error", ...}} - 작업 실패 — 제출은
200과taskId를 반환하지만, 이후 폴링에서data.status == "fail"및data.error가 표시됩니다. 실패한 작업은 과금되지 않습니다(작업이 최종적으로 실패하면 사전 차감액이 환불됩니다). 소스 URL에 접근할 수 없거나 다운로드할 수 없는 경우가 여기에 해당합니다.
비용
kling-3.0-omni/transformation은 출력 초 단위로 과금되며, 요율은 요청한 해상도에 따라 달라집니다(720p 초당 $0.143, 1080p 초당 $0.193, 4k 초당 $0.479, 2026년 10월 21일 확인). 비디오를 대량 처리하기 전에 실시간 hiapi 가격 페이지에서 현재 초당 요율을 확인하세요. 비디오 작업은 이미지 작업보다 비용이 훨씬 빠르게 누적됩니다.
관련 문서
- 모델 페이지 및 사양: hiapi의 kling-3.0-omni/transformation
- 엔드포인트 참조: 작업 생성 — 통합 비동기 API
- 같은 엔드포인트의 동일 계열 튜토리얼: Python에서의 Kling AI 이미지-투-비디오 API
자주 묻는 질문
리스타일링 강도는 어떻게 제어하나요?
파라미터가 아니라 프롬프트로 제어합니다. strength, fidelity, creativity 필드는 없습니다. 약한 편집은 "약하게 리스타일링하고 얼굴과 조명을 유지"라고 쓰고, 큰 편집은 "완전히 재상상하여
관련 글
모든 아티클 보기 →-
튜토리얼
HiAPI API로 hailuo-2.3-fast/image-to-video 호출하는 방법: curl과 Python 실전
빠르고 저렴한 이미지-투-비디오 등급의 첫 실행 요청 — 모델 ID부터 MP4 다운로드까지
-
튜토리얼
HiAPI API로 hailuo-2.3/text-to-video를 호출하는 방법: curl, Python 및 실행 가능한 요청 예시
-
튜토리얼
HiAPI에서 Kandinsky 6.0 Pro 텍스트-투-비디오 사용하기: curl 및 Python 튜토리얼
요청 우선 실전 데모: 프롬프트에서 비디오 클립까지의 호출 구성, 요청 제출, 완료 상태 폴링 및 결과 다운로드