튜토리얼
HiAPI 작업 출력 URL 만료(expireAt): 만료 전에 다운로드하고 결과를 이전하세요
종료 상태의 output[].url에는 expireAt이 붙어 있고 만료되면 404가 됩니다—어떻게 판단하고, 제때 다운로드하며, 만료 후 어떻게 복구할지 정리합니다.
POST /v1/tasks로 이미지나 영상을 생성하면 작업이 끝난 뒤 data.output[0].url에서 temp.hiapi.ai 링크를 받게 됩니다. 그때는 열리지만 며칠 뒤 다시 접속하면 HTML「Not Found」페이지로 바뀝니다:
HTTP/2 404
content-type: text/html
반환되는 것은 이미지/영상 바이트가 아니라 Cloudflare의 404 페이지입니다. 원인은 단 하나: 작업 출력 URL은 유효기간이 있는 임시 링크이며, 종료 상태의 expireAt(Unix 타임스탬프)이 되면 temp.hiapi.ai의 객체가 정리되어 핫링크가失效합니다.
먼저 종료 상태의 필드를 이해하기
작업 종료 상태(GET /v1/tasks/{taskId})가 성공했을 때의 주요 필드는 다음과 같습니다:
{
"code": 200,
"data": {
"taskId": "tk-hiapi-xxxxxxxx",
"status": "success",
"storage": "temp",
"created": 1791828181,
"completed": 1791828201,
"output": [
{
"artifactId": "...",
"type": "image",
"url": "https://temp.hiapi.ai/....png",
"expireAt": 1792432981
}
]
},
"message": "success"
}
data.status == "success"여야 종료 상태 성공입니다(실패는"fail", 대기/처리 중은queued/handling/archiving).data.output은 배열이며, 각 요소에 자체url과expireAt이 있습니다.expireAt은 Unix 정수 타임스탬프입니다(ISO 문자열 아님). 만료 여부는 이것만 보면 됩니다:now >= expireAt이면 만료.data.storage의 값은"temp"입니다—이 자체가 힌트입니다: 임시 저장소이며 장기 참조용이 아닙니다.
유효기간은 얼마나 될까요? 한 샘플을 측정해 보니
expireAt - completed = 604800초(정확히 7일)였습니다. 하지만 「7일」을 코드에 하드코딩하지 마세요—각 출력의expireAt을 기준으로 하며, 모델/저장 정책에 따라 다를 수 있습니다.
흔한 원인(발생 확률 순)
- 핫링크를 데이터베이스에 장기 참조로 저장: 저장 시
temp.hiapi.ai/...라는 임시 URL을 넣어 두면expireAt이 지나면 일괄 404가 됩니다. 가장 흔한 함정입니다. - 종료 상태를 받고 즉시 다운로드하지 않음: 작업이 끝난 뒤 한참(TTL 초과) 지나서야 바이트를 가져옴.
- 다시 폴링하면 링크가 「갱신」된다고 생각: 같은
taskId로 다시 GET해도 반환되는 것은 같은 url과 같은expireAt입니다—메타데이터는 영속되지만 객체 자체는 만료 후 재생성되지 않으며, 다시 GET해도 새 링크를 주지 않습니다. - 404를 작업 실패로 오인: 작업은 이미 오래전에
success였고 출력 자산만 만료된 것일 뿐, 이는 별개의 문제입니다.
복구 단계
- 종료 상태가 오면 즉시 바이트를 다운로드하세요. 폴링에서
data.status == "success"를 확인한 후, 곧바로 각output[].url에 GET을 보내 바이너리를 받아오세요. 대기시키거나 미루지 마세요. - 자신의 객체 스토리지로 이전하세요(R2 / S3 / 로컬 디스크). 그리고 자신의 영속 URL로 바꾸세요.
- 데이터베이스에는 자신의 영속 URL만 저장하고,
temp.hiapi.ai핫링크는 절대 저장하지 마세요. - 다운로드 전에 만료되지 않았는지 확인:
now < expireAt일 때만 다운로드하고, 이미 만료됐다면 재실행 로직으로 넘어가세요. - 만료되면 작업을 다시 실행하는 수밖에 없습니다. 「taskId로 새 링크를 받는」 방법은 없습니다—같은 taskId로 다시 GET해도 받는 것은 그 만료된 url입니다. 다운로드 가능한 결과를 다시 얻으려면 작업을 다시 제출해야 합니다(재과금).
- 배치 작업의 다운로드 순서를 제어하세요: 한 배치에서 가장 먼저 완료된 항목의
expireAt도 가장 먼저 만료됩니다. 완료 순서대로 즉시 다운로드하고, 배치 전체가 끝날 때까지 기다렸다가 일괄 다운로드하지 마세요. 그러면 먼저 완료된 항목이 만료에 임박할 수 있습니다.
최소 검증 예시
키가 통하는지, 작업 API가 결과를 내는지, expireAt을 직접 확인하세요. model id는 맨 id를 사용하세요(z-image, /text-to-image 같은 접미사를 붙이면 400이 납니다):
# 1. 작업 제출
curl -s https://api.hiapi.ai/v1/tasks \
-H "Authorization: Bearer $HIAPI_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "z-image",
"input": { "prompt": "a red apple on a wooden table" }
}'
# → {"code":200,"data":{"taskId":"tk-hiapi-..."},"message":"success"}
# 2. 이전 단계의 taskId로 종료 상태를 폴링하여 url과 expireAt 읽기
curl -s https://api.hiapi.ai/v1/tasks/tk-hiapi-xxxx \
-H "Authorization: Bearer $HIAPI_API_KEY"
# data.status가 "success"로 바뀌면 data.output[0].url / .expireAt이 생깁니다
인증이 실패하면 HTTP 401 + {"error":{"code":"permission_denied","type":"hiapi_error","request_id":"..."}}가 반환됩니다—이는 키 문제이지 만료 문제가 아닙니다. 작업을 찾을 수 없으면 {"code":404,"data":null,"message":"task not found"}입니다—보통 taskId를 잘못 적었거나 다른 환경의 키를 사용한 경우입니다.
관련 링크
- 작업 API 제출 및 폴링 방법: HiAPI 빠른 시작 문서
- API key 확인, 작업 이력 보기: 콘솔
- 호출 가능한 모델 목록: 모델 마켓
- 개별 모델 페이지 예시(본문 검증에 사용한 것): Z-Image 텍스트→이미지
FAQ
질문: expireAt은 정확히 어떤 형식인가요?
답변: Unix 정수 타임스탬프(초)입니다. 예를 들어 1792432981이며 ISO 문자열이 아닙니다. now >= expireAt으로 만료를 판단하면 됩니다.
질문: 링크가 만료된 후 작업을 다시 GET해서 링크를 「연장」할 수 있나요?
답변: 안 됩니다. 같은 taskId로 다시 GET해도 받는 것은 그 원본 url과 원본 expireAt이며 객체는 이미 정리되었습니다. 다운로드 가능한 결과를 다시 얻으려면 작업을 다시 실행해야 합니다(재과금).
질문: 만료 후 접근하면 403인가요, 404인가요?
답변: HTTP 404이며, body는 text/html의 Cloudflare「Not Found」페이지입니다. 이미지 바이트도 아니고 XML의 AccessDenied도 아닙니다. 다운로드 로직이 200만 인정한다면 「비200은 모두 실패로 처리」하도록 하세요.
질문: 유효기간은 고정 7일인가요?
답변: 측정 샘플은 7일(604800초)이었지만, 각 출력의 expireAt을 기준으로 하세요. 코드에 일수를 하드코딩하지 마세요.
질문: 배치 작업은 어떻게 다운로드하는 것이 가장 안정적일까요?
답변: 완료 순서대로, 먼저 success된 항목의 바이트를 먼저 받으세요. 가장 먼저 완료된 출력의 expireAt도 가장 먼저 만료되므로, 마지막까지 미뤘다가 일괄 다운로드하면 만료에 임박하기 쉽습니다.
관련 글
모든 아티클 보기 →-
튜토리얼
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 튜토리얼
요청 우선 실전 데모: 프롬프트에서 비디오 클립까지의 호출 구성, 요청 제출, 완료 상태 폴링 및 결과 다운로드