Specbook
04 · Monitor

One file. Just node.

specbook bundle compiles your requests and flows, their dependencies and the runner into a single .mjs file. Run it on any machine with node, on a schedule in production. It needs no install and no spec, and it holds no secrets.

Build one file

Compile the tests you want to watch. The file holds your requests and flows and the runner, and a .sha256 file beside it lets your pipeline verify the download.

Terminal window
npx specbook bundle --tag monitor --out specbook-tests.mjs
node specbook-tests.mjs --env prod --safe --retries 1 --timeout 10000

Run it anywhere

Node is all the machine needs. This recording runs the file against a staging address.

node specbook-tests.mjs --env demo --var petstoreUrl=$STAGING/api/petstore --var countriesUrl=$STAGING/api/countries
$ node specbook-tests.mjs --env demo --var petstoreUrl=$STAGING/api/petstore --var countriesUrl=$STAGING/api/countries

Know when it breaks

This is the same run in your browser. Choose what the demo API does, then press Run. When the API is down every request errors and the run exits 1, which is what pages someone.

specbook test --env demo --tag monitor
What the demo API does during the runthe API answers. This shows the runner, not real uptime.
Press Run to start.
Starting the demo API…
specbook test --env demo
$ specbook test --env demo

Keep production safe

By default a run sends everything, so you can test flows that create and delete against a lower environment. Against production, pass --safe. Any request that is not a GET, HEAD or OPTIONS (or a GraphQL query) is refused before it is sent, so a monitor cannot change production data. Mark a POST that only reads with safe: true.

--retries 1 runs a failed flow once more, and one that then passes is reported as flaky and exits 0. --timeout limits each request. The report separates failed from errored, so an API that is down reads differently from one that answered wrongly.

Run it on a schedule

A scheduled workflow downloads the file, runs it and fails when a flow does.

monitor.yml
# .github/workflows/monitor.yml
on:
schedule: [{ cron: '*/15 * * * *' }]
jobs:
monitor:
runs-on: ubuntu-latest
steps:
# download the file your pipeline built, then:
- uses: actions/setup-node@v4
with: { node-version: 24 }
- run: node specbook-tests.mjs --env prod --safe --tag monitor --retries 1 --timeout 10000 --reporter json:report.json
env:
PETSTORE_API_KEY: ${{ secrets.PETSTORE_API_KEY }}