Gitpedia

Gemini web2api

Convert Google Gemini web into OpenAI-compatible API. Zero auth, cross-platform, single file.

From Sophomoresty·Updated May 31, 2026·View on GitHub·

Convert Google Gemini's web interface into an OpenAI-compatible API. Zero authentication, zero cost, cross-platform. The project is written primarily in Python, distributed under the MIT License license, first published in 2026.

gemini-web2api

<p align="center"> <img src="logo.png" width="200" alt="gemini-web2api logo"> </p>

中文文档

Convert Google Gemini's web interface into an OpenAI-compatible API. Zero authentication, zero cost, cross-platform.

Features

  • Optional API Keys: no auth when api_keys is empty, OpenAI-style Bearer auth when configured
  • OpenAI Compatible: Drop-in replacement for /v1/chat/completions and /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=N suffix (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

Quick Start

bash
python gemini_web2api.py

Server starts at http://localhost:8081/v1.

Client Configuration

Cherry Studio / ChatBox / any OpenAI client

FieldValue
Base URLhttp://localhost:8081/v1
API Keyany api_keys value from config.json; anything if not configured
Modelgemini-3.5-flash-thinking

curl

bash
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!"}]}'

OpenAI Python SDK

python
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)

Gemini CLI

bash
export GEMINI_API_KEY=none export GOOGLE_GEMINI_BASE_URL=http://localhost:8081 gemini

Supports Google native API endpoints:

  • GET /v1beta/models — list models
  • POST /v1beta/models/{model}:generateContent — non-streaming
  • POST /v1beta/models/{model}:streamGenerateContent — streaming (SSE)

Available Models

ModelDescriptionOutput
gemini-3.5-flashFast general-purpose~12k chars
gemini-3.5-flash-thinkingDeep thinking, longest output~20k chars
gemini-3.5-flash-thinking-liteAdaptive thinking depth~15k chars
gemini-3.1-proPro (needs cookie for real routing)~12k chars
gemini-autoAuto model selectionvaries
gemini-flash-liteLightweight fast~10k chars

Thinking Depth

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:

bash
python gemini_web2api.py --cookie-file cookie.txt

How to get cookies

  1. Open Chrome, go to gemini.google.com and sign in with any free Google account
  2. Open DevTools (F12) → Application → Cookies → https://gemini.google.com
  3. Copy these cookie values: SID, HSID, SSID, APISID, SAPISID, __Secure-1PSID
  4. Create cookie.txt in 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:

json
{"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.

Authenticated account path and XSRF token

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:

json
{ "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.

Configuration

Create config.json in the same directory:

json
{ "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>.

Docker

bash
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-web2api

Or use Docker Compose:

bash
cp config.example.json config.json docker compose up -d

To mount a cookie file:

bash
docker run -d --name gemini-web2api -p 8081:8081 -v ./config.json:/app/config.json -v ./cookie.txt:/app/cookie.txt gemini-web2api

Set "cookie_file": "/app/cookie.txt" in config.json.

Proxy

If you cannot access gemini.google.com directly (connection timeout), configure a proxy:

Method 1: CLI argument

bash
python gemini_web2api.py --proxy http://127.0.0.1:7890

Method 2: config.json

json
{"proxy": "http://127.0.0.1:7890"}

Method 3: Environment variable (auto-detected)

bash
export HTTPS_PROXY=http://127.0.0.1:7890 python gemini_web2api.py

Works with Clash, V2Ray, Shadowsocks, or any HTTP proxy.

Tool Calling

python
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"]} } }] )

Limitations

  • 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-pro routes 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.

Requirements

  • Python 3.8+
  • No external dependencies (stdlib only)
  • Network access to gemini.google.com (proxy/VPN may be needed in some regions)

How It Works

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).

Acknowledgments

  • Inspired by the open-source API proxy ecosystem

License

MIT


致谢

本项目的开发 agent 能力由 GenericAgent 提供。

🚩 友情链接

GenericAgent
LinuxDo

Contributors

Showing top 4 contributors by commit count.

View all contributors on GitHub →

This article is auto-generated from Sophomoresty/gemini-web2api via the GitHub API.Last fetched: 5/31/2026