Aplikasi: Daftar dan Biarkan Pengguna Terhubung
Dua hal untuk orang-orang yang membangun aplikasi di UberLLM. Keduanya bekerja dengan cara yang sama seperti di OpenRouter, jadi aplikasi yang sudah melakukannya hanya perlu mengubah base URL.
- Daftar. Kirim dua header dan aplikasi Anda akan muncul di uberllm.dev/apps, diurutkan berdasarkan token yang dikirimnya. Halaman model mencantumkan aplikasi yang paling sering menggunakannya.
- Biarkan pengguna terhubung. Kirim pengguna ke UberLLM, mereka menyetujui, dan aplikasi Anda mendapatkan API key di akun mereka. Mereka membayar untuk penggunaan mereka sendiri; Anda tidak pernah menangani detail pembayaran mereka.
Terdaftar di peringkat aplikasi
Tambahkan header ini ke permintaan Anda (chat, pesan, atau media, endpoint apa pun):
| Header | Fungsinya |
|---|---|
HTTP-Referer |
Alamat aplikasi Anda, contohnya https://myapp.com. Wajib: ini yang mengidentifikasi aplikasi Anda. Referer juga berfungsi. |
X-Title |
Nama aplikasi Anda seperti yang seharusnya dilihat orang. X-OpenRouter-Title juga berfungsi. |
X-OpenRouter-Categories |
Opsional. Hingga 2 dari kategori di bawah, dipisahkan koma. |
X-OpenRouter-App-Visibility |
Opsional. hidden menjaga aplikasi baru agar tidak muncul di peringkat publik. |
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"}]}'
Dengan 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',
},
});
Bagaimana penghitungannya:
- Hanya alamat yang disimpan:
https://myapp.com/some/page?user=…disimpan sebagaihttps://myapp.com. Path, query string, dan login dihilangkan. Tautan GitHub, GitLab, Codeberg, Bitbucket, atau Hugging Face mempertahankanowner/repo-nya, sehingga aplikasi open-source mendapatkan entri mereka sendiri. - Nama dipotong menjadi 60 karakter. Karakter tersembunyi dan kontrol dihapus.
- Akun pertama yang mengirimkan traffic untuk suatu aplikasi akan menetapkan nama dan kategorinya. Traffic dari akun lain tetap dihitung untuk aplikasi tersebut, tetapi tidak dapat mengubah namanya.
- Alamat di mesin atau jaringan Anda sendiri (
localhost,127.0.0.1, IP pribadi,*.local) tidak pernah ditampilkan secara publik. - Permintaan dari browser mengirimkan
Referersecara otomatis, sehingga aplikasi web dihitung bahkan tanpa header. TambahkanX-Titleuntuk memilih namanya. - Peringkat menghitung permintaan yang dijawab, berdasarkan token, selama 24 jam, 7 hari, atau 30 hari terakhir. Peringkat ini diperbarui setiap beberapa menit.
Kategori: 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. Kategori yang tidak dikenal akan diabaikan. Sebuah aplikasi dapat memiliki hingga 10.
Peringkat ini juga merupakan API: GET https://uberllm.dev/api/v1/public/apps?period=day|week|month&category=<slug>.
Hubungkan UberLLM (OAuth PKCE)
Aplikasi Anda mendapatkan kunci di akun pengguna sendiri, yang dinamai sesuai aplikasi Anda. Pengguna dapat menetapkan batas pengeluaran untuknya saat mengizinkannya, dan dapat mematikannya kapan saja di halaman kunci mereka.
1. Buat verifier dan challenge kode
Verifier adalah string acak yang Anda simpan (43 hingga 128 karakter). Challenge adalah SHA-256, base64url-encoded tanpa 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. Kirim pengguna ke UberLLM
https://uberllm.dev/auth?callback_url=https://myapp.com/uberllm/callback&code_challenge=<CHALLENGE>&code_challenge_method=S256
| Parameter | |
|---|---|
callback_url |
Tempat pengguna kembali. Harus https://; http://localhost (port apa pun) diizinkan untuk pengembangan. Biarkan kosong untuk menampilkan kode di layar agar pengguna dapat menempelkannya ke aplikasi Anda. |
code_challenge |
Dari langkah 1. Wajib. |
code_challenge_method |
S256. Wajib. plain tidak diterima. |
key_label |
Nama opsional untuk kunci (default: nama aplikasi Anda). |
state |
Opsional. Dikirim kembali tidak berubah bersama kode, sehingga Anda dapat memeriksa bahwa balasan tersebut milik permintaan yang Anda mulai. |
Pengguna masuk (atau mendaftar), melihat "Aplikasi Anda ingin menggunakan kredit UberLLM Anda", dan memilih Izinkan atau Batalkan. Pada Izinkan mereka dikirim ke:
https://myapp.com/uberllm/callback?code=<CODE>&state=<STATE>
Pada Batalkan tidak ada yang dikirim ke mana pun.
3. Tukarkan kode dengan kunci
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"}'
Balasannya adalah {"key": "ull_…", "key_id": "…", "name": "My App"}. Gunakan kunci
sebagai Authorization: Bearer pada https://api.uberllm.dev/v1. Endpoint
menjawab permintaan browser dari situs mana pun (CORS), sehingga berfungsi dari aplikasi web.
| Status | Kode | Arti |
|---|---|---|
| 400 | invalid_code_challenge_method |
Gunakan S256. |
| 403 | invalid_code |
Kode salah atau code_verifier, atau kode sudah digunakan. |
| 403 | code_expired |
Kode berlaku selama 10 menit. Mulai lagi dari langkah 2. |
| 405 | method_not_allowed |
Gunakan POST. |
| 429 | rate_limited |
Terlalu banyak percobaan dari satu alamat; tunggu sebentar. |
Satu kode hanya berfungsi sekali. code_verifier yang salah juga menghabiskannya, jadi kode yang
bocor tidak dapat ditebak.
Perbedaan dari OpenRouter
code_challengewajib dan hanyaS256yang diterima (OpenRouter juga menerimaplainatau tanpa challenge). Tanpa itu, siapa pun yang melihat kode di riwayat browser atau log dapat mengambil kunci tersebut.workspace_id/required_workspace_idtidak digunakan: akun UberLLM memiliki satu saldo.