Model Router Client Credentials
Build a service app that calls the OpenAI-compatible Model Router with OAuth client credentials
Overview
This example shows a backend service using OAuth client credentials to call the OpenAI-compatible Model Router.
Use this pattern for services, automation jobs, bots, and server-side applications that should authenticate as an app. The app receives a short-lived OAuth access token with the llm:proxy scope, then uses that token as the Model Router bearer token.
The full example is available at github.com/archestra-ai/examples/tree/main/model-router-client-credentials.
What the App Does
- Uses an OAuth client created on the LLM Proxy page
- Exchanges
client_idandclient_secretfor an access token - Sends the access token to
/v1/model-router/chat/completions
OAuth client credentials do not use a browser consent screen and do not inherit a user's Model Provider keys. Provider access comes from the OAuth client's provider key mappings.
Run the Example
Go to LLM Proxy, open the OAuth Clients tab, and create an OAuth client. Map the provider keys it can use, and copy the generated secret.
Then run:
git clone https://github.com/archestra-ai/examples
cd examples/model-router-client-credentials
cp .env.example .env
Set these values in .env:
OAUTH_CLIENT_ID=<client id>
OAUTH_CLIENT_SECRET=<client secret>
MODEL=openai:gpt-4o-mini
Install dependencies and run:
npm install
npm start
OAuth Routes Used
The example uses these Archestra OAuth routes:
| Route | Purpose |
|---|---|
/.well-known/oauth-authorization-server | OAuth server metadata |
/api/auth/oauth2/token | Client-credentials token exchange |
The token exchange includes:
grant_type=client_credentials
client_id=<client id>
client_secret=<client secret>
scope=llm:proxy
Model Router Call
After token exchange, the app calls the OpenAI-compatible Model Router:
curl -X POST "http://localhost:9000/v1/model-router/chat/completions" \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"model": "openai:gpt-4o-mini",
"messages": [{"role": "user", "content": "Hello"}]
}'
The requested model prefix determines which provider mapping is needed on the OAuth client.
