HiAPI
블로그

튜토리얼

FLUX.1 Fill Pro API 사용 방법: curl과 Python으로 마스크 인페인팅하기

Oct 24, 2026
FLUX.1 Fill Pro API 사용 방법: curl과 Python으로 마스크 인페인팅하기

flux-1-fill-pro는 hiapi의 마스크 기반 인페인팅 모델입니다. 소스 이미지, 흑백 마스크, 프롬프트를 보내면 흰색 영역만 다시 그려집니다. 본 가이드에서는 실행 가능한 curl 및 Python 요청, 비동기 흐름, 그리고 실제 실행에서 마스크 경계와 출력 크기와 관련해 확인된 결과를 제시합니다. API key는 dashboard에서 발급받아야 합니다.

요청 구조

이 모델은 통합 태스크 API에서 동작합니다. POST https://api.hiapi.ai/v1/tasks로 태스크를 생성하고, GET /v1/tasks/<taskId>를 폴링한 다음 data.output[0].url을 읽습니다. 아래 입력은 모델 페이지와 API 문서에서 가져왔습니다:

필드 타입 설명
input.image URL, 필수 소스 이미지. JPEG, PNG, GIF 또는 WebP.
input.mask URL, 필수 검은색은 소스 이미지를 유지하고, 흰색은 다시 그려집니다. 소스 이미지와 크기가 같아야 합니다.
input.prompt string, 필수 흰색 영역 안의 새 콘텐츠를 설명합니다. 최대 4,000자.
input.steps int, 15–50 기본값 50.
input.guidance number, 1.5–100 기본값 60.
input.seed int 동일한 입력에서 seed를 고정하면 일관된 결과를 얻습니다.
input.output_format jpg | png 기본값 jpg.
input.prompt_upsampling bool 기본값 false. 꺼 두면 정확한 문구가 유지됩니다.

image와 mask는 모두 URL이며, base64나 파일 업로드가 아닙니다. API가 http(s)로 가져올 수 있는 위치에 호스팅하세요.

최소 curl 요청

curl -s https://api.hiapi.ai/v1/tasks \
  -H "Authorization: Bearer $HIAPI_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "flux-1-fill-pro",
    "input": {
      "image": "https://dev-static.hiapi.ai/model-onboarding/flux-1-fill-pro/2026/10/19/2026/10/19/1792418738578-4e5072a121d7018f-source.jpg",
      "mask": "https://dev-static.hiapi.ai/model-onboarding/flux-1-fill-pro/2026/10/19/2026/10/19/1792418739459-82bb18075f29c864-mask.png",
      "prompt": "아침 안개에 잠긴 산과 호수의 흐릿한 풍경을 담은 대형 유화 작품, 얇은 검은 액자에 담아 벽에 평평하게 걸려 있음; 소파, 바닥, 조명은 그대로 유지.",
      "steps": 30,
      "guidance": 60,
      "seed": 42,
      "output_format": "png"
    }
  }'

응답은 {"code":200,"data":{"taskId":"tk-hiapi-..."},"message":"success"}입니다. 해당 ID를 폴링하여 data.status가 success 또는 fail이 될 때까지 확인합니다.

Python: 생성, 폴링, 다운로드

import os, time, requests

API = "https://api.hiapi.ai"
HEADERS = {"Authorization": f"Bearer {os.environ['HIAPI_KEY']}"}

def inpaint(image_url, mask_url, prompt, **opts):
    body = {"model": "flux-1-fill-pro",
            "input": {"image": image_url, "mask": mask_url, "prompt": prompt, **opts}}
    r = requests.post(f"{API}/v1/tasks", headers=HEADERS, json=body, timeout=30)
    r.raise_for_status()
    task_id = r.json()["data"]["taskId"]

    while True:
        try:
            d = requests.get(f"{API}/v1/tasks/{task_id}", headers=HEADERS, timeout=20).json()["data"]
        except requests.RequestException:
            time.sleep(5)          # transient network error: poll the same taskId again
            continue
        if d["status"] == "success":
            return d["output"][0]["url"]
        if d["status"] == "fail":
            raise RuntimeError(d.get("error", d))
        time.sleep(5)

url = inpaint(
    "https://example.com/room.jpg",
    "https://example.com/room-mask.png",
    "얇은 검은 액자에 담긴 풍경화; 방은 그대로 유지.",
    steps=30, seed=42, output_format="png",
)
open("out.png", "wb").write(requests.get(url, timeout=60).content)

결과는 즉시 다운로드하세요. 출력 URL에는 expireAt이 있으며 파일은 임시 저장되므로, 해당 링크를 영구 주소로 저장하지 마세요.

프로덕션 환경 유의 사항

  • 폴링 또는 콜백.대량 작업의 경우 태스크 body에 "callback": {"url": "https://your-domain.com/hiapi/callback", "when": "final"}을 추가하고, 태스크 ID로 알림을 중복 제거하세요. 폴링은 대체 수단으로 유지하세요.
  • 재시도는 생성이 아니라 폴링에서.새 POST는 새 태스크를 생성하고 과금합니다. 폴링 요청이 실패하면 같은 taskId를 다시 폴링하세요.
  • 마스크는 소스 이미지와 일치시키세요.마스크는 소스 이미지와 크기가 정확히 같아야 하므로, 스크린샷을 확대/축소하지 말고 동일한 파일에서 생성하세요(다각형 도구, 세그멘테이션 출력).
  • 파라미터 조정 시 seed를 고정하세요.같은 seed를 사용하고 steps 또는 guidance만 변경하면, 각 차이는 해당 파라미터에서 비롯됩니다.

이미지당 비용은 가격 페이지에서 확인할 수 있으며, 대량 소재를 처리하기 전에 먼저 확인하세요.

실제 실행에서 확인된 결과

이 페이지에 포함된 예제 방 사진(1600×900)과 그 사각형 마스크(흰색 상자가 x 840–1240, y 160–580에 위치)에 대해 위 curl 요청을 한 번 실행했습니다. 설정은 steps: 30, guidance: 60, seed: 42, output_format: png입니다.

  • 소요 시간.태스크가 약 25초 동안 handling 상태였다가 archiving으로 넘어갔고, 종단 간 약 38초 만에 success에 도달했습니다.
  • 출력 크기가 소스 이미지와 다름.반환된 PNG는 1600×900이 아니라 1440×810입니다. 종횡비는 같지만 픽셀 크기는 다릅니다. 결과를 원본 이미지에 합성하려면 1:1이라고 가정하지 말고 먼저 둘 중 하나의 크기를 조정하세요.
  • 마스크 밖은 그대로 유지.소스 이미지를 1440×810으로 축소한 뒤 출력과 차분했을 때, 흰색 상자 안 픽셀의 81%가 8단계(0–255)를 초과해 변했지만, 상자 밖에서는 0.03%의 픽셀만 그랬습니다. 마스크 가장자리에서 12 px 이상 떨어진 곳의 최대 차이는 11단계였습니다. 소파, 쿠션, 화분, 바닥, 창문 빛은 모두 다시 그려지지 않았습니다.
  • 프롬프트 범위.프롬프트는 그림과 유지해야 할 내용만 설명했으며, 결과는 흰색 상자를 가득 채운 액자에 담긴 산과 호수 장면이었습니다.
  • 잘못된 URL은 생성 시가 아니라 폴링 시 실패함.image와 mask를 URL이 아닌 문자열로 설정한 다른 요청은 200과 taskId를 반환했지만, 태스크는 약 3초 후 status: fail 및 error.code: TASK_FAILED로 종료되었습니다. POST가 성공했다고 입력이 유효한 것은 아니므로 반드시 최종 상태를 확인하세요.

미검증:마스크와 소스 이미지 크기 불일치, 회색(부드러운 가장자리) 값을 가진 마스크, 알파 채널 마스크, 그리고 guidance 또는 steps의 극단값은 테스트하지 않았습니다. 문서에는 마스크가 소스 이미지와 크기가 일치해야 한다고 되어 있지만, 저는 하드 이진 사각형만 테스트했습니다. 여러 seed를 실행하지 않았으므로 채우기 결과가 실행 간에 얼마나 달라지는지는 말할 수 없습니다.

Fill Pro를 선택할 때

편집이 사용자가 제어하는 경계에서 정확히 멈춰야 할 때 사용하세요. 예를 들어 제품 라벨, 벽선, 의류 솔기 등입니다. 마스크 없이 텍스트로 설명하는 편집에는 순수 프롬프트 모델을 사용하세요. 이미지 인페인팅과 객체 제거 가이드에서 이들을 비교합니다. 프롬프트 없이 마스크에서 무언가를 지우려면 Bria Eraser 가이드를 참고하세요.

관련 문서

자주 묻는 질문

image와 mask는 모두 필수인가요?

네. 현재 문서에서는 image, mask, prompt를 필수로 명시하고 있습니다.

모델은 어떤 색상을 다시 그리나요?

흰색입니다. 검은색 픽셀은 소스 이미지를 유지합니다.

마스크는 소스 이미지와 크기가 같아야 하나요?

문서에서는 그렇게 설명합니다. 제 실행에서는 크기가 일치하는 한 쌍을 사용했고, 불일치 상황은 테스트하지 않았습니다.

출력 크기는 어떻게 되나요?

제 실행에서는 1600×900 소스 이미지에 대해 1440×810 PNG가 반환되었으며, 종횡비는 같았습니다.

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

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

API 문서 보기