# Share a Bruno API Test Report — One Link From bru run

Canonical: https://commareports.com/share-bruno-report
Published: 2026-09-14

> bru run --reporter-html writes a self-contained API test report. Publish it to Comma from CI: a stable URL, comments on the failing request, a revision per run.

# Share a Bruno API test report

Bruno's whole argument is that an API collection belongs in the repository, as
files, under review, with no cloud account in the middle. That argument holds
right up until a request fails in CI, at which point the result is back in a
log that needs a login — the exact thing the collection was moved out of.

The CLI already writes the artifact that fixes it:

```bash
bru run --env staging --reporter-html results.html
```

One self-contained file: every request, the assertions that ran, status codes,
response times, and the assertion that failed with what it got instead.

## Publish it

Drag `results.html` into [Comma](https://commareports.com/), or publish from CI
and keep one permanent URL per suite:

```bash
bru run --env staging --reporter-html results.html || FAILED=1

curl -fsS -X PATCH "https://commareports.com/api/v1/reports/$REPORT_ID" \
  -H "Authorization: Bearer $COMMA_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d "$(jq -n --rawfile html results.html \
        --arg t "API — staging — $(date -u +%FT%TZ)" '{title: $t, html: $html}')"

exit "${FAILED:-0}"
```

Publish before failing the job, or the only runs that ever get a link are the
green ones. See the [API reference](/docs/api) and
[publishing from CI](/docs/ci).

## Redact before you publish

An API test report contains request and response bodies, and those contain
whatever your staging environment returns: bearer tokens in headers, customer
records in payloads, internal hostnames.

Two things worth doing before the first CI publish:

- Keep secrets in environment variables Bruno resolves at runtime rather than
  in the collection, so they are not in the repo _or_ the report.
- Set the report's access to **private or team**, not link-anyone. Access is
  per report — see [sharing & access control](/docs/sharing).

## The failure is a cross-team conversation

An API test fails for one of two reasons: the API changed, or the test was
wrong about what the API does. Deciding which requires the person who owns the
endpoint, who is on another team, probably in another repository, and does not
have your CI.

A link they can open — with the request, the assertion, and the actual response
in front of them — turns a two-day thread into a two-minute one. Anchored
comments keep the verdict on the request: "intentional, we dropped `legacy_id`
in v3". See [commenting on HTML](/comment-on-html).

## One URL per environment

The pattern that works: one saved report id per environment, PATCHed on every
run. `#api-staging` and `#api-prod-smoke` become two stable links instead of a
stream of artifact URLs, each publish appends a revision, and "when did this
start failing?" is answered by scrubbing the history rather than by hunting
expired artifacts — see [expired CI artifacts](/fix/ci-artifact-expired).

## Limits

- **Entry HTML: 5 MB.** A collection with large response bodies can exceed it —
  Bruno's report includes them, so trim the assertions that dump whole payloads.
- Assets: 25 MB per file, **250 MB and 500 files total**.
- **60 requests/minute per token.**

## Try it

Comma is free — unlimited reports, unlimited commenters, unlimited revision
history.

**[Publish an API test report →](https://commareports.com/)**

### Related

- [Share a Newman/Postman report](/share-newman-postman-report) · [Share OpenAPI docs](/share-openapi-docs)
- [Share Swagger UI docs](/share-swagger-ui-docs) · [Share Scalar API docs](/share-scalar-api-docs)
- [Share a k6 load test report](/share-k6-load-test-report) · [Publishing from CI](/docs/ci)
