https://api.cortex.foundation.
The four endpoints
All four areGET, and all four are unauthenticated.
Every response carries
api_version: 1, generated_at and a decimal-string revision, with cache-control: no-store. The status, leaderboard and report list identify a publication snapshot. A report detail instead identifies the revision that published its latest version; it does not accept a historical revision filter.
Leaderboard entries contain hotkey, valid, valid_count, duplicate, already_fixed_not_prod, invalid_malicious and total. valid and valid_count are equal. These are report counts, not scores or payments. See Verdicts and scoring.
What a public row contains
Chat transcripts stay private. They are never on the public routes, and neither is the report body, your email address, your display name, a conversation id, a pairing code or a token of any kind. The full list is on File a report.
Legacy
valid reports without severity are excluded from report lists and leaderboard counts until repriced. Their detail can still show severity: null; that historical verdict is not scoreable. Duplicate chains rooted in an unpriced report are also withheld from the scoring list.
Windows
since and until are RFC 3339 timestamps, and they behave the same way on the leaderboard and on the reports listing.
sinceis inclusive.untilis exclusive. So consecutive windows can share a bound without double-counting a row.- Both filter on
adjudicated_at, the moment the verdict was recorded. Neither filters on filing time. A report filed in one window and judged in the next belongs to the second. until <= sinceis refused. It is not answered with an empty page, and the reason is worth understanding: an empty page reads exactly like “this hotkey earned nothing”.- An
adjudicated_atvalue taken from a response is reusable as a bound byte for byte. It is truncated to microseconds. A+00:00offset needs percent-encoding in a query string, though the un-encoded form is accepted too.
Revisions and pagination
Read status first. Pass itsrevision to the leaderboard and the first report page so both read the same immutable publication snapshot. Without a revision, a first-page request reads the latest publication.
limitis clamped to 1 through 100.- While
has_moreis true, sendnext_cursorback verbatim ascursor, preserving the same filters. - The opaque cursor binds the revision, filters and position. A conflicting revision or changed filters is refused; restart from page one to change the query.
- The ordering is newest
adjudicated_atfirst, thenid. New verdicts or corrections appear only in later revisions and cannot move page two of an existing walk. idis assigned at filing time, not at verdict time, so ids are not in verdict order. That is exactly why the cursor exists: you cannot page this log by sorting ids.
has_more when there are more than that. If you need a complete enumeration, walk the reports endpoint instead. The leaderboard is a summary, and the reports listing is the record.
Reading zero correctly
A missing leaderboard row is not proof of a zero payout. Check the status response before interpreting an empty publication.
A failed request is not an empty publication. Never substitute an empty list for a transport, server or validation error.
last_adjudicated_at gives the time of the latest published adjudication; it does not prove the scoring or payment pipeline is running.
Verify a public report count
1
Pin the publication
Read
/v1/bounty/public/status and retain its revision. Check the availability, backlog and unpriced counters before interpreting the result.2
Read the leaderboard for the window
Call
/v1/bounty/public/leaderboard with that revision and the since and until bounds you need. Note the hotkey’s valid_count. If has_more is true, absence from the board is inconclusive.3
Walk the reports listing over the same window
Call
/v1/bounty/public/reports with the same revision, hotkey, since and until. Follow next_cursor until has_more is false, keeping filters unchanged. Count the valid rows.4
Compare the counts
The board count and complete walk must agree at the same revision and window. Check pagination and filters on a mismatch; if it persists, treat the data as inconsistent, not as a score.
5
Inspect a finding
Read
/v1/bounty/public/reports/{id} for its latest explanation. A later correction may differ from your pinned walk; use the page you retained when auditing the older snapshot.This verifies published evidence and counts, not a payment. These endpoints are not a general platform API. See Platform API.