all docs
/ integrations

OpenRouter integration

Run OpenRouter traffic through the ACE gateway: endpoint, the headers a call sets, what passes through untouched, and a runnable example.

OpenRouter is the openai channel pointed at https://openrouter.ai/api/v1, and it works today. The ACE key is the SDK's api_key; the OpenRouter key rides on x-ace-openai-key and is used for that call only. Model slugs and OpenRouter's own body fields (models, provider, transforms) reach OpenRouter as sent, and x-ace-served-by names the channel (openai), not the host. Storing the OpenRouter key as the tenant's openai vendor key, with https://openrouter.ai/api/v1 as its endpoint, replaces both headers. The cURL form is under Provider Integrations → OpenAI; the AI SDK form is in the Vercel AI SDK guide.

Endpoint: https://engine.acefleet.dev/v1/chat/completions · also https://engine.acefleet.dev/v1/responses. ACE credential: Authorization: Bearer ace_dev_....

Topology Shape
ACE in front Client → ACE → https://openrouter.ai/api/v1, as the openai channel pointed at OpenRouter.
ACE behind Not offered.
Header Required Description
x-ace-openai-key Yes The OpenRouter key (sk-or-v1-...), used for this call only.
x-ace-openai-base-url Yes https://openrouter.ai/api/v1.
x-ace-provider Situational openai, so a slug such as anthropic/claude-sonnet-4.5 is not resolved to the Anthropic channel.

Passed through untouched

  • the model slug, verbatim
  • body fields models, provider, transforms

Storing the OpenRouter key as the openai vendor key with endpoint https://openrouter.ai/api/v1 replaces x-ace-openai-key and x-ace-openai-base-url.

OpenRouter through ACE (Python)

from openai import OpenAI

client = OpenAI(
    base_url="https://engine.acefleet.dev/v1",
    api_key="ace_dev_<your-dev-key>",
    default_headers={
        "x-ace-provider": "openai",
        "x-ace-openai-base-url": "https://openrouter.ai/api/v1",
        "x-ace-openai-key": "sk-or-v1-...",  # OpenRouter key, used for this call only
    },
)

response = client.chat.completions.create(
    model="anthropic/claude-sonnet-4.5",  # OpenRouter's own slug, sent verbatim
    messages=[{"role": "user", "content": "Summarise the failing checks."}],
    # OpenRouter routing fields are relayed as written.
    extra_body={
        "models": ["anthropic/claude-sonnet-4.5", "openai/gpt-4o"],
        "provider": {"sort": "price"},
    },
)
print(response.choices[0].message.content)