Download OpenAPI specification:Download
REST API for qa-clone (testsbot.com). All JSON error responses use the envelope { ok: false, error }; success bodies are either the documented resource shape or { ok: true, data? }. The /projects* and /runs* paths of this document are generated from the zod-openapi route definitions in the API source; the remaining paths are maintained by hand and drift-gated in CI (see docs/runbooks/openapi-drift.md).
Reports whether the API can serve database-backed traffic. Answers 200 only when the database responds; 503 when it does not, with ok in lockstep with the HTTP status. This is the endpoint for uptime monitoring and the status page — use /live for orchestrator probes.
{- "db_ok": true,
- "ok": true
}Reports only that the process is up and serving HTTP — it performs no database call and stays 200 during a database outage. This is what the Fly http_service check polls; probing the DB-aware /health there would let a database fault evict the machine from the load balancer.
{- "ok": true
}All projects of the active org, newest first. Soft-deleted projects are excluded.
[- {
- "appId": "28c365d5-df94-4a54-8217-3ce51d068868",
- "captchaSolvingEnabled": true,
- "crawlCron": "string",
- "createdAt": "2019-08-24T14:15:22Z",
- "deletedAt": "2019-08-24T14:15:22Z",
- "devicePreset": {
- "locale": "string",
- "preset": "desktop",
- "timezone": "string"
}, - "generateGapTests": true,
- "githubInstallationId": "string",
- "githubRepo": "string",
- "healAutoApplyThreshold": "string",
- "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
- "name": "string",
- "orgId": "string",
- "pageCount": 0,
- "prFeedbackEmojiReactionEnabled": true,
- "prFeedbackReviewContextChars": 0,
- "prFeedbackVerdictEnabled": true,
- "runBudgetMinutes": 0,
- "runCount": 0,
- "stateLifetimeMinutes": 0,
- "stepTimeoutSeconds": 0,
- "testDataRetentionDays": 0,
- "testDataRetentionPolicy": "30d",
- "updatedAt": "2019-08-24T14:15:22Z",
- "vercelProtectionBypassConfigured": true
}
]| app_id | string <uuid> |
| base_url required | string <uri> |
| name required | string non-empty |
{- "app_id": "affd1d10-9538-4fc8-9e0b-4594a28c1335",
- "name": "string"
}{- "appId": "28c365d5-df94-4a54-8217-3ce51d068868",
- "captchaSolvingEnabled": true,
- "crawlCron": "string",
- "createdAt": "2019-08-24T14:15:22Z",
- "deletedAt": "2019-08-24T14:15:22Z",
- "devicePreset": {
- "locale": "string",
- "preset": "desktop",
- "timezone": "string"
}, - "generateGapTests": true,
- "githubInstallationId": "string",
- "githubRepo": "string",
- "healAutoApplyThreshold": "string",
- "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
- "name": "string",
- "orgId": "string",
- "pageCount": 0,
- "prFeedbackEmojiReactionEnabled": true,
- "prFeedbackReviewContextChars": 0,
- "prFeedbackVerdictEnabled": true,
- "runBudgetMinutes": 0,
- "runCount": 0,
- "stateLifetimeMinutes": 0,
- "stepTimeoutSeconds": 0,
- "testDataRetentionDays": 0,
- "testDataRetentionPolicy": "30d",
- "updatedAt": "2019-08-24T14:15:22Z",
- "vercelProtectionBypassConfigured": true
}{- "appId": "28c365d5-df94-4a54-8217-3ce51d068868",
- "captchaSolvingEnabled": true,
- "crawlCron": "string",
- "createdAt": "2019-08-24T14:15:22Z",
- "deletedAt": "2019-08-24T14:15:22Z",
- "devicePreset": {
- "locale": "string",
- "preset": "desktop",
- "timezone": "string"
}, - "generateGapTests": true,
- "githubInstallationId": "string",
- "githubRepo": "string",
- "healAutoApplyThreshold": "string",
- "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
- "name": "string",
- "orgId": "string",
- "pageCount": 0,
- "prFeedbackEmojiReactionEnabled": true,
- "prFeedbackReviewContextChars": 0,
- "prFeedbackVerdictEnabled": true,
- "runBudgetMinutes": 0,
- "runCount": 0,
- "stateLifetimeMinutes": 0,
- "stepTimeoutSeconds": 0,
- "testDataRetentionDays": 0,
- "testDataRetentionPolicy": "30d",
- "updatedAt": "2019-08-24T14:15:22Z",
- "vercelProtectionBypassConfigured": true
}Partial update; at least one field is required. run_budget_minutes above the org's plan cap answers 402.
| id required | string <uuid> |
| app_id | string or null <uuid> |
| base_url | string <uri> |
| captcha_solving_enabled | boolean |
| crawl_cron | string or null non-empty |
object or object or (any or null) | |
| generate_gap_tests | boolean |
| heal_auto_apply_threshold | number or null [ 0 .. 1 ] |
| name | string non-empty |
| pr_feedback_emoji_reaction_enabled | boolean |
| pr_feedback_review_context_chars | integer or null >= 50 |
| pr_feedback_verdict_enabled | boolean |
| run_budget_minutes | integer or null >= 1 |
| state_lifetime_minutes | integer or null [ 5 .. 10080 ] |
| step_timeout_seconds | integer or null [ 5 .. 120 ] |
| test_data_retention_days | integer or null [ 1 .. 3650 ] |
| test_data_retention_policy | string Enum: "30d" "90d" "custom" "default" |
| vercel_protection_bypass_secret | string or null non-empty |
{- "app_id": "affd1d10-9538-4fc8-9e0b-4594a28c1335",
- "captcha_solving_enabled": true,
- "crawl_cron": "string",
- "device_preset": {
- "locale": "string",
- "preset": "desktop",
- "timezone": "string"
}, - "generate_gap_tests": true,
- "heal_auto_apply_threshold": 1,
- "name": "string",
- "pr_feedback_emoji_reaction_enabled": true,
- "pr_feedback_review_context_chars": 50,
- "pr_feedback_verdict_enabled": true,
- "run_budget_minutes": 1,
- "state_lifetime_minutes": 5,
- "step_timeout_seconds": 5,
- "test_data_retention_days": 1,
- "test_data_retention_policy": "30d",
- "vercel_protection_bypass_secret": "string"
}{- "appId": "28c365d5-df94-4a54-8217-3ce51d068868",
- "captchaSolvingEnabled": true,
- "crawlCron": "string",
- "createdAt": "2019-08-24T14:15:22Z",
- "deletedAt": "2019-08-24T14:15:22Z",
- "devicePreset": {
- "locale": "string",
- "preset": "desktop",
- "timezone": "string"
}, - "generateGapTests": true,
- "githubInstallationId": "string",
- "githubRepo": "string",
- "healAutoApplyThreshold": "string",
- "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
- "name": "string",
- "orgId": "string",
- "pageCount": 0,
- "prFeedbackEmojiReactionEnabled": true,
- "prFeedbackReviewContextChars": 0,
- "prFeedbackVerdictEnabled": true,
- "runBudgetMinutes": 0,
- "runCount": 0,
- "stateLifetimeMinutes": 0,
- "stepTimeoutSeconds": 0,
- "testDataRetentionDays": 0,
- "testDataRetentionPolicy": "30d",
- "updatedAt": "2019-08-24T14:15:22Z",
- "vercelProtectionBypassConfigured": true
}The project's crawl history, newest first (limit 20). Replaces guessing crawl completion from page counts — status is the real lifecycle.
| id required | string <uuid> |
[- {
- "endedAt": "2019-08-24T14:15:22Z",
- "error": "string",
- "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
- "intent": "string",
- "maxDepth": 0,
- "maxPages": 0,
- "pagesFound": 0,
- "startedAt": "2019-08-24T14:15:22Z",
- "status": "processing"
}
]Enqueues a BFS crawl of the project's base URL with the background worker. The body is optional — an empty body starts an anonymous default crawl.
| id required | string <uuid> |
| auth_test_case_id | string <uuid> |
| intent | string [ 3 .. 500 ] characters |
| max_actions | integer [ 1 .. 1000 ] |
| max_depth | integer [ 1 .. 10 ] |
| max_pages | integer [ 1 .. 1000 ] |
{- "auth_test_case_id": "11bfa731-3ee6-401d-a3f1-7994c29dc81c",
- "intent": "string",
- "max_actions": 1,
- "max_depth": 1,
- "max_pages": 1
}{- "crawl_id": "c9eee371-0b50-4a83-baff-95c2f0e36a00"
}Run count and LLM cost of the project since the start of the current UTC calendar month, plus the configured daily LLM cap. Browser-agent costs (Stagehand act()) are not included.
| id required | string <uuid> |
{- "dailyCapUsd": 0,
- "llmCostUsdThisMonth": 0,
- "runsThisMonth": 0
}| id required | string <uuid> |
| offset | integer >= 0 Default: 0 |
| limit | integer [ 1 .. 100 ] Default: 20 |
| include_archived | boolean Default: false |
| owner | string Owner filter (GAP-057): a Clerk user id (created_by) or the literal "system" (created_by IS NULL). Absent ⇒ all owners. |
| group | string Group filter (GAP-002): a test-group uuid (group_id) or the literal "ungrouped" (group_id IS NULL). Absent ⇒ all groups. |
{- "items": [
- {
- "createdAt": "2019-08-24T14:15:22Z",
- "createdBy": "string",
- "dependsOnId": "cd8cc4c3-8195-4c5b-b408-6c93dab2991a",
- "dsl": { },
- "flakyScore": "string",
- "groupId": "eb54e96e-21b8-4f54-9cd4-80fccbd06f55",
- "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
- "name": "string",
- "parentId": "70850378-7d3c-4f45-91b7-942d4dfbbd43",
- "projectId": "5a8591dd-4039-49df-9202-96385ba3eff8",
- "quarantined": true,
- "status": "draft",
- "tags": [
- "string"
]
}
], - "limit": 0,
- "offset": 0,
- "total": 0
}Generates up to count DSL test cases for the project's base URL (or an explicit url) from a natural-language goal and persists them as drafts.
| id required | string <uuid> |
| count | integer [ 1 .. 5 ] Default: 1 |
| goal required | string [ 3 .. 2000 ] characters |
| url | string <uri> |
{- "count": 1,
- "goal": "string",
}{- "items": [
- {
- "createdAt": "2019-08-24T14:15:22Z",
- "createdBy": "string",
- "dependsOnId": "cd8cc4c3-8195-4c5b-b408-6c93dab2991a",
- "dsl": { },
- "flakyScore": "string",
- "groupId": "eb54e96e-21b8-4f54-9cd4-80fccbd06f55",
- "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
- "name": "string",
- "parentId": "70850378-7d3c-4f45-91b7-942d4dfbbd43",
- "projectId": "5a8591dd-4039-49df-9202-96385ba3eff8",
- "quarantined": true,
- "status": "draft",
- "tags": [
- "string"
]
}
]
}| name required | string non-empty |
required | Array of objects (TestStep) |
| tags | Array of strings |
Array of objects (TestVar) | |
| parent_id | string <uuid> |
| project_id required | string <uuid> |
{- "name": "string",
- "steps": [
- {
- "op": "navigate"
}
], - "tags": [
- "string"
], - "vars": [
- {
- "name": "string",
- "secret": false,
- "value": "string"
}
], - "parent_id": "1c6ca187-e61f-4301-8dcb-0e9749e89eef",
- "project_id": "405d8375-3514-403b-8c43-83ae74cfe0e9"
}{- "createdAt": "2019-08-24T14:15:22Z",
- "createdBy": "string",
- "dependsOnId": "cd8cc4c3-8195-4c5b-b408-6c93dab2991a",
- "dsl": { },
- "flakyScore": "string",
- "groupId": "eb54e96e-21b8-4f54-9cd4-80fccbd06f55",
- "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
- "name": "string",
- "parentId": "70850378-7d3c-4f45-91b7-942d4dfbbd43",
- "projectId": "5a8591dd-4039-49df-9202-96385ba3eff8",
- "quarantined": true,
- "status": "draft",
- "tags": [
- "string"
]
}{- "createdAt": "2019-08-24T14:15:22Z",
- "createdBy": "string",
- "dependsOnId": "cd8cc4c3-8195-4c5b-b408-6c93dab2991a",
- "dsl": { },
- "flakyScore": "string",
- "groupId": "eb54e96e-21b8-4f54-9cd4-80fccbd06f55",
- "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
- "name": "string",
- "parentId": "70850378-7d3c-4f45-91b7-942d4dfbbd43",
- "projectId": "5a8591dd-4039-49df-9202-96385ba3eff8",
- "quarantined": true,
- "status": "draft",
- "tags": [
- "string"
]
}Partial update; at least one field is required. depends_on_id is validated against same-project membership and cycle freedom; null clears the dependency.
| id required | string <uuid> |
| depends_on_id | string or null <uuid> |
object TestCaseDsl without the row-level | |
| name | string non-empty |
| status | string Enum: "draft" "active" "archived" |
| tags | Array of strings |
{- "depends_on_id": "e79ffb3f-428a-4576-b513-cbe989c3463c",
- "dsl": {
- "steps": [
- {
- "op": "navigate"
}
], - "tags": [
- "string"
], - "vars": [
- {
- "name": "string",
- "secret": false,
- "value": "string"
}
]
}, - "name": "string",
- "status": "draft",
- "tags": [
- "string"
]
}{- "createdAt": "2019-08-24T14:15:22Z",
- "createdBy": "string",
- "dependsOnId": "cd8cc4c3-8195-4c5b-b408-6c93dab2991a",
- "dsl": { },
- "flakyScore": "string",
- "groupId": "eb54e96e-21b8-4f54-9cd4-80fccbd06f55",
- "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
- "name": "string",
- "parentId": "70850378-7d3c-4f45-91b7-942d4dfbbd43",
- "projectId": "5a8591dd-4039-49df-9202-96385ba3eff8",
- "quarantined": true,
- "status": "draft",
- "tags": [
- "string"
]
}| id required | string <uuid> |
{- "createdAt": "2019-08-24T14:15:22Z",
- "createdBy": "string",
- "dependsOnId": "cd8cc4c3-8195-4c5b-b408-6c93dab2991a",
- "dsl": { },
- "flakyScore": "string",
- "groupId": "eb54e96e-21b8-4f54-9cd4-80fccbd06f55",
- "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
- "name": "string",
- "parentId": "70850378-7d3c-4f45-91b7-942d4dfbbd43",
- "projectId": "5a8591dd-4039-49df-9202-96385ba3eff8",
- "quarantined": true,
- "status": "draft",
- "tags": [
- "string"
]
}Regenerates the steps from the persisted goal/expected result (P5-W23-T03) and/or an ad-hoc instruction. Returns the current and the proposed DSL WITHOUT persisting anything — accepting happens via PATCH /test-cases/{id} with the proposed dsl.
| id required | string <uuid> |
| instruction | string [ 3 .. 1000 ] characters Optional revision instruction in natural language. |
{- "instruction": "string"
}{- "current": {
- "name": "string",
- "steps": [
- {
- "op": "navigate"
}
], - "tags": [
- "string"
], - "vars": [
- {
- "name": "string",
- "secret": false,
- "value": "string"
}
]
}, - "proposed": {
- "name": "string",
- "steps": [
- {
- "op": "navigate"
}
], - "tags": [
- "string"
], - "vars": [
- {
- "name": "string",
- "secret": false,
- "value": "string"
}
]
}
}| id required | string <uuid> |
| offset | integer >= 0 Default: 0 |
| limit | integer [ 1 .. 100 ] Default: 20 |
{- "items": [
- {
- "actor": "string",
- "changedAt": "2019-08-24T14:15:22Z",
- "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
- "newData": { },
- "oldData": { },
- "operation": "string"
}
], - "limit": 0,
- "offset": 0,
- "total": 0
}Paginated run history, newest first; filterable by project, test case, plan run, status, result (passed|failed|skipped), owner (Clerk user id or 'system') and a case-insensitive name search (q).
| projectId | string <uuid> |
| testCaseId | string <uuid> |
| planRunId | string <uuid> |
| deviceMatrixId | string <uuid> |
| status | string Enum: "queued" "running" "passed" "failed" "error" "cancelled" "skipped" |
| result | string Enum: "passed" "failed" "skipped" |
| owner | string non-empty |
| q | string [ 1 .. 200 ] characters |
| limit | integer [ 1 .. 100 ] Default: 20 |
| offset | integer or null >= 0 Default: 0 |
{- "items": [
- {
- "costUsd": "string",
- "createdBy": "string",
- "endedAt": "2019-08-24T14:15:22Z",
- "error": "string",
- "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
- "kind": "string",
- "projectId": "5a8591dd-4039-49df-9202-96385ba3eff8",
- "projectName": "string",
- "startedAt": "2019-08-24T14:15:22Z",
- "status": "queued",
- "testCaseId": "002c56e7-6058-4022-8bc6-a15202014bf1",
- "testCaseName": "string"
}
], - "limit": 0,
- "offset": 0,
- "total": 0
}Inserts a queued run for the test case and enqueues it with the background worker.
object or object | |
Array of objects or objects [ 1 .. 4 ] items | |
| environment_id | string <uuid> |
| model_tier | string Enum: "fast" "thorough" |
| test_case_id required | string <uuid> |
Array of objects |
{- "device_preset": {
- "locale": "string",
- "preset": "desktop",
- "timezone": "string"
}, - "device_presets": [
- {
- "locale": "string",
- "preset": "desktop",
- "timezone": "string"
}
], - "environment_id": "40ef0e48-a11f-4963-a229-e396c9f7e7c4",
- "model_tier": "fast",
- "test_case_id": "738e7d5d-48c4-4b50-859a-47ff022bef7f",
- "vars": [
- {
- "name": "string",
- "secret": false,
- "value": "string"
}
]
}{- "device_matrix_id": "42f61057-1e60-4145-bc66-63ac8f25c3ff",
- "run_id": "dded282c-8ebd-44cf-8ba5-9a234973d1ec"
}Distinct owners of the org's runs (for the run-list owner filter): one entry per Clerk user id plus a single { id: null } System entry when at least one system-triggered run exists.
{- "items": [
- {
- "id": "string"
}
]
}{- "agentSteps": [
- {
- "action": "string",
- "createdAt": "2019-08-24T14:15:22Z",
- "instruction": "string",
- "pageExcerpt": "string",
- "pageUrl": "string",
- "reasoning": "string",
- "stepIndex": 0,
- "success": true
}
], - "artifacts": [
- {
- "byteSize": 0,
- "createdAt": "2019-08-24T14:15:22Z",
- "download_url": "string",
- "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
- "stepIndex": 0,
- "type": "string",
- "when": "pre"
}
], - "costUsd": "string",
- "deviceMatrixId": "string",
- "devicePreset": {
- "locale": "string",
- "notApplied": [
- "locale"
], - "preset": "desktop",
- "source": "run",
- "timezone": "string",
- "viewport": {
- "height": 320,
- "width": 320
}
}, - "downloadResults": [
- {
- "contentType": "string",
- "filename": "string",
- "sizeBytes": 0,
- "stepIndex": 0
}
], - "endedAt": "2019-08-24T14:15:22Z",
- "environmentId": "string",
- "error": "string",
- "exploratoryFindings": [
- {
- "countInRun": 0,
- "findingKind": "console_error",
- "normalizedMessage": "string",
- "normalizedUrl": "string",
- "sample": "string",
- "severity": "minor"
}
], - "failureClass": "string",
- "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
- "kind": "string",
- "liveViewUrl": "string",
- "modelTier": {
- "source": "run",
- "tier": "fast"
}, - "outputValues": {
- "property1": "string",
- "property2": "string"
}, - "planRunId": "string",
- "projectId": "5a8591dd-4039-49df-9202-96385ba3eff8",
- "startedAt": "2019-08-24T14:15:22Z",
- "status": "queued",
- "stepResults": [
- {
- "postArtifactId": "string",
- "preArtifactId": "string",
- "status": "passed",
- "stepIndex": 0
}
], - "testCase": {
- "dsl": {
- "name": "string",
- "steps": [
- {
- "op": "navigate",
- "url": "string"
}
], - "tags": [ ],
- "vars": [ ]
}, - "executionMode": "steps",
- "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
- "name": "string"
}, - "testCaseId": "002c56e7-6058-4022-8bc6-a15202014bf1",
- "vars": [
- {
- "name": "string",
- "secret": false,
- "value": "string"
}
], - "verdict": {
- "actual": "string",
- "confidence": "low",
- "errorClass": "transport",
- "expected": "string",
- "keyObservations": [
- "string"
], - "suggestion": "string",
- "summary": "string"
}
}Mails delivered to the run's system-managed inbox addresses (text view only), newest first.
| id required | string <uuid> |
{- "items": [
- {
- "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
- "receivedAt": "2019-08-24T14:15:22Z",
- "recipient": "string",
- "sender": "string",
- "subject": "string",
- "textBody": "string"
}
], - "total": 0
}| id required | string <uuid> |
{- "items": [
- {
- "autoApplied": true,
- "confidence": "string",
- "createdAt": "2019-08-24T14:15:22Z",
- "failureClass": "string",
- "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
- "newSelector": "string",
- "oldSelector": "string",
- "runId": "78c33d18-170c-44d3-a227-b3194f134f73",
- "stepIndex": 0,
- "userDecision": "approved"
}
]
}| window | string Default: "7d" Enum: "7d" "30d" |
{- "data": {
- "auto_apply_rate": 0,
- "by_day": [
- {
- "applied": 0,
- "attempts": 0,
- "date": "2019-08-24",
- "rejected": 0
}
], - "flaky_rate": 0,
- "manual_approval_count": 0,
- "total_heals": 0,
- "window": "7d"
}, - "ok": true
}Pass rate, p50/p95 duration and cost per calendar day plus whole-window totals. Days without runs are zero-filled so the series always spans the window; percentile durations only consider finished runs (ended_at set) and are null for days without one.
| window | string Default: "7d" Enum: "7d" "30d" |
{- "data": {
- "byDay": [
- {
- "costUsd": 0,
- "error": 0,
- "failed": 0,
- "p50DurationMs": 0,
- "p95DurationMs": 0,
- "passRate": 0,
- "passed": 0,
- "total": 0,
- "date": "2019-08-24"
}
], - "totals": {
- "costUsd": 0,
- "error": 0,
- "failed": 0,
- "p50DurationMs": 0,
- "p95DurationMs": 0,
- "passRate": 0,
- "passed": 0,
- "total": 0
}, - "window": "7d"
}, - "ok": true
}| id required | string <uuid> |
{- "counts": {
- "cancelled": 0,
- "error": 0,
- "failed": 0,
- "passed": 0,
- "queued": 0,
- "running": 0,
- "skipped": 0,
- "total": 0
}, - "created_at": "2019-08-24T14:15:22Z",
- "parent_plan_run_id": "f2fdae15-9bed-4c3a-9bc2-932348c73555",
- "plan_id": "00713021-9aea-41da-9a88-87760c08fa72",
- "plan_run_id": "ff73d59b-fc5c-4e85-875b-517d79259fcf",
- "result": "passed",
- "run_mode": "ci",
- "status": "running",
- "trigger": "manual"
}| id required | string <uuid> |
| scope | string Default: "failed" Enum: "failed" "all" |
{- "plan_run_id": "ff73d59b-fc5c-4e85-875b-517d79259fcf"
}| id required | string <uuid> |
| owner | string Owner filter (GAP-057): a Clerk user id (created_by) or the literal "system" (created_by IS NULL). Absent ⇒ all owners. |
{- "items": [
- {
- "createdAt": "2019-08-24T14:15:22Z",
- "createdBy": "string",
- "cron": "string",
- "enabled": true,
- "environmentId": "19f5cc2e-7657-437a-9268-83cd3d563563",
- "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
- "lastRunAt": "2019-08-24T14:15:22Z",
- "name": "string",
- "nextRunAt": "2019-08-24T14:15:22Z",
- "projectId": "5a8591dd-4039-49df-9202-96385ba3eff8",
- "runMode": "ci",
- "tags": [
- "string"
]
}
], - "total": 0
}| id required | string <uuid> |
| cron | string or null |
| enabled | boolean Default: true |
| environment_id | string or null <uuid> |
| name required | string non-empty |
| run_mode | string Default: "nightly" Enum: "ci" "nightly" |
| tags | Array of strings[ items non-empty ] |
| test_case_ids | Array of strings <uuid> [ items <uuid > ] |
{- "cron": "string",
- "enabled": true,
- "environment_id": "40ef0e48-a11f-4963-a229-e396c9f7e7c4",
- "name": "string",
- "run_mode": "ci",
- "tags": [
- "string"
], - "test_case_ids": [
- "497f6eca-6276-4993-bfeb-53cbbbba6f08"
]
}{- "createdAt": "2019-08-24T14:15:22Z",
- "createdBy": "string",
- "cron": "string",
- "enabled": true,
- "environmentId": "19f5cc2e-7657-437a-9268-83cd3d563563",
- "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
- "lastRunAt": "2019-08-24T14:15:22Z",
- "name": "string",
- "nextRunAt": "2019-08-24T14:15:22Z",
- "projectId": "5a8591dd-4039-49df-9202-96385ba3eff8",
- "runMode": "ci",
- "tags": [
- "string"
]
}{- "createdAt": "2019-08-24T14:15:22Z",
- "createdBy": "string",
- "cron": "string",
- "enabled": true,
- "environmentId": "19f5cc2e-7657-437a-9268-83cd3d563563",
- "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
- "lastRunAt": "2019-08-24T14:15:22Z",
- "name": "string",
- "nextRunAt": "2019-08-24T14:15:22Z",
- "projectId": "5a8591dd-4039-49df-9202-96385ba3eff8",
- "runMode": "ci",
- "tags": [
- "string"
], - "explicitMembers": [
- {
- "position": 0,
- "testCaseId": "002c56e7-6058-4022-8bc6-a15202014bf1"
}
], - "resolvedMemberIds": [
- "497f6eca-6276-4993-bfeb-53cbbbba6f08"
]
}| id required | string <uuid> |
| cron | string or null |
| enabled | boolean |
| environment_id | string or null <uuid> |
| name | string non-empty |
| run_mode | string Enum: "ci" "nightly" |
| tags | Array of strings[ items non-empty ] |
| test_case_ids | Array of strings <uuid> [ items <uuid > ] |
{- "cron": "string",
- "enabled": true,
- "environment_id": "40ef0e48-a11f-4963-a229-e396c9f7e7c4",
- "name": "string",
- "run_mode": "ci",
- "tags": [
- "string"
], - "test_case_ids": [
- "497f6eca-6276-4993-bfeb-53cbbbba6f08"
]
}{- "createdAt": "2019-08-24T14:15:22Z",
- "createdBy": "string",
- "cron": "string",
- "enabled": true,
- "environmentId": "19f5cc2e-7657-437a-9268-83cd3d563563",
- "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
- "lastRunAt": "2019-08-24T14:15:22Z",
- "name": "string",
- "nextRunAt": "2019-08-24T14:15:22Z",
- "projectId": "5a8591dd-4039-49df-9202-96385ba3eff8",
- "runMode": "ci",
- "tags": [
- "string"
]
}| id required | string <uuid> |
| offset | integer >= 0 Default: 0 |
| limit | integer [ 1 .. 100 ] Default: 20 |
{- "items": [
- {
- "createdAt": "2019-08-24T14:15:22Z",
- "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
- "parentPlanRunId": "19b6f86b-d166-4d22-9537-cf69647e5536",
- "planId": "b3f60ba2-c1fd-4b3a-a23d-8e876e0ef75d",
- "projectId": "5a8591dd-4039-49df-9202-96385ba3eff8",
- "runMode": "ci",
- "trigger": "manual"
}
], - "total": 0
}Dispatches the plan's resolved member cases as individual runs grouped under one plan run. Gated by the org's monthly run budget (402).
| id required | string <uuid> |
{- "plan_run_id": "ff73d59b-fc5c-4e85-875b-517d79259fcf"
}| id required | string <uuid> |
| parent | string <uuid> A test-group uuid lists that group's direct children; absent lists the project's root groups (parent_group_id IS NULL). |
{- "items": [
- {
- "createdAt": "2019-08-24T14:15:22Z",
- "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
- "name": "string",
- "parentGroupId": "e5e63afb-859b-44be-b014-ce932bd8bf74",
- "position": 0,
- "projectId": "5a8591dd-4039-49df-9202-96385ba3eff8"
}
], - "total": 0
}| id required | string <uuid> |
| name required | string [ 1 .. 200 ] characters |
| parent_group_id | string or null <uuid> Nest under this group; absent/null = a root group. |
| position | integer >= 0 Default: 0 |
{- "name": "string",
- "parent_group_id": "fe5e9949-7da4-4318-86fb-b3b64b2df380",
- "position": 0
}{- "createdAt": "2019-08-24T14:15:22Z",
- "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
- "name": "string",
- "parentGroupId": "e5e63afb-859b-44be-b014-ce932bd8bf74",
- "position": 0,
- "projectId": "5a8591dd-4039-49df-9202-96385ba3eff8"
}| id required | string <uuid> |
{- "tree": [
- {
- "caseCount": 0,
- "children": [
- { }
], - "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
- "name": "string",
- "parentGroupId": "e5e63afb-859b-44be-b014-ce932bd8bf74",
- "position": 0
}
]
}Deletes the group and its whole subtree (cascade). Member test cases are orphaned (group_id set to NULL), never deleted.
| id required | string <uuid> |
{- "ok": true
}Partial update; at least one field is required. parent_group_id is validated against same-project membership and cycle freedom (a group may not be re-parented under itself or one of its descendants); null re-parents the group to the root.
| id required | string <uuid> |
| name | string [ 1 .. 200 ] characters |
| parent_group_id | string or null <uuid> Re-parent under this group; null re-parents to the root. |
| position | integer >= 0 |
{- "name": "string",
- "parent_group_id": "fe5e9949-7da4-4318-86fb-b3b64b2df380",
- "position": 0
}{- "createdAt": "2019-08-24T14:15:22Z",
- "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
- "name": "string",
- "parentGroupId": "e5e63afb-859b-44be-b014-ce932bd8bf74",
- "position": 0,
- "projectId": "5a8591dd-4039-49df-9202-96385ba3eff8"
}The caller's own test cases AND test plans across the whole org, newest first, paginated. The owner is always the verified caller — there is no cross-user view, so this route takes no owner parameter.
| offset | integer >= 0 Default: 0 |
| limit | integer [ 1 .. 100 ] Default: 20 |
{- "items": [
- {
- "createdAt": "2019-08-24T14:15:22Z",
- "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
- "kind": "test_case",
- "name": "string",
- "projectId": "5a8591dd-4039-49df-9202-96385ba3eff8",
- "projectName": "string"
}
], - "limit": 0,
- "offset": 0,
- "total": 0
}| id required | string <uuid> |
| base_url | string <uri> |
object | |
Array of objects (TestVar) | |
| is_production | boolean |
| kind | string Enum: "standard" "preview" |
| name | string non-empty |
{- "default_headers": {
- "property1": "string",
- "property2": "string"
}, - "default_vars": [
- {
- "name": "string",
- "secret": false,
- "value": "string"
}
], - "is_production": true,
- "kind": "standard",
- "name": "string"
}{- "createdAt": "2019-08-24T14:15:22Z",
- "defaultHeaders": {
- "property1": "string",
- "property2": "string"
}, - "defaultVars": [
- {
- "name": "string",
- "secret": false,
- "value": "string"
}
], - "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
- "isProduction": true,
- "kind": "standard",
- "name": "string",
- "projectId": "5a8591dd-4039-49df-9202-96385ba3eff8"
}| id required | string <uuid> |
{- "items": [
- {
- "createdAt": "2019-08-24T14:15:22Z",
- "defaultHeaders": {
- "property1": "string",
- "property2": "string"
}, - "defaultVars": [
- {
- "name": "string",
- "secret": false,
- "value": "string"
}
], - "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
- "isProduction": true,
- "kind": "standard",
- "name": "string",
- "projectId": "5a8591dd-4039-49df-9202-96385ba3eff8"
}
], - "total": 0
}| id required | string <uuid> |
| base_url required | string <uri> |
object | |
Array of objects (TestVar) | |
| is_production | boolean Default: false |
| kind | string Default: "standard" Enum: "standard" "preview" |
| name required | string non-empty |
{- "default_headers": {
- "property1": "string",
- "property2": "string"
}, - "default_vars": [
- {
- "name": "string",
- "secret": false,
- "value": "string"
}
], - "is_production": false,
- "kind": "standard",
- "name": "string"
}{- "createdAt": "2019-08-24T14:15:22Z",
- "defaultHeaders": {
- "property1": "string",
- "property2": "string"
}, - "defaultVars": [
- {
- "name": "string",
- "secret": false,
- "value": "string"
}
], - "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
- "isProduction": true,
- "kind": "standard",
- "name": "string",
- "projectId": "5a8591dd-4039-49df-9202-96385ba3eff8"
}Tunnels map a developer's local port to a public tunnel URL exposed by an EXTERNAL transport (ngrok / cloudflared / localtunnel). The platform only stores the mapping; a run targets the tunnel URL as its effective base.
| id required | string <uuid> |
{- "items": [
- {
- "createdAt": "2019-08-24T14:15:22Z",
- "createdBy": "string",
- "expiresAt": "2019-08-24T14:15:22Z",
- "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
- "localPort": 1,
- "projectId": "5a8591dd-4039-49df-9202-96385ba3eff8",
- "status": "active",
}
], - "total": 0
}Stores a (local_port → public tunnel_url) mapping. The actual tunnel process is external — the platform never establishes it. project_id in the body must match the path project.
| id required | string <uuid> |
| expires_at | string <date-time> |
| local_port required | integer [ 1 .. 65535 ] |
| project_id required | string <uuid> |
| tunnel_url required | string <uri> |
{- "expires_at": "2019-08-24T14:15:22Z",
- "local_port": 1,
- "project_id": "405d8375-3514-403b-8c43-83ae74cfe0e9",
}{- "createdAt": "2019-08-24T14:15:22Z",
- "createdBy": "string",
- "expiresAt": "2019-08-24T14:15:22Z",
- "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
- "localPort": 1,
- "projectId": "5a8591dd-4039-49df-9202-96385ba3eff8",
- "status": "active",
}Flip the status (active → revoked/expired). The port and URL are immutable once registered — re-register to change them.
| id required | string <uuid> |
| status required | string Enum: "active" "expired" "revoked" |
{- "status": "active"
}{- "createdAt": "2019-08-24T14:15:22Z",
- "createdBy": "string",
- "expiresAt": "2019-08-24T14:15:22Z",
- "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
- "localPort": 1,
- "projectId": "5a8591dd-4039-49df-9202-96385ba3eff8",
- "status": "active",
}data/overrides are validated against the STORED row's type. A secret field echoing the mask *** keeps the stored value.
| id required | string <uuid> |
| data | object |
| name | string non-empty |
| overrides | object Per-environment override blocks keyed by environment id. |
{- "data": { },
- "name": "string",
- "overrides": { }
}{- "createdAt": "2019-08-24T14:15:22Z",
- "data": { },
- "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
- "name": "string",
- "overrides": { },
- "projectId": "5a8591dd-4039-49df-9202-96385ba3eff8",
- "type": "credentials",
- "updatedAt": "2019-08-24T14:15:22Z"
}Secret fields inside data and overrides are masked as ***.
| id required | string <uuid> |
{- "items": [
- {
- "createdAt": "2019-08-24T14:15:22Z",
- "data": { },
- "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
- "name": "string",
- "overrides": { },
- "projectId": "5a8591dd-4039-49df-9202-96385ba3eff8",
- "type": "credentials",
- "updatedAt": "2019-08-24T14:15:22Z"
}
], - "total": 0
}| id required | string <uuid> |
| data required | object Shape depends on |
| name required | string non-empty |
| type required | string Enum: "credentials" "credentials_totp" "email" "file" |
{- "data": { },
- "name": "string",
- "type": "credentials"
}{- "createdAt": "2019-08-24T14:15:22Z",
- "data": { },
- "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
- "name": "string",
- "overrides": { },
- "projectId": "5a8591dd-4039-49df-9202-96385ba3eff8",
- "type": "credentials",
- "updatedAt": "2019-08-24T14:15:22Z"
}Returns a short-lived presigned PUT URL plus the r2_key (configs/<projectId>/<uuid>/<file_name>) to persist on a file config after the client uploaded the file directly to storage. size_bytes is validated against the 25 MB limit.
| id required | string <uuid> |
| content_type required | string non-empty |
| file_name required | string non-empty |
| size_bytes required | integer >= 1 |
{- "content_type": "string",
- "file_name": "string",
- "size_bytes": 1
}{- "expires_in": 0,
- "r2_key": "string",
- "upload_url": "string"
}Includes revoked keys; never the hash or plaintext.
{- "data": [
- {
- "createdAt": "2019-08-24T14:15:22Z",
- "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
- "keyPrefix": "tb_live_0123…",
- "lastUsedAt": "2019-08-24T14:15:22Z",
- "name": "string",
- "projectId": "5a8591dd-4039-49df-9202-96385ba3eff8",
- "revokedAt": "2019-08-24T14:15:22Z",
- "scope": "read"
}
], - "ok": true
}The plaintext key (tb_live_…) is embedded in THIS response only — afterwards it is unrecoverable by design.
| name required | string [ 1 .. 200 ] characters |
| project_id | string <uuid> |
| scope required | string Enum: "read" "read_write" |
{- "name": "string",
- "project_id": "405d8375-3514-403b-8c43-83ae74cfe0e9",
- "scope": "read"
}{- "data": {
- "createdAt": "2019-08-24T14:15:22Z",
- "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
- "keyPrefix": "tb_live_0123…",
- "lastUsedAt": "2019-08-24T14:15:22Z",
- "name": "string",
- "projectId": "5a8591dd-4039-49df-9202-96385ba3eff8",
- "revokedAt": "2019-08-24T14:15:22Z",
- "scope": "read",
- "key": "tb_live_0123456789abcdef0123456789abcdef"
}, - "ok": true
}The HMAC secret is masked as *** on every read.
{- "items": [
- {
- "active": true,
- "createdAt": "2019-08-24T14:15:22Z",
- "events": [
- "run.completed"
], - "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
- "projectId": "5a8591dd-4039-49df-9202-96385ba3eff8",
- "secret": "string",
}
], - "total": 0
}The HMAC secret (whsec_…) is generated server-side and returned in THIS response only; every later read masks it.
| events required | Array of strings non-empty Items Enum: "run.completed" "crawl.completed" |
| project_id | string <uuid> |
| url required | string <uri> |
{- "events": [
- "run.completed"
], - "project_id": "405d8375-3514-403b-8c43-83ae74cfe0e9",
}{- "active": true,
- "createdAt": "2019-08-24T14:15:22Z",
- "events": [
- "run.completed"
], - "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
- "projectId": "5a8591dd-4039-49df-9202-96385ba3eff8",
- "secret": "string",
}| id required | string <uuid> |
| active | boolean |
| events | Array of strings non-empty Items Enum: "run.completed" "crawl.completed" |
| url | string <uri> |
{- "active": true,
- "events": [
- "run.completed"
],
}{- "active": true,
- "createdAt": "2019-08-24T14:15:22Z",
- "events": [
- "run.completed"
], - "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
- "projectId": "5a8591dd-4039-49df-9202-96385ba3eff8",
- "secret": "string",
}{- "items": [
- {
- "channel": "slack",
- "createdAt": "2019-08-24T14:15:22Z",
- "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
- "onlyFailures": true,
- "planId": "b3f60ba2-c1fd-4b3a-a23d-8e876e0ef75d",
- "projectId": "5a8591dd-4039-49df-9202-96385ba3eff8",
- "target": "string"
}
], - "total": 0
}| channel required | string Enum: "slack" "email" |
| only_failures | boolean Default: true |
| plan_id | string <uuid> |
| project_id | string <uuid> |
| target | string Webhook-URL override for |
{- "channel": "slack",
- "only_failures": true,
- "plan_id": "00713021-9aea-41da-9a88-87760c08fa72",
- "project_id": "405d8375-3514-403b-8c43-83ae74cfe0e9",
- "target": "string"
}{- "channel": "slack",
- "createdAt": "2019-08-24T14:15:22Z",
- "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
- "onlyFailures": true,
- "planId": "b3f60ba2-c1fd-4b3a-a23d-8e876e0ef75d",
- "projectId": "5a8591dd-4039-49df-9202-96385ba3eff8",
- "target": "string"
}Anonymous endpoint for status.testsbot.com — open incidents plus everything resolved within the visibility window, newest first.
{- "incidents": [
- {
- "affected": [
- "api"
], - "body": "string",
- "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
- "resolvedAt": "2019-08-24T14:15:22Z",
- "severity": "minor",
- "startedAt": "2019-08-24T14:15:22Z",
- "status": "investigating",
- "title": "string"
}
]
}| affected required | Array of strings Items Enum: "api" "worker" "browserbase" |
| body required | string non-empty |
| severity | string Default: "minor" Enum: "minor" "major" "critical" |
| status required | string Enum: "investigating" "identified" "monitoring" "resolved" |
| title required | string non-empty |
{- "affected": [
- "api"
], - "body": "string",
- "severity": "minor",
- "status": "investigating",
- "title": "string"
}{- "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08"
}| id required | string <uuid> |
| resolved_at | string or null <date-time> |
| status | string Enum: "investigating" "identified" "monitoring" "resolved" |
{- "resolved_at": "2019-08-24T14:15:22Z",
- "status": "investigating"
}{- "affected": [
- "api"
], - "body": "string",
- "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
- "resolvedAt": "2019-08-24T14:15:22Z",
- "severity": "minor",
- "startedAt": "2019-08-24T14:15:22Z",
- "status": "investigating",
- "title": "string"
}{- "ok": true
}Sets the org-wide monthly LLM spend limit in USD enforced as a hard 402 on POST /runs. A null value clears the ceiling (no limit). Admin only.
| limitUsd required | number or null <double> >= 0 USD ceiling, or null to clear the limit. |
{- "limitUsd": 0.1
}{- "data": {
- "limitUsd": 0.1
}, - "ok": true
}GAP-070. Given the org's executionCount for the current month, computes the overage beyond the plan's runsPerMonth quota, reports those units to Stripe as metered usage (with an idempotency key), and increments the running overage_runs_tracked counter. This is SOFT overage billing ALONGSIDE the still-enforced hard monthly quota. INERT (503) until a Stripe metered Price/Product is configured in the Stripe dashboard and a subscription-item id has been captured via webhook.
| executionCount required | integer >= 0 |
{- "executionCount": 0
}{- "data": {
- "overage": 0,
- "plan": "free",
- "reported": true,
- "tracked": 0
}, - "ok": true
}| message | string |
| rating required | string Enum: "up" "down" |
{- "message": "string",
- "rating": "up"
}{- "data": {
- "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08"
}, - "ok": true
}| event_type required | string Enum: "signup" "first_crawl" "first_test_generated" "first_run" |
{- "event_type": "signup"
}{- "ok": true
}Provisions the demo sample project with a canonical DSL test case for the caller's org. Idempotent: a second call returns the existing project with 200 instead of creating a duplicate.
{- "ok": true
}Creates a conversation, optionally pinned to a project. The project pin scopes the assistant's system-prompt context and the LLM cost cap.
| project_id | string <uuid> |
{- "project_id": "405d8375-3514-403b-8c43-83ae74cfe0e9"
}{- "created_at": "2019-08-24T14:15:22Z",
- "created_by": "string",
- "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
- "project_id": "405d8375-3514-403b-8c43-83ae74cfe0e9",
- "title": "string"
}Full chronological history including assistant tool calls and tool results.
| id required | string <uuid> |
{- "items": [
- {
- "content": "string",
- "conversation_id": "cc71b11a-25cd-4c2d-9950-df2cc38e3407",
- "created_at": "2019-08-24T14:15:22Z",
- "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
- "role": "user",
- "tool_calls": [
- {
- "id": "string",
- "input": null,
- "name": "string"
}
]
}
], - "total": 0
}Persists the user message, runs the LLM tool loop (create/generate/ list test cases, trigger/read runs — max 5 tool iterations) and answers synchronously with every message the turn produced (user, assistant, tool results). Tool failures come back as tool-result messages, never as a 5xx; a cost-cap breach ends the turn with an assistant hint message.
| id required | string <uuid> |
| content required | string [ 1 .. 8000 ] characters |
{- "content": "string"
}{- "items": [
- {
- "content": "string",
- "conversation_id": "cc71b11a-25cd-4c2d-9950-df2cc38e3407",
- "created_at": "2019-08-24T14:15:22Z",
- "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
- "role": "user",
- "tool_calls": [
- {
- "id": "string",
- "input": null,
- "name": "string"
}
]
}
], - "total": 0
}| tour_completed required | boolean |
{- "tour_completed": true
}{- "data": {
- "tourCompleted": true
}, - "ok": true
}30-day confirmation/cancel window before the deletion runs.
{- "data": {
- "graceDays": 0,
- "requestId": "d385ab22-0f51-4b97-9ecd-b8ff3fd4fcb6",
- "scheduledFor": "2019-08-24T14:15:22Z",
- "status": "pending_confirmation"
}, - "ok": true
}| id required | string <uuid> |
| installation_id required | string non-empty |
| repo required | string^[a-zA-Z0-9._-]+/[a-zA-Z0-9._-]+$ |
{- "installation_id": "string",
- "repo": "acme/webshop"
}{- "installation_id": "string",
- "ok": true,
- "repo": "string"
}| id required | string <uuid> |
| status required | string Enum: "active" "ignored" "resolved" |
{- "status": "active"
}{- "fingerprint": "string",
- "firstSeenAt": "2019-08-24T14:15:22Z",
- "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
- "kind": "test_failure",
- "lastSeenAt": "2019-08-24T14:15:22Z",
- "occurrences": 1,
- "payload": { },
- "projectId": "5a8591dd-4039-49df-9202-96385ba3eff8",
- "sampleRunId": "feff50ef-cbc6-418b-b66f-5ac23e638431",
- "severity": "minor",
- "status": "active",
- "title": "string"
}One issue per recurring fingerprint: failed tests (test case + failure class + step) and console errors (normalized message + source URL, GAP-051). Recurrences bump occurrences and lastSeenAt instead of creating new rows. Optionally filtered by triage status and/or kind (both filters combine).
| id required | string <uuid> |
| status | string Enum: "active" "ignored" "resolved" |
| kind | string Enum: "test_failure" "console_error" "a11y" |
{- "items": [
- {
- "fingerprint": "string",
- "firstSeenAt": "2019-08-24T14:15:22Z",
- "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
- "kind": "test_failure",
- "lastSeenAt": "2019-08-24T14:15:22Z",
- "occurrences": 1,
- "payload": { },
- "projectId": "5a8591dd-4039-49df-9202-96385ba3eff8",
- "sampleRunId": "feff50ef-cbc6-418b-b66f-5ac23e638431",
- "severity": "minor",
- "status": "active",
- "title": "string"
}
], - "total": 0
}