API tokens and /api/v1

API tokens give scripts read-only access to one organisation: gate a deploy on the last restore test, pull coverage into a dashboard, or fetch evidence for an audit. A token can never change anything: there are no write routes for tokens, and the app API refuses them.

1. Create a token

Organisation → API tokens (owners and admins). Pick a name, the scopes and an expiry, then copy the token: it is shown once and stored only as a SHA-256 hash. The list shows its first characters, scopes and when it was last used. Revoking takes effect on the next request.

Scope Routes
runs:read GET /api/v1/runs?target_id=…, GET /api/v1/runs/{run_id}
coverage:read GET /api/v1/targets, GET /api/v1/targets/{target_id}/coverage
reports:read GET /api/v1/runs/{run_id}/report.pdf
evidence:read GET /api/v1/runs/{run_id}/verification, GET /api/v1/evidence/{period}, GET /api/v1/evidence/{period}/download

Give each pipeline its own token with the fewest scopes it needs.

2. Call the API

curl -sf -H "Authorization: Bearer $VERESTORE_TOKEN" \
  https://app.verestore.dev/api/v1/targets
  • GET /api/v1/targets: every target with its last run and coverage sentence.
  • GET /api/v1/runs?target_id=tgt_…&limit=25&cursor=…: a target's runs, newest first (items, nextCursor).
  • GET /api/v1/runs/{run_id}: status, verdict, timings, backup identity, checks and countersignature state. The raw result is not included, and no row data ever is.
  • GET /api/v1/runs/{run_id}/verification: the verification bundle to check offline or at /verify.
  • GET /api/v1/evidence/2026-Q4 (or 2026-11, optionally ?target_id=): the evidence pack for a quarter or month, built on demand; …/download returns the ZIP with its SHA-256 in X-Content-SHA256.

Gate a deploy on the last test:

status=$(curl -sf -H "Authorization: Bearer $VERESTORE_TOKEN" \
  "https://app.verestore.dev/api/v1/runs?target_id=$TARGET_ID&limit=1" | jq -r '.items[0].status')
[ "$status" = passed ] || { echo "last restore test: $status"; exit 1; }

3. Errors and limits

Errors are application/problem+json:

  • 401: missing, malformed, unknown, expired or revoked token.
  • 403: the token lacks the route's scope.
  • 404: no such resource in the token's organisation (another organisation's IDs look the same as missing ones).
  • 429: more than 120 requests a minute from one address; wait for Retry-After.

Signed-in members can call the same routes from the browser session; organisation-wide lists then take ?org_id=org_….