API keys
Outside GitHub Actions, push with a project API key. A key starts with bs_, is shown once, pushes to one project and can't read anything. A project can have 20 active keys. In GitHub Actions, pass a key to the step's token input instead of using OIDC.
For CI outside GitHub, create a project at buildstats.io/claim under Any other CI. It lives at buildstats.io/p/name and comes with its first key. Admins add keys to any project in the Keys tab of its settings.
Push metrics
Send a POST to /api/v1/push with the key as a bearer token:
curl https://buildstats.io/api/v1/push \ -H "Authorization: Bearer $BUILDSTATS_KEY" \ -H "Content-Type: application/json" \ --data @- <<EOF{ "metrics": [ { "name": "bundle_size", "value": 42.8, "unit": "kB", "better": "lower" }, { "name": "coverage", "value": 94.2, "unit": "%", "better": "higher" } ], "meta": { "ref": "main", "sha": "$(git rev-parse HEAD)" }}EOFmetrics- 1 to 50 objects with
nameandvalue, plus optionalunitandbetter(higherorlower). Names follow the metric format. meta.ref- A branch like
main, or a full ref likerefs/pull/12/mergeto record on a pull request. Defaults to the project's default branch. meta.sha- The commit. Without it every push counts as its own commit, in push order. Pushing a metric again for the same commit, ref,
meta.run_idandmeta.run_attemptreplaces its value. meta.base_ref- Branch to compare against. Defaults to the project's default branch.
meta.message- Commit message, cut at 256 characters, and
meta.committed_at, an ISO 8601 time. Both show on the project page. meta.variant- Stores every metric of the push as
name/variant.
Request bodies are capped at 64 KiB.
The response
A 200 carries project_url, locked, and one entry per metric in results:
stored- Whether the value was saved. When it wasn't,
errorsays why. previous- The last value on the same ref from an earlier commit.
base- The value on the base branch, with the change against it in
deltaanddelta_pct. verdictbetter,worseorsame, for metrics markedhigherorlower.chart_url- The metric's chart, and its badge in
badge_url.
error is one of these:
metric_full- The series on this ref already holds 50,000 points.
metric_limit- The project already has 100 metrics.
project_limit- The owner already has 100 public or 25 private projects.
locked- The private project's trial or plan has ended, see locked projects.
duplicate_in_run- The same Action run already stored a different value for this metric.
ignored_ref- The run is not recorded, like a merge queue run.
Read the history
Public projects can be read without a key, private projects only by signed-in members. {slug} is owner/repo, or p/name for projects outside GitHub.
/api/v1/projects/{slug} - The project with every metric, its latest value, a sparkline and image URLs.
.../refs- Branches and pull requests with data.
.../metrics/{name}/points - Values of one metric on
ref. A base name returns every variant. .../commits- Commits on
refwith the value of every metric. .../pulls- Pull requests, and
.../pulls/{number}compares one with its base.
Lists come newest first, in pages. n sets the page size, for points 50 by default and up to 1,000. Pass the response's next_before as before for the next page.
curl "https://buildstats.io/api/v1/projects/acme/orbit/metrics/bundle_size/points?ref=main&n=100"Charts and badges
/{slug}/{metric}.svg- History chart.
refpicks the branch, the default branch unless set.nis the number of commits: 30, 50, 100, 200, 500, 1000, default 200.wis the width in pixels: 400, 600, 800, 1000, 1200, default 800.themeislightordark. /{slug}/{metric}/badge.svg - The latest value on the default branch.
/{slug}/{metric}/badge.json - The same badge as a Shields endpoint, for
img.shields.io/endpoint?url=....
Public images are cached for 5 minutes. Images of private projects need the project's t token, see private images.
Errors and limits
Errors are JSON with an error code like invalid_request, a readable message, and a request_id to quote when you report a problem. Validation errors list up to 10 issues, and a 429 carries retry_after and a Retry-After header in seconds.
| Metrics per push | 50 |
|---|---|
| Request body | 64 KiB |
| Metrics per project | 100 |
| Points per metric and ref | 50,000 |
| Active API keys per project | 20 |
| Pushes | 60 a minute per project, and 60 a minute per IP for key pushes |
| Read API | 120 requests a minute per IP |
| Images | 600 requests a minute per IP, counted per project for GitHub's image proxy |