NeuVerbinde jeden Agenten mit UberLLM: ein Schlüssel, alle Modelle, zum Listenpreis oder günstiger.
UberLLM

Apps: gelistet werden und Nutzer verbinden

Zwei Dinge für Leute, die Apps auf UberLLM entwickeln. Beide funktionieren genauso wie auf OpenRouter, sodass eine App, die dies bereits tut, nur die base URL ändern muss.

  1. Gelistet werden. Senden Sie zwei headers und Ihre App erscheint auf uberllm.dev/apps, sortiert nach den tokens, die sie sendet. Modellseiten listen die Apps auf, die sie am häufigsten nutzen.
  2. Nutzer verbinden lassen. Leiten Sie Nutzer zu UberLLM weiter, sie stimmen zu, und Ihre App erhält einen API key auf ihrem Konto. Sie zahlen für ihre eigene Nutzung; Sie handhaben niemals ihre Zahlungsdetails.

Im App-Ranking gelistet werden

Fügen Sie diese Header zu Ihren Anfragen hinzu (Chat, Nachrichten oder Medien, jeder Endpoint):

Header Funktion
HTTP-Referer Die Adresse Ihrer App, z.B. https://myapp.com. Erforderlich: Sie identifiziert Ihre App. Referer funktioniert auch.
X-Title Der Name Ihrer App, wie er für Nutzer sichtbar sein soll. X-OpenRouter-Title funktioniert auch.
X-OpenRouter-Categories Optional. Bis zu 2 der untenstehenden Kategorien, kommagetrennt.
X-OpenRouter-App-Visibility Optional. hidden verhindert, dass eine neue App im öffentlichen Ranking erscheint.
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"}]}'

Mit dem OpenAI SDK:

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',
  },
});

So wird gezählt:

  • Nur die Adresse wird gespeichert: https://myapp.com/some/page?user=… wird als https://myapp.com gespeichert. Pfade, Query Strings und Logins werden entfernt. Ein GitHub-, GitLab-, Codeberg-, Bitbucket- oder Hugging Face-Link behält sein owner/repo, damit Open-Source-Apps einen eigenen Eintrag erhalten.
  • Der Name wird auf 60 Zeichen gekürzt. Versteckte Zeichen und Steuerzeichen werden entfernt.
  • Das erste Konto, das Traffic für eine App sendet, legt deren Namen und Kategorien fest. Der Traffic anderer Konten zählt weiterhin für die App, kann sie aber nicht umbenennen.
  • Adressen auf Ihrem eigenen Rechner oder Netzwerk (localhost, 127.0.0.1, private IPs, *.local) werden niemals öffentlich angezeigt.
  • Anfragen von Browsern senden Referer von selbst, sodass eine Web-App auch ohne die Header gezählt wird. Fügen Sie X-Title hinzu, um ihren Namen zu wählen.
  • Das Ranking zählt beantwortete Anfragen, nach Tokens, über die letzten 24 Stunden, 7 Tage oder 30 Tage. Es wird alle paar Minuten aktualisiert.

Kategorien: 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. Unbekannte werden ignoriert. Eine App behält bis zu 10.

Das Ranking ist auch eine API: GET https://uberllm.dev/api/v1/public/apps?period=day|week|month&category=<slug>.

UberLLM verbinden (OAuth PKCE)

Ihre App erhält einen Schlüssel auf dem Konto des Benutzers, benannt nach Ihrer App. Der Benutzer kann beim Erlauben ein Ausgabenlimit dafür festlegen und es jederzeit auf seiner Schlüsselseite deaktivieren.

1. Einen Code-Verifier und Challenge erstellen

Der Verifier ist eine zufällige Zeichenkette, die Sie behalten (43 bis 128 Zeichen). Die Challenge ist dessen SHA-256, base64url-kodiert ohne Padding.

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. Den Benutzer zu UberLLM senden

https://uberllm.dev/auth?callback_url=https://myapp.com/uberllm/callback&code_challenge=<CHALLENGE>&code_challenge_method=S256
Parameter
callback_url Wohin der Benutzer zurückkehrt. Muss https:// sein; http://localhost (beliebiger Port) ist für die Entwicklung erlaubt. Lassen Sie es weg, um den Code auf dem Bildschirm anzuzeigen, damit der Benutzer ihn in Ihre App einfügen kann.
code_challenge Aus Schritt 1. Erforderlich.
code_challenge_method S256. Erforderlich. plain wird nicht akzeptiert.
key_label Optionaler Name für den Schlüssel (Standard: Name Ihrer App).
state Optional. Wird unverändert mit dem Code zurückgesendet, damit Sie überprüfen können, ob die Antwort zu der von Ihnen gestarteten Anfrage gehört.

Der Benutzer meldet sich an (oder registriert sich), sieht „Ihre App möchte Ihr UberLLM-Guthaben verwenden“ und wählt Zulassen oder Abbrechen. Bei Zulassen werden sie gesendet an:

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

Bei Abbrechen wird nichts gesendet.

3. Den Code gegen einen Schlüssel tauschen

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"}'

Die Antwort ist {"key": "ull_…", "key_id": "…", "name": "My App"}. Verwenden Sie den Schlüssel als Authorization: Bearer auf https://api.uberllm.dev/v1. Der Endpoint beantwortet Browser-Anfragen von jeder Site (CORS), sodass er von einer Web-App aus funktioniert.

Status Code Bedeutung
400 invalid_code_challenge_method Verwenden Sie S256.
403 invalid_code Falscher Code oder code_verifier, oder der Code wurde bereits verwendet.
403 code_expired Codes funktionieren für 10 Minuten. Beginnen Sie erneut bei Schritt 2.
405 method_not_allowed Verwenden Sie POST.
429 rate_limited Zu viele Versuche von einer Adresse; warten Sie eine Minute.

Ein Code funktioniert einmal. Ein falscher code_verifier verbraucht ihn ebenfalls, sodass ein Code, der geleakt ist, nicht erraten werden kann.

Unterschiede zu OpenRouter

  • code_challenge ist erforderlich und nur S256 wird akzeptiert (OpenRouter akzeptiert auch plain oder keine Challenge). Ohne ihn könnte jeder, der den Code in einem Browserverlauf oder Log sieht, den Schlüssel entwenden.
  • workspace_id / required_workspace_id werden nicht verwendet: Ein UberLLM-Konto hat ein einziges Guthaben.