Read results and publish
Read the run
GET /api/v2/runs/{run_id}
GET /api/v2/runs/{run_id}/events?after={cursor}
GET /api/v2/me/runs?limit=30&before={iso timestamp}
GET /api/v2/runs/{id} is one snapshot plus a cursor; .../events
pages forward from that cursor and carries a done flag so a poller can
stop on its own. Take the snapshot once, then follow the cursor — that is what
makes reopening the page cheap and a client-side progress timer unnecessary.
Both accept the canonical run id or the client_run_id you generated. The
run is owner-only until it is published, and a run you cannot see answers
404.
Per-case verdicts appear as the grader finishes each case. The numeric score
appears once the whole set is graded — a partially graded run reports
score_status rather than a partial number dressed as a result.
The human view of the same run is https://trapstreet.run/runs/{run_id}, and it
needs no publishing and no deploy: signing in as the run's owner is enough.
Publish, if the user asks
POST /api/v2/runs/{run_id}/publish
Nothing else publishes. Finishing a run does not; reporting context does not; being asked to "run this and send me the link" does not.
{ "published": true, "run_id": null, "ranked": false, "reason": "PUBLISHED", "message": "…" }
published and ranked are separate facts, because they are: a run
can be public at its URL and appear on no board — no platform score, no
published task version and solution to link it to. Reporting that as one
"success" is how somebody ends up believing they are on a board they are not
on, so read both.
reason is machine-readable: PUBLISHED, ALREADY_PUBLISHED,
NOT_FINISHED (including "graded, but not yet — the score is the grader's
to write"), NO_REPORT, NOT_LINKABLE and WRONG_CHANNEL. The call
answers 200 when the run is published and 409 when it is not, and it
is idempotent: publishing twice returns the first outcome instead of creating
a second public record. The run's URL never changes and never stops meaning
the same run.
Publishing accepts either credential — a bearer token or a signed-in browser session — because it is the one step a person may reasonably want to take from the page they are already looking at.
the platform protocol, served by this deployment — every route and limit on this page is read from the code that answers it