LLM gateway

One key in front of every model.

Relays puts one API in front of every provider you already call. Keep your SDK, keep your wire protocol, change one line. Every call comes back with a receipt.

Change one line.

The base URL is the migration. Your client, your request bodies, your streaming loop and your error handling all stay where they are.

triage.py

import osfrom openai import OpenAIclient = OpenAI(    base_url="https://api.relays.ai/v1",the only edit    api_key=os.environ["RELAYS_API_KEY"],)stream = client.chat.completions.create(    model="relays/support-triage",    messages=[{"role": "user", "content": "Summarize this thread."}],    stream=True,)

Washttps://api.openai.com/v1

Nowhttps://api.relays.ai/v1

Every provider, one key.

Relays holds your upstream credentials and issues one key to your application. Aliases sit in front of provider model IDs, so an upstream model change never reaches your code.

11 connections · bring your own upstream key
ProviderTypeWire protocolEndpointsUpstream base URL
OpenAIDirect model providerOpenAI
  • Chat Completions
  • Responses
https://api.openai.com/v1
AnthropicDirect model providerAnthropic
  • Messages
https://api.anthropic.com/v1
GeminiDirect model providerOpenAI-compatible
  • Chat Completions
https://generativelanguage.googleapis.com/v1beta/openai
Mistral AIDirect model providerOpenAI-compatible
  • Chat Completions
https://api.mistral.ai/v1
DeepSeekDirect model providerOpenAI-compatible
  • Chat Completions
https://api.deepseek.com/v1
GroqInference providerOpenAI-compatible
  • Chat Completions
  • Responses
https://api.groq.com/openai/v1
Together AIInference providerOpenAI-compatible
  • Chat Completions
https://api.together.xyz/v1
Fireworks AIInference providerOpenAI-compatible
  • Chat Completions
https://api.fireworks.ai/inference/v1
OpenRouterModel routing platformOpenAI-compatible
  • Chat Completions
https://openrouter.ai/api/v1
vLLMSelf-hosted inference runtimeOpenAI-compatible
  • Chat Completions
http://localhost:8000/v1
OllamaLocal model runtimeOpenAI-compatible
  • Chat Completions
http://localhost:11434/v1

Native contracts stay native.

Relays speaks the protocols your SDK already speaks. It does not flatten them into a lowest common denominator on the way through.

  1. POST /v1/chat/completionsOpenAI SDK and every OpenAI-compatible client
  2. POST /v1/responsesOpenAI SDK, Responses API
  3. POST /v1/messagesAnthropic SDK
Relays edgeapi.relays.ai

Passes through unchanged

Streaming
Server-sent events arrive in the shape the provider emits them.
Tools
Tool calls go out and tool results come back unchanged.
Reasoning
Reasoning content stays attached to the response.
Prompt caching
Cache directives reach the upstream provider intact.

A receipt per call.

Every request records the decision behind it: the alias you called, the providers Relays tried, what came back, and the estimated cost.

Route receiptIllustrative · syntheticreq_7c41ba9e
Endpoint
POST /v1/chat/completions
Alias
relays/support-triage
Attempt 1
openai/gpt-5.6-luna · 429 rate limited · not served
Attempt 2
moonshot/kimi-k3 · 200 · served
Tokens
1,284 in · 512 out
Est. cost
$0.041
Synthetic values, shown to illustrate the fields a receipt carries.

The route is a decision you can read back.

Attempts, tokens, and estimated cost stay tied to the request that caused them, so you can explain spend per call instead of per invoice.

See how a route is chosen

Point your SDK at Relays.

Bring the client you already wrote. We set up the key, the aliases, and the first route with you.

Start a conversation