Skip to main content

AIRelay: an independent OpenAI-compatible local relay for single-user subscription-backed access.

Project description

AIRelay

AIRelay is an independent local OpenAI-compatible HTTP server backed by a ChatGPT subscription login that AIRelay stores independently. It exposes the verified OpenAI-shaped routes this upstream can support, protects the local relay with its own bearer token, and logs every transit to hourly JSONL files.

AIRelay does not require a user-supplied OpenAI platform API key for upstream inference. Instead, it uses the same upstream ChatGPT login protocol that Codex uses while keeping AIRelay auth storage separate from Codex storage. Clients that call AIRelay should use the relay bearer token as the local client credential they present to AIRelay.

Independence And Intended Use

  • AIRelay is an independent third-party project. It is not affiliated with, endorsed by, or sponsored by OpenAI.
  • Provider and product names are used only to describe compatibility targets and upstream behavior.
  • AIRelay is designed for a single user running a local relay for personal convenience.
  • AIRelay is not presented as a shared, pooled, multi-user, or resale service.
  • You are responsible for complying with the terms and usage policies that apply to any upstream account or subscription you use with AIRelay.

See DISCLAIMER.md for the short project notice.

Quick Start

python -m pip install .
airelay init
airelay login
airelay serve --port 8080

If you are installing from a published package instead of a source checkout, use python -m pip install airelay.

Smoke test the public and protected surfaces:

curl http://127.0.0.1:8080/healthz
curl http://127.0.0.1:8080/v1/relay/status \
  -H 'authorization: Bearer YOUR_AIRELAY_TOKEN'

Inspect the resolved relay and upstream-auth state at any point:

airelay status

CLI status and setup commands default to readable terminal output. Use --json on airelay init, airelay status, airelay logout, airelay token show, or airelay token rotate when you need machine-readable output for automation.

Point your client at:

http://127.0.0.1:8080/v1

Use the token generated by airelay init as the client credential when you point an OpenAI-compatible SDK at AIRelay. Standard OpenAI SDKs will then send Authorization: Bearer <relay-token> automatically.

If you want to provide the relay token yourself instead of using the default token file, launch the server with:

AIRELAY_BEARER_TOKEN='YOUR_AIRELAY_TOKEN' airelay serve --port 8080

or point AIRelay at a specific token file:

airelay serve --bearer-token-file /path/to/relay-token --port 8080

What AIRelay Does

  • Uses the same upstream login protocol as Codex browser login and device-code login.
  • Stores upstream auth under AIRelay-owned state instead of reusing ~/.codex.
  • Generates and persists a separate relay bearer token for client-to-relay access.
  • Protects /v1/* and /no-tools/v1/* with bearer auth, per-IP rate limits, concurrent-request caps, and temporary blocks after repeated bad tokens.
  • Exposes OpenAI-compatible routes for:
    • GET /v1/models
    • GET /v1/subscription/status
    • GET /v1/account/rate_limits
    • POST /v1/completions
    • POST /v1/responses
    • POST /v1/chat/completions
    • POST /v1/files
    • GET /v1/files
    • GET /v1/files/{file_id}
    • GET /v1/files/{file_id}/content
    • DELETE /v1/files/{file_id}
    • POST /v1/conversations
    • GET /v1/conversations/{conversation_id}
    • POST /v1/conversations/{conversation_id}
    • DELETE /v1/conversations/{conversation_id}
    • /no-tools/v1/models
    • /no-tools/v1/completions
    • /no-tools/v1/responses
    • /no-tools/v1/chat/completions
  • Logs inbound requests, endpoint rejects, outbound responses, upstream requests, upstream responses, stream lines, and usage summaries to logs/YYYY/MM/DD-HH.log.

First-Run Flow

  1. airelay init
    • writes ~/.config/airelay/config.toml if it does not already exist
    • creates ~/.airelay/relay-token with 0600 permissions if a relay token is missing
    • prints a formatted setup summary and reveals the token only when it was newly created
  2. airelay login
    • creates an AIRelay-owned ChatGPT subscription session
  3. airelay serve --port 8080
    • starts the protected local endpoint
    • fails fast if bearer auth is enabled but no relay token is configured
    • prints the client base URL, token file path, and the required Authorization header shape

You can show the current relay token at any time:

airelay token show

You can also rotate the relay token later:

airelay token rotate

Example Client Usage

Python with the OpenAI SDK:

from openai import OpenAI

client = OpenAI(
    base_url="http://127.0.0.1:8080/v1",
    api_key="YOUR_AIRELAY_TOKEN",
)

response = client.responses.create(
    model="gpt-5.4-mini",
    input="Summarize the purpose of AIRelay.",
)
print(response.output_text)

Raw curl:

curl http://127.0.0.1:8080/v1/responses \
  -H 'authorization: Bearer YOUR_AIRELAY_TOKEN' \
  -H 'content-type: application/json' \
  -d '{
    "model": "gpt-5.4-mini",
    "input": "Summarize the purpose of AIRelay.",
    "stream": false
  }'

Shell example with the OpenAI Python SDK environment variables:

export OPENAI_BASE_URL='http://127.0.0.1:8080/v1'
export OPENAI_API_KEY="$(tr -d '\n' < ~/.airelay/relay-token)"

Verified Compatibility Boundary

This server is intentionally explicit about what is and is not verified.

  • Inference uses https://chatgpt.com/backend-api/codex.
  • Subscription status uses https://chatgpt.com/backend-api/wham/usage.
  • The upstream requires stream=true, so non-stream OpenAI responses are reconstructed locally from streamed event sequences.
  • The upstream requires store=false, so requests that try to enable upstream storage are rejected with 422.
  • The upstream requires non-empty instructions, so the compatibility layer injects the minimal verified placeholder "." only when the caller omitted instructions entirely.
  • Image input is supported.
  • Text and JSON-like document input is supported by local inlining up to 1 MB.
  • Local file uploads are capped at 32 MiB each and 256 MiB total by default.
  • Audio input, embeddings, image generation, realtime sessions, and other unverified routes return explicit 501 unsupported_error.

Security Defaults

  • Listener default: 127.0.0.1:8080
  • Protected routes: /v1/* and /no-tools/v1/*
  • Public routes: / and a minimal GET /healthz
  • Protected diagnostics: GET /v1/relay/status
  • Relay auth: bearer token required by default
  • Token storage: ~/.airelay/relay-token
  • Default rate limit: 120 requests/minute with burst 40
  • Default concurrent request cap: 8 per IP
  • Default repeated-auth-failure block: 8 bad attempts in 300 seconds -> 900 second block

See Security for the full behavior.

Configuration

AIRelay reads configuration in this order:

  1. explicit CLI flags such as --config, --port, or --auth-storage
  2. AIRELAY_* environment variables
  3. legacy OPENAI_ENDPOINT_* environment variables where supported as a migration fallback
  4. ~/.config/airelay/config.toml
  5. built-in defaults

auth.storage = "auto" prefers the AIRelay keyring namespace and falls back to ~/.airelay/auth.json when keyring access is unavailable.

Important paths:

  • config: ~/.config/airelay/config.toml
  • data dir: ~/.airelay
  • upstream auth fallback file: ~/.airelay/auth.json
  • logs: ~/.airelay/logs
  • relay token: ~/.airelay/relay-token

To override the default token source at launch time:

  • AIRELAY_BEARER_TOKEN
  • airelay serve --bearer-token-file /path/to/relay-token

See Configuration for field details and a sample config.

Publication Surface

  • package name: airelay
  • CLI command: airelay
  • legacy CLI alias kept for migration: openai-endpoint
  • Python package: airelay

Documentation

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

airelays-0.2.0.tar.gz (62.8 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

airelays-0.2.0-py3-none-any.whl (45.1 kB view details)

Uploaded Python 3

File details

Details for the file airelays-0.2.0.tar.gz.

File metadata

  • Download URL: airelays-0.2.0.tar.gz
  • Upload date:
  • Size: 62.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.13

File hashes

Hashes for airelays-0.2.0.tar.gz
Algorithm Hash digest
SHA256 d53f420e6b213d6e3fb28dcf7fc176273d9e0a10ff9c564c6636f0204b330c5d
MD5 645cd636d337cfa93170175137bcce8a
BLAKE2b-256 dbb64dd5c280f7533b7ec7dc1bfa425d6635417c38a8f8aef7fe837ac096e08e

See more details on using hashes here.

File details

Details for the file airelays-0.2.0-py3-none-any.whl.

File metadata

  • Download URL: airelays-0.2.0-py3-none-any.whl
  • Upload date:
  • Size: 45.1 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.13

File hashes

Hashes for airelays-0.2.0-py3-none-any.whl
Algorithm Hash digest
SHA256 283f8b810964ed9122e2ea2dd03e2f806e9b4b7b1965c030642f1d96c6519541
MD5 c0201671315616561ba86aad518ad804
BLAKE2b-256 884877f6626bea4b07a7301d86c5ac0c89276466bf57a22f48b1958017029d4c

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page