가입하면 프리미엄 플랜 할인할인 받기
eroq

블로그/developers·2026년 10월 8일·6분·eroq 팀 작성

GPT Image, Nano Banana, Seedream API: 엔드포인트 하나

GPT Image 2.5, Nano Banana Pro, Seedream 5.0 Pro, Flux 3를 eroq 엔드포인트 하나로 호출하는 방법을 curl과 JS로 설명해요.


이미지 생성 업체가 다섯 곳이면 보통 SDK도 다섯 개, 키도 다섯 개, 결제 대시보드도 다섯 개, 그리고 "비동기"에 대한 생각도 다섯 가지가 돼요. eroq에서는 엔드포인트가 하나이고 바뀌는 건 model뿐이에요. OpenAI의 GPT Image 2.5, Google의 Nano Banana, ByteDance의 Seedream, Black Forest Labs의 Flux 3, xAI의 Grok Imagine 2.0이 모두 POST /v1/images/generations를 거치고, 같은 본문, 같은 비동기 방식, 테이크당 정액 크레딧 가격으로 동작해요. 스튜디오와 같은 엔진, 가격, 정책이에요. 레퍼런스는 /docs/images에 있고, 이 글은 그 실전 버전이에요.

모델 ID

모델 model ID 제작사 테이크당 크레딧 일반적인 렌더 시간
GPT Image 2.5 Sunburst gpt-image-2-5-sunburst OpenAI 31 약 15초
GPT Image 2.5 Flare gpt-image-2-5-flare OpenAI 31 약 15초
Nano Banana Pro nano-banana-pro Google 124 약 25초
Nano Banana 2.1 nano-banana-2-1 Google 31 약 8초
Seedream 5.0 Pro seedream-5-0-pro ByteDance 36 약 20초
Flux 3 Image flux-3-image Black Forest Labs 32 약 20초
Grok Imagine 2.0 grok-imagine-2-0 xAI 32 약 15초

모든 모델이 다섯 가지 포맷에서 같은 가격이에요. Flux 3 Image와 Grok Imagine 2.0은 Hobby 플랜부터, 나머지 다섯 개는 Creator부터 열려요. 그 아래 플랜에서는 호출이 403 plan_required로 응답하고 아무것도 청구하지 않아요.

렌더 제출하기

curl https://eroq.ai/v1/images/generations \
  -H "Authorization: Bearer $EROQ_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "nano-banana-pro",
    "prompt": "An aerial view of a harbour city at blue hour, lit windows and light trails along the quays, layered haze between the towers, crisp architectural detail, cinematic wide shot",
    "aspect": "16:9",
    "batch": 2
  }'

호출은 배치 비용을 청구하고 곧바로 202로 응답해요. 잡은 테이크마다 하나씩이에요.

{
  "object": "image.generation",
  "jobs": [
    { "id": "b7e6c2d4-…", "poll": "/v1/images/generations/b7e6c2d4-…" },
    { "id": "4f19a0e3-…", "poll": "/v1/images/generations/4f19a0e3-…" }
  ],
  "created": 1791450000,
  "model": "nano-banana-pro",
  "failed": 0,
  "usage": { "credits_spent": 248, "credits_remaining": 752 }
}

이 엔진들에서 중요한 필드는 다음과 같아요.

  • model: 항상 보내세요. 생략하면 기본값은 eroq-uncensored이고, 모르는 ID는 유효한 ID 목록과 함께 400 invalid_body로 응답해요.
  • prompt: 요청 내용 전체예요. 글자는 큰따옴표로 묶어요.
  • aspect: 1:1(기본값), 3:4, 4:3, 9:16, 16:9이고, 네이티브로 렌더돼요.
  • batch: 1~4테이크이고, 선결제돼요. failed는 시작하지 못한 테이크 수이고, 이미 환불됐어요.
  • store: 영구 공개 URL이 필요하면 true예요. 시작한 10 MB마다 2 크레딧이 추가돼요.
  • folder_id: 렌더를 라이브러리 폴더 중 하나에 바로 넣어 줘요.

이 엔진들이 무시하는 것

위의 엔진들은 텍스트 투 이미지 전용이라서, 일부 필드는 아무 효과가 없어요.

  • references는 버려져요. 사진과 맞아야 하는 얼굴이나 제품이라면 eroq-one(최대 열 장)이나 eroq-krea2(최대 네 장)로 요청을 보내세요.
  • negative_prompt와 cfg_scale은 검증은 통과하지만 이 엔진들에서는 쓰이지 않아요. 원하는 결과를 프롬프트로 묘사하세요.
  • edit: true는 400 edit_unsupported로, aspect: "retain"은 400 retain_requires_reference로 응답해요. 둘 다 이미지 작업이니 Eroq One으로 보내세요.

잡이 끝날 때까지 폴링하기

const BASE = 'https://eroq.ai/v1'
const headers = {
  Authorization: `Bearer ${process.env.EROQ_API_KEY}`,
  'Content-Type': 'application/json',
}
const sleep = ms => new Promise(resolve => setTimeout(resolve, ms))

export async function generate(body) {
  const res = await fetch(`${BASE}/images/generations`, { method: 'POST', headers, body: JSON.stringify(body) })
  const json = await res.json()
  if (!res.ok) throw Object.assign(new Error(json.error.message), { status: res.status, code: json.error.code })
  // One job per take: each succeeds, or fails and refunds, on its own
  return Promise.all(json.jobs.map(job => waitFor(job.id)))
}

async function waitFor(id, { every = 2500, timeout = 11 * 60_000 } = {}) {
  const started = Date.now()
  while (Date.now() - started < timeout) {
    const res = await fetch(`${BASE}/images/generations/${id}`, { headers })
    const job = await res.json()
    if (!res.ok) return { id, error: job.error?.code ?? `http_${res.status}` }
    if (job.status === 'succeeded') {
      const [image] = job.data
      return { id, url: image.url, libraryId: image.library_id, ms: job.generation_ms }
    }
    if (job.status === 'failed') return { id, error: job.error.code } // credits already back
    await sleep(every) // processing: phase is "queued" or "generating"
  }
  return { id, error: 'client_timeout' }
}

폴링은 무료이고, 몇 초에 한 번이 의도된 주기예요. status가 succeeded나 failed가 될 때까지 계속하세요. image.generation.succeeded와 image.generation.failed 웹훅은 대체가 아니라 추가 알림이에요. 서명을 검증하는 방법은 비동기 API 가이드에서 볼 수 있어요.

성공하면 data[0].url은 30분간 유효한 서명된 URL이에요. 잡 ID는 24시간 유지되고, 잡(또는 library_id로 작품)을 다시 가져오면 새 URL이 발급돼요. 사용자에게 바뀌지 않는 주소가 필요하면 store: true를 보내세요. generation_ms는 렌더의 실제 소요 시간이고, 서버 기한인 10분을 넘겨도 처리 중인 잡은 generation_timeout으로 실패 처리되고 환불돼요. 위의 클라이언트 타임아웃이 그 바로 뒤에 있는 이유예요.

배치, 간단히

배치는 호출 한 번, 프롬프트 하나, 최대 네 테이크예요. 각 테이크는 독립된 잡이니 병렬로 폴링하고 가장 잘 나온 것을 남기세요. 실패한 테이크는 다른 테이크에 영향 없이 자동으로 환불돼요. 또한 배치는 분당 속도 제한에서 호출 한 번으로 계산돼요. 서로 다른 프롬프트 네 개라면 호출을 네 번 보내세요.

오류

상태 code 무슨 일이 있었나 해야 할 일
400 invalid_body 필드가 검증에 실패함 본문을 고치세요. 메시지에 필드 이름이 나와요
400 content_blocked 이용 정책에 따라 청구 전에 거부됨 프롬프트를 바꾸고, 그대로 재시도하지 마세요
400 edit_unsupported 텍스트 전용 엔진에 이미지 작업을 보냄 eroq-one을 쓰세요
402 insufficient_credits 잔액이 가격 × 배치보다 적음 충전하세요. 반복문으로 재시도하지 마세요
403 plan_required 모델에 더 높은 플랜이 필요함, 청구 전 업그레이드하거나 플랜에 포함된 모델을 고르세요
429 rate_limit_exceeded 이 키로 이번 분에 호출이 너무 많음 Retry-After만큼 기다리세요
502 generation_failed 렌더를 시작하지 못함 청구되지 않아요. 재시도하세요
503 model_unavailable 이 배포에서 엔진이 오프라인임 청구되지 않아요. 다른 ID를 고르세요
404 not_found 모르는 잡 ID이거나 24시간이 지남 ID와 이미지를 제때 저장하세요

failed로 끝난 잡에는 error.code로 content_blocked(제공사가 거부), generation_failed, generation_timeout 중 하나가 담기고, 크레딧은 이미 지갑에 돌아와 있어요. 플랜은 모든 키의 분당 한도를 높여 줘요. Creator는 2배, Studio는 4배예요.

작업별로 라우팅하기

const ENGINE = {
  text: 'gpt-image-2-5-sunburst', // posters, packaging, UI mockups
  keyArt: 'gpt-image-2-5-flare', // dramatic, cinematic frames
  detail: 'seedream-5-0-pro', // texture, architecture, landscapes
  hero: 'nano-banana-pro', // the final frame, top fidelity
  draft: 'nano-banana-2-1', // fast iteration
  explore: 'grok-imagine-2-0', // many directions, characterful
  daylight: 'flux-3-image', // natural light and typography
}

model: "auto"를 쓰면 eroq의 라우터가 플랜에서 열리는 엔진 중 하나를 고르고, 고른 모델의 비용을 청구해요. 고른 모델은 model로 돌려줘요. 124 크레딧 / 이미지인 Nano Banana Pro가 될 수도 있으니, 비용이 중요할 때는 모델을 직접 지정하세요. 테이크당 계산은 2026년 AI 이미지 비용에, 라우팅 선택의 이유는 2026년 최고의 AI 이미지 모델에 있어요.

MCP와 CLI

같은 모델이 MCP 서버의 generate_image 도구(렌더를 기다렸다가 이미지를 돌려주며, 오래 걸리는 것에는 get_image_status가 있어요) 뒤에도, CLI 뒤에도 있어요. CLI에서는 eroq image "a foggy harbour at dawn" -m seedream-5-0-pro --aspect 16:9 -o harbour.webp처럼 써요. 둘의 설정 방법은 /docs/mcp에 있어요.

자주 묻는 질문

OpenAI, Google, ByteDance의 API 키가 필요한가요?

아니요. eroq 키 하나로 모든 모델을 쓸 수 있고, 모든 비용은 하나의 지갑에서 eroq 크레딧으로 청구돼요.

eroq를 통해 Nano Banana Pro나 GPT Image 2.5에 참조 이미지를 보낼 수 있나요?

아니요. eroq에서 이 둘은 텍스트 투 이미지 엔진이라 참조는 버려져요. 이미지 기반 작업에는 참조를 최대 열 장까지 읽고 지시로 편집하는 eroq-one을 쓰세요.

이미지 URL은 얼마나 오래 유효한가요?

data의 서명된 URL은 30분, 잡은 24시간이에요. 다시 가져오면 새 URL을 받을 수 있고, 영구 공개 URL이 필요하면 store: true로 제출하세요.

실패하거나 차단된 렌더에도 크레딧이 드나요?

아니요. 정책으로 거부된 프롬프트는 청구 전에 응답하고, 실패했거나 제공사에서 거부된 잡은 자동으로 환불돼요.

키를 받고, 모델 ID를 고르고, /docs/images로 요청을 하나 보내 보세요.

태그image-apigpt-imagenano-bananaseedreamflux-3async

eroq에서 만들기

API로 만들어 보세요

API 키는 1분이면 발급됩니다. 같은 엔진, 같은 가격, 비동기 작업과 웹훅.

무료 크레딧 40개 · 카드 등록 불필요 · 모든 계정에 프라이빗 모드