Standard library
package main
import (
"bytes"
"encoding/json"
"fmt"
"io"
"net/http"
"os"
"time"
)
type chatReq struct {
Model string `json:"model"`
Messages []msg `json:"messages"`
}
type msg struct {
Role string `json:"role"`
Content string `json:"content"`
}
func main() {
body, _ := json.Marshal(chatReq{
Model: "auto",
Messages: []msg{{Role: "user", Content: "hi"}},
})
req, _ := http.NewRequest("POST",
"https://api.routeur.ai/v1/chat/completions",
bytes.NewReader(body))
req.Header.Set("Authorization", "Bearer "+os.Getenv("ROUTEUR_KEY"))
req.Header.Set("Content-Type", "application/json")
client := &http.Client{Timeout: 30 * time.Second}
res, err := client.Do(req)
if err != nil { panic(err) }
defer res.Body.Close()
out, _ := io.ReadAll(res.Body)
fmt.Println(string(out))
}
Official OpenAI Go client
The official openai-go package lets you set a base URL:
import (
"context"
"os"
"github.com/openai/openai-go"
"github.com/openai/openai-go/option"
)
client := openai.NewClient(
option.WithAPIKey(os.Getenv("ROUTEUR_KEY")),
option.WithBaseURL("https://api.routeur.ai/v1/"),
)
res, err := client.Chat.Completions.New(context.TODO(),
openai.ChatCompletionNewParams{
Model: openai.F("auto"),
Messages: openai.F([]openai.ChatCompletionMessageParamUnion{
openai.UserMessage("hi"),
}),
})
Choosing a model
Every request picks an upstream model in one of three ways — in this order of precedence:
- Routeur-* request headers. If
Routeur-ProviderorRouteur-Modelare set, they win, regardless of what is in the body. Useful from middleware or transports that can't change the JSON. - An explicit upstream id in the
modelfield. Pass something like"gpt-4o-mini"or"claude-3-5-sonnet"to bypass routing rules and pin the request to that model. "auto"(or any alias). Lets routeur.ai pick the upstream model from your routing rules. This is the recommended default.
Force a specific provider+model on a single call via headers:
req.Header.Set("Routeur-Provider", "openai")
req.Header.Set("Routeur-Model", "gpt-4o")