HiAPI
블로그

튜토리얼

hiapi API로 veo-3.1-lite/text-to-video 사용하기: curl, Python 및 실행 가능한 요청

Aug 27, 2026
hiapi API로 veo-3.1-lite/text-to-video 사용하기: curl, Python 및 실행 가능한 요청

veo-3.1-lite/text-to-video는 텍스트 프롬프트 하나만으로 짧은 동영상 클립을 생성합니다——시작 이미지가 필요 없습니다. 이 가이드는 실제 hiapi 태스크 API에 대한 복사-붙여넣기 가능한 curl 및 Python 예제, 정확한 입력 schema(실제 엔드포인트와 대조 확인 완료), 그리고 프로덕션 환경에서 실제로 마주치게 될 오류 형태를 제공합니다.

1. 사전 요구 사항

  • hiapi 계정 및 API Keys 대시보드에서 발급받은 API key(sk-...).
  • curl 또는 requests가 설치된 Python 3(pip install requests).
  • 그 외에는 아무것도 필요하지 않습니다——text-to-video에는 프롬프트 문자열 하나만 있으면 됩니다.

hiapi의 모든 생성 모델은 동일한 통합 비동기 태스크 API를 통해 동작합니다: POST /v1/tasks로 태스크를 생성한 뒤, 폴링하거나 콜백을 기다려 결과를 받습니다. veo-3.1-lite/text-to-video의 호출 방식은 다른 어떤 비디오 모델과도 완전히 같습니다——동일한 인증 헤더, 동일한 태스크 생명주기——model과 input만 다릅니다. 모델 id는 /text-to-video 접미사가 붙은 veo-3.1-lite/text-to-video이며, 같은 계열에는 원본 이미지를 애니메이션화하는 별도의 모델 id인 veo-3.1-lite/image-to-video도 제공됩니다.

2. 최소 실행 예제

2.1 태스크 생성(curl)

curl -s -X POST https://api.hiapi.ai/v1/tasks \
  -H "Authorization: Bearer sk-<your-api-key>" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "veo-3.1-lite/text-to-video",
    "input": {
      "prompt": "a paper boat drifting down a rain-slicked city street at night, neon signs reflecting on wet asphalt",
      "duration": 6,
      "resolution": "720p",
      "aspect_ratio": "16:9",
      "generate_audio": true
    }
  }'

호출에 성공하면 태스크 id가 즉시 반환됩니다——생성은 비동기로 진행됩니다:

{"code":200,"data":{"taskId":"tk-hiapi-01XXXXXXXXXXXXXXXXXXXXXXXX"},"message":"success"}

2.2 결과 폴링

curl -s https://api.hiapi.ai/v1/tasks/tk-hiapi-01XXXXXXXXXXXXXXXXXXXXXXXX \
  -H "Authorization: Bearer sk-<your-api-key>"

클립이 렌더링되는 동안 status는 "handling"입니다. 완료되면:

{
  "code": 200,
  "data": {
    "taskId": "tk-hiapi-01XXXXXXXXXXXXXXXXXXXXXXXX",
    "model": "veo-3.1-lite/text-to-video",
    "status": "success",
    "storage": "temp",
    "output": [
      {"artifactId": "...", "type": "video", "url": "https://temp.hiapi.ai/.../result.mp4", "expireAt": 1786932195}
    ]
  },
  "message": "success"
}

output[0].url은 임시이며 만료되는 링크입니다——expireAt이 지나기 전에 파일을 다운로드하세요(또는 출력을 영구 스토리지로 옮기세요).

2.3 전체 Python 예제

import time
import requests

API_KEY = "sk-<your-api-key>"
BASE = "https://api.hiapi.ai/v1/tasks"
HEADERS = {"Authorization": f"Bearer {API_KEY}", "Content-Type": "application/json"}


def create_task(prompt: str) -> str:
    resp = requests.post(BASE, headers=HEADERS, json={
        "model": "veo-3.1-lite/text-to-video",
        "input": {
            "prompt": prompt,
            "duration": 6,
            "resolution": "720p",
            "aspect_ratio": "16:9",
        },
    }, timeout=30)
    resp.raise_for_status()
    return resp.json()["data"]["taskId"]


def wait_for_result(task_id: str, poll_seconds: int = 5, timeout_seconds: int = 600) -> str:
    deadline = time.time() + timeout_seconds
    while time.time() < deadline:
        resp = requests.get(f"{BASE}/{task_id}", headers=HEADERS, timeout=30)
        resp.raise_for_status()
        data = resp.json()["data"]
        if data["status"] == "success":
            return data["output"][0]["url"]
        if data["status"] == "failed":
            raise RuntimeError(f"task {task_id} failed: {data}")
        time.sleep(poll_seconds)
    raise TimeoutError(f"task {task_id} did not finish in {timeout_seconds}s")


if __name__ == "__main__":
    tid = create_task("a paper boat drifting down a rain-slicked city street at night")
    video_url = wait_for_result(tid)
    print(video_url)

3. 입력 schema

아래 모든 필드는 input 아래에 위치합니다. 이 schema는 엄격합니다——존재하지 않는 필드를 보내면 400이 반환되며(additional properties '<field>' not allowed), 이는 렌더링 전에 요청을 빠르게 검증하는 좋은 방법입니다.

필드 타입 필수 설명
prompt string 예 장면 설명. 피사체, 움직임, 카메라 동작을 구체적으로 기술하세요.
duration integer 아니오 4, 6, 8 중 하나(초).
resolution string 아니오 "720p" 또는 "1080p".
aspect_ratio string 아니오 "16:9" 또는 "9:16".
generate_audio boolean 아니오 렌더링에 동기화된 환경/효과음 오디오를 포함합니다.
negative_prompt string 아니오 렌더링에서 피해야 할 콘텐츠 요소.
seed integer 아니오 재시도 간에 동일한 구도/움직임을 재현하기 위한 고정 값.

더 긴 길이와 더 높은 해상도는 렌더링 비용을 증가시킵니다——대량 태스크 규모를 확장하기 전에 가격 페이지에서 모델별 현재 과금 가격을 확인하세요.

4. 프로덕션 환경 패턴

규모가 커지면 폴링보다 콜백을 우선하세요

일회성 스크립트를 넘어서는 모든 경우에는 루프에서 폴링하는 대신 콜백을 등록하세요:

{
  "model": "veo-3.1-lite/text-to-video",
  "input": {"prompt": "..."},
  "callback": {"url": "https://your-app.example.com/webhooks/hiapi", "when": "final"}
}

callback.url은 접근 가능한 http(s) URL이어야 하며, when은 "final"만 허용합니다——hiapi는 태스크가 최종 상태(success 또는 failed)에 도달하면 해당 URL로 한 번 POST합니다. 이렇게 하면 폴링 루프에 요청 할당량을 낭비하지 않고 결과가 준비되는 순간 받을 수 있으며, 이는 비디오에서 더 중요합니다(렌더링 시간이 이미지 생성보다 길기 때문입니다).

멱등성과 재시도

태스크 실행기가 제출을 재시도할 수 있다면(크래시, 타임아웃, 재배포), 요청을 보내기 전에 자체 멱등 키를 반환된 taskId와 함께 기록해 두세요. 그러면 재시도 시 "이미 제출했는가?"를 확인할 수 있어, 중복 렌더링을 생성하고 두 번 결제하는 일을 피할 수 있습니다.

오류 처리

실제로는 두 가지 서로 다른 오류 형태가 나타납니다:

  • 잘못된 입력(400)——요청 본문 검증 오류:
    {"code":400,"data":null,"error_code":"INVALID_REQUEST","message":"invalid input: prompt: missing required field \"prompt\""}
    
  • 인증/권한 실패(401)——키 누락, 무효 또는 권한 부족:
    {"error":{"code":"permission_denied","message":"This API key cannot use the selected model...","request_id":"...","type":"hiapi_error"}}
    

먼저 HTTP 상태 코드로 분기한 뒤 응답 본문을 확인하세요——400은 거의 항상 필드 이름이나 값이 잘못되었음을 의미하므로(요청을 수정), 401은 키 자체를 처리해야 함을 의미합니다(대시보드 권한 또는 새 키).

5. 관련 페이지

자주 묻는 질문

veo-3.1-lite/text-to-video에 시작 이미지가 필요한가요? 아니요. prompt 문자열만으로 생성합니다. 애니메이션화할 원본 이미지가 있다면 별도의 veo-3.1-lite/image-to-video 모델 id를 사용하세요.

어떤 해상도와 길이를 지원하나요? resolution은 "720p" 또는 "1080p"이며, duration은 4, 6, 8초입니다. 다른 값을 보내면 허용되는 값 집합을 나열한 400이 반환됩니다.

생성된 클립에 오디오를 포함할 수 있나요? 예——input에 "generate_audio": true를 설정하면 동기화된 환경/효과음 오디오가 포함됩니다.

루프에서 폴링하지 않으려면 어떻게 하나요? webhook url과 "when": "final"을 포함한 callback 객체를 전달하세요. 태스크가 완료되면 hiapi가 해당 URL로 POST하므로, 주기적으로 GET /v1/tasks/<id>를 다시 확인할 필요가 없습니다.

왜 내 요청이 400이 아니라 401을 반환하나요? 401과 error_code/code가 "permission_denied"인 경우는 API key 자체가 무효이거나 해당 모델에 대한 접근 권한이 없음을 의미합니다——API Keys 대시보드를 확인하세요. 400은 유효한 key에 대해 요청 본문 형식이 잘못되었음을 의미합니다.

반환된 비디오 URL은 영구적인가요? 아니요——output[0].url은 expireAt 타임스탬프가 있는 임시 링크입니다. 만료 전에 다운로드하거나 영구 스토리지로 옮기세요.

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

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

API 문서 보기