An audit is two steps that never mix. Collection reads the organisation into a snapshot. Analysis turns the snapshot into findings, with no network access and no clock but the snapshot's own. The snapshot is stored with each report, so a figure can always be traced back to what GitHub returned.
What is read
| Data | Endpoint | Window |
|---|---|---|
| Plan and seat count | GET /orgs/{org} |
now |
| Members, outside collaborators, invitations | GET /orgs/{org}/members and siblings |
now |
| Copilot seats and last activity | GET /orgs/{org}/copilot/billing/seats |
now |
| Repository activity | GET /repos/{org}/{repo}/events |
90 days |
| Workflow files | GET /repos/{org}/{repo}/contents/.github/workflows/… |
now |
| Workflow runs | GET /repos/{org}/{repo}/actions/runs |
30 days |
| Job timings, for runs a finding prices | GET …/actions/runs/{id}/jobs |
30 days |
| Billed Actions spend | GET /organizations/{org}/settings/billing/usage |
last month |
| Copilot AI Credits by model | GET /organizations/{org}/settings/billing/ai_credit/usage |
last month |
Job timings are fetched only for the runs a finding will price: superseded runs, scheduled runs on dormant repositories, and runs long enough to have hung. Fetching every job of every run is the expensive way to learn what the billing report already says.
Every other platform
After GitHub, each platform connected in settings is read with its own key and priced into the same report. Each has a section in the report (sources in the JSON) whose lines add up to what it costs, and findings for what is paid for and not used. A platform that cannot be read is listed in the report footer as Not read this time, with the reason, and the rest of the report is complete.
| Platform | What is read | Guide |
|---|---|---|
| GitLab | Billable members and last activity, plan, Duo seats and last Duo use, compute minutes, merged merge requests | GitLab |
| Azure DevOps | Access levels, Visual Studio subscribers, last sign-in, completed pull requests | Azure DevOps |
| Atlassian | Users and last visit per product for Jira, Confluence, Service Management and Bitbucket | Atlassian |
| JetBrains | Every licence, its holder and the IDE's last check-in | JetBrains |
| CircleCI | Credits per project and workflow, run outcomes | CircleCI |
| Claude Code, Cursor, OpenAI | Spend per engineer, seats and usage, API spend by project | Claude Code, Cursor, OpenAI |
A workspace without GitHub runs only this part.
How figures are priced
Seats and Copilot are counted, then multiplied by a price: your contract price if you have entered one, otherwise the list price in Prices. The finding's basis line says which.
Actions figures are measured. Each job's runner labels map to a per-minute rate, and only the minutes the finding is about are counted. For a superseded run, only the minutes after the newer run started. Where a figure could be read two ways, the smaller is used:
- A whole job is rounded up to the minute, as GitHub bills it. A partial job is not rounded.
- A runner label opsen does not recognise is priced as the cheapest hosted runner of its operating system.
- Self-hosted runners are priced at zero.
Monthly figures are the 30-day measurement. Yearly is twelve times monthly.
What is withheld
A finding opsen cannot support is left out of the total and listed under Not reported, and why:
| Withheld | When |
|---|---|
| Dormant seats | The installation can see only selected repositories |
| Dormant seats | Activity could not be read for more than 10% of repositories |
| Dormant seats | The organisation's plan was not readable |
| Idle Copilot seats | Copilot seats were not readable (no Copilot Business, or permission not granted) |
Failed reads are counted on every report. A partial audit that says so is useful; a zero that hides a 403 is not.
Limits
| Limit | Value |
|---|---|
| Repositories read, most recently pushed first | 500 |
| Workflow runs read per repository | 1,000 |
| Runs whose job timings are fetched | 1,500 |
| Events read per repository | 300 (GitHub's own limit) |
When a limit is hit the report footer says which and where.
Schedule
Audits rerun every seven days, and on demand. One runs per organisation at a time. An audit interrupted by a restart is marked failed after an hour and the previous report stays visible.