cjpais / cjpais/LocalScore

GET /api/results returns 403 at the edge — is the bulk read endpoint intentionally closed?

Open
#42 1 comment 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
TypeScript
Stars
132
Forks
17
PR merge metrics
No merged PRs in 30d

Description

What I'm seeing

GET /api/results returns a Vercel edge 403 rather than reaching the handler:

$ curl -s -o /dev/null -w '%{http_code}\n' 'https://www.localscore.ai/api/results?page=1&limit=2'
403

Body is the plain-text Vercel Forbidden page with a request id, not the JSON
{"error":"Access forbidden"} that src/middleware.ts produces — and that middleware's
matcher is "/api/search" only, so this isn't coming from the app. /api/search works
fine with a browser referer, so it's specific to this route.

The handler itself looks very much designed to be read from: GET takes page, limit
(capped at 100) and sortDirection, and getBenchmarkResults joins the run, accelerator,
model variant, system and runtime. That reads like a public bulk endpoint, which is why
I wanted to check whether the 403 is deliberate.

If it's intentional — anti-scraping, cost control, whatever — no argument, and it'd be
worth a line in the README so people stop trying. Feel free to close this.

Why I'm asking

We ingest LocalScore as a hardware baseline in an open-source ML benchmarking harness. The
question we use it to answer is "is this machine fast in absolute terms", which our own
numbers can't answer because they only ever run on hardware we own. Your corpus covers 828
accelerators we don't have, and the per-accelerator rank turns a bare tok/s figure into
something interpretable.

With /api/results closed, the reachable path is the Next.js data route the public
per-model pages already render:

/_next/data/<buildId>/model/<id>.json?id=<id>

That's actually the polite option — three requests for the whole official-model corpus
(~1,623 rows) instead of ~400 paginated ones, and it hits your existing page cache. But it
depends on buildId, which changes on every deploy, so it has to be re-scraped from the
homepage each run and will break in ways that generate confused traffic rather than clean
404s.

The reason this is worth your time and not just mine: an endpoint that's documented and
stable means downstream consumers converge on one cheap, cacheable path instead of each
inventing their own way in through the rendering layer. Right now the incentive points the
wrong way.

What would help

Any of these, in descending order of usefulness to us — all of them fine:

  1. Unblock GET /api/results and treat it as the supported read path (it already has
    sane pagination and a hard MAX_PAGE_SIZE).
  2. A static dump — even a nightly results.json or CSV artifact — which would be cheaper
    for you than serving pagination at all.
  3. Keep it closed and say so in the README, so the data routes are understood as the
    only option and I'll leave the buildId resolution in place.

Happy to send a PR for whichever you'd prefer, including the README line if the answer is
option 3.

Unrelated to this, but same repo and same afternoon: #41 / #40 cover the homepage
leaderboard currently rendering empty in production.

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by reading src/middleware.ts and tracing the GET /api/results handler, then compare the edge 403 with the middleware matcher and the existing Next.js data route. Confirm with the maintainer whether the intended outcome is an opened API, a static dump, or documentation of the closed endpoint; done means one supported path is chosen and its behavior is documented.

Written by the indexing model from the issue text.

Assessment

Tech stack
nextjs, typescript
Domain
api, backend
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Quiet
Clarity
Needs clarification
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.