Skip to content

aoyukkk/gemini-web2api

 
 

Repository files navigation

gemini-web2api

gemini-web2api logo

中文文档

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.

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

python gemini_web2api.py

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

Client Configuration

Cherry Studio / ChatBox / any OpenAI client

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

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

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

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

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

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

Optional: Cookie for Pro

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

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:

{"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:

{
  "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:

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

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:

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

To 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-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

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

Method 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.py

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

Tool Calling

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

Disclaimer

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.

License

MIT


致谢

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

🚩 友情链接

GenericAgent LinuxDo

About

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

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages

  • Python 99.7%
  • Dockerfile 0.3%