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(or2026-11, optionally?target_id=): the evidence pack for a quarter or month, built on demand;…/downloadreturns the ZIP with its SHA-256 inX-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 forRetry-After.
Signed-in members can call the same routes from the browser session; organisation-wide lists then take ?org_id=org_….