| name | codex-console-automation |
| description | AI skill for managing OpenAI account automation using codex-console - registration, payment, token management, and batch operations |
| triggers | ["help me automate OpenAI account registration","set up codex-console for batch account creation","configure email services for codex account automation","manage OpenAI accounts with codex-console","automate OpenAI subscription and payment binding","export and upload OpenAI tokens to API gateway","troubleshoot codex-console registration issues","configure auto-replenishment for OpenAI accounts"] |
codex-console Automation Skill
Skill by ara.so — Codex Skills collection.
Overview
codex-console is a comprehensive automation platform for managing OpenAI accounts at scale. It handles registration, login, token extraction, subscription management, payment binding, auto-replenishment, and integration with API gateways like CPA, Sub2API, Team Manager, and New-API.
This is a maintained fork that fixes compatibility issues with OpenAI's evolving authentication flow, including Sentinel POW solving, split registration/login flows, and improved OTP handling.
Key capabilities:
- Web UI for task management and monitoring
- Batch account registration with email service integration
- Semi-automated payment card binding with 3DS support
- Automated token refresh and upload to API gateways
- Self-check and repair system
- Auto-replenishment based on inventory levels
- Tag-based account pooling and team management
- SQLite or PostgreSQL backend
Installation
Using Python (Recommended for Development)
git clone https://github.com/dou-jiang/codex-console.git
cd codex-console
uv sync
pip install -r requirements.txt
Using Docker
docker-compose up -d
docker run -d \
-p 1455:1455 \
-p 6080:6080 \
-e WEBUI_HOST=0.0.0.0 \
-e WEBUI_PORT=1455 \
-e WEBUI_ACCESS_PASSWORD=your_secure_password \
-v $(pwd)/data:/app/data \
--name codex-console \
ghcr.io/dou-jiang/codex-console:latest
Building Standalone Executable
build.bat
bash build.sh
The executable will be in dist/codex-console-windows-X64.exe or equivalent.
Configuration
Environment Variables
Create .env from template:
cp .env.example .env
Key variables:
APP_HOST=0.0.0.0
APP_PORT=8000
APP_ACCESS_PASSWORD=admin123
APP_DATABASE_URL=data/database.db
APP_DATABASE_URL=postgresql://user:password@host:5432/dbname
LOG_LEVEL=info
DEBUG=false
Priority: CLI args > .env > database settings > defaults
First-Time Setup
- Start the web UI:
python webui.py --access-password mypassword
-
Access at http://127.0.0.1:8000
-
Configure in Settings page:
- Email service credentials
- Proxy settings
- Upload targets (CPA/Sub2API/New-API)
- Payment automation options
Core Usage Patterns
Starting the Web UI
import uvicorn
from src.web.app import app
from src.utils.settings import get_settings
if __name__ == "__main__":
settings = get_settings()
uvicorn.run(
app,
host=settings.app_host,
port=settings.app_port,
log_level=settings.log_level.lower()
)
CLI options:
python webui.py
python webui.py --host 0.0.0.0 --port 8080
python webui.py --access-password mypassword
python webui.py --debug
Email Service Integration
codex-console supports multiple email providers:
from src.services.email_service import EmailServiceFactory
email_config = {
"service_type": "cloudmail",
"api_key": None,
"config": {
"base_url": "https://api.cloudmail.com",
"timeout": 30
}
}
service = EmailServiceFactory.create(email_config)
otp = await service.get_verification_code(
email="test@example.com",
timeout=60
)
Supported services:
- CloudMail (API-based)
- LuckMail (API-based)
- YYDS Mail (API-based)
- Outlook (self-hosted accounts)
Registration Flow
from src.core.register import RegisterService
from src.models.task import RegisterTask
async def register_account(email: str, password: str, proxy: str):
"""Register a new OpenAI account"""
task = RegisterTask(
email=email,
password=password,
proxy=proxy,
status="pending"
)
service = RegisterService(task)
result = await service.execute()
return result
Key steps handled:
- Sentinel POW solving
- Email verification (auto-fetch from email service)
- Split registration/login flow
- Token extraction
- Workspace caching
Batch Registration
from src.core.auto_register import AutoRegisterService
async def batch_register(count: int):
"""Register multiple accounts"""
service = AutoRegisterService()
await service.configure({
"target_count": count,
"email_service": "cloudmail",
"proxy_pool": "residential",
"auto_upload": True,
"upload_target": "newapi"
})
await service.start()
status = await service.get_status()
Payment Binding
from src.core.payment import PaymentService
from src.models.task import BindCardTask
async def bind_payment_card(account_id: int, card_info: dict):
"""Bind payment card to account (semi-automated)"""
task = BindCardTask(
account_id=account_id,
card_number=card_info["number"],
expiry=card_info["expiry"],
cvv=card_info["cvv"],
billing_address={
"street": "auto-generated",
"city": "New York",
"state": "NY",
"zip": "10001",
"country": "US"
},
status="pending"
)
service = PaymentService(task)
result = await service.execute()
return result
Token Management
from src.core.account_manager import AccountManager
from src.models.account import Account
async def refresh_account_token(account_id: int):
"""Refresh access token for an account"""
manager = AccountManager()
account = await manager.get_account(account_id)
new_token = await manager.refresh_token(account)
await manager.upload_to_targets(account)
return new_token
Auto-Upload to API Gateways
from src.services.upload_service import UploadService
async def upload_account(account_id: int, target: str):
"""Upload account to API gateway"""
service = UploadService()
result = await service.upload(
account_id=account_id,
target=target
)
return result
New-API configuration example:
newapi_config = {
"base_url": "https://api.example.com",
"api_key": None,
"auto_upload": True,
"upload_on_register": True,
"quota_per_account": 20
}
Task Management
from src.services.task_service import TaskService
async def manage_tasks():
"""Unified task management"""
service = TaskService()
task_id = await service.create_task(
task_type="register",
count=10,
config={"email_service": "cloudmail"}
)
await service.pause_task(task_id)
await service.resume_task(task_id)
await service.cancel_task(task_id)
await service.retry_task(task_id)
status = await service.get_task_status(task_id)
Auto-Replenishment
from src.core.auto_replenishment import AutoReplenishmentService
async def configure_auto_replenish():
"""Configure automatic account replenishment"""
service = AutoReplenishmentService()
await service.configure({
"enabled": True,
"min_threshold": 10,
"target_count": 50,
"check_interval": 3600,
"max_daily_registers": 100
})
await service.start()
Self-Check and Repair
from src.services.selfcheck import SelfCheckService
async def run_system_selfcheck():
"""Run comprehensive system self-check"""
service = SelfCheckService()
results = await service.run_all_checks()
if results["has_issues"]:
await service.auto_repair(results)
return results
Account Pooling and Tags
from src.core.account_manager import AccountManager
async def manage_account_pools():
"""Organize accounts with tags and pools"""
manager = AccountManager()
await manager.update_account(
account_id=123,
updates={
"role_tag": "team_member",
"biz_tag": "project_alpha",
"pool_state": "team_pool",
"priority": 5
}
)
team_accounts = await manager.get_accounts_by_pool("team_pool")
project_accounts = await manager.get_accounts_by_tag("project_alpha")
Database Models
Account Model
from sqlalchemy import Column, Integer, String, DateTime, JSON
from src.database import Base
class Account(Base):
__tablename__ = "accounts"
id = Column(Integer, primary_key=True)
email = Column(String, unique=True, nullable=False)
password = Column(String, nullable=False)
access_token = Column(String)
refresh_token = Column(String)
session_token = Column(String)
status = Column(String, default="active")
subscription_status = Column(String)
role_tag = Column(String)
biz_tag = Column(String)
pool_state = Column(String)
priority = Column(Integer, default=0)
quota = Column(Integer, default=0)
workspace_id = Column(String)
last_used_at = Column(DateTime)
created_at = Column(DateTime)
updated_at = Column(DateTime)
upload_status = Column(JSON)
Task Model
from sqlalchemy import Column, Integer, String, DateTime, JSON
from src.database import Base
class RegisterTask(Base):
__tablename__ = "register_tasks"
id = Column(Integer, primary_key=True)
email = Column(String, nullable=False)
password = Column(String, nullable=False)
proxy = Column(String)
status = Column(String, default="pending")
progress = Column(Integer, default=0)
error_message = Column(String)
account_id = Column(Integer)
access_token = Column(String)
created_at = Column(DateTime)
started_at = Column(DateTime)
completed_at = Column(DateTime)
retry_count = Column(Integer, default=0)
API Routes
Account Management
GET /api/accounts?status=active&pool=team_pool&limit=50
GET /api/accounts/123
POST /api/accounts/123/refresh
POST /api/accounts/123/upload
{
"target": "newapi"
}
DELETE /api/accounts/123
Task Management
POST /api/tasks/register
{
"count": 10,
"email_service": "cloudmail",
"auto_upload": true,
"upload_target": "newapi"
}
POST /api/tasks/123/pause
POST /api/tasks/123/resume
POST /api/tasks/123/cancel
POST /api/tasks/123/retry
Export and Import
GET /api/export/accounts?format=codex&pool=team_pool
POST /api/import/accounts
Content-Type: multipart/form-data
file: accounts.json
Common Workflows
Complete Registration Pipeline
import asyncio
from src.core.register import RegisterService
from src.services.upload_service import UploadService
from src.models.task import RegisterTask
async def full_registration_workflow():
"""End-to-end: register account, verify, bind card, upload"""
task = RegisterTask(
email="auto-generated@cloudmail.com",
password="SecurePass123!",
proxy="http://proxy.example.com:8080"
)
reg_service = RegisterService(task)
result = await reg_service.execute()
if not result["success"]:
raise Exception(f"Registration failed: {result['error']}")
account_id = result["account_id"]
from src.core.payment import PaymentService
from src.models.task import BindCardTask
bind_task = BindCardTask(
account_id=account_id,
card_number="encrypted_card_data",
expiry="12/25",
cvv="123",
billing_address={"auto": True}
)
payment_service = PaymentService(bind_task)
payment_result = await payment_service.execute()
upload_service = UploadService()
upload_result = await upload_service.upload(
account_id=account_id,
target=
)
{
: account_id,
: task.email,
: upload_result[]
}
asyncio.run(full_registration_workflow())
Batch Account Refresh
from src.core.account_manager import AccountManager
import asyncio
async def batch_refresh_tokens():
"""Refresh tokens for all active accounts"""
manager = AccountManager()
accounts = await manager.get_accounts(status="active")
results = []
for account in accounts:
try:
new_token = await manager.refresh_token(account)
if manager.settings.auto_upload_on_refresh:
await manager.upload_to_targets(account)
results.append({
"account_id": account.id,
"success": True,
"token": new_token
})
except Exception as e:
results.append({
"account_id": account.id,
"success": False,
"error": str(e)
})
return results
asyncio.run(batch_refresh_tokens())
Scheduled Auto-Replenishment
from apscheduler.schedulers.asyncio import AsyncIOScheduler
from src.core.auto_replenishment import AutoReplenishmentService
scheduler = AsyncIOScheduler()
async def check_and_replenish():
"""Check inventory and trigger replenishment if needed"""
service = AutoReplenishmentService()
status = await service.check_inventory()
if status["current_count"] < status["min_threshold"]:
needed = status["target_count"] - status["current_count"]
await service.start_replenishment(count=needed)
scheduler.add_job(
check_and_replenish,
'interval',
hours=1,
id='auto_replenish'
)
scheduler.start()
Troubleshooting
Sentinel POW Solving Fails
Issue: Registration fails with "Sentinel POW required" error.
Solution: Ensure you're using latest version (v1.1.2+) which includes POW solving:
from src.utils.proxy import test_proxy
result = await test_proxy("http://proxy.example.com:8080")
if not result["sentinel_pass"]:
print("Proxy blocked by Sentinel - use residential proxy")
Email OTP Not Received
Issue: Registration hangs waiting for verification code.
Solution:
- Check email service status in Settings
- Verify API key is set correctly
- Test email service manually:
from src.services.email_service import EmailServiceFactory
service = EmailServiceFactory.create({
"service_type": "cloudmail",
"api_key": "test_key"
})
status = await service.test_connection()
print(status)
Token Refresh Fails
Issue: refresh_token returns 401 Unauthorized.
Solution:
- Check if refresh token is expired (30 days typically)
- Force re-login instead:
from src.core.account_manager import AccountManager
manager = AccountManager()
account = await manager.get_account(account_id)
await manager.re_login(account)
Payment Binding Stuck on 3DS
Issue: Browser opens for 3DS but verification never completes.
Solution:
3DS cannot be automated. Monitor the browser window and:
- Complete 3DS challenge manually
- Wait for callback
- codex-console will detect completion and continue
Database Migration Issues
Issue: Alembic migration fails after update.
Solution:
alembic stamp head
alembic upgrade head
cp data/database.db data/database.db.backup
rm data/database.db
python webui.py
Auto-Upload Not Working
Issue: Accounts registered but not uploaded to New-API/CPA.
Solution:
- Verify upload target is configured in Settings
- Test connection:
from src.services.upload_service import UploadService
service = UploadService()
test_result = await service.test_target("newapi")
print(test_result)
- Enable auto-upload in task config:
{
"auto_upload": true,
"upload_target": "newapi",
"upload_on_register": true
}
High Registration Failure Rate
Issue: Most registration attempts fail.
Solution:
- Use residential proxies - datacenter IPs are often blocked
- Slow down - add delays between attempts
- Check email service quota - may be rate-limited
- Review logs - look for specific error patterns
export LOG_LEVEL=debug
python webui.py
tail -f data/logs/register.log
Port Already in Use
Issue: Address already in use error on startup.
Solution:
codex-console auto-switches ports if 8000 is taken. To force a specific port:
python webui.py --port 8080
Or kill the process using port 8000:
lsof -ti:8000 | xargs kill -9
netstat -ano | findstr :8000
taskkill /PID <PID> /F
Advanced Configuration
Custom Email Service
Implement custom email provider:
from src.services.email_service import BaseEmailService
class CustomEmailService(BaseEmailService):
async def get_verification_code(self, email: str, timeout: int = 60) -> str:
"""Fetch OTP from custom provider"""
pass
async def test_connection(self) -> dict:
"""Test API connectivity"""
pass
EMAIL_SERVICES["custom"] = CustomEmailService
Custom Upload Target
Add new API gateway integration:
from src.services.upload_service import BaseUploadTarget
class CustomUploadTarget(BaseUploadTarget):
async def upload_account(self, account: Account) -> dict:
"""Upload account to custom gateway"""
pass
UPLOAD_TARGETS["custom"] = CustomUploadTarget
Security Best Practices
- Never commit secrets - use environment variables:
export CLOUDMAIL_API_KEY=your_key_here
export NEWAPI_API_KEY=your_key_here
- Change default password immediately:
python webui.py --access-password strong_password_here
- Use PostgreSQL for production - SQLite is development-only:
export APP_DATABASE_URL=postgresql://user:pass@host:5432/db
-
Encrypt sensitive fields - card data, passwords are encrypted at rest
-
Enable audit logging - track all operations:
from src.models.audit import OperationAuditLog
Resources