Files
autoreg-skills-max/skills/bulk-account-registration/references/chatgpt-dalle-api.md

3.0 KiB

ChatGPT DALL-E Image Generation API Pattern (2026-07-30)

ChatGPT web auth is cookie-based, not Bearer token. The session token from DB works as a cookie:

headers = {
    "Content-Type": "application/json",
    "User-Agent": "Mozilla/5.0 ... Chrome/[REDACTED-IP] Safari/537.36",
    "Origin": "https://chatgpt.com",
    "Referer": "https://chatgpt.com/",
    "Accept": "text/event-stream",
}
if csrf_token:
    headers["X-CSRF-Token"] = csrf_token.split("|")[0]  # Before the pipe

cookies = {
    "__Secure-next-auth.session-token": session_token,
}
if csrf_token:
    cookies["__Host-next-auth.csrf-token"] = csrf_token

Do NOT use Authorization: Bearer ... — returns 403.

CSRF Token Format

CSRF token from DB: bad91657060abdd7517223227f1a51...%7C2a80b3e7...

  • For header X-CSRF-Token: use the part BEFORE %7C (or |)
  • For cookie __Host-next-auth.csrf-token: use the FULL value

Endpoint: SSE Streaming

POST https://chatgpt.com/backend-api/conversation
Body: {
    "action": "next",
    "messages": [{
        "id": "<uuid>",
        "author": {"role": "user"},
        "content": {"content_type": "text", "parts": ["Generate an image: {prompt}"]}
    }],
    "model": "auto",
    "parent_message_id": "<uuid>",
    "conversation_id": None,
    "history_and_training_disabled": False,
    "timezone_offset_min": 180,
}

The response is SSE (text/event-stream), NOT JSON. Parse as:

for line in resp.text.split('\n'):
    if line.startswith('data: '):
        data_str = line[6:]
        if data_str == '[DONE]':
            break
        data = json.loads(data_str)
        # Image URLs appear as markdown ![...](url) in message parts

Extracting Image URLs from SSE

3 extraction methods, tried in order:

  1. Parse SSE lines → message.content.parts → regex for ![...](url) and raw image URLs
  2. Full-text regex over entire response: r'!\[.*?\]\((https?://[^\)]+)\)'
  3. Domain search: r'https?://(?:oaistatic|files\.oaiusercontent)\.com[^\s<>"\']+'

Rate Limits & Token Expiry

  • Session tokens from __Secure-next-auth.session-token expire in ~1 week
  • Free plan accounts may NOT have DALL-E access (returns text responses, not images)
  • 429 rate limit = 1-2 minute cooldown between requests
  • Each image generation burns credits on paid plans

Round-Robin Pattern

_account_idx = 0
_lock = asyncio.Lock()

async def _get_next_account() -> tuple[dict, int]:
    global _account_idx
    async with _lock:
        idx = _account_idx % len(ACCOUNTS)
        _account_idx += 1
        return ACCOUNTS[idx], idx

Full Implementation

See C:/Users/User/Desktop/GPT-AUTOREG/image_api_server.py — FastAPI server on :8400 with:

  • GET /health — account count + status
  • GET /accounts — list accounts with index + token status
  • POST /generate — {"prompt": "...", "account_index": null} → {"success": bool, "images": [...], "account_used": "...", "error": "..."}