Configuration¶
AIRelays resolves settings in this order:
- CLI flags
AIRELAYS_*environment variables- legacy
OPENAI_ENDPOINT_*migration variables where supported ~/.config/airelays/config.toml- built-in defaults
Default Paths¶
- config:
~/.config/airelays/config.toml - data dir:
~/.airelays - logs dir:
~/.airelays/logs - auth fallback file:
~/.airelays/auth.json - relay token file:
~/.airelays/relay-token
Earlier singular AIRelay paths remain compatible for local upgrades.
Sample Config¶
[server]
host = "127.0.0.1"
port = 8080
[paths]
data_dir = "~/.airelays"
logs_dir = "~/.airelays/logs"
[auth]
storage = "auto"
browser_open = false
login_timeout_seconds = 900
[upstream]
base_url = "https://chatgpt.com/backend-api/codex"
issuer_base_url = "https://auth.openai.com"
client_id = "app_EMoamEEZ73f0CkXaXp7hrann"
client_version = "0.124.0"
request_timeout_seconds = 120.0
[security]
require_bearer_auth = true
bearer_token_file = "~/.airelays/relay-token"
auto_generate_bearer_token = false
rate_limit_per_minute = 120
rate_limit_burst = 40
concurrent_requests_per_ip = 8
failed_auth_window_seconds = 300
failed_auth_max_attempts = 8
failed_auth_block_seconds = 900
trust_x_forwarded_for = false
[uploads]
max_upload_bytes = 33554432
max_total_upload_bytes = 268435456
[logging]
# Opt-in: log every raw upstream SSE line. Hundreds of records per
# streamed response (~50x log growth under load); summary records
# (request, usage, response, errors) are always logged regardless.
stream_lines = false
[providers.openai]
enabled = true
models_cache_ttl_seconds = 300.0
# Multi-account routing: "balanced" (default) routes to the account with
# the most remaining weekly quota so consumption equalizes as a
# percentage of each plan's capacity; "round_robin" sends equal request
# counts; "ordered" drains the first account first.
balance = "balanced"
# Extra model ids to advertise in /v1/models beyond the upstream catalog,
# which lags what the backend actually serves (requests for unlisted ids
# pass through regardless; the upstream stays the final authority).
extra_models = ["gpt-5.6-sol", "gpt-5.6-terra"]
# Fallback bench duration (seconds) when a limited account's reset time is
# unknown; upstream-reported reset times are used when available.
account_cooldown_seconds = 300
# Automatic retry for failed upstream LLM calls. Each retry re-runs the
# full account-pool failover pass, then waits the next backoff delay.
# 0 disables. A schedule shorter than the attempt count repeats its last
# delay. Retries only happen before any response byte reached the client
# (non-streaming requests, and the pre-header phase of streaming ones);
# retries that cannot succeed (a quota window that resets far beyond the
# backoff budget) are skipped so the honest 429 is not delayed.
retry_attempts = 3
retry_backoff_seconds = [5, 20, 60]
[providers.claude]
enabled = false
bin = "claude"
timeout_seconds = 600.0
max_concurrent_requests = 2
strip_api_key_env = true
models = ["claude:sonnet", "claude:opus", "claude:haiku", "claude:fable"]
Important Environment Variables¶
AIRELAYS_CONFIGAIRELAYS_HOSTAIRELAYS_PORTAIRELAYS_DATA_DIRAIRELAYS_LOGS_DIRAIRELAYS_AUTH_STORAGEAIRELAYS_BROWSER_OPENAIRELAYS_LOGIN_TIMEOUT_SECONDSAIRELAYS_UPSTREAM_BASE_URLAIRELAYS_ISSUER_BASE_URLAIRELAYS_CLIENT_IDAIRELAYS_CLIENT_VERSIONAIRELAYS_REQUEST_TIMEOUT_SECONDSAIRELAYS_REQUIRE_BEARER_AUTHAIRELAYS_BEARER_TOKENAIRELAYS_BEARER_TOKEN_FILEAIRELAYS_LOG_STREAM_LINESAIRELAYS_ENABLE_OPENAIAIRELAYS_OPENAI_MODELS_CACHE_TTL_SECONDSAIRELAYS_OPENAI_BALANCE(balanceddefault,round_robin, orordered)AIRELAYS_OPENAI_EXTRA_MODELS(comma-separated ids advertised beyond the upstream catalog)AIRELAYS_OPENAI_ACCOUNT_COOLDOWN_SECONDSAIRELAYS_OPENAI_RETRY_ATTEMPTS(automatic retries for failed upstream calls;3default,0disables)AIRELAYS_OPENAI_RETRY_BACKOFF_SECONDS(comma-separated wait before each retry;5,20,60default)AIRELAYS_ENABLE_CLAUDE(legacyAIRELAYS_ENABLE_CLAUDE_EXPERIMENTALis still honored)AIRELAYS_CLAUDE_BINAIRELAYS_CLAUDE_TIMEOUT_SECONDSAIRELAYS_CLAUDE_MAX_CONCURRENT_REQUESTSAIRELAYS_CLAUDE_STRIP_API_KEY_ENVAIRELAYS_CLAUDE_MODELS
Relay Token Inputs¶
AIRelays resolves the relay token in this order:
AIRELAYS_BEARER_TOKEN- the configured
bearer_token_file
Override examples:
AIRELAYS_BEARER_TOKEN='YOUR_AIRELAYS_TOKEN' airelays serve --port 8080
airelays serve --bearer-token-file /path/to/relay-token --port 8080
Provider Notes¶
OpenAI runtime:
- enabled by default
- uses AIRelays-owned auth storage
airelays loginmanages its subscription session- caches successful upstream model-list responses for
models_cache_ttl_secondsseconds by default - the model-list cache is process-local, in-memory, and disabled when
models_cache_ttl_seconds = 0 - cache state is visible under
providers.openai.models_cacheinGET /v1/relay/status
AIRELAYS_MODELS_CACHE_TTL_SECONDS remains accepted as a shorter alias for
AIRELAYS_OPENAI_MODELS_CACHE_TTL_SECONDS.
Claude runtime:
- enabled by default; set
[providers.claude].enabled = falseorAIRELAYS_ENABLE_CLAUDE=falseto opt out (requests still require the localclaudeCLI to be installed and signed in) - uses the local
claudeCLI - browser login is handled by
claude auth login --claudeai - headless login is handled by
claude setup-tokenplusCLAUDE_CODE_OAUTH_TOKEN - follows the relay's protected or open local auth mode
- requires loopback binding