Claude
Skills
Sign in
โ† Back

chatgpt-codex-onboarding

Included with Lifetime
$97 forever

Connect a ChatGPT or Codex subscription via OAuth device-code login. Use when the user wants to sign in with their ChatGPT Plus, Pro, or Team account (e.g. "use my Codex subscription", "log in with ChatGPT").

Generalopenaioauthchatgptcodexgpt-5loginsubscription

What this skill does


# ๐Ÿ” ChatGPT / Codex OAuth Onboarding

Use the user's existing **ChatGPT or Codex subscription** for `gpt-5-codex`, `gpt-5`, `gpt-5-mini` access โ€” without an API key.

This is a **script-mode skill** โ€” no tools registered. Read this file, then call the exports from a `bash` block.

## See also
- `byok-custom-model` skill โ€” for vendor-key BYOK setup (DIFFERENT mechanism, NOT OAuth)
- `config/context/references/model-onboarding.md` โ€” overall model-selection landscape

---

## When to use this skill

โœ… **Use** when the user EXPLICITLY says one of:
- "Sign in with my ChatGPT account"
- "Use my Codex subscription"
- "Connect my ChatGPT Plus / Pro / Team / Enterprise"
- "Login with OpenAI / ChatGPT"

โŒ **Do NOT use** for:
- BYOK / API-key-based setup ("Add OpenAI API key", "I have an OpenAI key")
- Other vendors that sound similar (Anthropic, Gemini, Qwen, etc.) โ†’ use `byok-custom-model`
- "Add the OpenAI model" without subscription context โ€” ASK first whether they want OAuth (subscription) or BYOK (API key)

โš ๏ธ Vendor names that sound similar (Codex, OpenAI, GPT) are **NOT a signal** to start OAuth on their own. Only an explicit user mention of "subscription / sign in / login with ChatGPT" qualifies.

---

## Onboarding flow

1. **status** โ€” check if a credential already exists (resume vs fresh).
2. **start** โ€” get a verification URL + user code from OpenAI; persisted to disk.
3. Tell the user: open the URL in a browser, log in to their ChatGPT / Codex account, and enter the code. Do NOT auto-poll.
4. Wait for the user to confirm they approved the device.
5. **poll** โ€” finalize the OAuth handshake; on success, the new model becomes available.

If poll returns `status='pending'`, the user hasn't finished yet โ€” wait for them, then poll again. Don't loop poll automatically.

---

## Script usage

```bash
python3 - <<'EOF'
import sys, json
sys.path.insert(0, "/data/workspace/skills/chatgpt-codex-onboarding")
from exports import status, start, poll, logout, refresh, models, usage

# Check current state
print(json.dumps(status(), indent=2))

# Start a flow
result = start()
print(f"Open: {result['verification_url']}\nCode: {result['user_code']}")
EOF
```

After the user approves:

```bash
python3 - <<'EOF'
import sys, json
sys.path.insert(0, "/data/workspace/skills/chatgpt-codex-onboarding")
from exports import poll
print(json.dumps(poll(), indent=2))
EOF
```

---

## Functions

| Function | Required args | Purpose |
|---|---|---|
| `status()` | โ€” | Inspect current OAuth state, expiry, model list |
| `start()` | โ€” | Begin device-code flow โ†’ verification_url + user_code |
| `poll(pending_id=None)` | โ€” | Check authorization (call after user confirms approval) |
| `logout()` | โ€” | Disconnect + remove credentials |
| `refresh()` | โ€” | Force-refresh access token (debug; normally automatic) |
| `models(force=False)` | โ€” | List available models from the OAuth endpoint |
| `usage(force=False)` | โ€” | Subscription usage stats |

`force=True` on `models` / `usage` bypasses the cache TTL.

All functions return a dict with `ok: True` on success or `ok: False, error: "..."` on failure.

---

## After connecting

When `poll()` returns `status='connected'`, the **first thing you must do** is tell the user:

> "Connection successful. Please refresh your browser page โ€” once it reloads, the new `openai-codex/*` models will appear in the model picker."

The web frontend caches the model list client-side and does not auto-refresh after an OAuth connect completes. Without a manual page refresh the user will not see their newly available models and will think the connection failed. Always include this instruction in your reply โ€” do not assume the picker updates on its own.

Models appear with the `openai-codex/` prefix:
- `openai-codex/gpt-5-codex` โ€” primary
- `openai-codex/gpt-5` โ€” full GPT-5
- `openai-codex/gpt-5-mini` โ€” smaller / faster

After refresh, the user switches via `/model openai-codex/gpt-5-codex` or the model picker UI.

Subsequent calls hit OpenAI directly using the OAuth token โ€” bypasses the platform proxy. Subscription usage limits apply (not the platform's credit balance).

---

## Reauth

Tokens auto-refresh via `refresh_token`. If a 401 surfaces:
1. `refresh()` โ€” try the manual refresh path.
2. If still failing, `logout()` + restart from `start()`.

---

## Critical rules

- **Never paste user_code in the verification_url.** They're separate โ€” user must enter the code manually after opening the URL.
- **Never start the flow without explicit user request.** "I want to use ChatGPT" is enough; "I have an OpenAI key" is NOT (that's BYOK).
- **Wait for user confirmation between `start` and `poll`.** Auto-polling wastes API calls and gives stale "pending" responses.

Related in General