gpt2api-openai-gateway
OpenAI-compatible SaaS gateway that reverse-engineers chatgpt.com to provide GPT Image 2, multi-account pooling, batch image generation, and billing management.
Best use case
gpt2api-openai-gateway is best used when you need a repeatable AI agent workflow instead of a one-off prompt.
OpenAI-compatible SaaS gateway that reverse-engineers chatgpt.com to provide GPT Image 2, multi-account pooling, batch image generation, and billing management.
Teams using gpt2api-openai-gateway should expect a more consistent output, faster repeated execution, less prompt rewriting.
When to use this skill
- You want a reusable workflow that can be run more than once with consistent structure.
When not to use this skill
- You only need a quick one-off answer and do not need a reusable workflow.
- You cannot install or maintain the underlying files, dependencies, or repository context.
Installation
Claude Code / Cursor / Codex
Manual Installation
- Download SKILL.md from GitHub
- Place it in
.claude/skills/gpt2api-openai-gateway/SKILL.mdinside your project - Restart your AI agent — it will auto-discover the skill
How gpt2api-openai-gateway Compares
| Feature / Agent | gpt2api-openai-gateway | Standard Approach |
|---|---|---|
| Platform Support | Not specified | Limited / Varies |
| Context Awareness | High | Baseline |
| Installation Complexity | Unknown | N/A |
Frequently Asked Questions
What does this skill do?
OpenAI-compatible SaaS gateway that reverse-engineers chatgpt.com to provide GPT Image 2, multi-account pooling, batch image generation, and billing management.
Where can I find the source code?
You can find the source code on GitHub using the link provided at the top of the page.
SKILL.md Source
# gpt2api OpenAI Gateway
> Skill by [ara.so](https://ara.so) — Daily 2026 Skills collection.
`gpt2api` is a self-hosted OpenAI-compatible API gateway that reverse-engineers `chatgpt.com` to expose GPT Image 2 / DALL·E 3 / IMG2 grayscale capabilities via standard `/v1/images/generations`, `/v1/images/edits`, and `/v1/chat/completions` endpoints. It provides multi-account pooling, proxy pooling, rate limiting, credit billing, and an admin dashboard.
---
## Installation & Deployment
### Docker Compose (Recommended)
```bash
git clone https://github.com/432539/gpt2api.git
cd gpt2api/deploy
cp .env.example .env
```
Edit `.env` — these three are **required**:
```env
JWT_SECRET=<generate with: openssl rand -base64 48 | tr -d '=/+' | cut -c1-48>
CRYPTO_AES_KEY=<generate with: openssl rand -hex 32>
MYSQL_ROOT_PASSWORD=<strong-password>
MYSQL_PASSWORD=<strong-password>
```
Generate secrets:
```bash
# CRYPTO_AES_KEY (must be exactly 64 hex chars = 32 bytes AES-256)
openssl rand -hex 32
# JWT_SECRET (>=32 chars)
openssl rand -base64 48 | tr -d '=/+' | cut -c1-48
```
Start services:
```bash
docker compose up -d --build
docker compose logs -f server
```
On startup the server automatically:
1. Waits for MySQL health check
2. Runs `goose up` database migrations
3. Starts HTTP on `:8080`
**Default admin credentials** (change immediately):
- URL: `http://<server-ip>:8080/`
- Email: `admin@example.com`
- Password: `admin123`
---
## Configuration
Main config file: `configs/config.yaml` (override with `GPT2API_*` env vars in Docker).
```yaml
app:
listen: ":8080"
base_url: "https://your-domain.com" # used for signed image proxy URLs
mysql:
dsn: "user:pass@tcp(mysql:3306)/gpt2api?parseTime=true"
max_open_conns: 500
redis:
addr: "redis:6379"
pool_size: 500 # needed for distributed locks & rate limiting
jwt:
secret: "${JWT_SECRET}"
access_ttl_sec: 7200
refresh_ttl_sec: 604800
crypto:
aes_key: "${CRYPTO_AES_KEY}" # 64-char hex, encrypts account AT/cookies
scheduler:
min_interval_sec: 10 # minimum seconds between uses of same account
daily_usage_ratio: 0.8 # daily usage cap ratio before circuit break
cooldown_429_sec: 300 # backoff when upstream returns 429
```
Environment variable override pattern (Docker):
```env
GPT2API_APP_BASE_URL=https://api.example.com
GPT2API_SCHEDULER_MIN_INTERVAL_SEC=15
GPT2API_SCHEDULER_COOLDOWN_429_SEC=600
```
---
## Quick Start: First Image Generation
### 1. Add a Proxy
Via admin dashboard → **Proxy Management** → New Proxy, or via API:
```bash
curl -X POST http://localhost:8080/api/admin/proxies \
-H "Authorization: Bearer $ADMIN_JWT" \
-H "Content-Type: application/json" \
-d '{
"name": "proxy-us-01",
"url": "http://user:pass@proxy.example.com:8080",
"type": "http"
}'
```
SOCKS5 example:
```bash
-d '{"name":"socks-01","url":"socks5://user:pass@proxy.example.com:1080","type":"socks5"}'
```
### 2. Import ChatGPT Accounts
Batch import via admin dashboard → **GPT Accounts** → Batch Import.
Supported formats — JSON session:
```json
[
{
"email": "user@example.com",
"access_token": "$CHATGPT_ACCESS_TOKEN",
"refresh_token": "$CHATGPT_REFRESH_TOKEN",
"proxy_id": 1
}
]
```
Or AT/RT/ST plain text (one per line in the UI).
### 3. Create an API Key
Admin dashboard → **User Management** → select user → **API Keys** → Create Key.
Or programmatically:
```bash
curl -X POST http://localhost:8080/api/user/apikeys \
-H "Authorization: Bearer $USER_JWT" \
-H "Content-Type: application/json" \
-d '{
"name": "my-app-key",
"rpm_limit": 60,
"daily_quota": 1000,
"model_whitelist": ["gpt-image-2", "picture_v2"]
}'
```
### 4. Generate an Image
```bash
curl -X POST http://localhost:8080/v1/images/generations \
-H "Authorization: Bearer sk-your-api-key" \
-H "Content-Type: application/json" \
-d '{
"model": "gpt-image-2",
"prompt": "A serene mountain lake at sunset, photorealistic",
"n": 2,
"size": "1024x1024"
}'
```
Response:
```json
{
"created": 1713456789,
"data": [
{
"url": "https://your-domain.com/p/img/task123/0?exp=1713460389&sig=abc123"
},
{
"url": "https://your-domain.com/p/img/task123/1?exp=1713460389&sig=def456"
}
]
}
```
---
## API Reference
### Image Generation
```
POST /v1/images/generations
```
```json
{
"model": "gpt-image-2", // or "picture_v2" for IMG2 grayscale
"prompt": "your prompt",
"n": 1, // number of images (1-4 recommended)
"size": "1024x1024", // "1024x1024" | "1792x1024" | "1024x1792"
"response_format": "url" // "url" | "b64_json"
}
```
### Image Edit (img2img)
```
POST /v1/images/edits
Content-Type: multipart/form-data
```
```bash
curl -X POST http://localhost:8080/v1/images/edits \
-H "Authorization: Bearer sk-your-api-key" \
-F "image=@input.png" \
-F "prompt=Make the sky more dramatic" \
-F "model=gpt-image-2" \
-F "n=1"
```
### Check Task Status
```
GET /v1/images/tasks/:id
Authorization: Bearer sk-your-api-key
```
### List Models
```
GET /v1/models
Authorization: Bearer sk-your-api-key
```
### Chat Completions (preserved, UI disabled)
```
POST /v1/chat/completions
```
```json
{
"model": "gpt-4o",
"messages": [{"role": "user", "content": "Hello"}],
"stream": true
}
```
---
## Using with OpenAI SDK
### Python
```python
from openai import OpenAI
import os
client = OpenAI(
api_key=os.environ["GPT2API_KEY"], # your sk- key from the dashboard
base_url="http://localhost:8080/v1" # or your production domain
)
# Single image
response = client.images.generate(
model="gpt-image-2",
prompt="A futuristic city skyline at night, cyberpunk style",
n=1,
size="1024x1024"
)
print(response.data[0].url)
# Batch images
response = client.images.generate(
model="gpt-image-2",
prompt="Abstract watercolor painting, vibrant colors",
n=4,
size="1024x1792" # 9:16 portrait
)
for img in response.data:
print(img.url)
```
### Node.js / TypeScript
```typescript
import OpenAI from "openai";
const client = new OpenAI({
apiKey: process.env.GPT2API_KEY,
baseURL: process.env.GPT2API_BASE_URL ?? "http://localhost:8080/v1",
});
async function generateImages(prompt: string, count: number = 2) {
const response = await client.images.generate({
model: "gpt-image-2",
prompt,
n: count,
size: "1024x1024",
});
return response.data.map((img) => img.url);
}
// Image edit
async function editImage(imagePath: string, prompt: string) {
const fs = await import("fs");
const response = await client.images.edit({
image: fs.createReadStream(imagePath),
prompt,
model: "gpt-image-2",
});
return response.data[0].url;
}
```
### Go
```go
package main
import (
"context"
"fmt"
"os"
openai "github.com/sashabaranov/go-openai"
)
func main() {
cfg := openai.DefaultConfig(os.Getenv("GPT2API_KEY"))
cfg.BaseURL = os.Getenv("GPT2API_BASE_URL") // e.g. "http://localhost:8080/v1"
client := openai.NewClientWithConfig(cfg)
resp, err := client.CreateImage(context.Background(), openai.ImageRequest{
Model: "gpt-image-2",
Prompt: "A tranquil Japanese garden with cherry blossoms",
N: 2,
Size: openai.CreateImageSize1024x1024,
})
if err != nil {
panic(err)
}
for _, img := range resp.Data {
fmt.Println(img.URL)
}
}
```
---
## Key Concepts
### IMG2 Grayscale Hit
IMG2 is a grayscale (A/B test) feature on `chatgpt.com` that returns multiple high-res final images in a single call. The gateway:
1. Sends the generation request
2. Detects `preview_only` in the tool message response
3. Automatically retries up to 3 times within the same conversation to capture IMG2 output
4. Returns all signed image URLs aggregated
Use model `picture_v2` to specifically target the IMG2 grayscale path:
```json
{ "model": "picture_v2", "prompt": "...", "n": 1 }
```
Successful IMG2 hit shows in logs:
```
image runner result summary turns_used=1 is_preview=false signed_count=2
```
### Account Pool Scheduling
The scheduler uses Redis distributed locks to serialize account usage:
- `min_interval_sec`: minimum gap between consecutive uses of the same account
- `daily_usage_ratio`: if an account hits this fraction of its daily limit, it's circuit-broken
- `cooldown_429_sec`: account is cooled down after receiving a 429 from upstream
- Accounts are bound 1:1 to `oai-device-id` / `oai-session-id` fingerprints (stored in DB)
### Image Proxy & Anti-Hotlink
All returned image URLs go through the built-in HMAC-signed proxy:
```
/p/img/:task_id/:index?exp=<unix_timestamp>&sig=<hmac_sha256>
```
This bypasses `chatgpt.com`'s `estuary/content` 403 hotlink protection. The proxy fetches and streams the image server-side when accessed.
### Credit Billing System
- Users have a credit wallet; credits are pre-deducted before generation
- Group multipliers allow VIP / internal / reseller pricing tiers
- Billing settled after successful generation; failed calls are refunded
- EPay (易支付) integration for recharge
---
## Admin Operations
### Account Pool Management
```bash
# Check account statuses via API
curl http://localhost:8080/api/admin/accounts \
-H "Authorization: Bearer $ADMIN_JWT"
# Manually trigger account token refresh
curl -X POST http://localhost:8080/api/admin/accounts/123/refresh \
-H "Authorization: Bearer $ADMIN_JWT"
# Bulk import accounts (JSON body)
curl -X POST http://localhost:8080/api/admin/accounts/batch \
-H "Authorization: Bearer $ADMIN_JWT" \
-H "Content-Type: application/json" \
-d @accounts.json
```
### Database Backup & Restore
Via admin dashboard → **Data Backup**, or:
```bash
# Trigger backup
curl -X POST http://localhost:8080/api/admin/backups \
-H "Authorization: Bearer $ADMIN_JWT"
# List backups
curl http://localhost:8080/api/admin/backups \
-H "Authorization: Bearer $ADMIN_JWT"
# Download backup
curl http://localhost:8080/api/admin/backups/backup-2026-04-21.sql.gz \
-H "Authorization: Bearer $ADMIN_JWT" \
-o backup.sql.gz
```
### User Credit Management
```bash
# Add credits to a user
curl -X POST http://localhost:8080/api/admin/users/42/credits \
-H "Authorization: Bearer $ADMIN_JWT" \
-H "Content-Type: application/json" \
-d '{"amount": 10000, "note": "Manual top-up"}'
```
---
## Directory Structure
```
gpt2api/
├── cmd/server/ # main entry point
├── configs/
│ ├── config.yaml # main config
│ └── config.example.yaml
├── deploy/
│ ├── docker-compose.yml
│ ├── .env.example
│ └── README.md # horizontal scaling guide
├── internal/
│ ├── api/ # Gin route handlers
│ ├── chatgpt/ # upstream client (utls, sentinel, SSE parser)
│ ├── scheduler/ # account pool scheduler + Redis leases
│ ├── billing/ # credit wallet + EPay integration
│ ├── proxy/ # proxy pool health checks
│ ├── imgproxy/ # HMAC-signed image proxy
│ └── model/ # DB models + migrations (goose)
├── web/ # Vue 3 frontend source
└── docs/screenshots/
```
---
## Enabling Chat Completions
The `/v1/chat/completions` route is fully implemented but the UI entry is disabled via a feature flag due to upstream sentinel instability. To re-enable:
```go
// internal/api/routes.go — find the feature flag:
const enableChatCompletions = false // change to true
```
Rebuild and redeploy:
```bash
docker compose up -d --build server
```
---
## Troubleshooting
### No accounts available / all accounts idle
```bash
# Check account pool status
docker compose logs server | grep "scheduler"
# Common causes:
# 1. min_interval_sec too high — reduce in config
# 2. All accounts in cooldown — check for 429s upstream
# 3. Proxy unhealthy — verify proxy health score in dashboard
```
### Images return 403 when accessed directly
Expected behavior — all image URLs must go through the `/p/img/` proxy. Ensure `base_url` in config matches your actual domain so signed URLs are correct.
### `is_preview=true` in logs (IMG2 not hitting)
The account doesn't have IMG2 grayscale enabled. Either:
- Try different accounts (grayscale is account-specific)
- Use `gpt-image-2` model instead of `picture_v2`
- The gateway retries up to 3 times automatically
### Redis lock timeout errors
```yaml
redis:
pool_size: 500 # increase if seeing lock contention under high concurrency
```
### Database migration fails on startup
```bash
docker compose exec server goose -dir /app/migrations mysql "$DSN" status
docker compose exec server goose -dir /app/migrations mysql "$DSN" up
```
### TLS fingerprint / JA3 detection
The gateway uses `refraction-networking/utls` to mimic Edge 143 browser TLS fingerprint. If accounts are getting flagged:
- Ensure each account is bound to a dedicated proxy (avoid IP mixing)
- Check `oai-device-id` binding is consistent (stored per-account in DB)
- Rotate accounts that have been flagged
### High memory usage
Reduce connection pool sizes for smaller deployments:
```yaml
mysql:
max_open_conns: 50
redis:
pool_size: 50
```
---
## Security Checklist
- [ ] Change default admin password immediately after first login
- [ ] Set strong `JWT_SECRET` (≥32 chars random)
- [ ] Set `CRYPTO_AES_KEY` to exactly 64 hex chars
- [ ] Set strong MySQL passwords
- [ ] Configure `base_url` to your HTTPS domain
- [ ] Set up nginx reverse proxy with TLS in front of `:8080`
- [ ] Configure API key IP whitelists for sensitive keys
- [ ] Enable audit log review in admin dashboardRelated Skills
openai-symphony-autonomous-agents
Symphony turns project work into isolated, autonomous implementation runs, allowing teams to manage work instead of supervising coding agents.
openai-privacy-filter
OpenAI Privacy Filter — bidirectional token-classification model for PII detection and masking in text
freebuff2api-openai-proxy
OpenAI-compatible proxy server for Freebuff that translates standard OpenAI API requests into Freebuff's backend format with multi-token rotation and Docker deployment.
cc-gateway-ai-proxy
Deploy and configure CC Gateway, a reverse proxy that normalizes Claude Code device fingerprints and telemetry for privacy-preserving API proxying
```markdown
---
zeroboot-vm-sandbox
Sub-millisecond VM sandboxes for AI agents using copy-on-write KVM forking via Zeroboot
yourvpndead-vpn-detection
Android app that detects VPN/proxy servers (VLESS/xray/sing-box) via local SOCKS5 vulnerability, exposing exit IPs and server configs without root
xata-postgres-platform
Expert skill for Xata open-source cloud-native Postgres platform with copy-on-write branching, scale-to-zero, and Kubernetes deployment
x-mentor-skill-nuwa
AI-powered X (Twitter) content strategy skill that distills methodologies from 6 top creators + open-source algorithm data into actionable writing, growth, and monetization guidance.
wx-favorites-report
End-to-end pipeline to extract, decrypt, and visualize WeChat Mac favorites from encrypted SQLite DB into an interactive HTML report.
wterm-web-terminal
Web terminal emulator with Zig/WASM core, DOM rendering, and React/vanilla JS bindings
worldmonitor-intelligence-dashboard
Real-time global intelligence dashboard with AI-powered news aggregation, geopolitical monitoring, and infrastructure tracking