Skip to main content

Conventions & errors

Requests​

  • Base URL: https://testvibe.app/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://testvibe.app
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. Other mutation responses vary by operation: some return { "ok": true }, some the updated object, and load deletion returns { "deleted": true, "featureId": … }.

Errors​

Structured operation errors include an error code and a human-readable message:

{ "error": "conflict", "message": "This feature is already generating." }
HTTPCommon codeMeaning
400invalid_request, invalid_modelMalformed input, invalid file path, unsupported model id, or an operation-specific validation error.
401unauthorizedMissing, invalid, revoked, or expired key, or its creator is no longer a member.
402insufficient_creditsA credit-gated operation cannot reserve enough credits. Some run/generation dispatch refusals use 409 instead.
403plan_forbiddenThe cloud plan does not include API/CLI/MCP access.
404not_foundUnknown route or resource outside this workspace/project.
409conflictLifecycle or dispatch refusal. Specific routes can return confirmation_required, resume_unavailable, or secrets_unavailable.
429rate_limitedRequest budget exhausted; honor Retry-After.
502provider_errorNon-retryable model-provider failure.
503entitlement_unavailable, model_overloaded, capacity_unavailableRetryable admission/provider/capacity problem; honor Retry-After.
507storage_quota_exceededStorage quota prevents a new dispatch.

This is a list of common codes, not a closed enum. Some errors include retryable and retryAfterSeconds. A capacity refusal explicitly reports creditsCharged: false. Do not turn a monitoring/network error into a failed-test verdict.

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.

Retrying a dispatch​

For POST dispatches, send a unique Idempotency-Key (8–255 characters) and reuse it only when retrying the same method, route, and exact request body. Successful responses are replayed for 24 hours within the workspace, with Idempotent-Replay: true. A different request under the same key is a conflict. Failed dispatches are not stored as successful results.

This applies to generation, feature/load/automation/coverage run dispatches, suite runs, verify-change, and coverage scans. Other POST routes ignore the header and report Idempotency-Ignored: true. This is not a guarantee for arbitrary writes or every endpoint.