공지: GPT Image 2.6 Flare 및 Sunburst 출시 기념 한정 20% 할인, 지금 체험하기
HiAPI
블로그

튜토리얼

HiAPI API로 flux-1.1-pro 사용하기: curl, Python 및 실행 가능한 요청

실제로 실행되는 요청, 비동기 처리, 실제 출력과 함께 쓰는 프롬프트 레시피를 담은 실전 통합 가이드

Nov 10, 2026
Abstract tutorial cover art: terracotta stepped bands descending across a warm sand background, flat print style, no text.
이 페이지에서

코드를 작성하기 전에 알아야 할 flux-1.1-pro의 제공 기능

flux-1.1-pro는 HiAPI.ai를 통해 호스팅 엔드포인트 방식으로 호출하는 텍스트-이미지 모델입니다. 프롬프트와 생성 파라미터를 JSON으로 전송하면 생성된 이미지가 반환됩니다. 아무것도 설치할 필요가 없고, 가중치를 직접 호스팅하거나 GPU 리소스를 관리할 필요도 없습니다. 통합 지점은 HTTP 엔드포인트 하나와 인증용 자격 증명뿐입니다.

개발자 관점에서 이는 첫 줄의 코드를 작성하기 전에 설계를 형성하는 세 가지 사실을 의미합니다.

첫째, 요청은 JSON 입력, 이미지 출력입니다. 프롬프트, 종횡비, 소수의 제어 파라미터가 요청 본문에 담깁니다. 응답은 작업 전달 방식에 따라 이미지 데이터 또는 이미지 데이터에 대한 참조를 담습니다. 요청 본문을 계약으로 간주하고 한곳에 모아 두면 curl과 Python 두 경로가 절대 서로 어긋나지 않습니다.

둘째, 일반 API 호출에 비해 이미지 생성은 느린 작업입니다. 몇 초는 정상이며, 고해상도에서 복잡한 프롬프트는 더 오래 걸릴 수 있습니다. 모든 프로덕션 호출자는 지연을 전제로 계획해야 하며, 호출을 데이터베이스 읽기처럼 취급해서는 안 됩니다.

셋째, 출력 품질은 연결 방식이 아니라 프롬프트가 결정합니다. 통합은 쉬운 부분입니다. 실제 노력은 원하는 것을 정확히 서술하고, 출시 전에 실제 출력으로 레시피를 검증하는 데 들어갑니다.

이 세 가지를 기억하면 나머지 가이드는 기계적인 절차입니다. 요청을 구성하고, 작동을 확인하고, 이식한 다음, 견고하게 다듬고 튜닝합니다. 처음부터 끝까지 모든 것은 HiAPI API를 통해 라우팅됩니다. 자격 증명 하나, 기본 URL 하나, 배워야 할 JSON 구조 하나뿐입니다.

첫 curl 요청

curl부터 시작하세요. 사용자와 엔드포인트 사이의 모든 추상화 계층을 제거하므로, 실패가 발생하면 문제가 프레임워크가 아니라 요청 본문에 있다는 것을 분명히 알 수 있습니다.

최소 호출은 세 부분으로 구성됩니다. 엔드포인트, 인증 헤더, 그리고 JSON 요청 본문입니다.

curl -X POST "https://api.hiapi.ai/v1/images/generations" \
  -H "Authorization: Bearer $HIAPI_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "flux-1.1-pro",
    "prompt": "a ceramic coffee mug on a weathered wooden table, soft morning window light, shallow depth of field, product photography",
    "aspect_ratio": "1:1"
  }'

요청 본문을 필드별로 읽어 보세요:

  • model은 사용할 모델을 지정합니다. 명시적으로 작성하면 향후 기본값이 변경되어도 출력이 조용히 바뀌는 일이 없습니다.
  • prompt는 자연어 설명입니다. 품질 예산의 거의 전부가 여기에 있습니다.
  • aspect_ratio는 구도를 제어합니다. 검증하지 않은 기본값에 의존하지 말고 의도적으로 선택하세요.

키는 명령에 직접 붙여넣지 말고 환경 변수(HIAPI_API_KEY)에 두세요. 이 습관은 Python과 이후 추가할 모든 CI 단계로 그대로 이어집니다.

호출이 성공하면 완료된 이미지를 설명하는 JSON 응답을 받습니다. 터미널을 닫기 전에 이를 확인하고 이미지 참조나 데이터를 찾으세요. 호출이 실패하면 상태 코드와 메시지가 담긴 오류 본문을 받습니다. 메시지를 문자 그대로 읽으세요. 필드 형식 오류가 가장 흔한 첫 실패 원인이기 때문입니다.

한 시간을 아껴 줄 경고: 이스케이프되지 않은 따옴표가 포함된 여러 줄 프롬프트를 셸에 붙여넣지 마세요. 짧은 문장보다 긴 내용에는 heredoc이나 파일을 사용하세요.

curl -X POST "https://api.hiapi.ai/v1/images/generations" \
  -H "Authorization: Bearer $HIAPI_API_KEY" \
  -H "Content-Type: application/json" \
  --data @request.json

그 request.json이 바로 버전 관리에 커밋해야 하는 산출물입니다. 요청 본문의 단일 진실 공급원이며, 다음 섹션에서 그대로 재사용합니다.

같은 호출을 Python으로 이식하기

이식의 목표는 새 로직을 작성하는 것이 아니라 완전히 동일한 JSON 요청 본문을 보내는 것입니다. 같은 request.json을 로드하면 두 경로가 어긋날 수 없습니다.

import json
import os

import requests

API_URL = "https://api.hiapi.ai/v1/images/generations"

with open("request.json") as f:
    payload = json.load(f)

response = requests.post(
    API_URL,
    headers={
        "Authorization": f"Bearer {os.environ['HIAPI_API_KEY']}",
        "Content-Type": "application/json",
    },
    json=payload,
    timeout=120,
)

if response.status_code != 200:
    print(response.status_code)
    print(response.text)
    response.raise_for_status()

print(response.json())

여기서 세 가지 세부 사항이 중요합니다.

인증 헤더와 요청 헤더는 같은 헤더 집합입니다. json=payload를 사용하면 requests가 요청 본문을 직렬화하고 콘텐츠 유형을 설정합니다. 헤더를 명시적으로 작성해도 무해하며 의도를 기록할 수 있습니다.

타임아웃을 설정하세요. 생성 요청이 무한한 기본값에 매달리게 두지 마세요. 넉넉한 명시적 타임아웃은 괜찮습니다. 핵심은 그것이 명시적이라는 점입니다.

예외를 던지기 전에 오류 본문을 확인하세요. raise_for_status()를 먼저 실행하면 로그에서 응답 본문을 버리게 됩니다. 상태 코드와 텍스트를 먼저 출력한 후 예외를 던지세요. 필드가 거부될 때 그 텍스트가 필요합니다.

비동기 HTTP 클라이언트로 통일하고 있다면 구조는 동일합니다. 같은 URL, 같은 헤더, 같은 요청 본문에 await client.post(...)와 동일한 타임아웃을 사용할 뿐입니다. 요청 본문 계약은 상수이고, 클라이언트는 구현 세부 사항입니다.

요청 본문을 Python 소스 코드 외부에 두세요. 프롬프트 레시피가 유효해지면 함수 안에 묻힌 문자열 리터럴이 아니라 파일이나 데이터베이스 행에 속해야 합니다. 그래야 diff를 만들고 다시 실행할 수 있습니다.

애플리케이션을 차단하지 않고 비동기 작업 처리하기

생성을 함수 호출이 아니라 작업으로 취급하세요. 전달 경로가 동기적으로 보이든, 폴링해야 할 작업을 반환하든 실제 결과는 같습니다. 애플리케이션은 이미지 하나를 기다리느라 요청 스레드를 무한정 점유해서는 안 됩니다.

실행 가능한 패턴은 네 단계로 구성됩니다.

1. 사용자 요청이 아니라 워커에서 제출하기

웹 계층에서 사용자의 생성 작업을 수락하고, 작업 레코드를 영속화하고, 큐에 넣은 다음 즉시 반환하세요. 백그라운드 워커가 실제 API 호출을 수행합니다. 사용자는 모델이 아니라 당신의 엔드포인트를 폴링합니다.

2. 대기에 한계를 두기

각 시도에 의도적으로 선택한 타임아웃을 설정하세요. 플랫폼이 폴링해야 하는 작업을 반환한다면 고정 간격으로 폴링하되, 최대 시도 횟수와 시도 횟수가 아니라 작업 시작 시점부터 계산한 마감 시간을 두세요. 타이트한 루프보다 적당한 백오프를 선호하세요.

3. 재시도할 가치가 있는 실패만 재시도하기

전송 오류, 타임아웃, 서버 오류에는 지수 백오프와 지터를 사용해 재시도하되 시도 횟수를 소수로 제한하세요. 유효성 검사 오류는 재시도하지 마세요. 거부된 필드나 빈 프롬프트는 매번 같은 방식으로 실패하며, 재시도는 사용자가 실제 메시지를 보기 전에 더 오래 기다리게 만들 뿐입니다.

4. 자신의 쪽에서 작업을 멱등하게 만들기

데이터베이스에 정확한 요청 본문과 작업 ID를 기록하세요. 워커가 제출 후 성공 기록 전에 충돌한다면, 맹목적으로 다시 제출하는 대신 해당 작업을 다시 확인할 수 있습니다. 재제출이 불가피할 때는 짧은 클라이언트 중복 제거 키를 추가해 일시적 장애가 동일한 생성을 세 번 큐에 넣지 않게 하세요.

import time

def poll_until_done(fetch_status, job_id, deadline_seconds=180):
    start = time.monotonic()
    delay = 2.0
    while True:
        status = fetch_status(job_id)
        if status["state"] in ("succeeded", "failed"):
            return status
        if time.monotonic() - start > deadline_seconds:
            raise TimeoutError(f"generation {job_id} exceeded deadline")
        time.sleep(delay)
        delay = min(delay * 1.5, 10.0)

이 헬퍼는 의도적으로 범용으로 유지됩니다. 상태 가져오기 함수를 받으므로 이후 통합하는 모든 작업형 엔드포인트에 같은 루프가 적용됩니다. 중요한 속성은 마감 시간, 상한이 있는 백오프, 종료 상태 확인이며, 특정 전송 방식이 아닙니다.

안정적으로 렌더링되는 프롬프트 구성하기

긴 프롬프트가 더 나은 프롬프트는 아닙니다. 구조가 중요합니다. 반복 가능한 골격은 일관된 결과를 주고, 문제가 생겼을 때 한 번에 하나의 변수만 바꿀 수 있는 지점을 제공합니다.

다음 순서로 네 개의 슬롯을 사용하세요:

  1. 주제 — 화면에 무엇이 있는지, 구체적으로. "카페에서 쓰는 무언가"보다 "세라믹 커피 머그"가 낫습니다.
  2. 스타일 — 시각적 톤: 사진, 일러스트레이션, 수채화, 3D 렌더링, 제품 촬영. 매체를 명시하고 필요하면 조명도 명시하세요.
  3. 구도 — 프레이밍과 카메라: 종횡비, 촬영 거리, 각도, 심도, 화면 내 주제 위치.
  4. 제약 — 명확히 원하는 것과 원하지 않는 구체적 내용을 짧게 유지하세요.
[subject] a single ceramic coffee mug, matte glaze, small handle
[style] product photography, soft diffused window light, muted palette
[composition] 1:1, eye-level, subject centered, shallow depth of field, plain background
[constraints] no text, no logos, no hands

전송할 때는 이를 하나의 프롬프트로 평탄화하세요. 대괄호는 모델이 아니라 당신 자신을 위한 것입니다. 슬롯으로 작성하는 가치는 출력이 잘못되었을 때 어느 슬롯을 편집해야 하는지 알 수 있다는 데 있습니다.

몇 가지 실용적인 규칙:

  • 주제를 맨 앞에 두세요. 첫 번째 절이 가장 높은 가중치를 가집니다.
  • 추상적인 감정어보다 구체적인 명사와 형용사를 선호하세요. "매트 광택"은 픽셀을 바꾸지만 "고급스러움"은 거의 바꾸지 않습니다.
  • 카메라 언어는 주제 슬롯이 아니라 구도 슬롯에 두세요. 섞으면 조급하고 상충하는 지시가 생깁니다.
  • 반복할 때는 슬롯 하나만 바꾸고, 채택된 출력을 만든 정확한 프롬프트 텍스트를 보관하세요.

종횡비는 사후 패치가 아니라 구도 결정입니다. 이미지가 들어갈 위치에 맞춰 선택하세요. 그리드에는 정사각형, 히어로 배너에는 더 긴 비율을 선택하고, 프롬프트의 나머지 부분이 그 프레임에 맞게 하세요.

네거티브 프롬프트 목록 효과적으로 사용하기

네거티브 프롬프트 목록은 모델이 피해야 할 것을 알려줍니다. 날카로운 도구지만 유용한 범위는 좁습니다. 반복되는 결함을 억제하는 데는 아주 좋지만, 떠올릴 수 있는 모든 불완전함을 나열하는 쓰레기통으로는 형편없습니다.

네거티브 프롬프트는 짧고 구체적으로 유지하세요. 대부분의 프롬프트에는 짧은 항목 다섯에서 여덟 개면 충분합니다. 구체적인 것을 명시하세요:

no text, no watermark, no logos, no extra fingers, no harsh shadows

이 목록이 효과적인 이유는 각 항목이 눈에 보이고 확인 가능한 것을 명명하기 때문입니다. "not ugly"나 "bad quality" 같은 모호한 부정과 비교해 보세요. 실행 가능한 신호를 거의 담지 못하고 정말 중요한 항목을 희석시킵니다.

네거티브 프롬프트가 실제로 도움이 되는 경우:

  • 반복해서 보이는 결함 억제. 손이나 텍스트가 반복적으로 나타난다면, 이를 직접 명시하는 것이 가장 직접적인 해결책입니다.
  • 브랜드 및 법적 위생. 이미지가 사용자 대면 인터페이스에 도달하기 전에 로고와 워터마크를 배제합니다.
  • 제품 이미지나 UI에 가까운 이미지에 깨끗한 배경 강제.

네거티브 프롬프트가 방해가 되는 경우:

  • 포지티브 프롬프트와 모순. 네거티브의 "그림자 없음"과 주제의 "극적인 측광"이 충돌하면 모델은 예측 불가능한 방식으로 해결합니다. 포지티브 프롬프트를 고치세요.
  • 거의 나타날 가능성이 없는 것의 부정. 가능성이 낮은 실패 항목의 긴 목록은 노이즈만 늘리고 렌더링 결과를 바꾸지 않습니다.
  • 모호한 주제를 네거티브 프롬프트로 보완하려는 시도. 주제가 불명확하다면 어떤 네거티브 목록도 구할 수 없습니다.

실용적인 세부 사항 하나: 일부 클라이언트는 네거티브 프롬프트를 추가 텍스트가 아닌 별도 필드로 받습니다. 요청이 어느 방식을 지원하는지 확인하고, 저장된 요청 본문에 그 필드를 유지해 curl과 Python이 완전히 동일하게 동작하도록 하세요.

실제 출력과 함께 쓰는 프롬프트 레시피

아래 레시피는 출발점이지 보장이 아닙니다. 정직한 워크플로는 자신의 통합을 통해 레시피를 실행하고, 출력을 확인한 다음, 슬롯 하나를 조정하는 것입니다. 직접 생성해 보지 않은 출력은 모두 미검증으로 간주하세요.

레시피 1 — 깔끔한 제품 사진

A single matte-black wireless earbud case on a light concrete surface,
studio product photography, soft key light from the left, 1:1, centered,
shallow depth of field, plain background. No text, no logos, no hands.

예상 특징: 선명하고 중앙에 위치한 주제, 부드러운 감쇠, 어수선하지 않은 배경. 표면이 너무 복잡해 보이면 "plain background"를 강화하고 질감 단어를 제거하세요. 조명이 너무 평평하면 방향성 키워드를 하나 추가하세요. 그게 전부입니다.

레시피 2 — 편집 인물 사진

Portrait of a person in a wool coat, natural window light, calm expression,
3:4, chest-up framing, subject slightly off-center, muted film palette.
No text, no watermark.

예상 특징: 부드러운 방향성 조명, 절제된 색상. 프레이밍이 예상보다 넓다면 "chest-up framing"을 앞으로 옮기고 경쟁하는 구도 단어를 제거하세요.

레시피 3 — 아이소메트릭 일러스트레이션

Isometric illustration of a small reading nook: armchair, floor lamp, bookshelf,
flat vector style, limited palette of warm neutrals and one accent color,
1:1, centered composition, clean white background. No text, no gradients.

예상 특징: 선명한 기하학적 구조와 평면 채우기. 색상이 벗어나면 강조 색을 명시하고, "clean white background"를 마지막 절로 유지해 그것이 우선하도록 하세요.

레시피 4 — 히어로 배너

A wide misty mountain ridge at sunrise, layered depth, minimal detail,
16:9, subject occupying the lower third, generous empty sky for overlaid text.
No text, no watermark.

예상 특징: 조용하고 세부 묘사가 적은 이미지와 활용 가능한 여백. "overlaid text"라는 표현은 공간을 확보하라는 의미이며, 글자를 렌더링하지 않습니다. 네거티브 목록이 이미지 자체에서 텍스트를 배제합니다.

각 레시피마다 정확한 요청 본문, 종횡비, 날짜를 기록하세요. 한 달 뒤에 돌아보면 결과가 왜 바뀌었는지 추측하는 대신 기록된 요청 본문을 다시 실행해 기록된 출력과 비교할 수 있습니다.

오류, 제한, 그리고 먼저 확인할 것

생성이 실패하거나 출력이 잘못되었을 때 코드를 수정하기 전에 이 체크리스트를 순서대로 검토하세요.

먼저 요청 본문 확인

  • 요청 본문이 유효한 JSON인가요? 후행 쉼표나 이스케이프되지 않은 따옴표가 가장 흔한 첫 실패 원인입니다. 전송 전에 저장된 request.json을 검증하세요.
  • 필드 이름이 정확한가요? 오타가 있는 파라미터는 거부되거나 조용히 무시되는 경우가 많습니다. 기억이 아니라 문서의 요청 구조와 대조하세요.
  • 모델 이름이 정확하고 존재하나요? 기본값에 의존하지 마세요.
  • 프롬프트가 비어 있지 않고 문서가 정한 길이 이내인가요? 플랫폼 문서에 제한이 명시되어 있습니다. 숫자를 가정하지 말고 그곳에서 읽으세요.

그다음 인증과 전송 확인

  • API 키가 존재하고 현재 유효한가요? 401은 보통 헤더 누락, 형식 오류 또는 키 교체를 의미합니다.
  • 엔드포인트 URL과 메서드가 정확한가요? GET 경로에 POST를 보내면 키 문제처럼 실패합니다.
  • 타임아웃이 너무 타이트한가요? 클라이언트가 작업 완료 전에 포기하면 보이는 타임아웃은 모델과 무관합니다.

그다음 요청 구조 확인

  • 상태 코드 분류가 어디를 봐야 하는지 알려줍니다. 4xx는 거의 항상 당신의 요청 문제이고, 5xx는 보통 일시적이며 제한된 재시도가 가치 있습니다.
  • 오류 메시지를 문자 그대로 읽으세요. 예외를 던지기 전에 응답 본문을 출력하세요. 메시지에 언급된 필드가 고쳐야 할 필드입니다.
  • 속도 제한 또는 할당량 응답은 프롬프트를 다시 쓰는 것이 아니라 속도를 늦추고 백오프로 재시도하라는 의미입니다.

마지막으로 프롬프트 확인

호출은 성공했는데 이미지가 잘못되었다면 오류 범주가 아니라 프롬프트 범주에 있습니다:

  • 주제가 없거나 너무 일반적인가요? 첫 번째 절로 옮기고 구체적으로 만드세요.
  • 구도가 잘못되었나요? 종횡비와 프레이밍 단어를 함께 수정하세요. 하나로 다른 하나를 보완하지 마세요.
  • 결함이 반복되나요? 짧고 구체적인 네거티브 프롬프트를 추가하세요.
  • 모순이 있나요? 포지티브 프롬프트와 대립하는 네거티브 프롬프트를 찾아 삭제하세요.

가장 중요한 것은 하나의 습관을 유지하는 것입니다. 신경 쓰는 모든 생성에 대해 정확한 요청 본문, 응답 상태, 생성된 이미지 참조를 기록하세요. 재현 가능성은 디버깅을 추측에서 diff로 바꿔 줍니다. 첫 요청을 구성하고, 출력을 확인한 다음, 출시 전에 프롬프트를 다듬으세요. 그리고 출시할 때 사용한 요청 본문을 보관해 다음 변경이 실제 기준과 비교될 수 있게 하세요.

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

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

API 문서 보기