Skip to main content

Conventions & errors

Requests

  • Base URL: https://YOUR-TESTVIBE-SERVER/api/v1/ops
  • Authentication: Authorization: Bearer tvb_… on every request (details).
  • Bodies are JSON (application/json); a malformed body is rejected with 400 invalid_request.
  • {project} in paths is the project's public id (a GUID, from list_projects). {feature} accepts a numeric id or the feature name (case-insensitive).

The cURL examples throughout the reference assume:

export TESTVIBE_SERVER=https://YOUR-TESTVIBE-SERVER
export TESTVIBE_API_KEY=tvb_XXXXXXXX…
export PROJECT=7f3c9a4e-2b1d-4e8a-9c6f-0d5b8a1e2f34

Responses

  • JSON, with camelCase keys.
  • Timestamps are ISO-8601 UTC with a Z suffix: "2026-06-10T14:32:07Z". Fields that don't apply yet (e.g. finishedUtc on a running run) are null.
  • Reads return 200. Creates return 201. Dispatches (generate, run) return 202 with the id to poll. Mutations return 200 with { "ok": true }.

Errors

Every error has the same shape:

{ "error": "conflict", "message": "This feature is already generating." }
HTTPerrorWhen
400invalid_requestMalformed JSON, missing required field, write-allowlist violation, file too large.
401unauthorizedMissing, invalid, or revoked API key.
404not_foundUnknown route, or no such project / feature / run in this workspace.
409conflictLifecycle conflicts: feature already generating, not runnable yet, dispatch rejected.
info

message is human-readable and safe to surface directly — the MCP server and CLI both pass it through verbatim.

Versioning

The API is versioned in the path (/api/v1/). Additive changes (new fields, new routes) happen within v1; breaking changes get a new version. See Roadmap & changelog.