Open API

Gemini Image API

LMU AI의 네이티브 Gemini v1beta 엔드포인트로 텍스트-투-이미지, 이미지 편집, 이미지-투-이미지를 수행하며 1K / 2K / 4K, 일반적인 종횡비, Base64 파싱을 지원합니다.

LMU AI는 Gemini 네이티브 v1beta 호환 API를 제공하므로 Gemini 이미지 모델을 직접 호출하여 텍스트-투-이미지, 이미지 편집, 이미지-투-이미지를 수행할 수 있습니다.

API 프로토콜

Gemini 이미지 생성은 Google의 네이티브 Gemini generateContent 프로토콜을 사용합니다 — OpenAI의 /v1/chat/completions도 아니고, OpenAI Images의 /v1/images/generations도 아닙니다.

주요 엔드포인트:

POST https://api.lmuai.com/v1beta/models/{model}:generateContent

1. API 개요

메서드경로설명
GET/v1beta/modelsGemini 그룹에서 현재 API 키에 사용 가능한 네이티브 모델 목록
GET/v1beta/models/{model}특정 모델에 대한 정보 조회
POST/v1beta/models/{model}:generateContent텍스트-투-이미지, 이미지 편집, 이미지-투-이미지의 주요 엔드포인트
POST/v1beta/models/{model}:streamGenerateContent?alt=sse스트리밍 생성; 이미지 사용 사례에서는 첫 번째 선택으로 권장하지 않음
GET/v1/modelsOpenAI 호환 모델 목록; 일반적인 모델 선택기에 적합
POST/v1/images/batchesLMU AI Gemini 비동기 배치 이미지 확장 엔드포인트; Gemini Batch Image API 참조

Base URL:

https://api.lmuai.com

2. 인증

권장: Gemini 네이티브 헤더

x-goog-api-key: YOUR_API_KEY

호환: Bearer 헤더

Authorization: Bearer YOUR_API_KEY

서버는 다음 우선순위 순서로 API 키를 읽습니다:

  1. x-goog-api-key;
  2. Authorization: Bearer ...;
  3. x-api-key;
  4. /v1beta 경로의 ?key=... 쿼리 파라미터.

키를 URL에 넣지 마세요

?api_key=...는 더 이상 사용되지 않으며 400을 반환합니다. ?key=...는 여전히 작동하지만, 브라우저 기록, 리버스 프록시, 액세스 로그에 쉽게 기록됩니다 — 프로덕션에서는 헤더를 사용하세요.

일반적인 인증 오류:

{
  "error": {
    "code": 401,
    "message": "Invalid API key",
    "status": "UNAUTHENTICATED"
  }
}

API 키는 gemini 플랫폼 그룹에 바인딩되어 있어야 합니다. 그렇지 않으면 네이티브 Gemini API를 호출할 수 없습니다.


3. 모델 및 가용성

이 이미지 서비스는 주로 다음 클라이언트 측 모델 ID를 사용합니다:

모델 ID권장 용도이미지 편집 참고 사항
gemini-3.1-flash-image기본 권장inlineData 이미지 편집으로 프로덕션에서 검증됨
gemini-3.1-flash-image-preview프리뷰 호환동일한 generateContent 편집 프로토콜 사용; 프로덕션 통합 전 별도로 검증 필요
gemini-3-pro-image품질 우선 / 복잡한 편집동일한 generateContent 편집 프로토콜 사용; 현재 키의 가용성에 따라 다름
gemini-3-pro-image-previewPro 프리뷰 호환동일한 편집 프로토콜 사용; 실행 모델은 서버 응답이 나타내는 것
gemini-3.1-flash-lite-image경량 사용 사례모델 목록에서 반환되고 이미지 출력이 검증된 경우에만 사용

현재 키에 대한 Gemini 모델 목록 조회

curl 'https://api.lmuai.com/v1beta/models' \
  -H 'x-goog-api-key: YOUR_API_KEY'

OpenAI 호환 모델 목록:

curl 'https://api.lmuai.com/v1/models' \
  -H 'Authorization: Bearer YOUR_API_KEY'

모델 ID는 서버 측에서 매핑될 수 있습니다

클라이언트는 요청 모델 ID를 제출합니다. LMU AI는 호환 가능한 모델 별칭을 지원하므로, 요청된 모델 이름이 응답의 최종 모델 버전과 반드시 동일하지는 않습니다.

모델 이름만으로 가용성을 추측하지 마세요. 현재 키로 /v1beta/models를 호출한 실제 결과에 의존하세요.


4. 빠른 시작: 텍스트-투-이미지

curl --request POST \
  'https://api.lmuai.com/v1beta/models/gemini-3.1-flash-image:generateContent' \
  --header 'x-goog-api-key: YOUR_API_KEY' \
  --header 'Content-Type: application/json' \
  --data-raw '{
    "contents": [
      {
        "role": "user",
        "parts": [
          {
            "text": "An orange cat wearing an astronaut helmet, cinematic lighting, exquisite detail"
          }
        ]
      }
    ],
    "generationConfig": {
      "responseModalities": ["TEXT", "IMAGE"],
      "imageConfig": {
        "aspectRatio": "1:1",
        "imageSize": "1K"
      }
    }
  }'

성공 시 다음에서 이미지를 읽습니다:

candidates[].content.parts[].inlineData.data

5. 텍스트-투-이미지 요청 구조

{
  "contents": [
    {
      "role": "user",
      "parts": [
        {
          "text": "A cinematic rainy-night city street, neon lights reflected on the wet pavement, wide-angle composition"
        }
      ]
    }
  ],
  "generationConfig": {
    "responseModalities": ["TEXT", "IMAGE"],
    "imageConfig": {
      "aspectRatio": "16:9",
      "imageSize": "2K"
    }
  }
}

요청 필드

필드타입필수설명
contentsarray대화 콘텐츠 배열; 최소 하나의 사용자 메시지를 포함해야 함
contents[].rolestring권장사용자 입력에는 user 사용
contents[].partsarray텍스트 또는 입력 이미지 파트
parts[].textstring텍스트-투-이미지에 필수이미지 프롬프트
generationConfigobject생성 파라미터
generationConfig.responseModalitiesstring[]이미지 생성에는 IMAGE를 포함해야 함; ['TEXT', 'IMAGE'] 권장
generationConfig.imageConfigobject이미지 해상도 및 종횡비 구성

이미지 파라미터는 imageConfig에 넣어야 합니다

generationConfig.imageConfig를 사용하세요. responseFormat.image를 사용하지 마세요. 그 필드는 파라미터 오류를 일으키지 않을 수 있지만, 네이티브 Gemini 이미지 파라미터로 적용되지 않습니다.


6. 해상도 및 종횡비

지원 해상도

imageSize권장 용도특징
1K초안, 빠른 미리보기, 배치 스크리닝일반적으로 더 빠르고 저렴함
2K표준 전달, 기사 이미지, 이커머스 에셋품질, 시간, 비용의 균형
4K세밀한 대형 이미지, 고품질 전달일반적으로 생성 및 전송 시간이 더 김

imageSize는 대문자여야 합니다:

{
  "imageSize": "2K"
}

지원 종횡비

aspectRatio모델 수준 기능입니다. Pro 모델에서 Flash의 확장 비율을 사용할 수 없습니다. LMU AI는 알려진 무효한 조합을 업스트림에 보내지 않도록 요청된 모델에 대해 비율을 검증합니다.

10개의 일반 비율:

1:1
2:3
3:2
3:4
4:3
4:5
5:4
9:16
16:9
21:9

4개의 Flash 확장 비율:

1:4
1:8
4:1
8:1

모델 비율 매트릭스

클라이언트 모델 ID확인된 지원 비율개수
gemini-3.1-flash-image일반 10개 + Flash 확장 4개14
gemini-3.1-flash-image-preview일반 10개 + Flash 확장 4개14
gemini-3.1-flash-lite-image일반 10개 + Flash 확장 4개14
gemini-3-pro-image일반 10개만10
gemini-3-pro-image-preview일반 10개만10

Pro 모델은 Flash 확장 비율을 지원하지 않습니다

gemini-3-pro-image 또는 gemini-3-pro-image-preview1:4, 1:8, 4:1, 8:1을 전달하면 INVALID_ARGUMENT 또는 릴레이 400 파라미터 오류를 반환합니다. 예:

{
  "error": {
    "code": 400,
    "message": "generationConfig.imageConfig.aspectRatio has an unsupported value",
    "status": "INVALID_ARGUMENT"
  }
}

위 매트릭스는 Google의 공식 모델 문서와 LMU AI 프로덕션 API 테스트를 결합한 것입니다: 세 개의 Flash / Flash Lite 모델은 모두 확장 비율 테스트를 통과하고, 두 Pro 모델은 네 개의 확장 비율을 모두 명시적으로 거부합니다. 알 수 없거나 새로운 모델의 경우, 검증할 때까지 일반 10개 비율을 사용하세요.

aspectRatio를 지정하지 않으면, 모델이 입력 콘텐츠와 기본 정책에 따라 종횡비를 결정합니다. 임의의 소수나 임의의 WIDTHxHEIGHT를 전달하지 마세요. 대상 모델이 허용하는 비율 열거값을 사용해야 합니다.

예:

{
  "generationConfig": {
    "responseModalities": ["TEXT", "IMAGE"],
    "imageConfig": {
      "aspectRatio": "9:16",
      "imageSize": "4K"
    }
  }
}

해상도 등급은 고정된 픽셀 크기가 아닙니다

1K, 2K, 4K는 모델 해상도 등급입니다. 실제 너비와 높이는 등급과 종횡비로부터 모델이 계산합니다. 클라이언트는 항상 1024×1024, 2048×2048, 4096×4096이라고 가정해서는 안 됩니다.


7. 이미지 편집 / 이미지-투-이미지

Gemini는 이미지 편집을 지원합니다 — 단지 GPT처럼 별도의 /v1/images/edits 엔드포인트가 없을 뿐입니다.

텍스트-투-이미지와 이미지 편집 모두 다음을 호출합니다:

POST /v1beta/models/{model}:generateContent

둘의 차이점은:

사용 사례contents[].parts[] 콘텐츠
텍스트-투-이미지텍스트 프롬프트만
이미지 편집 / 이미지-투-이미지텍스트 편집 지시문 + inlineData 입력 이미지

프로덕션에서 검증됨

gemini-3.1-flash-imageinlineData를 통해 JPEG 입력 이미지를 제출하면 다음을 성공적으로 반환했습니다:

  • HTTP 200;
  • finishReason: STOP;
  • image/png 편집 결과;
  • 비어 있지 않은 inlineData.data;
  • usageMetadata 이미지 모달리티 토큰 수.

응답에는 이미지 파트만 포함되고 텍스트 파트가 없을 수 있으므로, 클라이언트는 응답에 텍스트가 있어야 한다고 요구해서는 안 됩니다.

7.1 최소 이미지 편집 요청

{
  "contents": [
    {
      "role": "user",
      "parts": [
        {
          "text": "Keep the person, composition, and lighting; change the background to a rainy-night neon street"
        },
        {
          "inlineData": {
            "mimeType": "image/png",
            "data": "INPUT_IMAGE_BASE64"
          }
        }
      ]
    }
  ],
  "generationConfig": {
    "responseModalities": ["TEXT", "IMAGE"],
    "imageConfig": {
      "aspectRatio": "1:1",
      "imageSize": "1K"
    }
  }
}

7.2 입력 이미지 필드

필드타입필수설명
contents[].parts[].textstring편집 지시문; 무엇을 유지하고 무엇을 변경할지 명확히 명시
inlineData.mimeTypestring예: image/png, image/jpeg, image/webp
inlineData.datastringData URL 접두사가 없는 원시 Base64
imageConfig.aspectRatiostring아니오출력 종횡비; 입력 비율을 유지해야 하는 경우 일치하는 비율 설정
imageConfig.imageSizestring아니오출력 등급: 1K, 2K, 4K, 모델 기능에 따라 다름

Base64에 Data URL 접두사를 포함하지 마세요

올바른 예:

/9j/4AAQSkZJRgABAQ...

전달하지 말 것:

data:image/jpeg;base64,/9j/4AAQSkZJRgABAQ...

지나치게 큰 입력 이미지는 업로드 및 처리 시간을 늘리고 게이트웨이 요청 본문 제한으로 인해 413을 반환할 수 있습니다.

7.3 전체 curl 예제

먼저 로컬 이미지를 한 줄 Base64로 변환합니다:

IMAGE_BASE64=$(base64 < input.jpg | tr -d '\n')

그런 다음 이미지 모델을 호출합니다:

curl --request POST \
  'https://api.lmuai.com/v1beta/models/gemini-3.1-flash-image:generateContent' \
  --header 'x-goog-api-key: YOUR_API_KEY' \
  --header 'Content-Type: application/json' \
  --data-raw "{
    \"contents\": [{
      \"role\": \"user\",
      \"parts\": [
        {
          \"text\": \"Keep the cup, composition, lighting, and background unchanged; only change the cup from blue to purple, and add three white star patterns on the cup body; do not add any text\"
        },
        {
          \"inlineData\": {
            \"mimeType\": \"image/jpeg\",
            \"data\": \"${IMAGE_BASE64}\"
          }
        }
      ]
    }],
    \"generationConfig\": {
      \"responseModalities\": [\"TEXT\", \"IMAGE\"],
      \"imageConfig\": {
        \"aspectRatio\": \"3:2\",
        \"imageSize\": \"1K\"
      }
    }
  }"

7.4 Python 이미지 편집 예제

import base64
import requests

api_key = "YOUR_API_KEY"
model = "gemini-3.1-flash-image"
input_path = "input.jpg"

with open(input_path, "rb") as f:
    image_base64 = base64.b64encode(f.read()).decode("utf-8")

payload = {
    "contents": [{
        "role": "user",
        "parts": [
            {
                "text": "Keep the subject and composition; change the background to a rainy-night neon street"
            },
            {
                "inlineData": {
                    "mimeType": "image/jpeg",
                    "data": image_base64,
                }
            },
        ],
    }],
    "generationConfig": {
        "responseModalities": ["TEXT", "IMAGE"],
        "imageConfig": {
            "aspectRatio": "3:2",
            "imageSize": "1K",
        },
    },
}

response = requests.post(
    f"https://api.lmuai.com/v1beta/models/{model}:generateContent",
    headers={
        "x-goog-api-key": api_key,
        "Content-Type": "application/json",
    },
    json=payload,
    timeout=300,
)
response.raise_for_status()
result = response.json()

saved = False
for candidate in result.get("candidates", []):
    for part in candidate.get("content", {}).get("parts", []):
        inline_data = part.get("inlineData", {})
        if inline_data.get("data"):
            mime_type = inline_data.get("mimeType", "image/png")
            extension = "jpg" if "jpeg" in mime_type else "webp" if "webp" in mime_type else "png"
            with open(f"gemini-edited.{extension}", "wb") as f:
                f.write(base64.b64decode(inline_data["data"]))
            saved = True
            break
    if saved:
        break

if not saved:
    raise RuntimeError("HTTP request succeeded, but the response contains no edited image")

7.5 편집 프롬프트 팁

이미지 편집 프롬프트의 경우, "유지할 것"과 "변경할 것"을 명확히 구분하는 것이 가장 좋습니다:

Keep: subject identity, pose, camera angle, composition, and lighting.
Change: change the background to a rainy-night neon street.
Forbidden: do not add text; do not change the person's face.

이 구조는 단순히 "더 멋지게 만들어줘"라고 쓰는 것보다 더 일관된 결과를 제공합니다.

7.6 여러 참조 이미지

일부 Gemini 이미지 모델은 스타일 참조, 캐릭터 참조, 에셋 블렌딩을 위해 동일한 parts[]에 여러 inlineData 이미지를 받을 수 있습니다. 그러나 허용되는 참조 이미지 수와 전체 요청 본문 크기는 모델마다 다르므로, 프로덕션 사용 전에 특정 모델에 대해 검증하세요.

/v1beta/models에서 반환되었다는 이유만으로 특정 이미지 모델이 무제한의 참조 이미지를 지원한다고 가정하지 마세요.


8. 성공 응답

일반적인 응답:

{
  "candidates": [
    {
      "content": {
        "role": "model",
        "parts": [
          {
            "text": "Image generated as requested."
          },
          {
            "inlineData": {
              "mimeType": "image/png",
              "data": "BASE64_IMAGE_DATA"
            }
          }
        ]
      },
      "finishReason": "STOP",
      "index": 0
    }
  ],
  "usageMetadata": {
    "promptTokenCount": 123,
    "candidatesTokenCount": 1120,
    "totalTokenCount": 1450,
    "candidatesTokensDetails": [
      {
        "modality": "IMAGE",
        "tokenCount": 1024
      }
    ]
  },
  "modelVersion": "MODEL_VERSION"
}

주요 응답 필드

필드설명
candidates[]후보 출력 목록
candidates[].content.parts[]텍스트 또는 이미지 파트
parts[].inlineData.mimeType반환된 이미지의 MIME 타입
parts[].inlineData.data반환된 이미지의 Base64 콘텐츠
candidates[].finishReason종료 이유; 일반적인 성공 값은 STOP
usageMetadata입력, 출력, 이미지 모달리티 토큰 수
modelVersion업스트림이 반환한 실제 모델 버전; 존재하는 경우 전달됨

이미지 생성 성공을 올바르게 판단하기

클라이언트는 다음을 모두 확인해야 합니다:

  1. HTTP 상태 코드가 2xx;
  2. candidates가 비어 있지 않음;
  3. 적어도 하나의 parts[]에 비어 있지 않은 inlineData.data가 있음;
  4. Base64가 성공적으로 디코딩됨;
  5. 필요할 때 finishReason 확인.

HTTP 200이 이미지가 생성되었음을 보장하지 않습니다

업스트림은 응답에 inlineData.data가 없는 상태로 HTTP 200을 반환할 수 있습니다. 이러한 요청은 "비즈니스 이미지 생성 실패"로 취급해야 하며 성공한 이미지로 계산해서는 안 됩니다.


9. Node.js 예제

import { writeFile } from 'node:fs/promises';

const BASE_URL = process.env.GEMINI_BASE_URL || 'https://api.lmuai.com';
const API_KEY = process.env.GEMINI_API_KEY;
const MODEL = 'gemini-3.1-flash-image';

if (!API_KEY) throw new Error('Missing GEMINI_API_KEY');

const payload = {
  contents: [
    {
      role: 'user',
      parts: [
        { text: 'A seaside lighthouse at sunset, watercolor illustration, warm tones, delicate paper texture' },
      ],
    },
  ],
  generationConfig: {
    responseModalities: ['TEXT', 'IMAGE'],
    imageConfig: {
      aspectRatio: '16:9',
      imageSize: '2K',
    },
  },
};

const controller = new AbortController();
const timer = setTimeout(() => controller.abort(), 300_000);

try {
  const response = await fetch(
    `${BASE_URL}/v1beta/models/${encodeURIComponent(MODEL)}:generateContent`,
    {
      method: 'POST',
      headers: {
        'x-goog-api-key': API_KEY,
        'Content-Type': 'application/json',
      },
      body: JSON.stringify(payload),
      signal: controller.signal,
    },
  );

  const text = await response.text();
  let data;
  try {
    data = JSON.parse(text);
  } catch {
    throw new Error(`Non-JSON response from the service: HTTP ${response.status}`);
  }

  if (!response.ok) {
    throw new Error(
      `HTTP ${response.status}: ${data?.error?.message || JSON.stringify(data)}`,
    );
  }

  const parts = data.candidates?.flatMap((candidate) => candidate.content?.parts || []) || [];
  const imagePart = parts.find((part) => part.inlineData?.data);

  if (!imagePart) {
    const reasons = data.candidates?.map((candidate) => candidate.finishReason).filter(Boolean);
    throw new Error(`Request completed but no image, finishReason=${reasons?.join(',') || 'unknown'}`);
  }

  const mimeType = imagePart.inlineData.mimeType || 'image/png';
  const extension = mimeType === 'image/jpeg'
    ? 'jpg'
    : mimeType === 'image/webp'
      ? 'webp'
      : 'png';

  await writeFile(
    `gemini-output.${extension}`,
    Buffer.from(imagePart.inlineData.data, 'base64'),
  );

  console.log('Image saved, usageMetadata:', data.usageMetadata || null);
} finally {
  clearTimeout(timer);
}

10. Python 예제

import base64
import os
from pathlib import Path
import requests

BASE_URL = os.getenv("GEMINI_BASE_URL", "https://api.lmuai.com")
API_KEY = os.environ["GEMINI_API_KEY"]
MODEL = "gemini-3.1-flash-image"

payload = {
    "contents": [
        {
            "role": "user",
            "parts": [
                {"text": "A futuristic building complex, early-morning mist, ultra-wide-angle photography, realistic materials"}
            ],
        }
    ],
    "generationConfig": {
        "responseModalities": ["TEXT", "IMAGE"],
        "imageConfig": {
            "aspectRatio": "16:9",
            "imageSize": "2K",
        },
    },
}

response = requests.post(
    f"{BASE_URL}/v1beta/models/{MODEL}:generateContent",
    headers={
        "x-goog-api-key": API_KEY,
        "Content-Type": "application/json",
    },
    json=payload,
    timeout=300,
)

data = response.json()
if not response.ok:
    message = data.get("error", {}).get("message", data)
    raise RuntimeError(f"HTTP {response.status_code}: {message}")

image_part = None
for candidate in data.get("candidates", []):
    for part in candidate.get("content", {}).get("parts", []):
        if part.get("inlineData", {}).get("data"):
            image_part = part
            break
    if image_part:
        break

if not image_part:
    reasons = [candidate.get("finishReason") for candidate in data.get("candidates", [])]
    raise RuntimeError(f"Request completed but no image was returned, finishReason={reasons}")

inline_data = image_part["inlineData"]
mime_type = inline_data.get("mimeType", "image/png")
extension = {
    "image/jpeg": "jpg",
    "image/webp": "webp",
}.get(mime_type, "png")

Path(f"gemini-output.{extension}").write_bytes(
    base64.b64decode(inline_data["data"])
)

print("Image saved")
print("usageMetadata:", data.get("usageMetadata"))

11. 일반적인 오류

네이티브 Gemini 엔드포인트는 일반적으로 Google 스타일의 오류를 반환합니다:

{
  "error": {
    "code": 429,
    "message": "upstream rate limit exceeded",
    "status": "RESOURCE_EXHAUSTED"
  }
}
HTTP 상태일반적인 원인권장 사항
400잘못된 요청 구조, 모델 경로, 또는 그룹 플랫폼요청 수정; 단순히 재시도하지 말 것
401API 키 누락, 무효, 또는 비활성화됨키와 헤더 확인
402 / 403잔액 부족, 구독, 청구 자격, 또는 권한 문제계정 및 그룹 권한 확인
413이미지-투-이미지 요청 본문이 너무 큼입력 이미지 압축
429사용자 동시성 제한 또는 업스트림 속도 제한지수 백오프; 동시성 및 RPM 감소
500내부 또는 용량 오류오류 코드 및 요청 ID 기록; 제한된 횟수만 재시도
502일시적 업스트림 인증, 권한, 또는 서비스 실패백오프 후 재시도; 필요 시 관리자에게 문의
503사용 가능한 Gemini 계정 없음 또는 업스트림 과부하지연 후 재시도하고 트래픽 감소
504게이트웨이 또는 업스트림 타임아웃독립적인 요청으로 재발행

오류 메시지에 모든 토큰이 비활성화, 쿨다운, 잠김, 또는 만료되었다고 나오면, 이는 프롬프트 형식 오류가 아니라 서비스 용량 문제입니다. 공격적으로 재시도하는 것을 멈추고 오류 코드와 요청 ID를 관리자에게 제공하세요.


12. 타임아웃, 재시도, 동시성

클라이언트 타임아웃 권장 사항

해상도권장 총 타임아웃
1K최소 120초
2K최소 180초
4K300초 권장

이는 통합 권장 사항이며 고정된 SLA가 아닙니다. 요청이 자체 Nginx, CDN, 또는 API 게이트웨이를 통과하는 경우, 해당 구성 요소의 읽기 타임아웃을 그에 맞게 조정하세요.

재시도 권장 사항

재시도 권장:

  • 429;
  • 502, 503, 504;
  • 네트워크 중단, 연결 재설정, 읽기 타임아웃;
  • HTTP 200을 받았지만 이미지가 없을 때 한 번(제한적으로) 재시도하고 원시 응답을 저장할 수 있음.

일반적으로 재시도하지 말 것:

  • 400;
  • 401;
  • 명시적인 잔액 또는 권한 오류;
  • 요청 파라미터 또는 콘텐츠 정책 오류.

지수 백오프를 사용하여 최대 2~3회 재시도:

Attempt 1: 1–2 seconds random jitter
Attempt 2: 3–5 seconds random jitter
Attempt 3: 8–12 seconds random jitter

여러 실시간 이미지

실시간 엔드포인트는 현재 "요청당 하나의 기본 이미지"로 사용됩니다. 여러 이미지가 필요할 때는 여러 개의 독립적인 요청으로 분할하고 동시에 다음을 제한하세요:

  • 최대 진행 중인 동시성;
  • 분당 요청 수(RPM);
  • 사용자당 작업 수;
  • 타임아웃 및 최대 재시도 횟수.

수십에서 수백 개의 프롬프트를 제출하고 결과를 비동기적으로 기다려야 하는 경우 Gemini Batch Image API를 사용하세요.


13. 사용량 및 청구

응답의 usageMetadata는 입력, 출력, 이미지 모달리티 토큰을 분석하는 데 사용할 수 있지만, 반드시 최종 청구 금액과 같지는 않습니다.

실제 청구는 다음에 영향을 받을 수 있습니다:

  • 요청된 모델 ID 대 실제 매핑된 모델;
  • 1K, 2K, 4K 이미지 등급;
  • 그룹의 이미지당 가격;
  • 사용자 그룹 배수 및 업스트림 계정 배수;
  • 배포 환경의 청구 규칙.

최종 금액은 LMU AI 콘솔의 사용량 세부 정보와 계정 잔액 변화에 의존하세요.

품질 또는 동시성 테스트를 실행할 때는 다음을 기록하세요:

  1. 테스트 전 잔액;
  2. 테스트 후 잔액;
  3. 성공한 요청 수;
  4. 실제로 반환된 이미지 수;
  5. 모델, 해상도, 종횡비;
  6. 잔액 차이;
  7. 성공한 이미지당 평균 비용.

사용 기록은 비동기적으로 게시될 수 있으므로, 최종 금액을 대조하기 전에 테스트 후 잠시 기다리세요.


14. 보안 권장 사항

  • API 키는 서버 측 환경 변수 또는 시크릿 관리자에만 저장하세요;
  • 키를 브라우저 프런트엔드, 모바일 앱 패키지, 또는 공개 코드 저장소에 임베드하지 마세요;
  • 전체 API 키 또는 전체 이미지 Base64를 로그에 기록하지 마세요;
  • 입력 이미지의 MIME 타입, 파일 크기, Base64 유효성을 검증하세요;
  • 응답을 저장할 때 inlineData.mimeType을 기반으로 파일 확장자를 선택하세요;
  • 각 비즈니스 요청에 대해 자체 추적 ID, 요청 시간, 모델, 해상도, HTTP 상태를 기록하세요;
  • 타임아웃 후에는 아주 짧은 시간 내에 동일한 요청을 대량으로 재생성하지 마세요.

15. 통합 검수 체크리스트

  • /v1beta/models를 사용하여 현재 키에 대한 Gemini 모델 목록을 가져올 수 있음;
  • x-goog-api-key 또는 Bearer 헤더로 인증할 수 있음;
  • 1K / 1:1 텍스트-투-이미지 생성을 완료할 수 있음;
  • 2K4K 텍스트-투-이미지 생성을 완료할 수 있음;
  • 적어도 하나의 이미지 편집 / 이미지-투-이미지를 완료할 수 있음;
  • inlineData.mimeTypeinlineData.data를 읽을 수 있음;
  • 이미지가 없는 HTTP 200을 실패로 표시할 수 있음;
  • 이미지 요청에 대한 타임아웃을 설정했음;
  • 429 및 5xx에 대해 제한된 지수 백오프를 구현했음;
  • 가격, 잔액, 동시성, RPM을 확인했음;
  • 로그가 API 키나 전체 Base64를 유출하지 않음.

다음 단계

마지막 업데이트:

이 페이지의 목차