The API
The versioned /api/v1 surface for scripts and CI: authentication, running tests, JUnit output, test impact, importing, and the error conventions.
Vera has two HTTP surfaces, and which one you want depends on who is calling.
| Surface | Auth | For |
|---|---|---|
/api/v1 | Authorization: Bearer vera_… token | Scripts, CI, anything outside Vera. Stable and versioned. |
/api/… | Session cookie | The dashboard itself. Internal; changes without notice. |
If you are automating Vera, use /api/v1. The unversioned routes exist because the
dashboard needs them, and documenting them as an integration contract would be
promising stability that is not offered.
There is also /api/mcp for AI coding agents — see MCP — and
/api/agent/v1, which the local agent uses to lease runs.
Authentication
Mint a token in the dashboard, then send it as a bearer token:
curl -H "Authorization: Bearer vera_xxx" \
https://your-vera-host/api/v1/projectsTokens are shown once. /api/v1 requires the Pro api-access feature; on a
plan without it every /api/v1 call returns 401, which is the usual explanation for
a token that "does not work". /api/mcp is available on the free tier.
The endpoints
Projects
GET /api/v1/projects List projects
GET /api/v1/projects/:id Get one projectThe projection is deliberately minimal — it does not include a project's stored credentials or auth configuration. A token that could read those would turn a CI secret into an app-credential leak.
Running tests
POST /api/v1/projects/:id/run Start a run (a suite, a tag, or the project)
GET /api/v1/runs/:id Run status and results
GET /api/v1/runs/:id/wait Long-poll until the run finishes/wait is the one to build a pipeline on: start a run, then wait on it, rather than
polling /runs/:id on a timer.
Reporting
GET /api/v1/runs/:id/junit JUnit XML for one run
GET /api/v1/suite-runs/:id/junit JUnit XML for a suite runJUnit XML is what makes results render natively in a CI provider's test UI, with per-test names and failure messages, instead of being buried in log output. See CI integration.
Test impact
GET /api/v1/projects/:id/impact Which tests a change set could affectThe API behind vera check — given changed files, the tests that cover them. See
vera check.
Importing
POST /api/v1/projects/:id/import/:format:format is one of the eight supported formats. See
Importing & exporting.
Conventions
Errors carry a machine-readable code alongside the message, so a caller can branch without string-matching:
{ "error": "This feature is available on the Team plan.",
"code": "plan_limit", "feature": "chains", "requiredPlan": "team" }plan_limit and plan_required mean the org's plan does not permit the call —
retrying will not help. A 4xx in general is not worth retrying; a 5xx may be.
Long-running operations stream. A run started with
Accept: text/event-stream streams step-by-step progress as Server-Sent Events;
without that header the same endpoint runs to completion and returns the final
result as JSON. Pick per caller: SSE for a live view, plain JSON for a script that
only wants the verdict.
Everything is org-scoped. A token resolves to exactly one organisation and cannot read another's projects, tests or runs. There is no cross-tenant read.
Rate limiting is keyed per organisation in cloud mode, so one noisy integration cannot starve another tenant.
Choosing an integration path
Before writing HTTP calls, check whether something already does the job:
- CI — the
vera-runaction, or the ready-made GitLab/Bitbucket configs. See CI integration. - A local or self-hosted runner —
vera-agent. See The local agent. - An AI coding agent — MCP, which gives it typed tools instead of a REST client. See MCP.
The raw API is the right answer when none of those fit — an unusual CI system, a dashboard of your own, a bulk migration.
See also
- CI integration — §6 covers driving the API from any CI
- MCP — the agent-facing surface
- The local agent — the lease API and the CLI over it
vera check— the impact endpoint in practice