Gemini 3.1 Pro の登場により、generativelanguage.googleapis.com エンドポイントは大幅なアップデートを受けています。SDK を使わず REST API を直接呼び出したい場面は意外と多く、サーバーレス環境・軽量スクリプト・言語を選ばない連携など、直接アクセスの需要は依然として高いです。
1. モデル名とエンドポイントの確認
Gemini 3.1 Pro を REST API で利用するときのモデル識別子は以下の通りです。
- 安定版:
gemini-3.1-pro - 最新エイリアス:
gemini-3.1-pro-latest(常に最新マイナーバージョンを指す) - プレビュー版:
gemini-3.1-pro-exp
ベース URL は変わらず https://generativelanguage.googleapis.com/v1beta/ です。
POST https://generativelanguage.googleapis.com/v1beta/models/{モデル名}:generateContent
v1beta は 2026 年 4 月現在も Gemini 最新機能(思考、Function Calling、マルチモーダル等)を含む実質的なメイン API バージョンです。v1 は安定版ですが、最新モデルの一部機能が使えないことがあるため、開発中は v1beta を推奨します。
2. API キーの取得と認証
API キー方式(個人開発・プロトタイプ向け)
Google AI Studio にアクセスして「API キーを作成」から取得します。取得したキーは環境変数に保存してください。
export GEMINI_API_KEY="YOUR_GEMINI_API_KEY"リクエスト時はクエリパラメータまたは x-goog-api-key ヘッダーで渡します。
# クエリパラメータ方式
POST .../generateContent?key=${GEMINI_API_KEY}
# ヘッダー方式(推奨)
-H "x-goog-api-key: ${GEMINI_API_KEY}"OAuth / サービスアカウント方式(本番環境向け)
本番環境では API キーの代わりに Google サービスアカウントの OAuth 2.0 アクセストークンを使います。Vertex AI と共通の認証フローになりますが、generativelanguage.googleapis.com の直接アクセスでも Bearer トークンは利用可能です。
ACCESS_TOKEN=$(gcloud auth print-access-token)
# または
ACCESS_TOKEN=$(gcloud auth application-default print-access-token)3. curl でまず試してみる
最もシンプルなテキスト生成リクエストです。
curl -s -X POST \
"https://generativelanguage.googleapis.com/v1beta/models/gemini-3.1-pro:generateContent" \
-H "x-goog-api-key: ${GEMINI_API_KEY}" \
-H "Content-Type: application/json" \
-d '{
"contents": [
{
"parts": [{"text": "Pythonのリスト内包表記を3行で説明してください。"}]
}
]
}'レスポンスは JSON 形式で返ります。
{
"candidates": [
{
"content": {
"parts": [{"text": "リスト内包表記は..."}],
"role": "model"
},
"finishReason": "STOP",
"index": 0
}
],
"usageMetadata": {
"promptTokenCount": 18,
"candidatesTokenCount": 142,
"totalTokenCount": 160
}
}candidates[0].content.parts[0].text に生成テキストが入っています。usageMetadata でトークン使用量を確認できるのでコスト管理に活用しましょう。
4. Python requests でテキスト生成
import os
import requests
import json
API_KEY = os.environ.get("GEMINI_API_KEY")
BASE_URL = "https://generativelanguage.googleapis.com/v1beta"
MODEL = "gemini-3.1-pro"
def generate_text(prompt: str, system_instruction: str = None) -> str:
"""Gemini 3.1 Pro でテキストを生成する"""
url = f"{BASE_URL}/models/{MODEL}:generateContent"
headers = {
"x-goog-api-key": API_KEY,
"Content-Type": "application/json",
}
payload = {
"contents": [
{"role": "user", "parts": [{"text": prompt}]}
],
"generationConfig": {
"temperature": 0.7,
"topP": 0.95,
"maxOutputTokens": 2048,
},
}
# システム指示(オプション)
if system_instruction:
payload["systemInstruction"] = {
"parts": [{"text": system_instruction}]
}
response = requests.post(url, headers=headers, json=payload, timeout=60)
response.raise_for_status()
data = response.json()
return data["candidates"][0]["content"]["parts"][0]["text"]
if __name__ == "__main__":
result = generate_text(
prompt="FastAPI と Django の違いを初心者向けに説明してください。",
system_instruction="あなたは経験豊富なバックエンドエンジニアです。技術的に正確かつ初心者にも優しい説明をしてください。"
)
print(result)
# 期待する出力例:
# FastAPI は ASGI ベースの軽量フレームワークで、型ヒントを活用した自動ドキュメント生成が特徴です...5. マルチターンチャット(会話履歴の管理)
REST API では会話履歴をクライアント側で保持してリクエストに含めます。
import os
import requests
API_KEY = os.environ.get("GEMINI_API_KEY")
BASE_URL = "https://generativelanguage.googleapis.com/v1beta"
MODEL = "gemini-3.1-pro"
class GeminiChat:
"""マルチターンチャットクラス(会話履歴を自動管理)"""
def __init__(self, system_instruction: str = None):
self.history = []
self.system_instruction = system_instruction
self.url = f"{BASE_URL}/models/{MODEL}:generateContent"
self.headers = {
"x-goog-api-key": API_KEY,
"Content-Type": "application/json",
}
def send_message(self, user_message: str) -> str:
# ユーザーメッセージを履歴に追加
self.history.append({
"role": "user",
"parts": [{"text": user_message}]
})
payload = {"contents": self.history}
if self.system_instruction:
payload["systemInstruction"] = {
"parts": [{"text": self.system_instruction}]
}
response = requests.post(
self.url, headers=self.headers, json=payload, timeout=60
)
response.raise_for_status()
data = response.json()
model_reply = data["candidates"][0]["content"]["parts"][0]["text"]
# モデルの返答を履歴に追加
self.history.append({
"role": "model",
"parts": [{"text": model_reply}]
})
return model_reply
# 使用例
chat = GeminiChat(system_instruction="あなたは Python チューターです。")
print(chat.send_message("変数の型変換を教えてください"))
print(chat.send_message("では int と float の違いは?"))
# 期待する出力例:
# 変数の型変換には int(), float(), str() などの関数を使います...
# int は整数(小数点なし)で、float は浮動小数点数(小数点あり)です...6. ストリーミングレスポンス
長い回答を待つ体験を改善するため、ストリーミングモードを使いましょう。
import os
import requests
import json
API_KEY = os.environ.get("GEMINI_API_KEY")
BASE_URL = "https://generativelanguage.googleapis.com/v1beta"
MODEL = "gemini-3.1-pro"
def stream_generate(prompt: str):
"""ストリーミングでテキストを生成する(チャンクごとに出力)"""
url = f"{BASE_URL}/models/{MODEL}:streamGenerateContent?alt=sse"
headers = {
"x-goog-api-key": API_KEY,
"Content-Type": "application/json",
}
payload = {
"contents": [{"role": "user", "parts": [{"text": prompt}]}],
"generationConfig": {"maxOutputTokens": 4096},
}
with requests.post(url, headers=headers, json=payload,
stream=True, timeout=120) as response:
response.raise_for_status()
for line in response.iter_lines():
if line and line.startswith(b"data: "):
data_str = line[6:].decode("utf-8")
if data_str == "[DONE]":
break
try:
chunk = json.loads(data_str)
parts = chunk.get("candidates", [{}])[0].get(
"content", {}).get("parts", [])
for part in parts:
if "text" in part:
print(part["text"], end="", flush=True)
except json.JSONDecodeError:
pass
print() # 改行
if __name__ == "__main__":
stream_generate("Pythonで簡単なWebスクレイパーを作る方法を説明してください")
# 期待する動作:
# テキストがリアルタイムに少しずつ出力される(SSE ストリーミング)streamGenerateContent エンドポイントに ?alt=sse を付けることで Server-Sent Events 形式で受け取れます。
7. JavaScript / fetch でのリクエスト
Node.js や Deno からも fetch API で簡単にアクセスできます。
const API_KEY = process.env.GEMINI_API_KEY;
const MODEL = "gemini-3.1-pro";
const BASE_URL = "https://generativelanguage.googleapis.com/v1beta";
async function generateContent(prompt) {
const url = `${BASE_URL}/models/${MODEL}:generateContent`;
const response = await fetch(url, {
method: "POST",
headers: {
"x-goog-api-key": API_KEY,
"Content-Type": "application/json",
},
body: JSON.stringify({
contents: [{ role: "user", parts: [{ text: prompt }] }],
generationConfig: {
temperature: 0.8,
maxOutputTokens: 1024,
},
}),
});
if (\!response.ok) {
const error = await response.json();
throw new Error(`API Error: ${response.status} — ${JSON.stringify(error)}`);
}
const data = await response.json();
return data.candidates[0].content.parts[0].text;
}
// 使用例
generateContent("TypeScript の型ガードとは何ですか?")
.then(console.log)
.catch(console.error);
// 期待する出力例:
// 型ガードとは、TypeScript においてある変数が特定の型であることを...8. よくあるエラーと対処法
400 Bad Request — INVALID_ARGUMENT
フロントマターの contents 配列の構造が正しくない場合に起きます。role は "user" か "model" のみで、"system" は無効です。システム指示は systemInstruction フィールドを使います。
403 Forbidden — API key not valid
API キーが正しくないか、対象プロジェクトで Generative Language API が有効になっていない場合です。Google Cloud Console でAPIを有効化してください。
429 Resource Exhausted — RATE_LIMIT_EXCEEDED
無料枠(Free Tier)では 1 分あたりのリクエスト数に制限があります。指数バックオフでリトライするか、有料プランへの移行を検討してください。
import time
def generate_with_retry(prompt, max_retries=3):
for attempt in range(max_retries):
try:
return generate_text(prompt)
except requests.HTTPError as e:
if e.response.status_code == 429:
wait_time = 2 ** attempt # 1, 2, 4 秒
print(f"Rate limit hit. Retrying in {wait_time}s...")
time.sleep(wait_time)
else:
raise
raise Exception("Max retries exceeded")500 Internal Server Error
一時的なサーバー側の問題です。数秒待ってリトライしてください。
9. generationConfig で出力を制御する
"generationConfig": {
"temperature": 0.7, // 0.0〜2.0(低いほど決定論的)
"topP": 0.95, // nucleus sampling
"topK": 40, // top-k sampling
"maxOutputTokens": 8192, // 最大出力トークン数
"stopSequences": ["---"], // この文字列が出たら停止
"candidateCount": 1, // 生成する候補数(1がデフォルト)
"responseMimeType": "application/json" // JSON出力を強制
}responseMimeType: "application/json" を指定すると、Gemini は JSON として整形されたレスポンスを返そうとします(response_schema と組み合わせてさらに厳密な制御が可能です)。
全体を振り返って
Gemini 3.1 Pro の REST API は、SDK を使わなくても curl や requests/fetch の数十行で強力な AI 機能をアプリに組み込めます。今回紹介したポイントをまとめます。
- エンドポイントは
https://generativelanguage.googleapis.com/v1beta/models/gemini-3.1-pro:generateContent - 認証は
x-goog-api-keyヘッダーが最もシンプル - 会話履歴はクライアント側で
contents配列として保持する - ストリーミングは
streamGenerateContent?alt=sseで対応 - 429 エラーは指数バックオフでリトライ
さらに高度な活用(Function Calling・構造化出力・Context Caching など)に興味がある方には、より深い実装手法を体系的に解説した Gemini 3.1 Pro カスタムツール・エージェント実践ガイド もぜひご覧ください。