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.
- 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.
- 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 alshttps://myapp.comgespeichert. Pfade, Query Strings und Logins werden entfernt. Ein GitHub-, GitLab-, Codeberg-, Bitbucket- oder Hugging Face-Link behält seinowner/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
Referervon selbst, sodass eine Web-App auch ohne die Header gezählt wird. Fügen SieX-Titlehinzu, 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_challengeist erforderlich und nurS256wird akzeptiert (OpenRouter akzeptiert auchplainoder keine Challenge). Ohne ihn könnte jeder, der den Code in einem Browserverlauf oder Log sieht, den Schlüssel entwenden.workspace_id/required_workspace_idwerden nicht verwendet: Ein UberLLM-Konto hat ein einziges Guthaben.