Model or dataset
zqbxdev/webchat2api avatar
zqbxdev/webchat2api

webchat2api: an OpenAI-compatible proxy for GPT, Grok and Gemini web sessions

OpenAI-compatible Web Chat API proxy with GPT, Grok, Gemini account management and Docker self-hosting

360 stars74 forksPythonMIT

At a glance

What is it?
webchat2api wraps ChatGPT Web, Grok and Gemini web access behind OpenAI-style and Gemini native endpoints, with a Next.js admin console and Docker self-hosting. It is a reverse-engineering project for personal and research use, and its reliability depends on upstream web behaviour it does not control.
Who is it for?
Adopt webchat2api if you want a single self-hosted endpoint in front of several web chat accounts and accept that the upstream web paths it impersonates can change without notice. Do not adopt it for commercial resale, bulk automation, or any workflow that needs a stability guarantee: the README itself restricts it to personal learning and non-commercial technical exchange.
Can I use it commercially?
Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 100 days ago.
What is it written in?
Mainly Python, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on September 15, 2026, and from our analysis. They are not legal advice.

DEEP OPEN-SOURCE ANALYSIS

What webchat2api actually does

The project turns three browser-based chat products into HTTP APIs. GPT/ChatGPT Web, Grok/xAI Web and Gemini Web are wrapped so that a client speaking the OpenAI wire format, or Gemini's native format, can talk to them through one service. The README describes a FastAPI backend, a Next.js admin front end, and provider modules for GPT, Grok and Gemini kept in separate directories under services/providers/.

The audience is narrow and the README says so. Its disclaimer states the project involves reverse research and wrapping of those web capabilities and is intended for personal study, technical research and non-commercial technical exchange. Commercial resale and bulk abuse are explicitly forbidden, and the user carries the risk of account restriction or bans. That is not boilerplate: it tells you the intended deployment is one person or a small group running their own instance, not a reseller platform.

The practical value is that an existing OpenAI SDK client can point at this service instead of the vendor API, and route each request to whichever provider account you have loaded. Whether that is worth the operational overhead depends on how much you value the account pool and the unified endpoint versus simply paying for API access.

How model routing and account selection work

Requests are dispatched by the model name. According to the README, /v1/chat/completions reads the model field and routes the call to a GPT, Grok or Gemini provider account. The /v1/models endpoint pulls GPT models dynamically from an account with provider=gpt, then merges static Grok and Gemini model lists. So the model catalogue you see is partly live and partly hardcoded, which is worth knowing if a model appears or disappears between restarts.

Grok gets a more elaborate path. Grok app-chat supports models that carry a mode_id, and there is a tier-aware selection step: the router matches the tier a model needs (basic, super or heavy) against an account's capabilities, and only falls back to ordinary Grok rotation when nothing matches. If your Grok accounts are all basic and you request a heavy-tier model, the fallback is what you get, not an error.

Provider code is split so that a new model or account field is changed in one provider directory, then checked against services/providers/registry.py, services/account_service.py and web/src/providers/. The README notes that services/models.py remains a compatibility facade for older import paths. That layout is a reasonable boundary, but it also means the model registry and the account service are the two files most likely to break when a provider changes shape.

Image handling is separate from text. Grok image generation uses grok-imagine-image-lite, grok-imagine-image and grok-imagine-image-pro through the app-chat image path, and grok-imagine-image-edit handles edits. The README lists grok-imagine-video as present but not implemented, and says Grok files and voice are not integrated.

Installing webchat2api with Docker and making a first request

The README gives Docker CLI and Docker Compose as the two deployment paths. Clone the repository and build the image locally first, because docker-compose.yml references the local tag webchat2api:latest rather than a registry image.

bash
git clone https://github.com/zqbxdev/webchat2api
cd webchat2api
docker build -t webchat2api:latest .

Run the container with a data volume and a real login secret. The published port is 83, and PORT and HOST are set to match. Do not leave LOGIN_SECRET at admin outside local testing.

bash
docker run -d \
  --name webchat2api \
  --restart unless-stopped \
  -p 83:83 \
  -v $(pwd)/data:/app/data \
  -e PORT=83 \
  -e HOST=0.0.0.0 \
  -e LOGIN_SECRET=your-strong-secret \
  webchat2api:latest

If the container needs to reach a proxy on the host, add the host gateway mapping and PROXY_URL. The README shows port 7890 as the example proxy port.

bash
docker run -d \
  --name webchat2api \
  --restart unless-stopped \
  --add-host=host.docker.internal:host-gateway \
  -p 83:83 \
  -v $(pwd)/data:/app/data \
  -e LOGIN_SECRET=your-strong-secret \
  -e PROXY_URL=http://host.docker.internal:7890 \
  webchat2api:latest

For a smoke test, the README warns against reusing the production container name or the 83:83 mapping when port 83 is already taken. Its suggested pattern is a separate container on 8083:83, then a health check against that port.

bash
docker run --rm -d \
  --name webchat2api-dev \
  -p 8083:83 \
  -v $(pwd)/data-dev:/app/data \
  -e PORT=83 \
  -e HOST=0.0.0.0 \
  -e LOGIN_SECRET=admin \
  webchat2api:dev

curl http://localhost:8083/health

After that, the admin console and the API base URL are both served from the same origin: http://localhost:83 for the UI and http://localhost:83/v1 for OpenAI-compatible clients. The README lists /health, /version and /auth/login as public endpoints, with AI endpoints using Bearer token authentication.

One deployment detail from the Dockerfile matters for debugging. The entrypoint script starts services/browser_bridge/server.js on BRIDGE_PORT, default 3080, probes /health briefly, and then starts FastAPI even if the bridge is not ready. A failed bridge therefore does not stop the service; it silently degrades the Grok browser path.

Storage backends, backups and what persists where

Persistence is configurable and the default is not a database. STORAGE_BACKEND accepts json, sqlite, postgres or git, with json as the default. The SQLite option falls back to data/accounts.db when DATABASE_URL is not set, and the PostgreSQL example in .env.example includes a Supabase pooler URL. The git backend needs GIT_REPO_URL and GIT_TOKEN, with optional GIT_BRANCH and GIT_FILE_PATH defaulting to main and accounts.json.

That spread is a real decision point rather than a detail. Choosing postgres pulls in psycopg2-binary, which is already in the dependency list, but it also means your account data lives outside the ./data volume that the Compose file mounts. Choosing git turns account storage into commits to a remote repository, which changes your threat model for credential material.

Image storage is separate from account storage. The README lists local, WebDAV and dual-write modes, with a WebDAV connectivity test and sync. The image index goes to data/image_index.json and tags to data/image_tags.json, so those two files are part of what you must back up alongside the accounts.

Cloud backup targets Cloudflare R2, on a schedule or manually, with optional openssl AES-256-CBC encryption. The README says the include switches cover configuration, CPA, Sub2API, logs, image tasks, account snapshots, user key snapshots and images. Read those switches before enabling a backup: an account snapshot contains credentials, and the encryption step is optional.

Where webchat2api breaks or is the wrong tool

The failure modes are upstream, and the README is unusually direct about them. Grok protection handling supports manual cf_clearance, FlareSolverr clearance refresh and an optional Browser Bridge path, and the README states these are best-effort and do not guarantee bypassing every Cloudflare or WAF challenge. GPT Turnstile solving is enabled by default through enable_turnstile_solver, which tries to generate a Sentinel Turnstile token when ChatGPT asks for one; the README warns that real GPT Turnstile challenges can still fail.

Account import is stricter than people expect. The README notes that front-end manual and TXT import for Grok accept only a bare SSO value or a single line in the form sso=<value>. Semicolons, a full Cookie header, sso-rw and other cookie key-value pairs are not accepted there, even though API and remote injection paths have their own validation rules. If you paste a copied cookie header into the UI, it will not work, and the failure will look like an authentication problem rather than an input-format problem.

Some features are listed but absent. grok-imagine-video appears in the model list without an implementation, and Grok files and voice are not integrated at all. Treating the model list as a capability list will lead you to request things that cannot succeed.

Finally, the licence and the disclaimer point in different directions. The repository is MIT, but the README restricts use to personal learning, technical research and non-commercial technical exchange and prohibits commercial resale and bulk abuse. MIT governs the code; the disclaimer governs the intended use of the service you build with it. If your plan is to resell access, this is the wrong project regardless of what the licence file permits.

How it compares with a direct provider SDK or a gateway

The obvious alternative is calling the official OpenAI, xAI or Google APIs directly with their SDKs. The difference is not protocol, since webchat2api speaks the OpenAI format anyway, but economics and control. Direct APIs give you a documented contract, rate limits you can plan against, and no Cloudflare or Turnstile layer between you and the model. webchat2api gives you no per-token billing, but in exchange you inherit every anti-automation measure those web front ends deploy, and you are responsible for keeping accounts alive.

The second alternative is a self-hosted LLM gateway such as one that fronts multiple official API keys with routing, retries and usage accounting. Those gateways assume the upstream endpoints are stable and authorised; webchat2api assumes the opposite and spends most of its code on session handling, cookie refresh and challenge solving. If your upstreams are official API keys, a gateway is the better fit and webchat2api adds risk without adding capability.

Within the project itself, the closest comparison is between the OpenAI-style routes and the Gemini native routes. The README lists /gemini/v1beta/models, generateContent, streamGenerateContent, deepresearch, deepresearch/stream and interactions, and says the native layer supports contents/parts/tools/toolConfig/generationConfig plus functionCall and functionResponse conversion. If you are building against Gemini tool calling, using the native routes avoids a lossy translation through the OpenAI schema. Clients that only speak OpenAI should stay on /v1.

Maintenance, versioning and licence cost

The last push to the repository was on 2026-06-07, and the repository is not archived. There are no retrieved releases, and versioning comes from the VERSION file, which the Docker build passes into the front end as NEXT_PUBLIC_APP_VERSION. pyproject.toml declares version 0.0.11, so expect pre-1.0 churn rather than a stable API contract.

The dependency set tells you what you are maintaining. Python 3.13 or newer is required, with curl-cffi for TLS impersonation, fastapi, uvicorn, sqlalchemy, psycopg2-binary, tiktoken, pillow and gitpython. The Docker image also installs Chromium, Node.js and npm for the Grok Browser Bridge, and builds the Next.js front end in a separate stage. That is a heavy image and a large surface to keep patched.

Upgrade cost is concentrated in the provider directories. The README instructs maintainers to change the relevant provider module first, then check services/providers/registry.py, services/account_service.py and web/src/providers/ for knock-on effects. Any upstream change to ChatGPT Web, Grok app-chat or Gemini Web can invalidate the request shapes those modules encode, and nothing in the repository can prevent that.

On licensing, the code is MIT, which permits modification and redistribution under its terms. The README's disclaimer adds use restrictions that MIT does not impose, and the two are not automatically reconciled. That is a question for your own legal review rather than something this article can settle.

Editorial conclusion

Adopt webchat2api if you want a single self-hosted endpoint in front of several web chat accounts and accept that the upstream web paths it impersonates can change without notice. Do not adopt it for commercial resale, bulk automation, or any workflow that needs a stability guarantee: the README itself restricts it to personal learning and non-commercial technical exchange. Before wiring anything to it, verify three things: that STORAGE_BACKEND matches the persistence you actually want, that LOGIN_SECRET or WEBCHAT2API_AUTH_KEY is set to a strong random value instead of the default admin, and that your GPT and Grok accounts can complete a request through the account pool without tripping Turnstile or a Cloudflare challenge.

Frequently asked questions

What is webchat2api and who is it for?

It is a proxy service that wraps GPT/ChatGPT Web, Grok/xAI Web and Gemini Web behind OpenAI-style and Gemini native HTTP APIs, with a FastAPI backend and a Next.js admin console. The README states it is intended for personal learning, technical research and non-commercial technical exchange.

How do I install webchat2api with Docker?

The README's quick start clones the repository, builds the image with docker build -t webchat2api:latest ., then runs it with a ./data volume, PORT=83, HOST=0.0.0.0 and a LOGIN_SECRET. Docker Compose is offered as an alternative, using the same locally built image tag.

What is the default login secret in webchat2api?

The default is admin, and the README says it is only suitable for local testing. For any public or production deployment you must change it through LOGIN_SECRET or the legacy WEBCHAT2API_AUTH_KEY variable.

Which models can webchat2api serve?

It routes by model name across GPT, Grok and Gemini provider accounts. /v1/models pulls GPT models dynamically from a provider=gpt account and merges static Grok and Gemini lists, and Grok app-chat models that carry a mode_id are matched against account tiers.

Does webchat2api bypass Cloudflare and Turnstile challenges?

No guarantee is given. The README describes manual cf_clearance, FlareSolverr refresh and the Browser Bridge as best-effort, and says real GPT Turnstile challenges can still fail even though enable_turnstile_solver is on by default.

What storage backends does webchat2api support?

STORAGE_BACKEND accepts json, sqlite, postgres or git, with json as the default. SQLite falls back to data/accounts.db, and the git backend requires GIT_REPO_URL and GIT_TOKEN.

Official sources

  1. Issues
  2. License: MIT
  3. README
  4. zqbxdev/webchat2api on GitHub
Community notes

Community notes