Gemini OpenAI 형식 (이미지)
curl --request POST \
--url https://api.gravitex.ai/v1/images/generationsimport requests
url = "https://api.gravitex.ai/v1/images/generations"
response = requests.post(url)
print(response.text)const options = {method: 'POST'};
fetch('https://api.gravitex.ai/v1/images/generations', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.gravitex.ai/v1/images/generations",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://api.gravitex.ai/v1/images/generations"
req, _ := http.NewRequest("POST", url, nil)
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.gravitex.ai/v1/images/generations")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.gravitex.ai/v1/images/generations")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
response = http.request(request)
puts response.read_body이미지 시리즈
Gemini OpenAI 형식 (이미지)
Gemini imagine 시리즈: OpenAI 호환 /v1/images/generations 및 /v1/images/edits
POST
/
v1
/
images
/
generations
Gemini OpenAI 형식 (이미지)
curl --request POST \
--url https://api.gravitex.ai/v1/images/generationsimport requests
url = "https://api.gravitex.ai/v1/images/generations"
response = requests.post(url)
print(response.text)const options = {method: 'POST'};
fetch('https://api.gravitex.ai/v1/images/generations', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.gravitex.ai/v1/images/generations",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://api.gravitex.ai/v1/images/generations"
req, _ := http.NewRequest("POST", url, nil)
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.gravitex.ai/v1/images/generations")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.gravitex.ai/v1/images/generations")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
response = http.request(request)
puts response.read_bodyGemini 네이티브
generateContent 이미지 생성은 Gemini 네이티브 (이미지)를 참고하세요. extra_body.google 세밀 제어가 필요하면 Gemini OpenAI 형식 (채팅)의 /v1/chat/completions 엔드포인트를 사용할 수 있습니다(부록 참고)./v1/images/generations 및 /v1/images/edits 인터페이스로 직접 호출할 수 있습니다.
Base URL: https://api.gravitex.ai
목차
- 인증
- 모델 목록
- 인터페이스 개요
/v1/images/generations— 텍스트-이미지 / 이미지-이미지/v1/images/edits— 이미지 편집- 사용 시나리오 및 예제
- 오류 처리
- 과금 규칙
- 제한 사항
- 모범 사례
- 자주 묻는 질문
- 부록:
/v1/chat/completions엔드포인트와 비교
인증
모든 인터페이스는 Bearer Token 인증을 사용합니다. Gravitex AI 콘솔에서 토큰을 생성한 후 요청 헤더에 추가하세요:Authorization: Bearer sk-{your_token_key}
Content-Type: application/json
모델 목록
| 모델 ID | 설명 | 이미지-이미지 지원 | 기본 출력 크기 |
|---|---|---|---|
gemini-3-pro-image-preview | Gemini 3 Pro 이미지 생성 프리뷰, 최고 품질, 정식 결과물에 적합 | ✅ | 1024×1024 / 2K |
gemini-3.1-flash-image-preview | Gemini 3.1 Flash 이미지 생성 프리뷰, 빠르고 비용 효율적(“nano banana”) | ✅ | 1024×1024 |
gemini-2.5-flash-image | Gemini 2.5 Flash 이미지 생성 안정판 | ✅ | 1024×1024 |
플랫폼은 지속적으로 새 imagine 시리즈 모델을 추가합니다. 최신 지원 목록은 Gravitex AI 콘솔 모델 페이지에서 확인하세요.
인터페이스 개요
| 인터페이스 | Method | 용도 |
|---|---|---|
/v1/images/generations | POST | 텍스트-이미지, 이미지-이미지, 다중 이미지 융합 |
/v1/images/edits | POST | 이미지 편집(generations 프로토콜과 동등, SDK 습관에 따라 선택) |
imagine 모델의 경우/v1/images/generations와/v1/images/edits는 완전히 동등합니다 —image필드 전달 여부가 텍스트-이미지/이미지-이미지를 결정하며, 인터페이스 경로가 아닙니다. OpenAI Python SDK의images.generatevsimages.edit중 사용하는 SDK 습관에 따라 선택하세요.
/v1/images/generations — 텍스트-이미지 / 이미지-이미지
POST https://api.gravitex.ai/v1/images/generations
요청 매개변수
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
model | string | 예 | — | 모델 ID, 모델 목록 참고 |
prompt | string | 예 | — | 생성할 이미지를 설명하는 텍스트 프롬프트 |
image | string / string[] | 아니오 | — | 입력 참조 이미지(이미지-이미지, 스타일 전환, 다중 이미지 융합용), 형식은 image 필드 형식 참고 |
size | string | 아니오 | 모델에 따라 결정 | 원하는 크기 또는 종횡비, size / quality 값 매핑 참고 |
quality | string | 아니오 | auto | 출력 품질 등급, size / quality 값 매핑 참고 |
n | integer | 아니오 | 1 | 현재 무시됨: imagine 단일 호출 시 업스트림에서 1장만 생성; 여러 장은 클라이언트에서 반복 호출 |
response_format | string | 아니오 | b64_json | 현재 패스스루 안 됨: 응답은 항상 b64_json 필드로 base64 반환 |
image 필드 형식
image 필드는 “이미지-이미지”용 — 하나 이상의 참조 이미지를 모델에 시각적 맥락으로 제공합니다. 다음 두 가지 JSON 형태를 지원합니다:
// (1) 단일: string
{ "image": "https://example.com/cat.jpg" }
{ "image": "data:image/png;base64,iVBORw0KGgo..." }
{ "image": "iVBORw0KGgo..." } // raw base64 (must be valid image)
// (2) Multiple: string array
{ "image": [
"https://example.com/a.jpg",
"data:image/png;base64,iVBORw0KGgo..."
] }
- URL 형태: 게이트웨이가 자동으로 fetch하고 이미지 유형을 검증합니다. URL은 공개 접근 가능해야 하며, https 사용을 권장합니다.
- base64 / data URI: 게이트웨이가 decode하고 MIME을 감지합니다.
- 지원 이미지 형식:
image/png,image/jpeg,image/jpg,image/webp,image/heic,image/heif. multipart/form-data파일 업로드 미지원 — 이미지를 base64로 변환하거나 객체 스토리지에 업로드해 URL을 획득하세요.
size / quality 값 매핑
imagine 모델의 출력은 고정 등급이 있습니다(기존 모델처럼 임의 픽셀 지정 불가). 게이트웨이가 OpenAI 스타일 값을 모델이 지원하는 등급으로 자동 매핑합니다.
size → 종횡비
size 값 | aspectRatio |
|---|---|
256x256, 512x512, 1024x1024 | 1:1(정사각형) |
1536x1024 | 3:2(가로) |
1024x1536 | 2:3(세로) |
1024x1792 | 9:16(모바일 세로) |
1792x1024 | 16:9(와이드스크린) |
종횡비 직접 전달(9:16, 16:9 등) | 그대로 사용 |
| 미전달 또는 위 표에 없음 | 모델 기본값(보통 1:1) |
quality → imageSize 등급
quality 값 | imageSize | 참고 |
|---|---|---|
hd, high, 2K | 2K | 고해상도, 파일 더 큼/시간 더 걸림 |
standard, medium, low, auto, 1K, 미전달 | 1K | 표준, 더 빠름 |
응답 형식
성공 응답
{
"created": 1747299537,
"data": [
{
"url": "",
"b64_json": "iVBORw0KGgoAAAANSUhEUgAA...",
"revised_prompt": "好的,我已为您生成了一只穿唐装写春联的柴犬..."
}
],
"metadata": {
"text": "好的,我已为您生成了一只穿唐装写春联的柴犬..."
},
"usage": {
"total_tokens": 1421,
"input_tokens": 27,
"output_tokens": 1394,
"input_tokens_details": {
"text_tokens": 27,
"image_tokens": 0
},
"output_tokens_details": {
"image_tokens": 1290,
"text_tokens": 104
}
}
}
| Field | Type | Description |
|---|---|---|
created | integer | Unix 타임스탬프(초) |
data[].b64_json | string | Base64 이미지(data: 접두사 없음) — decode하여 PNG로 저장 |
data[].url | string | 현재 빈 문자열(호환 필드 유지, 플랫폼이 외부 URL에 이미지 업로드 안 함) |
data[0].revised_prompt | string | 모델 설명/수정된 prompt(텍스트 + 이미지) |
metadata.text | string | revised_prompt의 복사본, 간단한 클라이언트용 |
usage.total_tokens | integer | 총 토큰 수 |
usage.input_tokens | integer | 입력 토큰(prompt + 참조 이미지) |
usage.output_tokens | integer | 출력 토큰(이미지 + 설명 텍스트) |
usage.input_tokens_details.text_tokens | integer | 입력 텍스트 토큰 |
usage.input_tokens_details.image_tokens | integer | 입력 이미지 토큰(참조 없으면 0) |
usage.output_tokens_details.image_tokens | integer | 출력 이미지 토큰(모델별 고정 비용) |
usage.output_tokens_details.text_tokens | integer | 출력 텍스트 토큰 |
Gemini imagine 모델은 이미지 생성과 함께 종종 텍스트 설명(“X를 그려 드렸습니다”)을 반환하며,revised_prompt+metadata.text형태로 반환됩니다. 클라이언트에서 선택적으로 표시할 수 있습니다.usage필드 형식은 OpenAI gpt-image-1과 완전히 정렬되어 OpenAI SDK 프로젝트의 원활한 통합을 지원합니다.
오류 응답
{
"error": {
"message": "request blocked by Gemini API: SAFETY",
"type": "invalid_request_error",
"code": "prompt_blocked"
}
}
/v1/images/edits — 이미지 편집
POST https://api.gravitex.ai/v1/images/edits
요청/응답 형식은 /v1/images/generations와 완전히 동일합니다(JSON + image 필드 수락, 동일 구조 반환). 차이는 OpenAI Python SDK에서 images.edit와 images.generate가 서로 다른 메서드라는 점뿐이며, 일부 사용자는 “편집” 의미로 edits 엔드포인트를 선호합니다.
⚠️ OpenAI 공식 dall-e-2의/images/edits와 다름: 이 인터페이스는multipart/form-data업로드 +mask필드를 지원하지 않습니다(imagine 모델은 prompt로 편집을 지시하며 mask가 필요 없음).image필드는 generations와 동일합니다.
사용 시나리오 및 예제
1. 순수 텍스트-이미지
가장 기본적인 사용:prompt만 전달.
curl -X POST https://api.gravitex.ai/v1/images/generations \
-H "Authorization: Bearer sk-your_token_key" \
-H "Content-Type: application/json" \
-d '{
"model": "gemini-3.1-flash-image-preview",
"prompt": "Shiba inu in Tang suit writing spring couplets, ink wash style",
"size": "1024x1024",
"quality": "hd"
}'
2. 이미지-이미지 / 스타일 전환
사진을 사이버펑크 스타일로 변경 —image 필드에 단일 참조 이미지 전달.
curl -X POST https://api.gravitex.ai/v1/images/generations \
-H "Authorization: Bearer sk-your_token_key" \
-H "Content-Type: application/json" \
-d '{
"model": "gemini-3.1-flash-image-preview",
"prompt": "Cyberpunk style, neon, rainy street",
"size": "16:9",
"quality": "hd",
"image": "https://example.com/portrait.jpg"
}'
curl -X POST https://api.gravitex.ai/v1/images/generations \
-H "Authorization: Bearer sk-your_token_key" \
-H "Content-Type: application/json" \
-d '{
"model": "gemini-3.1-flash-image-preview",
"prompt": "Anime character style",
"image": "data:image/jpeg;base64,/9j/4AAQSkZJRgABAQAAAQABAAD/..."
}'
3. 다중 이미지 융합
여러 참조 이미지를 하나로 합성 —image 필드에 문자열 배열 전달.
curl -X POST https://api.gravitex.ai/v1/images/generations \
-H "Authorization: Bearer sk-your_token_key" \
-H "Content-Type: application/json" \
-d '{
"model": "gemini-2.5-flash-image",
"prompt": "Both characters on a sunset beach",
"size": "16:9",
"image": [
"https://example.com/character-a.png",
"https://example.com/character-b.png"
]
}'
4. /v1/images/edits 동등 호출
시나리오 2와 동일하지만 edits 엔드포인트 사용:
curl -X POST https://api.gravitex.ai/v1/images/edits \
-H "Authorization: Bearer sk-your_token_key" \
-H "Content-Type: application/json" \
-d '{
"model": "gemini-3.1-flash-image-preview",
"prompt": "Cyberpunk style",
"image": "https://example.com/portrait.jpg"
}'
5. Python (OpenAI SDK) 호출
import base64
from openai import OpenAI
client = OpenAI(
api_key="sk-your_token_key",
base_url="https://api.gravitex.ai/v1",
)
# 텍스트-이미지
resp = client.images.generate(
model="gemini-3.1-flash-image-preview",
prompt="一只穿唐装在写春联的柴犬,水墨风格",
size="1024x1024",
quality="hd",
)
img_b64 = resp.data[0].b64_json
print("revised_prompt:", resp.data[0].revised_prompt)
# 로컬 PNG로 저장
with open("output.png", "wb") as f:
f.write(base64.b64decode(img_b64))
images.edit도 여기서는 generations 프로토콜 사용; /v1/images/edits 엔드포인트는 client.images.edit(...) 사용):
# I2I via generations (recommended):
# OpenAI SDK의 images.generate는 image 필드를 직접 지원하지 않으므로
# HTTP POST 사용:
import httpx
resp = httpx.post(
"https://api.gravitex.ai/v1/images/generations",
headers={"Authorization": "Bearer sk-your_token_key"},
json={
"model": "gemini-3.1-flash-image-preview",
"prompt": "Cyberpunk neon style",
"image": "https://example.com/portrait.jpg",
},
timeout=60,
).json()
print(resp["data"][0]["b64_json"][:80] + "...")
6. Node.js (OpenAI SDK) 호출
import OpenAI from "openai";
import { writeFile } from "fs/promises";
const client = new OpenAI({
apiKey: "sk-your_token_key",
baseURL: "https://api.gravitex.ai/v1",
});
// 텍스트-이미지
const resp = await client.images.generate({
model: "gemini-3.1-flash-image-preview",
prompt: "一只穿唐装在写春联的柴犬,水墨风格",
size: "1024x1024",
quality: "hd",
});
const b64 = resp.data[0].b64_json!;
await writeFile("output.png", Buffer.from(b64, "base64"));
console.log("revised_prompt:", resp.data[0].revised_prompt);
const r = await fetch("https://api.gravitex.ai/v1/images/generations", {
method: "POST",
headers: {
"Authorization": "Bearer sk-your_token_key",
"Content-Type": "application/json",
},
body: JSON.stringify({
model: "gemini-3.1-flash-image-preview",
prompt: "Cyberpunk style",
image: "https://example.com/portrait.jpg",
}),
});
const data = await r.json();
오류 처리
실패 시 HTTP ≠ 200:{
"error": {
"message": "...",
"type": "...",
"code": "..."
}
}
일반적인 오류 코드
| HTTP | code | Description | Action |
|---|---|---|---|
400 | prompt_blocked | Gemini 안전 정책에 의해 차단(폭력, 민감 콘텐츠) | prompt 또는 참조 이미지 변경 |
400 | invalid_request | imagine 목록에 없는 모델, 빈 prompt, 잘못된 image 형식, 허용되지 않은 MIME 등 | 오류 메시지에 따라 수정 |
401 | invalid_authentication | 유효하지 않거나 만료된 토큰 | 새 키 생성 |
402 | insufficient_quota | 할당량 부족 | 충전 또는 관리자 문의 |
429 | rate_limit_exceeded | 속도 제한 초과 | Retry-After에 따라 백오프 |
502 | empty_response | 업스트림 200이지만 이미지 없음(드묾) | 1–2회 재시도 후 지원 문의 |
503 | bad_response | 업스트림 일시적 불가 | 백오프 후 재시도 |
504 | request_timeout | 업스트림 타임아웃 | 재시도 |
prompt_blocked는 종종 민감한 주제를 의미합니다 — prompt를 다시 작성하세요.
과금 규칙
- “실제 생성된 이미지 수”로 과금: 업스트림이 실제 반환한 이미지 수만큼 차감, 요청의
n매개변수는 과금에 영향 없음(제한 사항 참고). - 차단되거나 이미지가 0장일 때 과금 없음.
- 모델/
quality등급별 단가는 콘솔 가격에서 확인. - 과금 내역은 토큰 사용 기록 페이지에서 확인 가능하며, 각 기록에
생성 수량 N필드가 포함됩니다.
제한 사항
| 제한 항목 | Description |
|---|---|
n 무시됨 | 호출당 1장; N장 필요 시 클라이언트에서 N회 반복 |
| 스트리밍 미지원 | /v1/images/generations와 /v1/images/edits 모두 비스트리밍, SSE chunk 없음 |
| multipart 업로드 미지원 | multipart/form-data 불가; image 필드는 JSON 문자열(URL / base64 / data URI)이어야 함 |
response_format 항상 b64_json | 호스팅 URL 없음 — base64를 직접 업로드 |
mask 필드 없음 | imagine 모델은 prompt로 편집 지시, mask 불필요; dall-e-2 mask 프로토콜 무효 |
| 참조 이미지 ≤ 8 MB 권장 | 큰 입력 이미지는 처리 시간 증가 및 HTTP body 크기 제한 가능 |
| 입력 MIME 허용 목록 필수 | png / jpeg / jpg / webp / heic / heif; 기타 형식(bmp, tiff, gif) 오류 |
| 참조 이미지 ≤ 4장 권장 | 다중 이미지 융합 시 이미지가 많을수록 지연 증가 |
이 엔드포인트에서 extra_body 없음 | imageConfig / safetySettings / thinking_config 제어는 /v1/chat/completions 사용(부록) |
모범 사례
- prompt: 구체적으로 작성(스타일, 색상, 구도, 카메라); 모호한 단어 피하기.
- I2I는 ≤512×512 참조로 시작, 이후 전체 크기로.
- 여러 번 재시도: 이미지 생성은 무작위성이 있으므로 “다시 생성” 버튼 제공 권장.
- 민감 주제에 재생성/신고 추가.
b64_json즉시 저장 — 업스트림 캐시 없음.revised_prompt를 UX 카피로 표시.- **초안은
1K, 최종은2K**로 비용 절감.
자주 묻는 질문
Q1: n=4를 전달했는데 1장만 반환되는 이유는?
A: Gemini imagine 모델은 업스트림 단일 호출당 1장만 생성합니다. 플랫폼은 실제 생성 수로 과금합니다. 여러 장은 클라이언트에서 여러 번 호출하세요.
Q2: I2I에서 영역별 mask를 사용할 수 있나요?
A: imagine 모델은mask 필드를 지원하지 않습니다. 모든 변경은 prompt로 설명합니다(예: “머리카락만 빨간색으로, 나머지는 유지”). 모델이 prompt를 이해해 영역을 자동으로 파악합니다.
Q3: b64_json에 data: 접두사가 없는 이유는?
A: b64_json은 순수 base64 문자열로 파일 저장이 편리합니다. HTML <img src>에 삽입하려면 "data:image/png;base64," + b64_json으로 접두사를 직접 붙이세요.
Q4: 텍스트 없이 이미지만 반환할 수 있나요?
A: 현재 불가 — imagine 모델의 특징이 텍스트+이미지 동시 반환입니다.revised_prompt/metadata.text는 표시하지 않을 수 있지만 요청 수준에서 비활성화는 불가합니다.
Q5: T2I와 I2I 과금이 동일한가요?
A: 예 — “출력 이미지 수 + 출력 quality 등급”으로 과금하며,image 필드 포함 여부와 무관합니다.
Q6: 텍스트 + 다중 참조 이미지를 동시에 전달할 수 있나요?
A: 가능합니다.image 필드는 string[]를 지원하며, prompt로 융합 방식을 설명하세요. 시나리오 3: 다중 이미지 융합 참고.
Q7: imagine 모델에 generations vs chat 차이는?
A: 부록 참고. 요약:/v1/images/generations: 프로토콜 단순(OpenAI Image API 표준), “이미지만 필요”한 경우에 적합./v1/chat/completions: Gemini 네이티브 매개변수(imageConfig,safetySettings,thinking_config등) 제어 가능, “세밀한 제어”가 필요한 경우에 적합.
부록: /v1/chat/completions 엔드포인트와 비교
Gemini imagine 모델은 OpenAI /v1/chat/completions 인터페이스로도 호출 가능합니다(prompt를 message로, 이미지를 content 배열에 넣음). 두 엔드포인트 비교:
| Aspect | /v1/images/generations & /v1/images/edits | /v1/chat/completions |
|---|---|---|
| Protocol | OpenAI Image API(경량) | OpenAI Chat Completions API(기능 풍부) |
| Input | prompt + image 필드 | messages[].content(멀티모달 배열) |
| Output | data[].b64_json + revised_prompt | choices[].message.content(배열: text + image_url) |
| Streaming | ❌ 없음 | ❌ imagine 모델도 chat에서 비스트리밍 강제 |
extra_body 패스스루 | ❌ 없음 | ✅ extra_body.google.*로 Gemini 네이티브 매개변수 완전 패스스루 |
| Multi-turn context | ❌ 단일 요청 | ✅ 다중 턴 messages |
| Best for | 일회성 이미지, 배치 스크립트, DALL·E 호환 클라이언트 | 대화형 상호작용(“다시 수정”), 네이티브 매개변수(imageConfig/safetySettings/thinking_config) 필요 시 |
curl -X POST https://api.gravitex.ai/v1/chat/completions \
-H "Authorization: Bearer sk-your_token_key" \
-H "Content-Type: application/json" \
-d '{
"model": "gemini-3.1-flash-image-preview",
"messages": [
{ "role": "user", "content": [
{ "type": "text", "text": "Cyberpunk style" },
{ "type": "image_url", "image_url": { "url": "https://example.com/portrait.jpg" } }
]
}
],
"extra_body": {
"google": {
"generationConfig": {
"imageConfig": { "aspectRatio": "16:9", "imageSize": "2K" }
}
}
}
}'
choices[0].message.content는 배열입니다:
[
{ "type": "text", "text": "Done, here is your edit..." },
{ "type": "image_url", "image_url": {
"url": "data:image/png;base64,iVBORw0KGgo...",
"mime_type": "image/png"
} }
]
