Leaderboard
Package leaderboard is the ranking of who uses AI most, in your org and globally.
Package leaderboard is the ranking of who uses AI most, in your org and globally.
| Base URL | https://api.hanzo.ai |
| Operations | 5 |
| Auth | Authorization: Bearer $HANZO_API_KEY |
Specification
HIP-1242 · Leaderboard — Who Uses AI Most — Draft · read the specification →
/v1/leaderboard ranks who uses AI most — inside an org, and globally across
the orgs that opt in — and draws a per-day contribution graph for one subject.
It is a derived, read-only lens over the one usage ledger: it adds no metering
path and double-counts nothing (apps/leaderboard/leaderboard.go:7-9). The
implementation is hanzoai/cloud apps/leaderboard.
Motivation
The capability today serves under /v1/usage/*, a prefix it co-owns with the
usage capability — and its own doc calls two packages under one prefix "one
prefix with no owner" (apps/leaderboard/leaderboard.go:24-25). The two stay
two capabilities, because a store boundary already exists: leaderboard owns an
opt-in store and usage owns none. Leaderboard therefore vacates the shared
prefix; this HIP states the surface it moves to.
Specification
The key words MUST, MUST NOT, SHOULD, SHOULD NOT and MAY are to be interpreted as in RFC 2119.
The addresses, and the prefix it vacates
Every route MUST be under /v1/leaderboard, except the operator's one-shot,
which is the operator's view (HIP-0139 §3.2):
GET /v1/leaderboard— ranked top users (personal or org scope) or orgs (global), todayGET /v1/usage/leaderboardGET /v1/leaderboard/activity— the per-day series for a heatmap and timeline, todayGET /v1/usage/activityGET|PUT /v1/leaderboard/optin— read both opt-ins; set the caller's ownPUT /v1/leaderboard/optin/org— set the org's public-board opt-inPOST /v1/admin/leaderboard/rollup— seed the rollup from ledger history, todayPOST /v1/usage/rollup/backfill. As an admin address it leaves the public document by address, which is correct: it is already SuperAdmin-only (apps/leaderboard/backfill.go:53).
All six operations are typed (plugin/leaderboard/openapi.json); none is
declared. The standing /v1/usage pair is ledgered in cloud's
openapi/misfiled.txt and closes by this move. The usage capability keeps
/v1/usage untouched (manifest/apps.go:271).
The store, and the rollup that is not one
The capability owns the opt-in store: one cek-encrypted SQLite opened by
sqlpool.Open("leaderboard", dir), single-connection, two tenant-keyed tables
— user_optin (user, org, handle, listed) and org_optin (org, display,
listed) (apps/leaderboard/store.go). No secret lands there.
Ranks are not stored here. They are reads of the shared warehouse through a
derived per-day pre-aggregation of hanzo.cloud_usage, kept fresh by an
incremental materialized view attached to the ledger and seeded once by the
admin backfill below a creation watermark that prevents double-counting
(apps/leaderboard/rollup.go:19-22,75-76). The rollup MUST remain derived: a
second metering path is the one thing this lens is defined not to be.
The tenant, and who is shown
The org is the validated IAM owner claim — principal.Org, minted by the
identity middleware from the verified bearer (HIP-0026), never a client
header — and a validated principal is required: no principal is 401. Every
warehouse read binds the org positionally, never interpolated
(apps/leaderboard/board.go:11, apps/leaderboard/sql.go:13). A user board
carries only the caller's own org's rows; the global board carries org-level
aggregates only, so cross-org detail is structurally impossible. With the
warehouse down it answers honest-empty (available:false), never fabricated
ranks.
Public listing is opt-in and private by default: a user always sees their own rank but is named to others only after opting in with a chosen handle; an org appears on the global board only after an org admin opts it in. The org opt-in requires an org admin; the backfill requires SuperAdmin.
Price, events, emission, stage
It is free, in those words: Price: cloud.Free
(plugin/leaderboard/main.go:26) — a lens over spend must not itself spend.
It publishes no events on the bus, so a customer's webhooks receive nothing
from it, and it emits nothing to observability beyond the request span every
route gets.
The stage is beta (HIP-0139 §8): a gamification surface reaches orgs by the
leaderboard flag and answers 404 without it. The manifest row declares no
stage today (manifest/apps.go:272), so the operations serve as ga does;
adopting the declaration here is one edit to that row's Stage field.
Upstream
It derives from none.
Rationale
The alternative to vacating the prefix is folding leaderboard into usage.
That is refused on the store boundary: usage composes the commerce ledger and
the warehouse and owns no store of its own (apps/usage/usage.go), while
leaderboard owns the opt-in store — and HIP-0139 §7.2 makes the store, not the
prefix, the unit of capability. The alternative to the incremental rollup is
ranking straight off the ledger, which prices every page view as a full-table
aggregation of the busiest table the warehouse has.
Security Considerations
The disclosure surface is social, not financial: the wrong implementation
names a person who never opted in, on a board other tenants read. Privacy is
therefore default-deny in the schema — an absent row IS "not listed" — and the
listing read carries the listed=1 predicate with the org key on every
statement. The other exposure is rank as an oracle for another org's spend;
the global board carries org-level aggregates for opted-in orgs only, and the
tenant is never an input, so there is no query a caller shapes to read a
neighbour's detail.
Four surfaces
| Surface | Reaches this capability as | Coverage |
|---|---|---|
| REST | leaderboard at its own prefix | 5 operations |
| CLI | — | no command reaches it yet — use HTTP or an SDK |
| SDK | — | no published client declares one yet — regenerating the clients is what adds them |
| MCP | tool leaderboard on https://api.hanzo.ai/v1/mcp | 6 operations, 0 under the document's own id — ask describe for the rest |
Quickstart
export HANZO_API_KEY=sk-... # console.hanzo.ai → API keysThen the first call — a read that needs nothing but the key. GET /v1/leaderboard, operation get_leaderboard:
hanzo has no subcommand for this operation — the CLI serves only what cloud's live route table confirms. Use HTTP or an SDK.
import { Configuration, LeaderboardApi } from 'hanzoai';
const api = new LeaderboardApi(new Configuration({ accessToken: process.env.HANZO_API_KEY }));
const { data } = await api.getLeaderboard();from hanzoai.cloud import ApiClient, Configuration
from hanzoai.cloud.api import LeaderboardApi
client = ApiClient(Configuration(access_token=os.environ["HANZO_API_KEY"]))
result = LeaderboardApi(client).get_leaderboard()cfg := cloud.NewConfiguration()
cfg.AddDefaultHeader("Authorization", "Bearer "+os.Getenv("HANZO_API_KEY"))
client := cloud.NewAPIClient(cfg)
resp, _, err := client.LeaderboardAPI.GetLeaderboard(context.Background()).Execute()
if err != nil {
return err
}use hanzo_cloud::apis::{configuration::Configuration, leaderboard_api};
let mut cfg = Configuration::new();
cfg.bearer_access_token = std::env::var("HANZO_API_KEY").ok();
let result = leaderboard_api::get_leaderboard(&cfg, Default::default()).await?;import ai.hanzo.cloud.ApiClient;
import ai.hanzo.cloud.api.LeaderboardApi;
ApiClient client = new ApiClient();
client.setRequestInterceptor(b -> b.header("Authorization", "Bearer " + System.getenv("HANZO_API_KEY")));
var result = new LeaderboardApi(client).getLeaderboard();The method above is the one at the current release of the document. [email protected] (npm) and [email protected] (PyPI) were generated from an earlier release, where this operation carried a different id, so it spells the method differently — regenerating the clients is what makes the two agree. SDKs →
curl https://api.hanzo.ai/v1/leaderboard \
-H "Authorization: Bearer $HANZO_API_KEY"The door reaches leaderboard through the leaderboard tool, which names its 6 operations with its own verbs — this one among them, under a name only the door declares. describe explains any of them:
curl -X POST https://api.hanzo.ai/v1/mcp \
-H "Content-Type: application/json" \
-d '{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "describe",
"arguments": {
"op": "get_usage_activity"
}
}
}'Answers 200 with object — ok.
Endpoints
| Endpoint | What it does |
|---|---|
GET /v1/leaderboard/activity | Activity returns the per-day usage series for ONE authorized subject — the points a contribution heatmap and a timeline are drawn from, gap-filled so… |
PUT /v1/leaderboard/optin/org | Sets the ORG's listing on the cross-org global board. |
GET /v1/leaderboard/optin | Returns the caller's own public-listing preference and their org's, each with whether the caller may change it. |
PUT /v1/leaderboard/optin | Sets the CALLER's own public-listing preference on the leaderboard. |
GET /v1/leaderboard | Leaderboard ranks AI usage over a window, either the users of the caller's own org or organizations against each other, and always reports the… |
How is this guide?