튜토리얼
HiAPI에서 kling-4.0/image-to-video를 호출하는 방법: curl, Python 및 폴링
kling-4.0/image-to-video 엔드포인트의 역할
kling-4.0/image-to-video는 단일 정적 이미지를 짧은 생성 비디오로 변환합니다. HiAPI에서는 작업 기반 엔드포인트로 제공됩니다. 이미지와 화면이 어떻게 움직이길 원하는지 설명하는 프롬프트 스타일의 설명을 제출하면, API는 최종 완성된 비디오 대신 작업 핸들을 즉시 반환합니다.
요청 수준에서 호출자는 다음을 제공해야 합니다:
- 모델 식별자(
kling-4.0/image-to-video), - 소스 이미지(일반적으로 공개적으로 접근 가능한 이미지 URL),
- 이미지가 어떻게 움직여야 하는지 또는 장면에서 어떤 일이 일어나야 하는지 안내하는 텍스트 설명,
- 이 엔드포인트에서 이 모델을 위해 기록된 모든 추가 생성 옵션.
반환되는 것은 비디오 자체가 아닙니다. 제출 응답은 작업 식별자와 초기 상태를 담고 있습니다. 실제 비디오 클립은 생성 작업이 완료된 후에야 사용할 수 있으며, 그때 해당 식별자를 참조하여 가져올 수 있습니다.
이러한 분리가 바로 이 엔드포인트의 완전한 사고 모델입니다: 제출 → 작업 id 획득 → 상태 폴링 → 결과 다운로드. 아래의 각 섹션은 이 루프의 변형입니다.
이 엔드포인트는 비동기이므로 통합 코드에는 한 가지가 아닌 두 가지 책임이 있습니다. 형식이 올바른 제출 요청을 보내야 하고, 작업이 종료 상태에 도달할 때까지 후속 흐름을 관리해야 합니다. 이 두 가지를 잘 처리하면 나머지는 일반적인 연결 작업일 뿐입니다.
사전 조건 및 인증
어떤 호출을 하기 전에도 두 가지가 필요합니다: 해당 모델에 대한 접근 권한이 있는 HiAPI 계정, 그리고 콘솔에서 발급받은 API 키입니다.
인증은 요청 단위로 이루어집니다. 모든 API 호출은 HTTP 헤더에 키를 포함합니다. 표준 방식은 bearer 스타일 인증 헤더입니다:
Authorization: Bearer <YOUR_HIAPI_API_KEY>
키를 소스 코드 관리에 포함하지 마세요. 일반적인 방법은 다음과 같습니다:
- 환경 변수(예:
HIAPI_API_KEY)에 저장하고 런타임에 읽습니다. - 클라이언트 코드나 나중에 저장소에 커밋할 curl 명령에 절대 붙여넣지 마세요.
- 키가 유출되면 콘솔에서 교체하세요.
아래 curl 및 Python 예제 모두에서 읽을 수 있도록 셸에서 내보내세요:
export HIAPI_API_KEY="your-key-here"
접근 가능한 이미지 URL도 필요합니다. 이 엔드포인트는 참조로 이미지를 사용하므로 노트북의 로컬 파일 경로는 작동하지 않습니다. 안정적인 HTTPS URL이 있는 위치에 이미지를 호스팅하거나, 플랫폼이 리소스 메커니즘을 제공하는 경우 이미지를 업로드하고 반환된 참조를 사용하세요.
키를 내보내고 이미지에 접근할 수 있게 되면 작업을 제출할 수 있습니다.
curl 요청 단계별 분석
완전한 제출 요청은 다음과 같습니다:
curl -X POST "https://api.hiapi.ai/v1/tasks" \
-H "Authorization: Bearer $HIAPI_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "kling-4.0/image-to-video",
"input": {
"image": "https://example.com/your-image.jpg",
"prompt": "A slow camera push-in as the subject turns toward the light; soft afternoon shadows"
}
}'
부분별로 살펴보겠습니다:
-X POST— 작업 생성은 GET이 아닌 POST입니다. 요청은 작업을 설명하는 본문을 담습니다.- URL — 통합 HiAPI 작업 엔드포인트입니다. 작업 기반 모델의 경우 동일한 경로이며, 모델은 경로가 아닌 본문에서 선택됩니다.
Authorization— 이전 섹션에서 설명한 키입니다.Content-Type: application/json— 본문은 JSON입니다. 이 헤더를 생략하거나 잘못 입력하면 서버는 보통 요청이 모델에 도달하기 전에 거부합니다.model— 리터럴 문자열kling-4.0/image-to-video입니다. 정확하고 대소문자를 구분하는 값으로 취급하세요. 오타가 있으면 유용한 힌트 대신 모델을 찾을 수 없다는 오류가 발생합니다.input.image— URL로 제공되는 소스 정적 이미지입니다. 모델이 움직이게 할 프레임이므로 선명하고 구도가 명확한 이미지를 선택하세요.input.prompt— 자연어 안내입니다. 움직임과 카메라 동작(푸시인, 팬, 피사체 이동) 및 전체적인 분위기를 설명하세요. 모호한 프롬프트는 모호한 움직임을 만들어냅니다.
즉각적인 응답은 비디오가 아닌 작업 객체입니다. 여기에는 작업의 식별자와 상태 필드가 포함되며, 제출 후에는 일반적으로 대기열 또는 처리 대기 상태와 유사합니다. 이 식별자를 저장하세요. 나중에 작업을 확인하는 데 필요한 유일한 정보입니다.
이 시점에는 비디오 클립이 아직 존재하지 않습니다. 이는 예상된 동작이며, 다음 섹션에서 처리 방법을 보여줍니다.
Python에서의 동일한 호출
Python 버전은 완전히 동일한 작업을 수행합니다. 동일한 엔드포인트, 동일한 헤더, 동일한 본문입니다. 따라서 선택한 도구가 프로토콜을 바꾸지 않습니다.
import os
import requests
API_KEY = os.environ["HIAPI_API_KEY"]
payload = {
"model": "kling-4.0/image-to-video",
"input": {
"image": "https://example.com/your-image.jpg",
"prompt": "A slow camera push-in as the subject turns toward the light; "
"soft afternoon shadows",
},
}
resp = requests.post(
"https://api.hiapi.ai/v1/tasks",
headers={
"Authorization": f"Bearer {API_KEY}",
"Content-Type": "application/json",
},
json=payload,
timeout=60,
)
resp.raise_for_status()
task = resp.json()
task_id = task["id"]
print("submitted:", task_id, task.get("status"))
실무에서 주의할 점 몇 가지:
- 문자열을 수동으로 직렬화하지 말고
json=payload를 사용하세요. 콘텐츠 유형을 자동으로 설정하고 따옴표 오류를 피할 수 있습니다. - 제출 요청과 후속 작업을 같은 함수나 클래스에 두어 작업 id가 단계 사이에서 유실되지 않도록 하세요.
- 명시적인 타임아웃을 설정하세요. 제출 호출은 빠르게 반환되어야 합니다. 비디오를 기다리는 것이 아니라 작업만 생성하기 때문입니다.
raise_for_status()를 호출한 뒤에도 작업이 존재한다고 가정하지 마세요. 2xx가 아닌 응답은 작업이 생성되지 않았음을 의미하며, 오류 본문은 보통 어떤 필드가 잘못되었는지 알려줍니다.
서비스를 구축하는 경우 이 호출을 소규모 클라이언트로 감싸세요. 제출용 메서드 하나, 상태 확인용 메서드 하나입니다. 이렇게 하면 재시도, 로깅, 키 처리를 여러 호출 지점에 분산하지 않고 한곳에 집중할 수 있습니다.
완료될 때까지 비동기 작업 폴링
이미지-투-비디오 생성은 채팅 완성보다 눈에 띄게 오래 걸립니다. 모델이 많은 프레임을 합성하고 인코딩하고 결과를 저장해야 하기 때문입니다. 제출 응답에서 연결을 오래 열어두지 않고는 비디오 클립을 반환할 수 없으므로 이 엔드포인트는 설계상 비동기입니다.
상태 확인 방법
식별자를 사용해 작업을 GET 요청으로 폴링하세요:
curl "https://api.hiapi.ai/v1/tasks/$TASK_ID" \
-H "Authorization: Bearer $HIAPI_API_KEY"
응답은 작업을 설명합니다: 상태와 완료 시 출력입니다. 상태는 일반적으로 대기열 상태에서 실행 상태를 거쳐 종료 상태로 진행됩니다. 예를 들어 성공 또는 오류 메시지와 함께 실패입니다.
Python의 간단한 폴링 루프
import time
def wait_for_task(session, base_url, task_id, timeout=900):
deadline = time.time() + timeout
delay = 2.0
while time.time() < deadline:
r = session.get(f"{base_url}/tasks/{task_id}", timeout=30)
r.raise_for_status()
data = r.json()
status = data.get("status")
if status in ("succeeded", "failed"):
return data
time.sleep(delay)
delay = min(delay * 1.5, 15.0) # gentle backoff, capped
raise TimeoutError(f"task {task_id} did not finish in time")
백오프 지침
- 짧은 간격으로 시작해 점차 늘리세요. 생성은 1초 만에 완료되지 않으므로 엔드포인트를 자주 요청하면 할당량만 낭비하고 속도 제한을 유발합니다.
- 완료된 작업을 적시에 알아챌 수 있도록 간격을 제한하세요. 안정 상태에서는 몇 초면 충분합니다.
- 항상 확실한 마감 시간을 설정하세요. 경계를 설정하지 않으면 영원히 완료되지 않는 작업과 비정상적으로 오래 걸리는 작업을 구분할 수 없습니다.
- 웹 요청을 차단하지 말고 백그라운드 워커나 예약 작업에서 폴링하세요. 사용자가 UI에서 기다리는 경우 프런트엔드가 자체 상태 엔드포인트를 폴링하도록 하세요.
- 상태 호출에서 일시적인 네트워크 오류는 재시도하되, 이미
failed로 보고된 작업은 재시도하지 마세요. 이 경우 올바른 조치는 새 작업을 제출하는 것입니다.
반환된 비디오 클립 검색 및 저장
폴링이 성공 종료 상태를 반환하면 작업 객체에 생성된 비디오의 출력 참조가 포함됩니다. 완성된 비디오를 가리키는 리소스 URL 또는 동등한 참조입니다.
result = wait_for_task(session, "https://api.hiapi.ai/v1", task_id)
if result["status"] != "succeeded":
raise RuntimeError(result.get("error") or "generation failed")
video_url = result["output"]["video_url"]
with session.get(video_url, stream=True, timeout=120) as r:
r.raise_for_status()
with open(f"{task_id}.mp4", "wb") as f:
for chunk in r.iter_content(chunk_size=1 << 16):
f.write(chunk)
여기서 일반적으로 두 가지 설계 결정이 발생합니다.
적시에 다운로드하세요. 출력 URL은 보통 시간 제한이 있습니다. 비디오 클립을 보관할 계획이라면 원본 URL을 사용자에게 넘기고 유효하게 유지되기를 바라지 말고 자체 저장소에 복사하세요.
메타데이터를 파일과 함께 저장하세요. 작업 id, 프롬프트, 소스 이미지 참조, 생성 시간을 비디오와 함께 영구 저장하세요. 나중에 누군가 왜 비디오 클립이 그렇게 보이는지 묻는다면 그 기록이 답이 됩니다.
서비스를 제공하는 경우 일반적인 패턴은 백엔드에서 생성하고, 파일을 객체 스토리지에 저장하고, 클라이언트에 자체 안정적인 URL을 반환하는 것입니다. 이렇게 하면 생성 리소스의 수명 주기에 의존하지 않고 애플리케이션이 접근, 만료, 캐싱을 제어할 수 있습니다.
다른 움직임으로 재생성하려면 프롬프트를 조정한 새 작업을 제출하세요. 각 작업은 독립적이며 완료된 작업을 수정할 필요가 없습니다.
실패한 요청 문제 해결
문제가 발생하면 요청 구조에서 바깥으로 조사하세요. 대부분의 실패는 몇 가지 원인으로 귀결됩니다.
제출 호출이 오류를 반환하는 경우
- 모델 문자열 오류.
kling-4.0/image-to-video는 대소문자와 슬래시를 포함해 정확히 일치해야 합니다. 소스 파일을 신뢰하지 말고 실제로 보내는 문자열을 출력하세요. - 인증 거부. 헤더가
Authorization: Bearer <key>인지 확인하세요. 맨 키가 아니고 쿼리 매개변수도 아니며, 환경 변수가 요청을 실행하는 동일한 셸이나 프로세스에 설정되어 있어야 합니다. - 이미지에 접근 불가. 이미지는 플랫폼이 HTTPS로 가져올 수 있어야 합니다. localhost URL, 비공개 버킷, 핫링크 방지 호스트는 실패합니다. 시크릿 브라우저에서 URL을 열어 인증 없이 해석되는지 확인하세요.
- 필드 누락 또는 이름 오류. 본문은 모델 입력을
input아래에 중첩합니다.prompt나image를input안이 아닌 최상위에 두는 것은 흔한 실수이며, 유효성 검사 오류는 보통 필드 이름을 지적합니다. - 콘텐츠 유형.
Content-Type: application/json없이 JSON 본문을 보내면 모델에 도달하기 전에 거부됩니다.
작업이 생성되었지만 성공하지 못한 경우
- 폴링이 너무 적거나 전혀 없음. 루프가 실제로 실행 중인지, 비교하는 상태 값이 API가 반환하는 값과 일치하는지 확인하세요. 종료 상태 검사의 오타는 무한 루프를 유발합니다.
- 작업이
failed로 바뀜. 작업 객체의 오류 메시지를 읽으세요. 보통 디코딩할 수 없는 이미지와 같은 입력을 지적합니다. - 마감 시간에 도달함. 작업이 타임아웃 근처에서도 계속 실행 중이라면 반복 재제출 대신 상한을 높이세요. 재제출은 부하와 비용만 증가시킵니다.
- 출력 링크 만료. 작업은 성공했지만 다운로드가 404를 반환하면 완료와 검색 사이에 너무 많은 시간이 흐른 것입니다. 성공 후 즉시 다운로드하세요.
빠른 진단 습관 하나: 처음 몇 번 통합할 때 제출 응답 본문을 그대로 기록하세요. 그러면 작업 id, 초기 상태, 해당 엔드포인트가 반환하는 정확한 필드 이름을 알 수 있어 이후 모든 실패에서 추측을 없앨 수 있습니다.
관련 글
모든 아티클 보기 →-
튜토리얼
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 튜토리얼
요청 우선 실전 데모: 프롬프트에서 비디오 클립까지의 호출 구성, 요청 제출, 완료 상태 폴링 및 결과 다운로드