Insights API

Every figure on the Insights page is read through these endpoints, but for the Candidates section of the Stations tab, which is read through the Replayed candidates API, and a station's "Runs by config" and judge agreement, which are read through the station's own endpoints. All are GET, under /api/teams/{teamId}/insights, and answer JSON.

Endpoints

EndpointReturns
/overviewThe headline figures against the period before, spend and merged pull requests per day, config changes, and the stations worth improving.
/flowWhere tasks wait at each station, queued, running or in the inbox, and the time to pull request, first review and merge.
/pull-requestsSpotlight's share of merged pull requests by week and repository, Spotlight's against people's, types, and review depth.
/pull-requests/listEvery pull request opened or closed in the period, or still open, the latest first, a page at a time.
/shippingHow fast Spotlight's pull requests ship against people's alone: time to merge by day and by type, review depth by week, time to first review, review bots, and how long merged pull requests spent at each stage. See /shipping.
/stationsEach station's tally, per day and against the period before, with its task failures apart from its run failures.
/changesEvery station config change in the period, with the station's runs before and after it, and the judge's scores where its judge is trusted.
/setupsHow runs went against what they cost on each harness, model, effort and harness profile, with the frontier marked for each outcome.
/peopleWhat the team's work asks of people, and who is active: new, weekly and monthly.
/costSpend by harness, model, station and repository, from model to station to repository.
/toolsWhich skills the runs were given and read, week by week, and how each MCP server they called behaved.
/memoryThe team's standing memories, how many runs were briefed or read them, which were flagged wrong, and runs with memories against runs without.
/runsEvery run that ended in the period, newest first, a page at a time.
/alerts/{alertId}A station alert that went off: the threshold it crossed, the run that crossed it, and the measure run by run around it.

Parameters

Every endpoint but /alerts/{alertId} takes period: 7d, 30d or 90d, whole UTC days up to and including today. Default: 30d. Every answer also covers the period before, as long.

/runs also takes:

ParameterNarrows to runs
lineIdOn this line.
stationIdAt this station.
outcomeThat ended this way: completed, failed, stopped, abandoned, withdrawn or superseded.
harnessOn this harness.
modelWith this model; ~default for runs that named none.
repositoryThat worked this repository; none for runs that worked none.
fingerprintWith this config fingerprint.
taskIdOf this task.
taskIdsOf these tasks, comma-separated, at most 200.
personIdOf tasks this person opened.
dayThat ended on this UTC day, as YYYY-MM-DD.
deliveryOf tasks whose pull request is now merged, closed or open.
nextWhose next person act was started, parked, closed, answered or sent-back.
askedtrue: of tasks that asked a person in the inbox during the period. false narrows nothing.
weekThat ended in the week starting this UTC Monday, as YYYY-MM-DD.
skillGivenWhose station config gave this skill.
skillUsedThat read this skill.
serverThat called this MCP server.
serverFailedWith a call to this MCP server that failed.
failedAfterThat failed where the run's last call to this MCP server failed.
refusedToolWhere a person refused this tool.
refusedServerWhere a person refused a tool of this MCP server; none for refusals of a tool with no server.
pageWhich page, from 1 to the last page with runs, at most 10,000. A value that is not a whole number above 0 is read as 1.
sizeRuns per page. Default: 50. At most 200; a larger number is read as 200.

/setups also takes:

ParameterNarrows to runs
stationIdAt this station. Judge scores are given only with it.
sizeOf this size: small, medium or large. See Harness, model, effort and profile.

/pull-requests/list also takes:

ParameterNarrows to pull requests
repositoryIn these repositories, comma-separated or repeated, at most 50.
authorWritten by spotlight, touched, people or bots.
typeOf type feature, fix, refactor, tests, chore or other.
statemerged or closed in the period, or still open.
weekClosed in the week starting this UTC day, as YYYY-MM-DD.
revertedtrue: reverted by another merged pull request.
comparedtrue: in the repositories Spotlight merged into in the period.
roundsThat took 0, 1, 2 or 3+ review rounds.
pageWhich page, from 1. A value that is not a whole number above 0 is read as 1. A page past the last is empty.
sizeAs for /runs.

With both taskId and taskIds, only that task's runs are listed, and only if it is among taskIds.

Every endpoint but /runs, the two pull request endpoints and /alerts/{alertId} counts at most 20,000 of the team's runs that ended over the period and the one before, those that started latest, and at most 20,000 each of its task pull requests, tasks people acted on, tasks with failures and agent chats. It answers truncated: true when any of them was more. The pull request endpoints count at most the newest 20,000 pull requests in the period, and /shipping the newest 20,000 over the period and the one before; /shipping also answers truncated: true when either limit was passed. /alerts/{alertId} reads the station's latest 500 runs.

/shipping

GET /api/teams/{teamId}/insights/shipping takes period alone. It sets Spotlight's pull requests against people's alone, those people opened with no Spotlight review task, in the repositories Spotlight merged into in the period. Times are in milliseconds. See What the agents ship and Review and approval for how each is measured.

FieldTypeDescription
periodobjectname, from, to, previousFrom, previousTo and days, every UTC day in the period, oldest first.
truncatedbooleanWhether only the latest pull requests or runs were counted.
toMergeby-authorOpened to merged, for pull requests merged in the period.
toMergeChangesobjectspotlight and people, each with p50, p75, p90 and p95: a change against the period before, or null.
mergeDays[]objectFor each day of the period: day, daily (by-author, for pull requests merged that day) and rolling (by-author, merged in the 7 days ending that day).
types[]objectFor each type with a pull request merged: type, merged (Spotlight's and people's alone) and toMerge (by-author).
slowestFirstobjectp50, p75, p90 and p95: the types in types, slowest first by Spotlight's time at that percentile, those with none last.
depth[]objectFor each week, from its UTC Monday: week, merged, and rounds[], a rounds count for each of 0, 1, 2 and 3+.
depthTotals[]rounds countThe weeks in depth summed, for each number of review rounds.
reviewDays[]objectFor each day of the period: toFirstReviewDaily and toFirstReviewRolling (percentiles, for pull requests first reviewed that day, or in the 7 days ending that day), awaiting (pull requests ready and not yet reviewed as the day ended) and humanReviews (reviews people submitted that day).
bots[]objectEach review bot, the most comments first: login, comments, reviews and resolvedShare, from 0 to 1, or null where it started no thread.
pipelineobjectmerged (Spotlight's pull requests merged in the period whose task opened in the period, the period before, or the last 30 days where that reaches further), types[] (type and merged) and layouts: stations (a stage for each station the tasks ran at, in order of first use, then the review stages) and stages (coding as one stage, then the review stages).
shippedAnybooleanWhether pipeline.merged is above 0, types is not empty, or any day of reviewDays has awaiting or humanReviews above 0. Pull requests written by bots or touched never count toward the first two, and people's count only in the repositories Spotlight merged into.

A percentiles object has p50Ms, p75Ms, p90Ms and p95Ms, each null when nothing was measured, and count. A by-author object has spotlight and people, each a percentiles object. A rounds count has rounds, merged and share, from 0 to 1, or null where nothing merged. A change has unit (percent or points), by (null when it rose from 0), fromZero, direction (up, down or same) and tone (good, bad or flat).

A stage in layouts has kind (coding, station, awaitingReview, inReview or awaitingMerge), lineId and stationId (null but for a station), and times: all, and types[] with type and times for each type that went through it. Each times object has:

FieldDescription
totalPercentiles of the stage's time.
partsAt a station, queued, running and inbox, each percentiles; otherwise null.
jamp50, p75, p90 and p95: the stage's time over the longest stage's in the same layout, for the same type, from 0 to 1.
worstp50, p75, p90 and p95: whether this is the longest stage in the layout for the same type; the first on a tie.
longestPartAt a station, p50, p75, p90 and p95: the part that took longest, queued first on a tie, or null where no part took any time. Otherwise null.

Who may read

A person on the team or an owner or admin of its workspace, signed in, or a workspace token of the team's workspace with the read scope, sent as Authorization: Bearer <token>. Anyone else is answered 404. See Team outcomes.

Errors

StatusCause
401No session or token, or an unknown, expired or revoked token.
404There is no such team, the team is not in the caller's workspace, the caller is a token without the read scope, or the caller is a person neither on the team nor an owner or admin of the workspace: Team <teamId> not found. For /alerts/{alertId}, also an alert of another team or none: Alert <alertId> not found.
422On every endpoint but /alerts/{alertId}, period is not 7d, 30d or 90d, or is given twice: Period must be 7d, 30d or 90d. See below for the filters.

On /runs, where <filter> names the parameter as line, station, outcome, harness, model, repository, station config, task, person, day, week, skill given, skill used, server, server that failed, server failed after, refused tool, refused server, delivery, next act or answer to whether the task asked:

CauseMessage
taskIds names more than 200 tasks.Run filter takes at most 200 tasks.
outcome, delivery, next or asked names a value it does not take.Run filter <filter> must be one of <values>, not <value>., as in Run filter next act must be one of started, parked, closed, answered, sent-back, not approved.
A filter that takes one value is given more than once.Run filter takes one <filter>, not <count>.
day is not a day of the period written YYYY-MM-DD.Run filter day must be a date in the period, in the form YYYY-MM-DD, not <value>.
week is not a Monday written YYYY-MM-DD.Run filter week must be a Monday in the form YYYY-MM-DD, not <value>.
A filter value other than a taskIds entry is longer than 200 characters.Run filter <filter> must be at most 200 characters.
page is past the last page with runs.Run page must be at most <last>, not <page>.
page is above 10,000.Run page must be at most 10000, not <page>.

On /pull-requests/list, where <filter> names the parameter as author, type, state, week, reverted, count of review rounds or compared:

CauseMessage
repository names more than 50 repositories.Pull request filter takes at most 50 repositories.
author, type, state, reverted, rounds or compared names a value it does not take.Pull request filter <filter> must be one of <values>, not <value>.
A filter that takes one value is given more than once.Pull request filter takes one <filter>, not <count>.
week does not match YYYY-MM-DD, or cannot be read as a date. A day past the end of its month, as in 2026-02-31, is read as a day of the next month.Pull request filter week must be a date in the form YYYY-MM-DD, not <value>.

On /setups, a size other than small, medium or large: Setup filter size must be one of small, medium, large, not <value>.

On this page