Self-hosted service
TQZHR/grok2api avatar
TQZHR/grok2api

grok2api and the three deployment shapes of a web API proxy

Grok2API (Cloudflare Workers) one-click deploy with auto D1+KV provisioning

705 stars918 forksPythonMIT

At a glance

What is it?
grok2api exposes the Grok web interface as a FastAPI service with streaming chat, image generation and a token pool, and this fork adds a Cloudflare Workers and Pages variant backed by D1 and KV. The interesting engineering is that one management surface has to behave identically across local Python, Docker and a TypeScript Worker, and the interesting constraint is that everything runs on session tokens rather than an official API key.
Who is it for?
grok2api is a good fit for a developer who wants an OpenAI-shaped endpoint in front of the Grok web interface and is willing to maintain the token pool, since the local FastAPI, Docker and Cloudflare Workers builds share one management surface and the same environment variables.
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?
Activity is slowing. The repository last received commits 6 months 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 October 23, 2026, and from our analysis. They are not legal advice.

Editorial analysis

A web interface repackaged as a REST API

grok2api is a FastAPI rework of chenyme/grok2api, and this repository is a secondary modification and enhancement of that project. The README states the scope: it is fully adapted to the latest web call format, supports streaming and non-streaming conversation, image generation and editing, and deep thinking, and it combines a token pool with concurrent use and automatic load balancing.

The architecture is worth understanding before the feature list, because it explains most of the design decisions. The core is FastAPI, and the repository runs as a local Python service, as a Docker container, or as a Cloudflare Workers and Pages deployment written in TypeScript. The Cloudflare variant uses D1 and KV and is described as suitable for running on Cloudflare and proxying outbound traffic, with its own deploy and configuration guide in README.cloudflare.md and a one-click deploy workflow in .github/workflows/cloudflare-workers.yml. The workflow needs two repository secrets, CLOUDFLARE_API_TOKEN and CLOUDFLARE_ACCOUNT_ID.

The dependency list in pyproject.toml gives a good picture of the Python side. Beyond fastapi and uvicorn, there is httpx and curl-cffi for outbound HTTP, sqlalchemy with asyncpg, aiomysql and redis for storage, orjson and pydantic-settings for serialisation and settings, loguru for logging, and beautifulsoup4, which is a fair signal that some responses are parsed as HTML. The Cloudflare side is much smaller, with hono as the only runtime dependency and wrangler and typescript as dev tools.

The licence is MIT, and the repository is not archived, with the last push on 2026-04-18.

Running it locally, in Docker, or on Cloudflare

The README gives three ways to start the project, and the local one is the shortest.

For local development, the flow is a uv sync to install the locked dependencies, then the entry point:

bash
uv sync
uv run main.py

An optional self-check follows, which calls the health endpoint of a running instance:

bash
python scripts/smoke_test.py --base-url http://127.0.0.1:8000

The Docker path clones the repository and brings up the compose stack, which by default pulls a prebuilt image from GHCR:

bash
git clone https://github.com/TQZHR/grok2api.git
cd grok2api
docker compose up -d

Updating is a pull followed by an up, and there is a separate compose file for building from the current source instead:

bash
docker compose pull
docker compose up -d
docker compose -f docker-compose.yml -f docker-compose.build.yml up -d --build

One-click deploy scripts exist for both Windows and WSL, as pwsh and bash variants of scripts/deploy-docker.ps1 and scripts/deploy-docker.sh, with the same pair for the Cloudflare variant.

The compose file itself is instructive. The main service runs the image with the host port and the container port both defaulting to 8000, and it accepts a long list of environment variables with defaults, including SERVER_HOST, SERVER_PORT, SERVER_WORKERS, SERVER_STORAGE_TYPE and SERVER_STORAGE_URL, plus a STORAGE_WAIT_TIMEOUT. It mounts ./data and ./logs, sets a one gigabyte shared memory size, and carries a healthcheck that fetches the /health endpoint with a 30 second interval and a 40 second start period.

Redis, PostgreSQL and MySQL are defined as separate services behind compose profiles, so they only start when you ask for them.

Storage backends, config file and upgrade migrations

The environment variables decide where state lives, and the choice is wider than the local deployment suggests. SERVER_STORAGE_TYPE accepts local, redis, mysql or pgsql, and the compose file provides ready-to-run services for the last three behind profiles named redis, pgsql and mysql. The sample connection string in the documentation is a PostgreSQL one using the asyncpg driver.

Configuration itself is a file. It lives at data/config.toml, generated on first start from config.defaults.toml, and the admin panel can edit it directly. Token data is kept separately in data/token.json.

The upgrade path is documented in detail, which is the sign of a project that expects people to run it for a long time. When an old data/setting.toml is detected, it is merged into the new configuration using a strategy of missing fields and still-default values. The old cache directories data/temp/{image,video} are moved to data/tmp/{image,video}. And there is a one-off best-effort repair of existing accounts after an upgrade, described as running the agreement acceptance, age setting and NSFW enabling once with a concurrency of 10 to avoid repeated calls.

That last item is a good example of how the project treats upstream account state as something it manages on the user's behalf. The Token management page offers a one-click NSFW refresh to fill in the same settings in bulk for existing tokens, and the README notes this refresh flow is only exposed in the local FastAPI and Docker deployments, while the Cloudflare Workers build keeps the interface compatible but does not show the local-only button.

The environment table also documents LOG_LEVEL, SERVER_HOST, SERVER_PORT and SERVER_WORKERS, with defaults of INFO, 0.0.0.0, 8000 and 1.

The admin panel: tokens, keys, cache and config

The management surface is a set of pages under /admin, and the token page is the interesting one.

The admin panel is reached at http://<host>:8000/login, and the default credentials are admin and admin, corresponding to the app.admin_username and app.app_key configuration items. The README recommends changing them after deployment, which is advice worth following literally.

The token page supports import, export, batch operations and account settings refresh. The filtering is the most engineered part: type filters for sso and supersso that can be combined, and status filters for active, invalid and quota exhausted, combined with union semantics, plus a result count and a way to clear filters. There is a result count and a clear-filters action. The important detail is that after filtering, selection, select-all, batch refresh and batch delete all operate on token unique values rather than row indices, which is what stops a filtered view from causing a wrong item to be deleted.

The status rules are spelled out. Invalid covers a status of invalid, expired or disabled. Quota exhausted covers a status of cooling, or a known quota at or below zero, or the same test on the heavy quota for a super account. Active is everything that is neither invalid nor quota exhausted. The type mapping translates ssoBasic to sso and ssoSuper to supersso, while the API field token_type carries the raw sso or ssoSuper values.

The API key page has statistics for total, enabled, disabled and quota exhausted today, a toolbar with search by name or key, a status filter, and a creation dialog that generates a key automatically, offers quota presets of recommended or unlimited, disables the submit button while the request is in flight to prevent a double submit, and offers a one-click copy after creation. Updating a key that does not exist returns a 404, and the README notes the FastAPI and Workers builds behave the same way there.

The other pages are the datacenter for common metrics and log viewing, config for configuration management, and cache for the local cache and online assets.

The model table and what the quota numbers mean

The README publishes a model table with a count column, an account type column and separate columns for conversation, image and video support. It is the most concrete statement of what the proxy can actually reach, and it is worth reading closely.

The conversation models listed are grok-3, grok-3-mini, grok-3-thinking, grok-4, grok-4-mini, grok-4-thinking, grok-4-heavy, grok-4.1-mini, grok-4.1-fast, grok-4.1-expert, grok-4.1-thinking and grok-4.20-beta. All of them support conversation and images, and none supports video. The heavier variants, grok-4-heavy, grok-4.1-expert, grok-4.1-thinking and grok-4.1-fast, are marked as counting 4 against the quota rather than 1, and grok-4-heavy is listed as requiring a super account.

The image models are grok-imagine-1.0, grok-imagine-1.0-edit and grok-imagine-1.0-video, with the first two supporting images and the last supporting video.

The quota accounting section is the honest part of the document. A basic account is given 80 uses per 20 hours, and for a super account the README says there is no account limit and that the author has not tested it.

That last line is worth pausing on. The whole load-balancing design, the token pool, the batch refresh and the status filtering all exist to spread requests across accounts so the per-account quota is not the binding constraint. That is a direct consequence of running on web session tokens rather than an official API key, and it explains why the account settings refresh, including accepting the terms of service on the user's behalf, is a first-class feature rather than a script.

It is also why the repository's own note matters. It states that the project is for study and research, that users must comply with Grok's terms of use and with the law, and that it must not be used for illegal purposes.

Checking the deployment before you trust it

The README recommends running a set of repository-level checks before a one-click deploy, and the list is a good description of what can break.

bash
uv run pytest -q
npm run typecheck
python scripts/check_model_catalog_sync.py
npx wrangler deploy --dry-run --config wrangler.toml
docker compose -f docker-compose.yml config
docker compose -f docker-compose.yml -f docker-compose.build.yml config

The Python test suite and the TypeScript typecheck cover the two code bases, the model catalog sync script checks that the published model list matches the code, the wrangler dry run validates the Worker bundle without deploying, and the two compose config calls validate the two compose files.

The note about a denied pull is worth keeping. If the image pull fails with denied, the GHCR image is not anonymously pullable, either because it is not public or because a login is required. The documented workarounds are to run docker login ghcr.io, to point GROK2API_IMAGE in the .env file at your own public image, or to build from source with the --build flag.

The optional configuration path is a .env file copied from .env.example, which covers the port, logging and storage settings and can enable the redis, pgsql and mysql services in one step through COMPOSE_PROFILES.

The repository also carries a mobile adaptation pass, with the same static assets used across all three deployments so the behaviour matches, covering the login, token, keys, cache, config and datacenter pages plus the chat pages, with a drawer menu on small screens, tables that scroll horizontally rather than compress, and a full-width bottom action bar.

Editorial conclusion

grok2api is a good fit for a developer who wants an OpenAI-shaped endpoint in front of the Grok web interface and is willing to maintain the token pool, since the local FastAPI, Docker and Cloudflare Workers builds share one management surface and the same environment variables. It is a poor fit for a production service that needs a supported upstream, because the whole thing depends on session tokens rather than an official API key, and the project itself states it is for study and research and requires compliance with Grok's terms of use. Before deploying, read the terms constraint in the repository's own note, decide how you will source the tokens, and set the admin credentials immediately, since the default login is admin over admin.

Frequently asked questions

How do I run grok2api locally?

Run uv sync to install the locked dependencies and then uv run main.py to start the FastAPI service, or use docker compose up -d to start the container. An optional self-check is available through python scripts/smoke_test.py --base-url http://127.0.0.1:8000.

What storage backends does grok2api support?

SERVER_STORAGE_TYPE accepts local, redis, mysql or pgsql, with SERVER_STORAGE_URL holding the connection string, and the compose file provides Redis, PostgreSQL and MySQL services behind profiles. The local backend is the default and needs no connection string.

What are the default admin credentials for grok2api?

The admin panel is at http://<host>:8000/login and the default username and password are admin and admin, corresponding to the app.admin_username and app.app_key settings. The README recommends changing them after deployment.

Can I deploy grok2api to Cloudflare Workers?

Yes. This fork adds a TypeScript Workers and Pages variant using D1 and KV, deployable with a one-click workflow in .github/workflows/cloudflare-workers.yml that requires CLOUDFLARE_API_TOKEN and CLOUDFLARE_ACCOUNT_ID secrets, or locally with scripts/deploy-cloudflare.ps1 or scripts/deploy-cloudflare.sh.

Official sources

  1. Issues
  2. License: MIT
  3. README
  4. TQZHR/grok2api on GitHub
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/tqzhr-grok2api.svg)](https://hysenlabs.com/projects/tqzhr-grok2api)

Was this useful?