NouveauBranchez n’importe quel agent sur UberLLM : une clé, tous les modèles, au prix catalogue ou moins.
UberLLM

Apps : faites-vous référencer et permettez aux utilisateurs de se connecter

Deux choses pour les personnes qui développent des applications sur UberLLM. Les deux fonctionnent de la même manière que sur OpenRouter, donc une application qui les utilise déjà n'a qu'à changer la base URL.

  1. Faites-vous référencer. Envoyez deux headers et votre application apparaît sur uberllm.dev/apps, classée par les tokens qu'elle envoie. Les pages des modèles listent les applications qui les utilisent le plus.
  2. Permettez aux utilisateurs de se connecter. Envoyez les utilisateurs vers UberLLM, ils disent oui, et votre application obtient une API key sur leur compte. Ils paient pour leur propre utilisation ; vous ne gérez jamais leurs détails de paiement.

Se faire lister dans le classement des applications

Ajoutez ces en-têtes à vos requêtes (chat, messages ou médias, n'importe quel endpoint) :

En-tête Ce qu'il fait
HTTP-Referer L'adresse de votre application, par exemple https://myapp.com. Obligatoire : c'est ce qui identifie votre application. Referer fonctionne aussi.
X-Title Le nom de votre application tel que les gens devraient le voir. X-OpenRouter-Title fonctionne aussi.
X-OpenRouter-Categories Optionnel. Jusqu'à 2 des catégories ci-dessous, séparées par des virgules.
X-OpenRouter-App-Visibility Optionnel. hidden maintient une nouvelle application hors du classement public.
curl https://api.uberllm.dev/v1/chat/completions \
  -H "Authorization: Bearer $UBERLLM_API_KEY" \
  -H "Content-Type: application/json" \
  -H "HTTP-Referer: https://myapp.com" \
  -H "X-Title: My App" \
  -H "X-OpenRouter-Categories: cli-agent" \
  -d '{"model":"deepseek/deepseek-v4-flash","messages":[{"role":"user","content":"Hello"}]}'

Avec le SDK OpenAI :

import OpenAI from 'openai';

const client = new OpenAI({
  baseURL: 'https://api.uberllm.dev/v1',
  apiKey: process.env.UBERLLM_API_KEY,
  defaultHeaders: {
    'HTTP-Referer': 'https://myapp.com',
    'X-Title': 'My App',
  },
});

Comment c'est compté :

  • Seule l'adresse est conservée : https://myapp.com/some/page?user=… est stocké comme https://myapp.com. Les chemins, les chaînes de requête et les identifiants sont supprimés. Un lien GitHub, GitLab, Codeberg, Bitbucket ou Hugging Face conserve son owner/repo, afin que les applications open-source obtiennent leur propre entrée.
  • Le nom est coupé à 60 caractères. Les caractères cachés et de contrôle sont supprimés.
  • Le premier compte qui envoie du trafic pour une application définit son nom et ses catégories. Le trafic des autres comptes compte toujours pour l'application, mais ne peut pas la renommer.
  • Les adresses sur votre propre machine ou réseau (localhost, 127.0.0.1, IPs privées, *.local) ne sont jamais affichées publiquement.
  • Les requêtes des navigateurs envoient Referer d'elles-mêmes, donc une application web est comptée même sans les en-têtes. Ajoutez X-Title pour choisir son nom.
  • Le classement compte les requêtes qui ont été répondues, par tokens, sur les 24 dernières heures, 7 derniers jours ou 30 derniers jours. Il se rafraîchit toutes les quelques minutes.

Catégories : cli-agent, ide-extension, cloud-agent, programming-app, native-app-builder, creative-writing, video-gen, image-gen, audio-gen, writing-assistant, general-chat, personal-agent, legal, roleplay, game. Les catégories inconnues sont ignorées. Une application en conserve jusqu'à 10.

Le classement est aussi une API : GET https://uberllm.dev/api/v1/public/apps?period=day|week|month&category=<slug>.

Connecter UberLLM (OAuth PKCE)

Votre application obtient une clé sur le compte de l'utilisateur, nommée d'après votre application. L'utilisateur peut définir une limite de dépenses pour celle-ci en l'autorisant, et peut la désactiver à tout moment sur sa page des clés.

1. Créer un vérificateur de code et un défi

Le vérificateur est une chaîne aléatoire que vous conservez (43 à 128 caractères). Le défi est son SHA-256, encodé en base64url sans remplissage.

function base64url(bytes) {
  return btoa(String.fromCharCode(...new Uint8Array(bytes)))
    .replace(/\+/g, '-').replace(/\//g, '_').replace(/=+$/, '');
}

const codeVerifier = base64url(crypto.getRandomValues(new Uint8Array(32)));
const codeChallenge = base64url(
  await crypto.subtle.digest('SHA-256', new TextEncoder().encode(codeVerifier)),
);
sessionStorage.setItem('uberllm_verifier', codeVerifier);

2. Envoyer l'utilisateur vers UberLLM

https://uberllm.dev/auth?callback_url=https://myapp.com/uberllm/callback&code_challenge=<CHALLENGE>&code_challenge_method=S256
Paramètre
callback_url Où l'utilisateur est redirigé. Doit être https:// ; http://localhost (n'importe quel port) est autorisé pour le développement. Omettez-le pour afficher le code à l'écran afin que l'utilisateur puisse le coller dans votre application.
code_challenge De l'étape 1. Obligatoire.
code_challenge_method S256. Obligatoire. plain n'est pas accepté.
key_label Nom facultatif pour la clé (par défaut : le nom de votre application).
state Facultatif. Renvoyé inchangé avec le code, afin que vous puissiez vérifier que la réponse correspond à la requête que vous avez initiée.

L'utilisateur se connecte (ou s'inscrit), voit "Votre application souhaite utiliser votre crédit UberLLM", et choisit Autoriser ou Annuler. En cas d'Autoriser, ils sont redirigés vers :

https://myapp.com/uberllm/callback?code=<CODE>&state=<STATE>

En cas d'Annuler, rien n'est envoyé.

3. Échanger le code contre une clé

const code = new URLSearchParams(location.search).get('code');
const res = await fetch('https://uberllm.dev/api/v1/auth/keys', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({
    code,
    code_verifier: sessionStorage.getItem('uberllm_verifier'),
    code_challenge_method: 'S256',
  }),
});
const { key } = await res.json(); // ull_…  Store it like a password.
curl https://uberllm.dev/api/v1/auth/keys \
  -H "Content-Type: application/json" \
  -d '{"code":"<CODE>","code_verifier":"<VERIFIER>","code_challenge_method":"S256"}'

La réponse est {"key": "ull_…", "key_id": "…", "name": "My App"}. Utilisez la clé comme Authorization: Bearer sur https://api.uberllm.dev/v1. L'endpoint répond aux requêtes du navigateur depuis n'importe quel site (CORS), il fonctionne donc depuis une application web.

Statut Code Signification
400 invalid_code_challenge_method Utilisez S256.
403 invalid_code Code incorrect ou code_verifier, ou le code a déjà été utilisé.
403 code_expired Les codes sont valides pendant 10 minutes. Recommencez à partir de l'étape 2.
405 method_not_allowed Utilisez POST.
429 rate_limited Trop de tentatives depuis une même adresse ; attendez une minute.

Un code ne fonctionne qu'une seule fois. Un code_verifier incorrect l'épuise également, donc un code qui a fuité ne peut pas être deviné.

Différences avec OpenRouter

  • code_challenge est obligatoire et seul S256 est accepté (OpenRouter accepte également plain ou aucun défi). Sans cela, quiconque voit le code dans l'historique du navigateur ou un journal pourrait s'emparer de la clé.
  • workspace_id / required_workspace_id ne sont pas utilisés : un compte UberLLM n'a qu'un seul solde.