Skip to content

REST API

Tripwire's backend is a FastAPI JSON API. Everything the dashboard does, you can do over HTTP — author suites, start and observe runs, manage issues and settings, generate suites from a URL, export to Playwright, and read analytics.

  • Base path: /api/v1
  • Auth: every endpoint requires Authorization: Bearer <jwt-or-api-token>, except the open ones: GET /health, GET /health/ready, POST /auth/login, and the first-run bootstrap GET /auth/setup + POST /auth/setup (the latter only works while no users exist). See Authentication.
  • Interactive OpenAPI / Swagger UI: /docs — try every endpoint live, with full request / response schemas.
  • Raw schema: /openapi.json

The live OpenAPI page is the source of truth for exact request and response shapes — the tables below are a map, not a substitute. Generate clients from /openapi.json.

Endpoints

Health

MethodPathDescription
GET/healthLiveness — always 200 if serving.
GET/health/readyReadiness — 200 if the data dir is writable, else 503.

Auth

Full details in Authentication.

MethodPathDescription
GET/auth/setupOpen. { needs_setup } — true while the instance has no admin yet.
POST/auth/setupOpen (only valid pre-first-user). { email, password } creates the first admin → { token, user }.
POST/auth/login{ email, password }{ token, user }. Open (no auth).
GET/auth/meThe current user.
POST/auth/tokensCreate an API token { name? } → returns the raw tw_… once.
GET/auth/tokensList your API tokens (metadata only).
DELETE/auth/tokens/{id}Revoke an API token.
GET/auth/usersList users (admin).
POST/auth/usersCreate a user { email, password, role } (admin).

Suites

MethodPathDescription
GET/suitesList suites (paginated: limit, offset, q).
POST/suitesCreate a new suite — body { yaml }. The server picks a unique filename (never overwrites). Returns { ok, file }.
GET/suites/{name}Get a suite ({ file, yaml, cases }).
PUT/suites/{name}Update a suite — body { yaml }; validates YAML, returns 400 on error.
DELETE/suites/{name}Delete a suite.
GET/suites/{name}/exportExport the suite as a portable Playwright .spec.ts (text/plain).

Runs

Runs are persisted to a durable queue and worked by a pool of up to TRIPWIRE_MAX_CONCURRENT_RUNS (default 2) workers — submit any number; they run in parallel up to that limit and the rest wait their turn (no 409). The queue survives a restart; a run interrupted by a crash is reconciled on the next startup. Each job is its own run id. State within a suite (generated fixtures and values a case capture:s) is shared across that suite's cases.

MethodPathDescription
GET/runsRun history (includes queued / running jobs).
POST/runsEnqueue one or more jobs. Single-suite form: { suite, cases?, file_issues?, headed?, sharded? }. Queue form: { jobs: [{ suite, cases? }, …], file_issues?, headed? }. cases is a subset of case ids (omit for all). headed: true runs a visible browser. Returns { run_id, run_ids, queued }.
GET/runs/queueCurrently running + pending jobs — { active, active_suite, running: [{ id, suite }], running_suites, pending: [{ id, suite, cases }], busy } (active/active_suite keep the single-run shape for back-compat).
GET/runs/{id}Run status + live events + report. Events include action (each LLM browser action) and shot (a per-step screenshot path).

Run artifacts (per-step screenshots, reports) are served read-only under /api/v1/artifacts/<run_id>/…; each case in the report carries a shots[] list of { label, note, path } you can render from that base.

Plans (ordered regression passes)

A plan bundles suites into an ordered pass you run on demand or on a cron schedule.

MethodPathDescription
GET/plansList plans.
GET/plans/{plan_id}Plan detail (suites, schedule, last run).
POST/plansCreate/update a plan — body { id?, name, description?, items: [{ suite, cases? }], schedule?, auth? } (schedule is a cron expression; set id to update).
DELETE/plans/{plan_id}Delete a plan.
POST/plans/{plan_id}/runEnqueue the whole plan as one ordered pass → { run_ids }.

Issues (built-in tracker)

MethodPathDescription
GET/issues?status=List native issues (paginated; optional status, q).
GET/issues/{id}Issue detail ({ …, body_md, comments }).
PATCH/issues/{id}Partial edit — any of { status, title, body_md, severity }. status is open / closed / acknowledged.
POST/issues/{id}/commentsAdd a comment — body { body }.

Settings (admin)

Writing settings requires an admin.

MethodPathDescription
GET/settingsIntegration settings — secrets are masked on read.
PUT/settingsSave settings — body is the settings object (only non-null fields are written).
POST/settings/test-notificationSend a test Slack/Teams notification with the current config.

Integrations

MethodPathDescription
GET/integrations/trackersWhich issue trackers are configured: { github, gitlab, jira } booleans. Drives the dashboard's tracker picker so it only offers what's set up.

Artifacts

MethodPathDescription
GET/artifacts/{path}A run artifact (per-step screenshot, report). Authenticated — send the Bearer token, or ?token=<jwt> for <img>/<a> tags. Confined to the artifacts directory.

Generate (anything → suite)

Generate a suite from a live app, your docs/spec, or a description. Exhaustive by default — a multi-pass generator (discover areas → expand each into happy-path, validation, edge, error, auth and negative scenarios in parallel).

MethodPathDescription
POST/generateBody { kind, url?, base_url?, text?, auth?, exhaustive?, save_as? }. kind is url | docs | text | openapi. For url, pass url (a deep page works; add auth: { username, password, login_path? } to reach pages behind login). For docs/text/openapi, pass base_url (what the suite targets) plus a url to fetch or pasted text. Returns { yaml } (plus saved_as). See generation.
POST/generate/planExhaustive generation that splits the app into several suites and saves them as a ready-to-run plan. Returns { plan_id, plan_name, suites }.

Analytics

MethodPathDescription
GET/analyticsFlake / run analytics over the full run history. See Flakiness analytics.

Record (clicks → suite)

A one-click recorder: open a real browser, click through a flow, and we capture it. (Or convert a trace you already have.)

MethodPathDescription
POST/record/startBody { base_url }. Opens a real (headed) browser at base_url and starts capturing clicks/typing/navigation. Returns { record_id }. Requires a desktop session on the API host.
GET/record/sessions/{id}Live status — { status, action_count, base_url, error }.
POST/record/stopBody { record_id, title?, save_as?, humanize? }. Stops the session, converts the captured trace to a suite. Returns { yaml, actions } (plus saved_as).
POST/record/convertBody { actions, base_url, title?, save_as?, humanize? }. Convert an action trace ({ type, selector?, value?, url?, text? }[]) you already have. humanize (default true) uses the LLM to phrase steps. See Record from clicks.

Checks (standalone)

Dry-run a single deterministic check core without authoring a whole suite. These are not suite expect kinds (suites use the four check kinds) — they are standalone endpoints for dashboards and visual baselines.

MethodPathDescription
POST/checks/apiBody { url, method?, status?, json_path?, equals?, headers?, body? }. Runs an HTTP request and asserts status and/or a JSON path. Returns { kind: "api", status, observed }.
POST/checks/screenshotBody { name, image_b64, tol? }. Compares a PNG against the stored baseline for name (first run for a name seeds the baseline and passes). Returns { kind: "screenshot_region", status, observed }.

Examples

Start a run:

bash
curl -X POST http://127.0.0.1:8400/api/v1/runs \
  -H 'Content-Type: application/json' \
  -d '{"suite": "signup-login.tripwire.yaml", "file_issues": "tripwire"}'

Poll its status, live events, and report:

bash
curl http://127.0.0.1:8400/api/v1/runs/<run-id>

Save (and validate) a suite — the body is JSON { "yaml": "..." }:

bash
curl -X PUT http://127.0.0.1:8400/api/v1/suites/signup-login.tripwire.yaml \
  -H 'Content-Type: application/json' \
  -d "{\"yaml\": $(jq -Rs . < signup-login.tripwire.yaml)}"

Generate a suite from a URL and save it:

bash
curl -X POST http://127.0.0.1:8400/api/v1/generate \
  -H 'Content-Type: application/json' \
  -d '{"url": "https://app.example.com", "save_as": "app-flows"}'

Export a suite to portable Playwright:

bash
curl http://127.0.0.1:8400/api/v1/suites/signup-login.tripwire.yaml/export -o tests/signup.spec.ts

List open issues from the built-in tracker:

bash
curl 'http://127.0.0.1:8400/api/v1/issues?status=open'

Error shape

Errors are returned as JSON via the app's error handlers — e.g. a missing/invalid token returns 401; an action needing admin returns 403; invalid YAML on PUT /suites/{name} returns 400 with a type of invalid_yaml; generation failures return 502 (generation_error).

See also

Tripwire — AI-native, self-healing E2E testing. Terms · Privacy · Legal Notice