AIR

OpenRouter

Import: from air.providers.openrouter import OpenRouterProvider

Class name: OpenRouterProvider

Provider name: "openrouter"

Constructor

python
OpenRouterProvider(
    api_key: str,
    model: str,
    base_url: str = "https://openrouter.ai/api/v1",
    timeout: float = 60.0,
    transport: httpx.AsyncBaseTransport | None = None,
)
  • api_key (required): your OpenRouter API key. Raises AuthenticationError immediately if empty.
  • model (required): any OpenRouter model identifier, including free models, for example "meta-llama/llama-3.1-405b", unless overridden per request by ChatRequest.model.
  • base_url, timeout, transport: same meaning as the other providers.

Authentication

No environment variable is read automatically. Pass your key explicitly, for example os.environ["OPENROUTER_API_KEY"].

Minimal setup

python
import os
from air import AIR
from air.providers.openrouter import OpenRouterProvider
 
air = AIR()
air.add_provider(
    OpenRouterProvider(api_key=os.environ["OPENROUTER_API_KEY"], model="meta-llama/llama-3.1-405b")
)
response = await air.chat("Hello")

Request format

Sends a POST to {base_url}/chat/completions with an OpenAI compatible body: {"model": ..., "messages": [{"role": ..., "content": ...}, ...]}, plus temperature and max_tokens if set.

Response parsing

Reads choices[0].message.content for the reply, model for the model actually used, and usage.prompt_tokens / usage.completion_tokens / usage.total_tokens if present.

Error behavior

  • HTTP 402: always QuotaExceededError ("insufficient credits").
  • HTTP 401 or 403: QuotaExceededError if the message mentions credit, quota, or billing; otherwise AuthenticationError.
  • HTTP 429: same keyword check; QuotaExceededError if matched, otherwise RateLimitError.
  • Any other HTTP 400+: ProviderAPIError.
  • Network timeout: ProviderTimeoutError.
  • Other network/connection errors: ProviderAPIError.
  • Non-JSON or unexpected response shape: ProviderResponseError.

Limitations

OpenRouter proxies many upstream models; error message text and available fields can vary by the underlying model. OpenRouterProvider classifies based on HTTP status and message keywords, which may not perfectly capture every upstream provider's error semantics. OpenRouter does not expose a remaining-quota endpoint that AIR queries directly; capacity tracking only reflects usage OpenRouter reports on each response.