Convert Google Gemini's web interface into an OpenAI-compatible API. Zero authentication, zero cost, cross-platform.
Important status notice: Due to recent Gemini Web updates, the web reverse-proxy approach used by this project is currently unavailable. The usage instructions below are kept for historical and technical reference only, and may not work unless the project is adapted to Gemini's updated web protocol.
- Optional API Keys: no auth when
api_keysis empty, OpenAI-style Bearer auth when configured - OpenAI Compatible: Drop-in replacement for
/v1/chat/completionsand/v1/models - Tool Calling: Full function calling support (OpenAI format)
- Multiple Models: Flash, Flash Thinking (20k+ char output), Pro, Auto, Lite
- Thinking Depth: Adjustable via
@think=Nsuffix (0=deepest, 4=shallowest) - Web Search: Built-in internet access (Gemini's native search)
- Cross-Platform: Pure Python, no dependencies beyond stdlib
- Streaming: SSE streaming support
- Codex CLI: Responses API (
/v1/responses) for OpenAI Codex integration - Gemini CLI: Google native API (
/v1beta/models) for Gemini CLI compatibility
python gemini_web2api.pyServer starts at http://localhost:8081/v1.
| Field | Value |
|---|---|
| Base URL | http://localhost:8081/v1 |
| API Key | any api_keys value from config.json; anything if not configured |
| Model | gemini-3.5-flash-thinking |
curl http://localhost:8081/v1/chat/completions \
-H "Content-Type: application/json" \
-H "Authorization: Bearer sk-your-key" \
-d '{"model":"gemini-3.5-flash","messages":[{"role":"user","content":"Hello!"}]}'from openai import OpenAI
client = OpenAI(base_url="http://localhost:8081/v1", api_key="sk-your-key")
resp = client.chat.completions.create(
model="gemini-3.5-flash-thinking",
messages=[{"role": "user", "content": "Explain quantum computing"}]
)
print(resp.choices[0].message.content)export GEMINI_API_KEY=none
export GOOGLE_GEMINI_BASE_URL=http://localhost:8081
geminiSupports Google native API endpoints:
GET /v1beta/models— list modelsPOST /v1beta/models/{model}:generateContent— non-streamingPOST /v1beta/models/{model}:streamGenerateContent— streaming (SSE)
| Model | Description | Output |
|---|---|---|
gemini-3.5-flash |
Fast general-purpose | ~12k chars |
gemini-3.5-flash-thinking |
Deep thinking, longest output | ~20k chars |
gemini-3.5-flash-thinking-lite |
Adaptive thinking depth | ~15k chars |
gemini-3.1-pro |
Pro (needs cookie for real routing) | ~12k chars |
gemini-auto |
Auto model selection | varies |
gemini-flash-lite |
Lightweight fast | ~10k chars |
Append @think=N to any model name:
gemini-3.5-flash-thinking@think=0 # deepest (default)
gemini-3.5-flash-thinking@think=2 # medium
gemini-3.5-flash-thinking@think=4 # shallowest
Anonymous access works for all models, but gemini-3.1-pro routes to Flash without authentication. To get real Pro routing, provide a cookie file:
python gemini_web2api.py --cookie-file cookie.txt- Open Chrome, go to gemini.google.com and sign in with any free Google account
- Open DevTools (F12) → Application → Cookies →
https://gemini.google.com - Copy these cookie values:
SID,HSID,SSID,APISID,SAPISID,__Secure-1PSID - Create
cookie.txtin this format:
SID=your_sid_value; HSID=your_hsid_value; SSID=your_ssid_value; APISID=your_apisid_value; SAPISID=your_sapisid_value; __Secure-1PSID=your_1psid_value
Or use the JSON format:
{"cookie": "SID=xxx; HSID=xxx; SSID=xxx; APISID=xxx; SAPISID=xxx; __Secure-1PSID=xxx", "sapisid": "your_sapisid_value"}Alternative (browser extension): Use any "Export Cookies" extension to export cookies for gemini.google.com in Netscape format, then convert to the single-line format above.
If the signed-in Gemini page URL contains an account index, such as:
https://gemini.google.com/u/1/app/...
set auth_user to that index. Authenticated web requests may also require the page XSRF token. In the rendered Gemini page source, this token is exposed as SNlM0e; pass it as xsrf_token in config.json. The server sends it as the at form field.
Example:
{
"cookie_file": "/app/cookie.txt",
"auth_user": "1",
"xsrf_token": "AOOh0P...",
"gemini_bl": "boq_assistant-bard-web-server_YYYYMMDD.xx_p0"
}If authenticated requests return HTTP 400 with an xsrf error, refresh Gemini Web, update xsrf_token, and make sure auth_user matches the /u/<index>/ part of the browser URL.
No paid subscription needed — a free Google account is sufficient.
Create config.json in the same directory:
{
"port": 8081,
"host": "0.0.0.0",
"retry_attempts": 3,
"retry_delay_sec": 2,
"request_timeout_sec": 180,
"gemini_bl": "boq_assistant-bard-web-server_20260525.09_p0",
"auth_user": null,
"xsrf_token": null,
"api_keys": ["sk-your-key"],
"cookie_file": null,
"proxy": null,
"log_requests": true
}When api_keys is [], authentication is disabled. When one or more keys are set, /v1/* endpoints require Authorization: Bearer <key> or x-api-key: <key>.
cp config.example.json config.json
docker build -t gemini-web2api .
docker run -d --name gemini-web2api -p 8081:8081 -v ./config.json:/app/config.json gemini-web2apiOr use Docker Compose:
cp config.example.json config.json
docker compose up -dTo mount a cookie file:
docker run -d --name gemini-web2api -p 8081:8081 -v ./config.json:/app/config.json -v ./cookie.txt:/app/cookie.txt gemini-web2apiSet "cookie_file": "/app/cookie.txt" in config.json.
If you cannot access gemini.google.com directly (connection timeout), configure a proxy:
Method 1: CLI argument
python gemini_web2api.py --proxy http://127.0.0.1:7890Method 2: config.json
{"proxy": "http://127.0.0.1:7890"}Method 3: Environment variable (auto-detected)
export HTTPS_PROXY=http://127.0.0.1:7890
python gemini_web2api.pyWorks with Clash, V2Ray, Shadowsocks, or any HTTP proxy.
resp = client.chat.completions.create(
model="gemini-3.5-flash",
messages=[{"role": "user", "content": "What's the weather in Tokyo?"}],
tools=[{
"type": "function",
"function": {
"name": "get_weather",
"description": "Get weather for a city",
"parameters": {"type": "object", "properties": {"city": {"type": "string"}}, "required": ["city"]}
}
}]
)- No image/multimodal input: Gemini's image upload requires a proprietary streaming RPC protocol (WIZ/ProcessFile) that cannot be replicated in a standard HTTP proxy. Image inputs in messages will be ignored with a note.
- Not real Pro/Ultra: Without a paid subscription cookie,
gemini-3.1-proroutes to the same Flash model. The "Pro" label is a UI preference, not a backend model switch. - Single-turn only: Each request is an independent conversation. Multi-turn context is simulated by including previous messages in the prompt.
- Rate limits: Google may throttle high-frequency requests. The server retries automatically but sustained heavy use may be blocked.
- Python 3.8+
- No external dependencies (stdlib only)
- Network access to
gemini.google.com(proxy/VPN may be needed in some regions)
This tool reverse-engineers Google Gemini's web StreamGenerate protocol. It sends requests to the same endpoint that the Gemini web app uses, converting between OpenAI's API format and Gemini's internal protobuf-like format.
The model selection is controlled by field [79] in the request payload, mapped from Gemini's frontend JavaScript source (MODE_CATEGORY enum).
- Inspired by the open-source API proxy ecosystem
This project is an unofficial personal project created for learning, research, and technical exploration only. It is not affiliated with, endorsed by, or sponsored by Google, Gemini, OpenAI, or any related organization.
This project attempts to convert Gemini Web behavior into an API-compatible interface. Because it depends on undocumented web endpoints and reverse-engineered behavior, it may stop working at any time when Gemini changes its frontend, backend protocol, authentication flow, rate limits, or access policies. Users should not rely on this project for production or commercial use.
Users are responsible for complying with all applicable laws, service terms, platform policies, and academic or organizational rules. Do not use this project for abuse, unauthorized access, commercial resale, policy circumvention, or improper academic conduct.
If any content in this repository is inappropriate for public sharing or infringes the rights of any party, please contact the maintainer and it will be removed or modified as soon as possible.
MIT
本项目的开发 agent 能力由 GenericAgent 提供。
