제미나이 무료 API, 키 발급, 분당 한도, 백오프 코드 | AI Studio 첫 호출 따라 하는 법은?
제미나이(Gemini) 무료 API를 키 발급부터 curl 스모크, Node SDK, 분당·일일 한도 확인, 429 지수 백오프, 일일 예산 카운터, 유료 전환 시 원화·부가세 손익 표까지 7단계 실습으로 정리한다. 구글 AI 스튜디오 무료 티어·LLM·개발자·API·SDK 운영과 FAQ, 공식 Rate limits·Pricing 링크를 담은 튜토리얼.
제미나이(Gemini) 무료 API는 구글 AI 스튜디오에서 키를 받은 뒤, 환경 변수 → 한 줄 호출 → 분당·일일 한도 확인 → 429 백오프 순서로 붙이면 됩니다. 카드 없이 토큰 요금 0원으로 시작할 수 있지만, 한도는 프로젝트 단위로 잡히고 RPM·TPM·RPD 중 하나만 넘어도 429가 납니다. 아래는 사이드 프로젝트에 바로 붙여 쓸 수 있는 실습 순서입니다. 고정 숫자는 시점에 따라 바뀌므로, 배포 전 AI Studio Rate Limit 화면을 최종 기준으로 두세요.
프로젝트 ID를 메모한다. 한도는 키마다 따로가 아니라 프로젝트 단위인 경우가 일반적이다.
키 문자열을 비밀번호처럼 취급한다. 슬랙·이슈·스크린샷에 올리지 않는다.
로컬·배포 모두 환경 변수(또는 시크릿 매니저)로만 주입한다.
아래는 로컬에서 쓰는 최소 패턴입니다. 커밋 전에 키 문자열이 워킹 트리에 없는지 한 번 더 검색하세요.
환경 변수 준비 (.env.local 예시, 깃 제외)
# .env.local — 반드시 .gitignore 에 추가
GEMINI_API_KEY=여기에_발급받은_키
# 셸에서 1회 테스트
export GEMINI_API_KEY="$(grep GEMINI_API_KEY .env.local | cut -d= -f2-)"
echo "key length: ${#GEMINI_API_KEY}"
# 실수로 커밋했는지 확인 (출력되면 즉시 폐기·재발급)
git grep -n "AIza" || echo "no key string in repo (good)"
키가 유출되면 AI Studio에서 폐기하고 새로 만듭니다. 무료라도 남이 내 한도를 다 쓰면 내 사이드 프로젝트가 종일 429를 맞습니다. 배포 환경(버셀·클라우드 런 등)에는 대시보드 시크릿으로만 넣고, 클라이언트 번들에는 절대 넣지 마세요.
제미나이 무료 API 키는 AI 스튜디오에서 발급하고 환경 변수로만 주입한다
2단계 | curl로 첫 호출 스모크 테스트
SDK를 깔기 전에 curl 한 방으로 “키·모델·네트워크”를 검증합니다. 여기서 실패하면 앱 코드 버그가 아니라 키나 모델명 문제입니다.
curl 스모크 테스트 (generateContent)
curl -sS "https://generativelanguage.googleapis.com/v1beta/models/gemini-2.5-flash:generateContent" \
-H "Content-Type: application/json" \
-H "x-goog-api-key: ${GEMINI_API_KEY}" \
-d '{
"contents": [{
"parts": [{ "text": "한 문장으로 자기소개해 줘" }]
}]
}' | head -c 800
# 기대: candidates[0].content.parts[0].text 가 보이는 JSON
# 401/403 → 키·권한 확인
# 404 → 모델 ID 가 계정·시점에 없음 (목록에서 다시 고르기)
# 429 → 한도 초과 (잠시 대기 또는 모델 변경)
응답 JSON이 길면 jq로 텍스트만 뽑을 수 있습니다. 엔드포인트·필드명은 SDK 버전에 따라 감싸져 있을 수 있으니, 공식 Quickstart와 맞춰 보세요. 스모크가 통과하면 이제 앱 코드로 옮깁니다.
3단계 | Node SDK로 앱에 붙이기
구글이 권장하는 최신 클라이언트 패키지명을 문서에서 확인한 뒤 설치합니다. 아래는 “키가 살아 있는지 + 텍스트 한 줄”을 확인하는 최소 예입니다. 패키지·API 표면은 업데이트될 수 있으니, 설치 직후 공식 예제와 한 번 대조하세요.
Node 최소 호출 (@google/genai 예시)
// npm i @google/genai
import { GoogleGenAI } from '@google/genai';
const ai = new GoogleGenAI({ apiKey: process.env.GEMINI_API_KEY });
export async function draftOneLine(prompt) {
if (!process.env.GEMINI_API_KEY) {
throw new Error('GEMINI_API_KEY missing');
}
const res = await ai.models.generateContent({
model: 'gemini-2.5-flash',
contents: prompt,
});
const text = res.text ?? '';
if (!text) throw new Error('empty model response');
return text.trim();
}
// node --env-file=.env.local scripts/smoke-gemini.mjs
console.log(await draftOneLine('사이드 프로젝트 소개 문장 하나'));
프로덕션에서는 모델 ID를 상수로 고정하고, 프롬프트 길이 상한·타임아웃·사용자 입력 검증을 붙입니다. 프론트엔드에서 직접 호출하면 키가 노출되므로, Next.js라면 Route Handler·서버 액션 뒤에서만 호출하세요.
Next.js Route Handler 스케치 (서버 전용)
// app/api/draft/route.js (서버에서만 실행)
import { NextResponse } from 'next/server';
import { draftOneLine } from '@/lib/gemini';
export async function POST(req) {
const body = await req.json().catch(() => ({}));
const prompt = String(body.prompt || '').slice(0, 2000);
if (!prompt) {
return NextResponse.json({ error: 'prompt required' }, { status: 400 });
}
try {
const text = await draftOneLine(prompt);
return NextResponse.json({ text });
} catch (e) {
const msg = e?.message || 'upstream error';
const status = /429|RESOURCE_EXHAUSTED/i.test(msg) ? 429 : 502;
return NextResponse.json({ error: msg }, { status });
}
}
curl 스모크 통과 후 SDK·Route Handler 순으로 붙이면 디버깅이 쉽다
4단계 | 무료 티어 한도 읽는 법 (RPM·TPM·RPD)
한도는 보통 세 갈래로 잡힙니다. 하나라도 넘으면 429입니다.
RPM — 분당 요청 수. 에이전트 루프·병렬 호출에서 먼저 터짐.
TPM — 분당 입력 토큰. 긴 문서 요약·대량 컨텍스트에서 터짐.
RPD — 일일 요청 수. 자정(태평양 시간 기준 리셋이 문서에 명시) 전후로 소진·회복.
블로그에 박힌 “Flash 15 RPM” 같은 숫자를 외우지 마세요. 모델·사용 티어·계정 상태에 따라 다르고, 프리뷰 모델은 더 빡센 경우가 많습니다. Rate Limit 대시보드에서 프로젝트·모델을 고른 뒤 표를 캡처해 배포 체크리스트에 붙이는 편이 안전합니다. 정책 설명은 공식 Rate limits를 기준으로 합니다.
사용 티어
들어가는 조건(요약)
사이드에 의미
Free
활성 프로젝트·무료 시작
카드 없이 프로토타입, 한도 빡셈
Tier 1
결제 계정 연결
한도↑·유료 단가 적용 시작
Tier 2
누적 결제 $100+ 등 조건
트래픽 커질 때
Tier 3
누적 결제 $1,000+ 등 조건
대규모·엔터프라이즈 근접
티어 조건·스펜드 캡 숫자는 공식 문서 표를 그대로 따르고, 승급이 안 되면 계정 리뷰 요인이 있을 수 있다고 문서에 적혀 있습니다. “키를 여러 개”로 무료 한도를 늘리려는 꼼수는 같은 프로젝트면 합산되는 경우가 많아 효과가 없습니다.
사이드 운영 감각 — 내부 도구·하루 수십~수백 호출·응답 캐시가 있으면 무료로 오래 갑니다. 공개 서비스 피크, 에이전트 다단 호출, 이미지·프리뷰 모델 필수는 무료 한도에 빨리 걸립니다. 2주 로그로 RPD 사용률을 보고 결정하세요.
5단계 | 429 대응 백오프와 재시도 상한 코드
무료 티어에서 가장 흔한 운영 장애는 429입니다. 위험은 “에러를 무시하고 즉시 재시도”해서 한도를 더 깎는 패턴입니다. 지수 백오프 + 최대 횟수 + 지터를 기본으로 둡니다.
지수 백오프 with 지터 (429 전용)
function sleep(ms) {
return new Promise((r) => setTimeout(r, ms));
}
function isRateLimited(err) {
const s = String(err?.status || err?.code || err?.message || '');
return /429|RESOURCE_EXHAUSTED|rate.?limit/i.test(s);
}
/** maxAttempts 포함 총 시도 횟수. 429만 재시도. */
export async function withBackoff(fn, { maxAttempts = 4, baseMs = 800 } = {}) {
let last;
for (let attempt = 1; attempt <= maxAttempts; attempt++) {
try {
return await fn();
} catch (err) {
last = err;
if (!isRateLimited(err) || attempt === maxAttempts) throw err;
const exp = baseMs * 2 ** (attempt - 1);
const jitter = Math.floor(Math.random() * 200);
await sleep(exp + jitter);
}
}
throw last;
}
// 사용
// const text = await withBackoff(() => draftOneLine(prompt));
크론·배치가 매분 폭주하면 백오프만으로 부족합니다. 그때는 큐(한 번에 N개), 사용자당 일일 캡, 동일 프롬프트 캐시를 같이 넣습니다. 회로 차단기 패턴이 필요하면 외부 API 회로 차단기 케이스를 참고하세요.
프로세스 내 분당 스로틀 (간단 실습용)
/** 단일 프로세스 한정. 서버리스 다중 인스턴스면 Redis 등으로 공유 필요 */
export function createRpmGate(maxPerMinute = 8) {
const stamps = [];
return async function acquire() {
const now = Date.now();
while (stamps.length && now - stamps[0] > 60_000) stamps.shift();
if (stamps.length >= maxPerMinute) {
const wait = 60_000 - (now - stamps[0]) + 50;
await new Promise((r) => setTimeout(r, wait));
return acquire();
}
stamps.push(Date.now());
};
}
const gate = createRpmGate(8); // AI Studio 표보다 여유 있게
export async function draftSafe(prompt) {
await gate();
return withBackoff(() => draftOneLine(prompt));
}
주의 — 위 스로틀의 8은 예시입니다. 실제 무료 RPM은 모델·계정마다 다릅니다. 대시보드 숫자보다 20~30% 낮게 잡고, 피크 로그를 2주 본 뒤 조정하세요.
6단계 | 일일 예산 카운터와 유료 전환 신호
무료로 버티는 기준은 “아직 429가 안 났다”가 아니라 일일 RPD의 70%를 넘기기 전에 알림이 오는 상태입니다. 간단한 카운터라도 로그에 남기면 전환 시점이 눈에 보입니다.
일일 호출 카운터 (파일 기반 실습)
import fs from 'node:fs';
import path from 'node:path';
const FILE = path.join(process.cwd(), '.data', 'gemini-daily.json');
function todayKey() {
return new Date().toLocaleString('sv-SE', { timeZone: 'Asia/Seoul' }).slice(0, 10);
}
export function bumpDaily(limit = 200) {
fs.mkdirSync(path.dirname(FILE), { recursive: true });
let state = { day: todayKey(), count: 0 };
try {
state = JSON.parse(fs.readFileSync(FILE, 'utf8'));
} catch {}
if (state.day !== todayKey()) state = { day: todayKey(), count: 0 };
state.count += 1;
fs.writeFileSync(FILE, JSON.stringify(state));
const ratio = state.count / limit;
if (ratio >= 0.7) {
console.warn(`[gemini] daily ${state.count}/${limit} (${Math.round(ratio * 100)}%)`);
}
if (state.count > limit) {
const err = new Error('local daily budget exceeded');
err.code = 429;
throw err;
}
return state;
}
유료로 넘길 신호 예시입니다. 체크리스트 전문은 체크리스트 글에 있고, 여기서는 코드 운영 관점만 짚습니다.
2주 연속 피크 시간대 429가 사용자 화면에 노출된다.
로컬·서버 일일 예산 경고(70%)가 평일마다 뜬다.
에이전트 다단 호출로 RPM이 구조적으로 부족하다.
무료 약관상 콘텐츠가 제품 개선에 쓰이는 점이 데이터 정책과 충돌한다 (API Terms).
이미지·고급 모델이 “Free of charge / Not available” 표에서 유료만 허용이다 (Pricing).
일일 사용률 70% 경고를 먼저 두고, 그다음 유료 전환 표를 채운다
7단계 | 유료 전환 손익을 원화·부가세로 잡기
유료 티어로 가면 토큰 단가(USD/1M)가 붙습니다. 단가는 모델마다 다르고 수시로 바뀌므로, 아래는 계산 방법만 고정하고 숫자는 Pricing 표로 덮어쓰세요. 부가세·해외 결제 수수료는 카드·청구 주체에 따라 달라 명세서 1회 실측이 정답에 가깝습니다.
항목
계산
메모
월 입력 비용(USD)
입력 단가 × (월 입력 토큰/1e6)
Pricing 표 기준
월 출력 비용(USD)
출력 단가 × (월 출력 토큰/1e6)
thinking 토큰 포함 여부 확인
원화 환산
USD 합 × 환율
월 1회 환율 고정
부가세·수수료 가정
명세 실측 또는 ×1.1 시나리오
단정 금지, 시나리오만
개발자 API vs Vertex
인증·IAM·청구 구조 비교
MVP는 개발자 API 유료 연동이 단순
골격 예시(반드시 최신 표로 재계산) — Flash-Lite 계열 입력 $0.25·출력 $1.50 / 1M 부근을 가정하고 월 입력 10M·출력 2M이면 대략 $0.25×10 + $1.50×2 = $5.5 전후(USD). 환율 1,400원이면 약 7,700원 수준이고, 부가세·수수료 시나리오를 더하면 달라집니다. 이 숫자는 교육용 골격일 뿐이며, 배포 전 공식 Pricing으로 덮어쓰세요. 배치 API 50% 할인·캐싱 단가도 표에 있으면 별도 열로 빼 둡니다.
AI 스튜디오(개발자 API) 유료와 Vertex 중 선택은 “같은 제미나이 모델”이라도 인증·VPC·감사 로그·청구 단위가 다릅니다. 빠른 MVP·기존 키 코드 유지는 개발자 API 결제 연동, 조직 IAM·규정 준수가 필요하면 Vertex 검토 쪽이 일반적입니다. 전환 케이스 서사는 무료 vs 유료 케이스를 참고하면 됩니다.
주의 — 원화·부가세 예시는 의사결정용 시나리오입니다. 실제 청구는 구글 청구서·카드 명세가 기준입니다. “월 몇 원 확정”처럼 단정하지 말고, 스프레드시트에 단가 조회일을 적어 두세요.
보안·운영 최소 세트 | 키가 새면 한도도 같이 새는 이유
무료라서 느슨해지기 쉬운 부분입니다. 키 하나 유출되면 한도 소진·악의 호출·계정 제재로 이어질 수 있습니다.
서버 사이드에서만 키 사용. 브라우저·모바일 앱 하드코딩 금지.
프론트 노출이 필요하면 백엔드 프록시 + 로그인 + 사용자별 레이트 리밋.
시크릿 로테이션(예: 90일)과 폐기 키 목록 한 줄 문서화.
프롬프트·응답 로그에 PII·결제 정보가 남지 않게 마스킹.
모델 업그레이드 시 회귀 프롬프트 10~20개 고정.
장애 시 폴백 문구·기능 플래그 off 경로를 유료 전환 전에도 동일하게 둠.
실습을 마쳤다면 오늘 한 일을 한 줄로 남기면 충분합니다. “키 발급 → curl 200 → SDK 연결 → Rate Limit 캡처 → 백오프·일일 캡 → 원화 표 초안”. 이 순서가 몸에 붙으면 제미나이 무료 API로 사이드를 돌리는 사고의 대부분이 줄어듭니다.