

A free, read-only JSON API over SETT Rank. Pull rankings, teams, tournaments, and bid data without scraping. No key, no signup.
Every endpoint is a plain GET that returns JSON. CORS is open (Access-Control-Allow-Origin: *), so you can call it from a browser tab, a Cloudflare Worker, a Python script, anything. Try it now:
curl -s 'https://settrank.com/api/v1/rankings?gender=Girls&age=17s&pageSize=3' | jq .data.teams[0]{ data, meta } on success or { error, meta } on failure. meta always includes version, fetchedAt, and (when rate limiting is active) your remaining quota.X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset) are on every response. 429 returns a retryAfterSeconds hint so backoff is straightforward.Cache-Control: public, s-maxage=300, stale-while-revalidate=86400 so a CDN-fronted client effectively gets free reads. Data refreshes nightly; high-frequency polling is wasteful.v1. We'll keep field names stable within a major version; additions are non-breaking. Removals or renames will ship under v2./api/v1/API root. Returns version, endpoint catalog, and rate-limit info.
{ data: { name, version, docs, endpoints, rateLimit }, meta }curl -s 'https://settrank.com/api/v1/' | jq ./api/v1/rankingsPaginated team rankings. Filter by gender, age, region; free-text search across team and club names.
| gender | "Girls" | "Boys" | "Girls" | Required if you want non-default |
| age | "12s".."18s" | "All" | "All" | USAV age bucket |
| region | "SE"|"SW"|"WE"|"MW"|"MA"|"NE"|"All" | "All" | Macro-region; All disables filter |
| search | string | "" | Min 2 chars; matches team name, club name, USAV code |
| page | 1..1000 | 1 | 1-indexed page number |
| pageSize | 1..5000 | 25 | Rows per page |
{ data: { teams: RankingTeam[], total, page, pageSize, totalPages }, meta }curl -s 'https://settrank.com/api/v1/rankings?gender=Girls&age=17s&pageSize=10' | jq ./api/v1/teams/{code}Single team profile, including all tournament results and any earned national qualifier bids.
| code | string (path) | — | USAV team code; case-insensitive |
{ data: { team, results, bids }, meta }curl -s 'https://settrank.com/api/v1/teams/sccvbcg17m' | jq ./api/v1/tournamentsAll tournaments in the current season (or just currently-live events with ?live=true).
| live | "true" | "false" | "false" | Only return events where today is between startDate and endDate |
{ data: { tournaments: TournamentSummary[], count }, meta }curl -s 'https://settrank.com/api/v1/tournaments?live=true' | jq ./api/v1/tournaments/{id}Single tournament detail (divisions, registered/finalized teams, location, dates).
| id | string (path) | — | AES event id (numeric) or "sw_<id>" / "vbs_<id>" for non-AES sources |
{ data: { tournament }, meta }curl -s 'https://settrank.com/api/v1/tournaments/45517' | jq .| Status | Meaning |
|---|---|
| 400 | Invalid query parameters (typically a bad gender/age/region value or a too-large pageSize). |
| 404 | Resource not found (team code or tournament id doesn't exist). |
| 429 | Rate limit exceeded. Body includes retryAfterSeconds. |
| 500 | Upstream Firestore error. Retry with backoff; if persistent, see /api/health. |
Building something cool with this? We'd love to see it.
Tell us about it