Scrapes LLM ranking data from openrouter.ai/rankings and provides an API to access the latest and historical rankings.
-
Install Dependencies:
bun install
-
Install Playwright Browsers & Dependencies: Playwright is used for scraping. You need to download the necessary browser binaries and system dependencies.
Install browsers
bunx playwright install
Install playwright dependencies
sudo bunx playwright install-deps
Start the development server with hot-reloading:
bun --watch run src/server.tsThe server will run on http://localhost:3000.
(Note: Production build/start steps might need adjustment based on deployment strategy, but bun run src/server.ts can also be used directly.)
- Latest Cache: The most recently scraped data is kept in memory for fast API access.
- Historical Data: Each scrape's results are saved as a timestamped JSON file (e.g.,
rankings_YYYYMMDD_HHMMSS.json) in the./data/directory. - Cache Loading: On server startup, the latest file from the
./data/directory is loaded into the in-memory cache.
| Method | Path | Description |
|---|---|---|
GET |
/api/rankings/{category} |
Get latest rankings for a specific category. |
GET |
/api/scrape |
Trigger a manual scrape and update cache. |
GET |
/api/rankings/history |
List available historical ranking file names. |
GET |
/api/rankings/history/{filename} |
Get the full data for a specific historical file. |
Retrieves the most recently scraped and cached rankings for a specific category.
- URL:
/api/rankings/{category} - Method:
GET - {category}: The category name (e.g.,
all,programming,science,seo).- Use
allfor the combined rankings. - Use
seoas a shortcut for themarketing/seocategory.
- Use
Example:
curl http://localhost:3000/api/rankings/programming
curl http://localhost:3000/api/rankings/seo # Gets marketing/seo data
curl http://localhost:3000/api/rankings/allResponse: An array of ModelEntry objects for the category:
[
{
"rank": 1,
"name": "Anthropic: Claude 3.7 Sonnet",
"link": "/anthropic/claude-3.7-sonnet",
"description": "Claude 3.7 Sonnet is an advanced large language model...",
"context": 200000,
"tokens": 1430000000,
"tokenChangePercent": 12,
"id": "claude-3.7-sonnet"
},
// ... more models
]Manually triggers the scraping process. Updates the in-memory cache and saves a new historical file.
- URL:
/api/scrape - Method:
GET
Example:
curl http://localhost:3000/api/scrapeResponse:
{
"status": "ok",
"updated": ["all", "roleplay", "programming", "marketing", "marketing/seo", "technology", "science", "translation", "legal", "finance", "health", "trivia", "academia"]
}Retrieves a list of available historical ranking snapshot filenames.
- URL:
/api/rankings/history - Method:
GET
Example:
curl http://localhost:3000/api/rankings/historyResponse: A JSON array of filenames, sorted newest first:
[
"rankings_20250426_160000.json",
"rankings_20250426_151545.json",
// ... more filenames
]Retrieves the full ranking data from a specific historical snapshot file.
- URL:
/api/rankings/history/{filename} - Method:
GET - {filename}: The exact filename obtained from the
/api/rankings/historyendpoint.
Example:
curl http://localhost:3000/api/rankings/history/rankings_20250426_151545.jsonResponse: The full Rankings JSON object as stored in that file.
Built with Bun and Playwright.