MớiTrỏ bất kỳ agent nào về UberLLM — một key, mọi model, bằng giá niêm yết hoặc rẻ hơn.
UberLLM

Ứng dụng: được liệt kê và cho phép người dùng kết nối

Hai điều dành cho những người xây dựng ứng dụng trên UberLLM. Cả hai đều hoạt động giống như trên OpenRouter, vì vậy một ứng dụng đã thực hiện chúng chỉ cần thay đổi base URL.

  1. Được liệt kê. Gửi hai header và ứng dụng của bạn sẽ hiển thị trên uberllm.dev/apps, được xếp hạng theo số lượng token mà nó gửi. Các trang model liệt kê những ứng dụng sử dụng chúng nhiều nhất.
  2. Cho phép người dùng kết nối. Gửi người dùng đến UberLLM, họ đồng ý, và ứng dụng của bạn sẽ nhận được một API key trên tài khoản của họ. Họ tự thanh toán cho việc sử dụng của mình; bạn không bao giờ xử lý thông tin thanh toán của họ.

Được xếp hạng trên bảng xếp hạng ứng dụng

Thêm các header này vào yêu cầu của bạn (chat, tin nhắn hoặc media, bất kỳ endpoint nào):

Header Chức năng
HTTP-Referer Địa chỉ ứng dụng của bạn, ví dụ https://myapp.com. Bắt buộc: đây là thứ nhận diện ứng dụng của bạn. Referer cũng hoạt động.
X-Title Tên ứng dụng của bạn như mọi người sẽ thấy. X-OpenRouter-Title cũng hoạt động.
X-OpenRouter-Categories Tùy chọn. Tối đa 2 danh mục bên dưới, phân tách bằng dấu phẩy.
X-OpenRouter-App-Visibility Tùy chọn. hidden giữ một ứng dụng mới không xuất hiện trên bảng xếp hạng công khai.
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"}]}'

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

Cách tính điểm:

  • Chỉ địa chỉ được giữ lại: https://myapp.com/some/page?user=… được lưu trữ dưới dạng https://myapp.com. Các paths, query strings và logins bị loại bỏ. Một liên kết GitHub, GitLab, Codeberg, Bitbucket hoặc Hugging Face giữ lại owner/repo của nó, vì vậy các ứng dụng mã nguồn mở có mục riêng.
  • Tên được cắt ngắn còn 60 ký tự. Các ký tự ẩn và ký tự điều khiển bị loại bỏ.
  • Tài khoản đầu tiên gửi traffic cho một ứng dụng sẽ đặt tên và danh mục của ứng dụng đó. Traffic từ các tài khoản khác vẫn được tính cho ứng dụng, nhưng không thể đổi tên ứng dụng.
  • Các địa chỉ trên máy hoặc mạng của riêng bạn (localhost, 127.0.0.1, private IPs, *.local) không bao giờ được hiển thị công khai.
  • Các yêu cầu từ trình duyệt tự động gửi Referer, vì vậy một ứng dụng web vẫn được tính ngay cả khi không có các header. Thêm X-Title để chọn tên của nó.
  • Bảng xếp hạng tính các yêu cầu đã được trả lời, theo tokens, trong 24 giờ, 7 ngày hoặc 30 ngày gần nhất. Bảng xếp hạng này làm mới sau mỗi vài phút.

Danh mục: 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. Các danh mục không xác định sẽ bị bỏ qua. Một ứng dụng giữ tối đa 10.

Bảng xếp hạng cũng là một API: GET https://uberllm.dev/api/v1/public/apps?period=day|week|month&category=<slug>.

Kết nối UberLLM (OAuth PKCE)

Ứng dụng của bạn nhận một khóa trên tài khoản của người dùng, được đặt tên theo ứng dụng của bạn. Người dùng có thể đặt giới hạn chi tiêu cho khóa đó khi cho phép, và có thể tắt nó bất cứ lúc nào trên trang khóa của họ.

1. Tạo bộ xác minh và thử thách mã

Bộ xác minh là một chuỗi ngẫu nhiên bạn giữ (43 đến 128 ký tự). Thử thách là SHA-256, base64url-encoded của nó, không có phần đệm.

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. Gửi người dùng đến UberLLM

https://uberllm.dev/auth?callback_url=https://myapp.com/uberllm/callback&code_challenge=<CHALLENGE>&code_challenge_method=S256
Tham số
callback_url Nơi người dùng quay lại. Phải là https://; http://localhost (bất kỳ cổng nào) được phép cho mục đích phát triển. Để trống để hiển thị mã trên màn hình cho người dùng dán vào ứng dụng của bạn.
code_challenge Từ bước 1. Bắt buộc.
code_challenge_method S256. Bắt buộc. plain không được chấp nhận.
key_label Tên tùy chọn cho khóa (mặc định: tên ứng dụng của bạn).
state Tùy chọn. Được gửi lại nguyên vẹn cùng với mã, để bạn có thể kiểm tra xem phản hồi có thuộc về yêu cầu bạn đã bắt đầu hay không.

Người dùng đăng nhập (hoặc đăng ký), thấy "Ứng dụng của bạn muốn sử dụng tín dụng UberLLM của bạn", và chọn Cho phép hoặc Hủy bỏ. Khi Cho phép, họ được gửi đến:

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

Khi Hủy bỏ, không có gì được gửi đi đâu cả.

3. Đổi mã lấy khóa

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

Phản hồi là {"key": "ull_…", "key_id": "…", "name": "My App"}. Sử dụng khóa làm Authorization: Bearer trên https://api.uberllm.dev/v1. Endpoint trả lời các yêu cầu trình duyệt từ bất kỳ trang web nào (CORS), vì vậy nó hoạt động từ một ứng dụng web.

Trạng thái Mã Ý nghĩa
400 invalid_code_challenge_method Sử dụng S256.
403 invalid_code Mã sai hoặc code_verifier, hoặc mã đã được sử dụng.
403 code_expired Mã có hiệu lực trong 10 phút. Bắt đầu lại từ bước 2.
405 method_not_allowed Sử dụng POST.
429 rate_limited Quá nhiều lần thử từ một địa chỉ; đợi một phút.

Một mã chỉ hoạt động một lần. Một code_verifier sai cũng làm mã bị sử dụng hết, vì vậy mã bị lộ không thể bị đoán.

Điểm khác biệt so với OpenRouter

  • code_challenge là bắt buộc và chỉ S256 được chấp nhận (OpenRouter cũng chấp nhận plain hoặc không có thử thách). Nếu không có nó, bất kỳ ai nhìn thấy mã trong lịch sử trình duyệt hoặc nhật ký đều có thể lấy khóa.
  • workspace_id / required_workspace_id không được sử dụng: một tài khoản UberLLM có một số dư.