grok2api

Application

chenyme/grok2api

Multi-account API gateway for Grok with OpenAI/Anthropic interfaces.

Overview

A pure Go implementation of a Grok API gateway that manages multi-account pools for Grok Build, Web, and Console. Exposes OpenAI and Anthropic-compatible endpoints with robust routing, rate limiting, and credential encryption.

README Preview

\n  \n\n\n\n  面向 Grok Build、Grok Web 与 Grok Console 的多账号 API 网关\n\n\n\n  \n  \n  \n\n\n> [!TIP]\n> **个人新项目**\n> 推荐个人新项目 [DEEIX-AI:DEEIX-Chat 轻量化 AI 平台](https://github.com/DEEIX-AI/DEEIX-Chat):企业级模型路由、对话、文件、工具、计费、身份和运维的一体化 AI 平台,全面且极致的低占用,空载运行时仅占用 34 MB。\n\n> [!NOTE]\n> 本项目仅供学习与研究交流。请务必遵循 Grok 的使用条款及当地法律法规,不得用于非法用途!\n\nGrok2API 是一个纯 Go 实现的 Grok API 网关。项目将 Grok Build OAuth、Grok Web SSO 与 Grok Console SSO 组织为独立账号池,对外提供 OpenAI 风格接口、Anthropic Messages 兼容接口,以及账号、模型、密钥、用量和代理管理后台。\n\n## 功能概览\n\n- **三 Provider**:`grok_build`、`grok_web` 与 `grok_console` 独立路由、额度和故障状态\n- **标准接口**:Responses、Chat Completions、Images、异步 Videos、Anthropic Messages\n- **多账号调度**:优先级、并发限制、额度门控、会话粘滞、冷却与故障切换\n- **账号接入**:Device OAuth、OAuth JSON、SSO JSON、逐行 SSO Token\n- **媒体能力**:图片生成、图片编辑、视频生成、图片本地归档与 URL/Base64 返回\n- **基础设施**:SQLite/PostgreSQL、Memory/Redis、HTTP 与 SOCKS 代理池\n- **安全边界**:AES-256-GCM 凭据加密、客户端密钥哈希、日志脱敏、SSRF 与传输上限\n- **管理后台**:Dashboard、账号、模型、客户端密钥、请求审计、接口文档与热加载设置\n\n## 架构\n\n```mermaid\nflowchart LR\n    Client["API Client"] --> Gateway["Go Gateway"]\n    Admin["React Admin"] --> Gateway\n\n    Gateway --> Router["Model Router"]\n    Router --> Build["Grok Build"]\n    Router --> Web["Grok Web"]\n    Router --> Console["Grok Console"]\n\n    Build --> BuildPool["OAuth Account Pool"]\n    Web --> WebPool["SSO Account Pool"]\n    Console --> ConsolePool["SSO Account Pool"]\n    Build --> Egress["Egress Pool"]\n    Web --> Egress\n    Console --> Egress\n\n    Gateway --> Database["SQLite / PostgreSQL"]\n    Gateway --> Runtime["Memory / Redis"]\n    Gateway --> Media["Media Storage"]\n```\n\n## 快速部署\n\n### Docker Compose\n\n1. 准备配置:\n\n```bash\ngit clone https://github.com/chenyme/grok2api.git\ncd grok2api\ncp config.example.yaml config.yaml\n```\n\n2. 生成并填写安全密钥:\n\n```bash\nopenssl rand -hex 32\nopenssl rand -base64 32\n```\n\n```yaml\nsecrets:\n  jwtSecret: "替换为 hex 随机值"\n  credentialEncryptionKey: "替换为 Base64 随机密钥"\n\nbootstrapAdmin:\n  username: "admin"\n  password: "替换为强密码"\n```\n\n3. 启动:\n\n

FAQ (2)

Troubleshooting
How to fix xAI Console API 400 error: "A tool_choice was set on the request but no tools were specified"?

This happens when a normalized request keeps tool_choice (for example "auto" or "none") while tools is empty or missing. xAI Console only accepts tool_choice when a non-empty tools array is present.

Add a pair-guard check before serializing the request in backend/internal/infra/provider/console/normalize.go:

func ensureConsoleToolChoicePair(payload map[string]any) {
	choice, hasChoice := payload["tool_choice"]
	if !hasChoice || choice == nil {
		return
	}

	tools, ok := payload["tools"].([]any)
	if !ok || len(tools) == 0 {
		delete(payload, "tools")
		delete(payload, "tool_choice")
	}
}

Call ensureConsoleToolChoicePair(payload) from normalizeRequestWithMetadata before the request body is serialized and sent to the xAI /responses endpoint.

Immediate client-side workaround: remove tool_choice from the request, or only send it when tools contains at least one valid tool. This prevents the HTTP 400 invalid-argument response from clients such as AxonHub, NextChat, or LibreChat that may send tool_choice: "none" with tools: [].

GitHub Issue #1042
Troubleshooting
Why does grok2api grok_web video generation return the same lighthouse demo video for different prompts even though the task is HTTP 200 and completed?

This is caused by degraded/free Grok Web accounts returning upstream stock or decoy clips (lighthouse, alpine lake, tabby cat, farmers market, etc.) that ignore the prompt. The clip may have a different assetId, URL, and whole-file SHA256 because metadata/packaging differs, while the decoded H.264 content is the same stock video. The 403: This page is out of date log also indicates the account/session is degraded.

Fix: upgrade grok2api from v3.1.5 to a release/build containing the PR feat(video): detect stock decoy clips by mdat fingerprint and retry. That fix fingerprints the MP4 mdat/decoded stream instead of relying on URL or file SHA256, identifies known decoy clips, treats the generation as failed, and retries with another account. Redeploy with:

docker pull ghcr.io/chenyme/grok2api:latest
docker compose up -d

If the PR is not in the release you are using, use a build from the merged commit. As an immediate workaround, re-authenticate or remove the account returning 403, rotate to a healthy/non-degraded or paid Grok account, or switch providers. Do not treat HTTP 200/completed as success until the decoy check passes; verify the actual decoded frames. Changing the prompt or proxy alone will not fix this.

GitHub Issue #1014