튜토리얼
HiAPI 이미지 입력 오류: 공개 접근 가능한 URL을 사용하고, Base64는 사용하지 마세요
HiAPI의 이미지-투-이미지(image-to-image) 및 참조 이미지 모델은 공개 인터넷에서 접근 가능한 HTTP(S) URL에서 소스 이미지를 가져옵니다——base64 바이트 문자열은 받지 않으며, 사설 주소도 가져올 수 없습니다. 가장 많이 빠지는 함정은 이것입니다: 잘못된 이미지 입력이 성공한 것처럼 보인다는 점입니다——POST /v1/tasks가 200을 반환하며 taskId를 함께 주고, 진짜 실패는 태스크를 폴링할 때에야 드러납니다. 실제로 보게 될 두 가지 실패는 이렇습니다:
{ "code": 200, "message": "success",
"data": { "status": "fail", "model": "gpt-image-2/image-to-image", "storage": "temp", "taskId": "tk-...",
"error": { "code": "INVALID_REQUEST",
"message": "The image URL could not be downloaded. Please provide a reachable public HTTP(S) URL and try again." } } }
{ "code": 200, "message": "success",
"data": { "status": "fail", "model": "gpt-image-2/image-to-image", "storage": "temp", "taskId": "tk-...",
"error": { "code": "TASK_FAILED", "message": "task failed" } } }
첫 번째는 접근 불가능한 URL의 반환값이고, 두 번째는 base64 data URI를 이미지로 전달했을 때 얻는 일반적인 결과입니다——아무런 힌트 없이 task failed 한 줄뿐이며, 이 점이 가장 막막한 부분입니다. 바깥쪽의 "message": "success"는 그 폴링 요청 자체가 성공했다는 것만 뜻하며, 실제 결과는 data.status에 있습니다.
흔한 원인 (적중 확률 높은 순)
base64를 이미지 필드에 붙여넣었습니다——
data:image/...;base64,...문자열입니다. 이 필드가 요구하는 것은 서버가 가져갈 수 있는 URL이지 인라인 바이트가 아닙니다.gpt-image-2/image-to-image에서는 data URI가 제출 단계에서는 수락되지만, 이후 태스크 종료 상태가status: fail, 오류 코드TASK_FAILED/task failed가 됩니다.URL이 공개 접근 가능하지 않습니다.
http://localhost,127.0.0.1, 내부 IP, 로그인해야 볼 수 있는 파일, 만료된 presigned 링크는 모두INVALID_REQUEST로 실패합니다——"The image URL could not be downloaded…".필드명을 잘못 사용했습니다 (모델마다 다름, 아래 표 참조). 이미지 입력 필드는 모델 계열마다 통일되어 있지 않습니다. 이름을 잘못 쓰면 제출 단계에서 HTTP
400으로 막힙니다. 예를 들어gpt-image-2/image-to-image에서image_url을 잘못 사용한 경우:{ "code": 400, "data": null, "error_code": "INVALID_REQUEST", "message": "invalid input: input_urls: missing required field \"input_urls\"; <root>: additional properties 'image_url' not allowed" }편집에 베어 model id를 사용했습니다. 베어 id(예:
gpt-image-2)는 순수 텍스트-투-이미지로, 이미지 필드가 아예 정의되어 있지 않으므로 이미지 필드가 거부됩니다:400 invalid input: <root>: additional properties 'input_urls' not allowed. 편집에는 이미지-투-이미지 라우트 id인gpt-image-2/image-to-image를 사용하세요.
오류 코드 읽는 법: 「입력 문제」인지 「업스트림 문제」인지 파악하기
반환값을 제출 단계(POST /v1/tasks의 직접 응답)와 종료 상태(폴링 GET /v1/tasks/<taskId>로 얻는 data.status) 두 구간으로 나누어 봅니다:
- 제출 단계 HTTP 400, 플랫 엔벨로프
{"code":400,"data":null,"error_code":"INVALID_REQUEST","message":"invalid input: ..."}→ 요청 구조/필드에 문제가 있습니다(입력 문제). 태스크가 생성되지 않았으므로 과금되지 않습니다. 필드명이나 model id를 고치면 됩니다. - 제출 단계 HTTP 401, 중첩 엔벨로프
{"error":{"code":"permission_denied","type":"hiapi_error","request_id":"..."}}→ 인증 문제(key가 틀렸거나 권한이 없음)이며 입력 문제가 아닙니다. - 제출 단계 HTTP 200 +
taskId인데 폴링 시data.status: "fail":data.error.code를 보세요——INVALID_REQUEST이고 message가 "could not be downloaded" → 이미지 URL을 가져올 수 없음(여전히 당신의 입력 문제: 이미지를 공개 접근 가능한 URL로 교체).TASK_FAILED이고 message가 "task failed" → 힌트 없는 일반 실패. 먼저 base64 / 잘못된 입력을 배제하고, 배제 후에도 실패하면 「업스트림 생성」 문제로 처리.
한마디로: 제출 단계의 4xx는 요청/인증 계층의 문제이고, 종료 상태의 fail이라야 다운로드나 업스트림 생성이 관련될 수 있습니다. 그리고 어느 쪽이든 바깥쪽 "message":"success"에 속지 말고, 모든 판단은 data.status를 기준으로 하세요.
이미지 입력 필드명은 모델마다 다릅니다
아래 표는 각 모델의 현재 input schema를 실측 대조한 것입니다(필드는 계열마다 다르므로 반드시 모델 페이지를 다시 기준으로 삼으세요):
| 모델 id (이미지-투-이미지 라우트) | 이미지 입력 필드 | 타입 |
|---|---|---|
gpt-image-2/image-to-image |
input_urls |
문자열 배열 |
seedream-5.0-pro/image-to-image |
image_urls |
문자열 배열 |
nano-banana-pro |
image_input |
문자열 배열 |
필드는 input 객체 안에 넣어야 하며, 대부분의 참조 이미지 모델은 배열을 요구합니다(이미지가 한 장뿐이어도).
수정 단계
- 이미지를 공개 접근 가능한 HTTP(S) URL에 호스팅하세요. 임의의 오브젝트 스토리지 / CDN(Cloudflare R2, S3, GCS 등)에 업로드하고 객체를 공개 읽기로 설정하거나, 아직 유효한 presigned URL을 사용하세요.
- 인증 없이 접근 가능한지 확인하세요. 깨끗한 세션에서(또는 당신의 로컬 머신이 아닌 다른 머신에서)
curl -sI "<당신의URL>"을 실행해200과 content-typeimage/*가 반환되어야 합니다. 쿠키, 헤더, VPN이 필요하다면 서버는 가져올 수 없습니다. - 이미지-투-이미지 model id를 사용하고, 베어 id는 쓰지 마세요. 편집에는
gpt-image-2/image-to-image(또는 해당 모델의 i2i 라우트)를 호출하고,gpt-image-2는 호출하지 마세요. - 해당 모델 문서의 필드명(
input_urls/image_urls/image_input)을 사용해input안에 넣으세요. - 절대 base64를 전달하지 마세요. 바이트만 있다면 먼저 업로드하고, 얻은 URL을 전달하세요.
- 먼저 제출하고, 그다음 폴링하세요.
GET /v1/tasks/<taskId>로data.status가success또는fail이 될 때까지 폴링하세요. 실패 시data.error.message를 읽으세요——"could not be downloaded"가 나오면 URL 문제이지 prompt 문제가 아닙니다.
최소 검증 예제
먼저 비용 없는 연결성 점검을 하세요: 모델 목록은 태스크를 생성하지 않고 비용도 들지 않습니다.
curl -s https://api.hiapi.ai/v1/models \
-H "Authorization: Bearer $HIAPI_API_KEY"
200과 함께 data 배열이 반환되면 key가 정상이라는 뜻입니다. 잘못된 key는 401 + {"error":{"code":"permission_denied", ... ,"type":"hiapi_error"}}를 반환합니다——이는 인증 문제이지 입력 문제가 아닙니다. 이어서 올바른 이미지-투-이미지 요청을 보내세요: 모델 필드에 공개 접근 가능한 URL을 넣습니다.
curl -s -X POST https://api.hiapi.ai/v1/tasks \
-H "Authorization: Bearer $HIAPI_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "gpt-image-2/image-to-image",
"input": {
"prompt": "배경을 깔끔한 스튜디오 화이트로 바꿔줘",
"input_urls": ["https://your-public-host.example.com/source.png"]
}
}'
input_urls를 당신이 접근 가능한 이미지 URL로 교체하세요. 제출에 성공하면 data.taskId가 반환되고, 이후 GET https://api.hiapi.ai/v1/tasks/<taskId>를 data.status가 success가 될 때까지 폴링한 다음, data.output[0].url에서 결과를 받으세요(해당 URL은 유효 기간이 있으므로 받은 후 가능한 한 빨리 다운로드하거나 다른 곳에 저장하고, 핫링크로 두지 마세요).
관련 링크
- HiAPI 400 Bad Request: 파라미터 오류를 고치는 방법——필드명이나 model id를 잘못 써서 태스크가 시작되기 전에 제출 단계 400으로 막히는 경우의 상세 설명.
- HiAPI 실패한 요청에도 과금되나요?——태스크가 수락된 후에 실패할 때의 과금 규칙.
- 필드 확인: gpt-image-2 모델 페이지 및 Nano Banana Pro 모델 페이지.
- API 가격, 그리고 콘솔에서 API Key 받기.
- API 문서: 태스크 생성, 태스크 상세 조회, 인증.
자주 묻는 질문
HiAPI 이미지-투-이미지 모델에 base64를 전달할 수 있나요?
아니요. 이미지 필드는 서버가 다운로드할 수 있는 공개 HTTP(S) URL을 요구합니다. data:image/...;base64,... 문자열은 일부 모델의 제출 단계에서는 수락되지만, 이후 태스크 종료 상태가 status: fail, 오류 코드 TASK_FAILED / task failed가 됩니다. 바이트를 공개 위치에 업로드하고, URL을 전달하세요.
제 POST /v1/tasks가 200을 반환했는데 태스크가 실패했습니다. 왜죠?
제출 단계의 200은 요청이 수락되었다는 것만 뜻합니다. 이미지 다운로드와 생성은 그 이후에 일어납니다. GET /v1/tasks/<taskId>를 폴링하세요. 잘못된 이미지 입력은 거기서 data.status: fail로 드러나며, error.code는 INVALID_REQUEST("The image URL could not be downloaded…") 또는 TASK_FAILED입니다.
이미지 URL은 도대체 어느 필드에 넣어야 하나요?
모델에 따라 다릅니다. gpt-image-2/image-to-image는 input_urls, seedream-5.0-pro/image-to-image는 image_urls, nano-banana-pro는 image_input을 사용합니다(모두 배열). 요청을 보내기 전에 모델 페이지에서 현재 schema를 확인하세요.
localhost나 사설 URL은 안 되나요?
안 됩니다. HiAPI는 자체 서버에서 이미지를 가져오므로 localhost, 127.0.0.1, 내부 주소, 로그인 후에만 보이는 링크, 만료된 presigned URL은 모두 "The image URL could not be downloaded."로 실패합니다. 공개적으로 해석 가능하고 인증이 필요 없는 URL을 사용하세요.
additional properties 'input_urls' not allowed는 무슨 뜻인가요?
이미지 필드가 정의되지 않은 모델에 이미지 필드를 전달한 것입니다——보통 베어 텍스트-투-이미지 id(gpt-image-2)를 이미지-투-이미지 라우트(gpt-image-2/image-to-image) 대신 사용했거나, 다른 모델의 필드명을 사용한 경우입니다. 이는 제출 단계의 400이며, 위의 400 Bad Request 가이드를 참조하세요.
실패한 이미지 태스크에도 과금되나요?
제출 단계에서 400으로 거부된 요청은 과금되지 않습니다. 그러나 일단 수락되고(200 + taskId) 이후에 실패한 태스크는 과금될 수 있습니다——자세한 내용은 위의 「실패한 요청에도 과금되나요?」를 참조하세요. 따라서 재실행 전에 먼저 URL을 올바르게 고치세요.
관련 글
모든 아티클 보기 →-
튜토리얼
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 튜토리얼
요청 우선 실전 데모: 프롬프트에서 비디오 클립까지의 호출 구성, 요청 제출, 완료 상태 폴링 및 결과 다운로드