Terminal-first API regression ledger

Regression history for APIs that change.

Backline gives backend teams a durable trail from HTTP check to CI decision.

Install Backline ./gradlew :apps:cli:installDist
Backline CLIfailed run and diff
$ cd examples/sample-api
$ backline run --timeout-seconds 120
RUN_ID: dc1aad4c-48b7-44f8-9849-6df62de09d8a
status: QUEUED
status: FAILED

$ backline diff dc1aad4c-48b7-44f8-9849-6df62de09d8a
[NEWLY_FAILING]
- broken-endpoint (Broken endpoint) null -> FAILED

[NEWLY_PASSING]
- get-user (Fetch user) null -> PASSED
- health (Health check) null -> PASSED

Verbatim CLI output from the documented Docker demo.

CLIAPIWorkerPostgreSQLReports

Verified output

Generated Markdown reports show what failed.

Backline writes a reviewable report from stored API data: run status, check counts, failures, latency, and comparison context.

backline reportsample-api
# Backline Run Report

## Run summary
- **Project**: sample-api (`sample-api`)
- **Environment**: local
- **Run ID**: dc1aad4c-48b7-44f8-9849-6df62de09d8a
- **Status**: FAILED
- **Attempt count**: 1

## Check summary
| Metric  | Count |
| ------- | ----- |
| Total   | 3     |
| Passed  | 2     |
| Failed  | 1     |
| Errored | 0     |

## Failed checks
- **Result status**: FAILED
- **HTTP status**: 500
- **Error code**: STATUS_MISMATCH
- **Error message**: Expected status 200 but was 500

Verbatim Markdown report excerpt from the same failed sample run.

Keep the evidence close to the API change.

Backline turns a YAML check into durable evidence without becoming a browser dashboard.

  1. Define the check

    Keep expected statuses, latency limits, and assertions in backline.yml.

    backline.yml
  2. Run it through the worker

    The CLI submits the run, while the worker executes checks and stores immutable results.

    backline run
  3. Compare what changed

    History and diff expose new failures, newly passing checks, latency changes, and missing checks.

    backline diff <runId>

Make a regression visible in CI.

Policy evaluates stored results and a chosen baseline. Terminal output remains readable for people, while JUnit output gives a pipeline a structured failure artifact.

Read the CI guide
backline.ymlpolicy
policy:
  max_newly_failing: 0
  max_errored_checks: 0
  max_latency_regression_ms: 200

$ backline run --enforce-policy \
  --junit-output ./build/backline-policy.xml

policy failed  exit 5

System ownership

Each part owns one part of the job.

The CLI is the interface. The API persists history. The worker runs checks. PostgreSQL is the durable record. Reports use API data, not direct database access.

CLIAPIWorkerPostgreSQLReports

What Backline does not do.

It stays useful by keeping the job focused on repeatable API behavior and durable regression history.

Interactive API exploration

Use a client such as Postman or Bruno when you need to explore requests by hand.

Hosted monitoring

There is no SaaS dashboard or cloud sync workflow. Run the stack locally or in CI.

Load testing

Use a dedicated load-testing tool for throughput and scale experiments.

Unbounded evidence

Response previews are bounded and sensitive headers are redacted according to repository guardrails.

Run the local demo.

Start with the path a reviewer can use to see a passing and intentionally failing check.

The complete local workflow.

Start the stack, install the CLI, then run the included sample project. The README has the platform-specific details.

quick startlocal
$ docker compose up --build -d
$ ./gradlew :apps:cli:installDist
$ backline doctor
$ cd examples/sample-api && backline run
$ backline history
$ backline diff <runId>
$ backline report <runId>