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.
npx specbook bundle --tag monitor --out specbook-tests.mjsnode specbook-tests.mjs --env prod --safe --retries 1 --timeout 10000Run 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
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.
Press Run to start.$ 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.
# .github/workflows/monitor.ymlon: 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 }}