{"openapi":"3.1.0","info":{"title":"Beryl API","description":"The Beryl HTTP API. Every path is under `https://api.beryl.so/api/v1`. The CLI and MCP server are built on these same routes.","version":"1.0.0"},"servers":[{"url":"https://api.beryl.so"}],"paths":{"/api/v1/account/":{"get":{"tags":["account"],"summary":"Get Account Profile","operationId":"get_account_profile_api_v1_account__get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AccountProfileResponse"}}}}},"security":[{"HTTPBearer":[]}]},"delete":{"tags":["account"],"summary":"Delete Account","operationId":"delete_account_api_v1_account__delete","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AccountDeleteRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AccountDeleteResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]},"patch":{"tags":["account"],"summary":"Update Account Profile","operationId":"update_account_profile_api_v1_account__patch","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AccountUpdateRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AccountProfileResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/api/v1/account/deletion-preview":{"get":{"tags":["account"],"summary":"Get Deletion Preview","operationId":"get_deletion_preview_api_v1_account_deletion_preview_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeletionPreviewResponse"}}}}},"security":[{"HTTPBearer":[]}]}},"/api/v1/account/tokens":{"get":{"tags":["tokens"],"summary":"List Tokens","operationId":"list_tokens_api_v1_account_tokens_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/TokenResponse"},"type":"array","title":"Response List Tokens Api V1 Account Tokens Get"}}}}},"security":[{"HTTPBearer":[]}]},"post":{"tags":["tokens"],"summary":"Create Token","operationId":"create_token_api_v1_account_tokens_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateTokenRequest"}}},"required":true},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateTokenResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/api/v1/account/tokens/{token_id}":{"delete":{"tags":["tokens"],"summary":"Revoke Token","operationId":"revoke_token_api_v1_account_tokens__token_id__delete","security":[{"HTTPBearer":[]}],"parameters":[{"name":"token_id","in":"path","required":true,"schema":{"type":"string","title":"Token Id"}}],"responses":{"204":{"description":"Successful Response"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/account/tokens/{token_id}/dismiss":{"post":{"tags":["tokens"],"summary":"Dismiss Token","operationId":"dismiss_token_api_v1_account_tokens__token_id__dismiss_post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"token_id","in":"path","required":true,"schema":{"type":"string","title":"Token Id"}}],"responses":{"204":{"description":"Successful Response"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/workspaces/":{"get":{"tags":["workspaces"],"summary":"Get User Workspaces","description":"Get all workspaces where the current user is a member.\n\nSelf-heals the rare case where signup/verify issued tokens but the\ndefault-workspace bootstrap failed: a verified user with zero workspaces\ngets one created on this first authed read rather than being stranded\nworkspace-less. ``ensure_user_has_default_workspace`` is idempotent.","operationId":"get_user_workspaces_api_v1_workspaces__get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/WorkspaceWithMembership"},"type":"array","title":"Response Get User Workspaces Api V1 Workspaces  Get"}}}}},"security":[{"HTTPBearer":[]}]},"post":{"tags":["workspaces"],"summary":"Create Workspace","operationId":"create_workspace_api_v1_workspaces__post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WorkspaceCreate"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WorkspaceWithMembership"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/api/v1/workspaces/{workspace_id}":{"get":{"tags":["workspaces"],"summary":"Get Workspace","operationId":"get_workspace_api_v1_workspaces__workspace_id__get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"workspace_id","in":"path","required":true,"schema":{"type":"string","title":"Workspace Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WorkspaceWithMembership"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"patch":{"tags":["workspaces"],"summary":"Update Workspace","operationId":"update_workspace_api_v1_workspaces__workspace_id__patch","security":[{"HTTPBearer":[]}],"parameters":[{"name":"workspace_id","in":"path","required":true,"schema":{"type":"string","title":"Workspace Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WorkspaceUpdate"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WorkspaceResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["workspaces"],"summary":"Delete Workspace","operationId":"delete_workspace_api_v1_workspaces__workspace_id__delete","security":[{"HTTPBearer":[]}],"parameters":[{"name":"workspace_id","in":"path","required":true,"schema":{"type":"string","title":"Workspace Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MessageResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/workspaces/discover":{"get":{"tags":["workspaces"],"summary":"Discover Workspaces For Current User","operationId":"discover_workspaces_for_current_user_api_v1_workspaces_discover_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/WorkspaceResponse"},"type":"array","title":"Response Discover Workspaces For Current User Api V1 Workspaces Discover Get"}}}}},"security":[{"HTTPBearer":[]}]}},"/api/v1/workspaces/{workspace_id}/features":{"get":{"tags":["workspaces"],"summary":"Get Workspace Features","description":"Get the workspace's feature flags (defaults applied for missing keys).","operationId":"get_workspace_features_api_v1_workspaces__workspace_id__features_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"workspace_id","in":"path","required":true,"schema":{"type":"string","title":"Workspace Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/FeaturesResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"patch":{"tags":["workspaces"],"summary":"Update Workspace Features","description":"Update workspace feature flags (owner-only).","operationId":"update_workspace_features_api_v1_workspaces__workspace_id__features_patch","security":[{"HTTPBearer":[]}],"parameters":[{"name":"workspace_id","in":"path","required":true,"schema":{"type":"string","title":"Workspace Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/FeaturesUpdate"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/FeaturesResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/workspaces/{workspace_id}/action-history":{"get":{"tags":["workspaces"],"summary":"Get Workspace Action History","description":"List the workspace's admin action history (owner-only).\n\nReturns the most recent admin actions taken under settings (workspace\nrename, member invite / role change / removal), newest first and capped at\nthe last 50. Restricted to workspace owners for auditability.","operationId":"get_workspace_action_history_api_v1_workspaces__workspace_id__action_history_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"workspace_id","in":"path","required":true,"schema":{"type":"string","title":"Workspace Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/SpaceAuditEventResponse"},"title":"Response Get Workspace Action History Api V1 Workspaces  Workspace Id  Action History Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/workspaces/{workspace_id}/visit":{"post":{"tags":["workspaces"],"summary":"Mark Workspace Visited","operationId":"mark_workspace_visited_api_v1_workspaces__workspace_id__visit_post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"workspace_id","in":"path","required":true,"schema":{"type":"string","title":"Workspace Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MessageResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/workspaces/{workspace_id}/projects":{"post":{"tags":["projects"],"summary":"Create Project","description":"Create a project in this workspace — name-first (empty) or URL-first (crawl).\n\n* **Name only** (``root_url`` omitted): create a real, empty, URL-less project\n  named ``name`` — every project, first included, is named up front by the user.\n  It lands on the empty-state where the explore/CLI fork lives; nothing crawls\n  until the user provides a URL there. Returns ``auth_status=\"ready\"``.\n* **URL present:** the crawl path. Deferred until auth is resolved: fresh\n  captured auth for this domain is reused and the crawl starts immediately\n  (``auth_status=\"ready\"``); otherwise the FE opens the Browserbase login modal\n  (``auth_status=\"needs_capture\"``). Flows through the same crawl → nlgen →\n  script-gen → run pipeline. Returns 400 with the reason if the URL fails\n  validation.\n\nReturns 403 if the workspace is already at its ``MAX_PROJECTS_PER_WORKSPACE`` cap.","operationId":"create_project_api_v1_workspaces__workspace_id__projects_post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"workspace_id","in":"path","required":true,"schema":{"type":"string","title":"Workspace Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateTestProjectRequest"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateProjectResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"get":{"tags":["projects"],"summary":"List Projects","operationId":"list_projects_api_v1_workspaces__workspace_id__projects_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"workspace_id","in":"path","required":true,"schema":{"type":"string","title":"Workspace Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/ProjectListItem"},"title":"Response List Projects Api V1 Workspaces  Workspace Id  Projects Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/workspaces/{workspace_id}/projects/reusable-auth":{"get":{"tags":["projects"],"summary":"Get Reusable Auth","description":"Pre-check: is there a fresh, reusable login captured for this ``(workspace, domain)``?\n\nRead-only — runs the same freshness gate as the reuse path but never returns\nthe secret blob. A malformed URL is treated as \"nothing to reuse\" — the\nenter-URL form owns validation; this is only a hint.","operationId":"get_reusable_auth_api_v1_workspaces__workspace_id__projects_reusable_auth_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"workspace_id","in":"path","required":true,"schema":{"type":"string","title":"Workspace Id"}},{"name":"url","in":"query","required":true,"schema":{"type":"string","title":"Url"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReusableAuthResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/workspaces/{workspace_id}/projects/{project_id}":{"delete":{"tags":["projects"],"summary":"Delete Project","description":"Permanently delete a Project and everything it owns.\n\nCascade reaches:\n  - ``tests``                (FK -> CASCADE)\n  - ``test_runs``(FK -> CASCADE)\n    |- ``test_results``   (FK -> CASCADE)\n    |- ``reports``           (FK -> CASCADE)\n    |- ``failure_analyses``  (FK -> CASCADE)\n  - ``schedules``            (FK -> CASCADE)\n  - ``execution_jobs``       (FK -> CASCADE)\n\nAll wiring is in the cross-cutting Beryl migration\n(``a7c1d2e3f4b5_add_beryl_post_signup.py``) — these FKs are declared\n``ON DELETE CASCADE`` so issuing a single ``DELETE`` against the\nproject is enough.\n\nSucceeds regardless of run status. Any in-progress run is signalled to\nstop first (best-effort — a no-op for an orphaned run whose worker died),\nthen the cascade drops the project and its executions. We don't gate on run\nstate, so a project wedged in ``running`` forever stays deletable.","operationId":"delete_project_api_v1_workspaces__workspace_id__projects__project_id__delete","security":[{"HTTPBearer":[]}],"parameters":[{"name":"workspace_id","in":"path","required":true,"schema":{"type":"string","title":"Workspace Id"}},{"name":"project_id","in":"path","required":true,"schema":{"type":"string","title":"Project Id"}}],"responses":{"204":{"description":"Successful Response"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"get":{"tags":["projects"],"summary":"Get Project","description":"One Project with the same counters + last-run summary as the list\nview, intended for the project-detail page header card.","operationId":"get_project_api_v1_workspaces__workspace_id__projects__project_id__get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"workspace_id","in":"path","required":true,"schema":{"type":"string","title":"Workspace Id"}},{"name":"project_id","in":"path","required":true,"schema":{"type":"string","title":"Project Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProjectDetailResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"patch":{"tags":["projects"],"summary":"Update Project","description":"Edit a project's user-owned fields: the name, the auto-quarantine and\nself-heal settings, the enabled surfaces and the findings gate. Only fields present\nin the body are applied; returns the same detail payload as GET so the FE can\nrefresh its cache.","operationId":"update_project_api_v1_workspaces__workspace_id__projects__project_id__patch","security":[{"HTTPBearer":[]}],"parameters":[{"name":"workspace_id","in":"path","required":true,"schema":{"type":"string","title":"Workspace Id"}},{"name":"project_id","in":"path","required":true,"schema":{"type":"string","title":"Project Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateTestProjectRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProjectDetailResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/workspaces/{workspace_id}/projects/{project_id}/re-explore":{"post":{"tags":["projects"],"summary":"Re Explore Project","operationId":"re_explore_project_api_v1_workspaces__workspace_id__projects__project_id__re_explore_post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"workspace_id","in":"path","required":true,"schema":{"type":"string","title":"Workspace Id"}},{"name":"project_id","in":"path","required":true,"schema":{"type":"string","title":"Project Id"}}],"responses":{"202":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReExploreResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/workspaces/{workspace_id}/projects/{project_id}/environments":{"get":{"tags":["environments"],"summary":"List Environments","description":"List this project's environments (oldest first).\n\nToday every project has exactly one default 'Default' environment; this\nreturns that one row. It is a list so the UI + client are already shaped for\nthe multi-environment model the ER split moves toward.","operationId":"list_environments_api_v1_workspaces__workspace_id__projects__project_id__environments_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"workspace_id","in":"path","required":true,"schema":{"type":"string","title":"Workspace Id"}},{"name":"project_id","in":"path","required":true,"schema":{"type":"string","title":"Project Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/EnvironmentResponse"},"title":"Response List Environments Api V1 Workspaces  Workspace Id  Projects  Project Id  Environments Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"post":{"tags":["environments"],"summary":"Create Environment","operationId":"create_environment_api_v1_workspaces__workspace_id__projects__project_id__environments_post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"workspace_id","in":"path","required":true,"schema":{"type":"string","title":"Workspace Id"}},{"name":"project_id","in":"path","required":true,"schema":{"type":"string","title":"Project Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EnvironmentCreateRequest"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/EnvironmentResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/workspaces/{workspace_id}/projects/{project_id}/environments/{environment_id}":{"get":{"tags":["environments"],"summary":"Get Environment","operationId":"get_environment_api_v1_workspaces__workspace_id__projects__project_id__environments__environment_id__get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"environment_id","in":"path","required":true,"schema":{"type":"string","title":"Environment Id"}},{"name":"workspace_id","in":"path","required":true,"schema":{"type":"string","title":"Workspace Id"}},{"name":"project_id","in":"path","required":true,"schema":{"type":"string","title":"Project Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/EnvironmentResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"patch":{"tags":["environments"],"summary":"Update Environment","operationId":"update_environment_api_v1_workspaces__workspace_id__projects__project_id__environments__environment_id__patch","security":[{"HTTPBearer":[]}],"parameters":[{"name":"environment_id","in":"path","required":true,"schema":{"type":"string","title":"Environment Id"}},{"name":"workspace_id","in":"path","required":true,"schema":{"type":"string","title":"Workspace Id"}},{"name":"project_id","in":"path","required":true,"schema":{"type":"string","title":"Project Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateEnvironmentRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/EnvironmentResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["environments"],"summary":"Delete Environment","description":"Delete an environment and everything scoped to it — its runs, results,\nexplorations, schedules and per-env test state all cascade at the DB level.\n\nThe project's app-level tests are untouched (they're project-scoped, shared\nacross environments), and the shared ``scripts/{project_id}/`` artifact prefix\nis left in place. Rejects deleting a project's LAST environment (409 — a project\nmust always keep at least one), and refuses (409) while a run or exploration is\nin flight on it rather than killing live work.","operationId":"delete_environment_api_v1_workspaces__workspace_id__projects__project_id__environments__environment_id__delete","security":[{"HTTPBearer":[]}],"parameters":[{"name":"environment_id","in":"path","required":true,"schema":{"type":"string","title":"Environment Id"}},{"name":"workspace_id","in":"path","required":true,"schema":{"type":"string","title":"Workspace Id"}},{"name":"project_id","in":"path","required":true,"schema":{"type":"string","title":"Project Id"}}],"responses":{"204":{"description":"Successful Response"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/workspaces/{workspace_id}/projects/{project_id}/report":{"get":{"tags":["projects"],"summary":"Get Project Report","description":"Aggregate report for the project's recent runs.\n\nReturns everything the project Reports page needs in one round-trip:\n  - The last ``run_limit`` project executions (newest first).\n  - A test-vs-run matrix: one row per TestCase that appeared in those\n    runs, with a status-per-run map for rendering the matrix grid.\n  - A pass-rate trend per run (for the sparkline).\n  - Headline counts (currently passing/failing, stable, tests added or\n    removed within the window).\n\nThe cap is enforced (1..100) so a single project can't OOM the server\nby asking for thousands of runs.","operationId":"get_project_report_api_v1_workspaces__workspace_id__projects__project_id__report_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"workspace_id","in":"path","required":true,"schema":{"type":"string","title":"Workspace Id"}},{"name":"project_id","in":"path","required":true,"schema":{"type":"string","title":"Project Id"}},{"name":"run_limit","in":"query","required":false,"schema":{"type":"integer","default":20,"title":"Run Limit"}},{"name":"environment_id","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Environment Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProjectReportResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/workspaces/{workspace_id}/projects/{project_id}/schedules":{"get":{"tags":["projects"],"summary":"List Project Schedules","description":"List this project's schedules. Each runs independently on its own cadence\n(daily or weekly, at a local time in its timezone) and covers the union of its\ngroups' active tests at fire time; no groups = every active test.","operationId":"list_project_schedules_api_v1_workspaces__workspace_id__projects__project_id__schedules_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"workspace_id","in":"path","required":true,"schema":{"type":"string","title":"Workspace Id"}},{"name":"project_id","in":"path","required":true,"schema":{"type":"string","title":"Project Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/ScheduleItemResponse"},"title":"Response List Project Schedules Api V1 Workspaces  Workspace Id  Projects  Project Id  Schedules Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"post":{"tags":["projects"],"summary":"Create Project Schedule","description":"Create a schedule: cadence (daily, or weekly on a day) at a local time in a\ntimezone, targeting a set of groups (empty = every active test). Schedules may\noverlap freely. An invalid config or a group outside the project is a 422.","operationId":"create_project_schedule_api_v1_workspaces__workspace_id__projects__project_id__schedules_post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"workspace_id","in":"path","required":true,"schema":{"type":"string","title":"Workspace Id"}},{"name":"project_id","in":"path","required":true,"schema":{"type":"string","title":"Project Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ScheduleWriteRequest"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ScheduleItemResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/workspaces/{workspace_id}/projects/{project_id}/schedules/{schedule_id}":{"put":{"tags":["projects"],"summary":"Update Project Schedule","description":"Replace one schedule's full config: cadence, local time, timezone, and group\nset (empty = every active test).","operationId":"update_project_schedule_api_v1_workspaces__workspace_id__projects__project_id__schedules__schedule_id__put","security":[{"HTTPBearer":[]}],"parameters":[{"name":"schedule_id","in":"path","required":true,"schema":{"type":"string","title":"Schedule Id"}},{"name":"workspace_id","in":"path","required":true,"schema":{"type":"string","title":"Workspace Id"}},{"name":"project_id","in":"path","required":true,"schema":{"type":"string","title":"Project Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ScheduleWriteRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ScheduleItemResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["projects"],"summary":"Delete Project Schedule","description":"Delete one schedule. The tests and groups it targeted stay.","operationId":"delete_project_schedule_api_v1_workspaces__workspace_id__projects__project_id__schedules__schedule_id__delete","security":[{"HTTPBearer":[]}],"parameters":[{"name":"schedule_id","in":"path","required":true,"schema":{"type":"string","title":"Schedule Id"}},{"name":"workspace_id","in":"path","required":true,"schema":{"type":"string","title":"Workspace Id"}},{"name":"project_id","in":"path","required":true,"schema":{"type":"string","title":"Project Id"}}],"responses":{"204":{"description":"Successful Response"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/workspaces/{workspace_id}/projects/{project_id}/schedule":{"get":{"tags":["projects"],"summary":"Get Project Schedule","description":"Deprecated: use GET /projects/{project_id}/schedules.","operationId":"get_project_schedule_api_v1_workspaces__workspace_id__projects__project_id__schedule_get","deprecated":true,"security":[{"HTTPBearer":[]}],"parameters":[{"name":"workspace_id","in":"path","required":true,"schema":{"type":"string","title":"Workspace Id"}},{"name":"project_id","in":"path","required":true,"schema":{"type":"string","title":"Project Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ScheduleResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"put":{"tags":["projects"],"summary":"Set Project Schedule","description":"Deprecated: use POST/PUT /projects/{project_id}/schedules. Upserts the\nall-tests schedule; enabled=false deletes it.","operationId":"set_project_schedule_api_v1_workspaces__workspace_id__projects__project_id__schedule_put","deprecated":true,"security":[{"HTTPBearer":[]}],"parameters":[{"name":"workspace_id","in":"path","required":true,"schema":{"type":"string","title":"Workspace Id"}},{"name":"project_id","in":"path","required":true,"schema":{"type":"string","title":"Project Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateScheduleRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ScheduleResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/workspaces/{workspace_id}/projects/{project_id}/groups/{group_id}/schedule":{"put":{"tags":["projects"],"summary":"Set Group Schedule","description":"Deprecated: use POST/PUT /projects/{project_id}/schedules with group_ids.\nUpserts this group's single-group schedule; enabled=false deletes it.","operationId":"set_group_schedule_api_v1_workspaces__workspace_id__projects__project_id__groups__group_id__schedule_put","deprecated":true,"security":[{"HTTPBearer":[]}],"parameters":[{"name":"group_id","in":"path","required":true,"schema":{"type":"string","title":"Group Id"}},{"name":"workspace_id","in":"path","required":true,"schema":{"type":"string","title":"Workspace Id"}},{"name":"project_id","in":"path","required":true,"schema":{"type":"string","title":"Project Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateScheduleRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GroupScheduleResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["projects"],"summary":"Delete Group Schedule","description":"Deprecated: use DELETE /projects/{project_id}/schedules/{schedule_id}.","operationId":"delete_group_schedule_api_v1_workspaces__workspace_id__projects__project_id__groups__group_id__schedule_delete","deprecated":true,"security":[{"HTTPBearer":[]}],"parameters":[{"name":"group_id","in":"path","required":true,"schema":{"type":"string","title":"Group Id"}},{"name":"workspace_id","in":"path","required":true,"schema":{"type":"string","title":"Workspace Id"}},{"name":"project_id","in":"path","required":true,"schema":{"type":"string","title":"Project Id"}}],"responses":{"204":{"description":"Successful Response"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/workspaces/{workspace_id}/projects/{project_id}/groups":{"get":{"tags":["projects"],"summary":"List Test Groups","description":"List the project's test groups (name-sorted) with how many tests each holds.","operationId":"list_test_groups_api_v1_workspaces__workspace_id__projects__project_id__groups_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"workspace_id","in":"path","required":true,"schema":{"type":"string","title":"Workspace Id"}},{"name":"project_id","in":"path","required":true,"schema":{"type":"string","title":"Project Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/TestGroupResponse"},"title":"Response List Test Groups Api V1 Workspaces  Workspace Id  Projects  Project Id  Groups Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"post":{"tags":["projects"],"summary":"Create Test Group","description":"Create a group. Names are unique per project, case-insensitively (409 on a\nclash). This is the only way a group comes into existence — assigning a test to\nan unknown name never creates one.","operationId":"create_test_group_api_v1_workspaces__workspace_id__projects__project_id__groups_post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"workspace_id","in":"path","required":true,"schema":{"type":"string","title":"Workspace Id"}},{"name":"project_id","in":"path","required":true,"schema":{"type":"string","title":"Project Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TestGroupWriteRequest"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TestGroupResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/workspaces/{workspace_id}/projects/{project_id}/groups/{group_id}":{"patch":{"tags":["projects"],"summary":"Rename Test Group","description":"Rename a group. Tests keep their membership; the new name shows everywhere.","operationId":"rename_test_group_api_v1_workspaces__workspace_id__projects__project_id__groups__group_id__patch","security":[{"HTTPBearer":[]}],"parameters":[{"name":"group_id","in":"path","required":true,"schema":{"type":"string","title":"Group Id"}},{"name":"workspace_id","in":"path","required":true,"schema":{"type":"string","title":"Workspace Id"}},{"name":"project_id","in":"path","required":true,"schema":{"type":"string","title":"Project Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TestGroupWriteRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TestGroupResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["projects"],"summary":"Delete Test Group","description":"Delete a group. Its tests stay (they just leave the group). A schedule\ntargeting ONLY this group goes with it; a schedule also targeting other groups\njust loses the member.","operationId":"delete_test_group_api_v1_workspaces__workspace_id__projects__project_id__groups__group_id__delete","security":[{"HTTPBearer":[]}],"parameters":[{"name":"group_id","in":"path","required":true,"schema":{"type":"string","title":"Group Id"}},{"name":"workspace_id","in":"path","required":true,"schema":{"type":"string","title":"Workspace Id"}},{"name":"project_id","in":"path","required":true,"schema":{"type":"string","title":"Project Id"}}],"responses":{"204":{"description":"Successful Response"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/projects/{project_id}/workspace":{"get":{"tags":["projects"],"summary":"Resolve Project Workspace","description":"Which workspace owns this project — for the caller, if they're a member.\n\nShared deep links carry only the projectId (``/projects/{id}``), so a recipient\nwhose last-selected workspace is a different one asks the workspace-scoped API\nunder the wrong workspace and gets a 404. This lets the webapp resolve the\nowning workspace and switch to it instead of silently bouncing to /projects.\n\nThe membership join is the whole security gate: a non-member gets the same 404\nas a nonexistent project, so this leaks no project's existence, name, or\nworkspace across a tenant boundary.","operationId":"resolve_project_workspace_api_v1_projects__project_id__workspace_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"project_id","in":"path","required":true,"schema":{"type":"string","title":"Project Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProjectWorkspaceResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/workspaces/{workspace_id}/projects/{project_id}/tests":{"get":{"tags":["tests"],"summary":"List Tests","description":"List the project's tests. The tests themselves are env-independent (one test\nruns against every environment), but each row's current status / last-run\nresolve from ``test_case_env_state`` for the SELECTED environment\n(``environment_id``, else the project's default env).\n\nAccepts a project-scoped CI token as well as a personal access token.","operationId":"list_tests_api_v1_workspaces__workspace_id__projects__project_id__tests_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"workspace_id","in":"path","required":true,"schema":{"type":"string","title":"Workspace Id"}},{"name":"project_id","in":"path","required":true,"schema":{"type":"string","title":"Project Id"}},{"name":"environment_id","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Environment Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/TestResponse"},"title":"Response List Tests Api V1 Workspaces  Workspace Id  Projects  Project Id  Tests Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"x-beryl-ci-token":true},"post":{"tags":["tests"],"summary":"Create Test","operationId":"create_test_api_v1_workspaces__workspace_id__projects__project_id__tests_post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"workspace_id","in":"path","required":true,"schema":{"type":"string","title":"Workspace Id"}},{"name":"project_id","in":"path","required":true,"schema":{"type":"string","title":"Project Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TestCreateRequest"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TestCreateResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/workspaces/{workspace_id}/projects/{project_id}/tests/page":{"get":{"tags":["tests"],"summary":"List Tests Page","description":"One page of the project's tests, newest-first, for the paginated Tests tab.\n\n``GET /tests`` returns every test in the project and stays that way for the CLI;\nthis route exists so the webapp stops downloading the whole project on every\npoll. ``status_totals`` and ``group_counts`` are both counted project-wide (not\nover the page), so the coverage donut and the group dropdown keep meaning what\nthey meant before pagination.","operationId":"list_tests_page_api_v1_workspaces__workspace_id__projects__project_id__tests_page_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"workspace_id","in":"path","required":true,"schema":{"type":"string","title":"Workspace Id"}},{"name":"project_id","in":"path","required":true,"schema":{"type":"string","title":"Project Id"}},{"name":"page","in":"query","required":false,"schema":{"type":"integer","minimum":1,"default":1,"title":"Page"}},{"name":"page_size","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"default":20,"title":"Page Size"}},{"name":"status","in":"query","required":false,"schema":{"anyOf":[{"type":"string","pattern":"^(passed|failing|failed|errored|cancelled|quarantined)$"},{"type":"null"}],"description":"Bucket to filter by; omit for all. failing is failed or errored, the same tests status_totals.failed counts; failed alone excludes errored.","title":"Status"},"description":"Bucket to filter by; omit for all. failing is failed or errored, the same tests status_totals.failed counts; failed alone excludes errored."},{"name":"group","in":"query","required":false,"schema":{"anyOf":[{"type":"string","pattern":"^[^\\x00]*$"},{"type":"null"}],"description":"Group name to filter by, or the sentinel '__ungrouped__' for tests carrying no group at all.","title":"Group"},"description":"Group name to filter by, or the sentinel '__ungrouped__' for tests carrying no group at all."},{"name":"q","in":"query","required":false,"schema":{"anyOf":[{"type":"string","maxLength":200,"pattern":"^[^\\x00]*$"},{"type":"null"}],"description":"Case-insensitive substring match on the test title.","title":"Q"},"description":"Case-insensitive substring match on the test title."},{"name":"access","in":"query","required":false,"schema":{"anyOf":[{"type":"string","pattern":"^(read|write)$"},{"type":"null"}],"description":"Only read or only write tests.","title":"Access"},"description":"Only read or only write tests."},{"name":"environment_id","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Environment Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TestListPage"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/workspaces/{workspace_id}/projects/{project_id}/flows/page":{"get":{"tags":["tests"],"summary":"List Flows Page","description":"One page of the project's test flows, newest-first, each with its surface tests\nand their head state in the selected environment.","operationId":"list_flows_page_api_v1_workspaces__workspace_id__projects__project_id__flows_page_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"workspace_id","in":"path","required":true,"schema":{"type":"string","title":"Workspace Id"}},{"name":"project_id","in":"path","required":true,"schema":{"type":"string","title":"Project Id"}},{"name":"page","in":"query","required":false,"schema":{"type":"integer","minimum":1,"default":1,"title":"Page"}},{"name":"page_size","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"default":20,"title":"Page Size"}},{"name":"status","in":"query","required":false,"schema":{"anyOf":[{"type":"string","pattern":"^(passed|failing|quarantined)$"},{"type":"null"}],"title":"Status"}},{"name":"group","in":"query","required":false,"schema":{"anyOf":[{"type":"string","pattern":"^[^\\x00]*$"},{"type":"null"}],"description":"Group name to filter by, or the sentinel '__ungrouped__' for flows carrying no group at all.","title":"Group"},"description":"Group name to filter by, or the sentinel '__ungrouped__' for flows carrying no group at all."},{"name":"q","in":"query","required":false,"schema":{"anyOf":[{"type":"string","maxLength":200,"pattern":"^[^\\x00]*$"},{"type":"null"}],"description":"Case-insensitive substring match on the flow title.","title":"Q"},"description":"Case-insensitive substring match on the flow title."},{"name":"environment_id","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Environment Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TestFlowListPage"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/workspaces/{workspace_id}/projects/{project_id}/flows/{flow_id}":{"get":{"tags":["tests"],"summary":"Get Flow","operationId":"get_flow_api_v1_workspaces__workspace_id__projects__project_id__flows__flow_id__get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"flow_id","in":"path","required":true,"schema":{"type":"string","title":"Flow Id"}},{"name":"workspace_id","in":"path","required":true,"schema":{"type":"string","title":"Workspace Id"}},{"name":"project_id","in":"path","required":true,"schema":{"type":"string","title":"Project Id"}},{"name":"environment_id","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Environment Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TestFlowResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/workspaces/{workspace_id}/projects/{project_id}/tests/{test_case_id}":{"get":{"tags":["tests"],"summary":"Get Test","operationId":"get_test_api_v1_workspaces__workspace_id__projects__project_id__tests__test_case_id__get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"test_case_id","in":"path","required":true,"schema":{"type":"string","title":"Test Case Id"}},{"name":"workspace_id","in":"path","required":true,"schema":{"type":"string","title":"Workspace Id"}},{"name":"project_id","in":"path","required":true,"schema":{"type":"string","title":"Project Id"}},{"name":"environment_id","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Environment Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TestResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"patch":{"tags":["tests"],"summary":"Update Test","description":"Update a test's own metadata: ``title``, ``access``, ``groups`` and/or\n``intent``, each optional and written only when present. All four belong to the\nflow, so every surface variant of the test changes with it. ``intent_key`` is the\nagent's reconcile handle, so neither a rename nor an intent edit moves it, or the next\nexploration would re-author the test as a duplicate. An intent edit appends one\n``user_edit`` version per variant (same plan, new ``nl_snapshot``), which is the text\nheal judges against; the plan is never regenerated.","operationId":"update_test_api_v1_workspaces__workspace_id__projects__project_id__tests__test_case_id__patch","security":[{"HTTPBearer":[]}],"parameters":[{"name":"test_case_id","in":"path","required":true,"schema":{"type":"string","title":"Test Case Id"}},{"name":"workspace_id","in":"path","required":true,"schema":{"type":"string","title":"Workspace Id"}},{"name":"project_id","in":"path","required":true,"schema":{"type":"string","title":"Project Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TestUpdateRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TestResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["tests"],"summary":"Delete Test","description":"Permanently delete a test and everything it owns — its versions, its run items\nand their results, and its S3 artifacts. The runs themselves survive (they belong\nto the project, not the test); a run that included this test keeps its row, minus\nthis test's item/result.\n\nHard delete, not a soft ``is_active`` flip: the only prior way to remove a bad test\nwas to delete the whole project, and a create-heavy authoring loop needs the junk\nactually gone.","operationId":"delete_test_api_v1_workspaces__workspace_id__projects__project_id__tests__test_case_id__delete","security":[{"HTTPBearer":[]}],"parameters":[{"name":"test_case_id","in":"path","required":true,"schema":{"type":"string","title":"Test Case Id"}},{"name":"workspace_id","in":"path","required":true,"schema":{"type":"string","title":"Workspace Id"}},{"name":"project_id","in":"path","required":true,"schema":{"type":"string","title":"Project Id"}}],"responses":{"204":{"description":"Successful Response"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/workspaces/{workspace_id}/projects/{project_id}/tests/compile":{"post":{"tags":["tests"],"summary":"Compile Test Plan","operationId":"compile_test_plan_api_v1_workspaces__workspace_id__projects__project_id__tests_compile_post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"workspace_id","in":"path","required":true,"schema":{"type":"string","title":"Workspace Id"}},{"name":"project_id","in":"path","required":true,"schema":{"type":"string","title":"Project Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TestCompileRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TestCompileResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/workspaces/{workspace_id}/projects/{project_id}/tests/{test_case_id}/plan":{"patch":{"tags":["tests"],"summary":"Edit Test Plan","description":"Edit a test's json_plan. The plan is validated against the ActionPlan\nschema (plus the runnable-plan rules). The FIRST human edit flips\nauthored_by system→user as provenance and appends a revision; this no longer\nchanges heal-eligibility — editing a step doesn't freeze the test against\nself-heal. The user opts out of healing only by marking the test \"fixed\"\n(PATCH .../heal-eligibility). The edited plan runs on the test's next run;\nauthored_by is returned so the provenance flip is explicit.","operationId":"edit_test_plan_api_v1_workspaces__workspace_id__projects__project_id__tests__test_case_id__plan_patch","security":[{"HTTPBearer":[]}],"parameters":[{"name":"test_case_id","in":"path","required":true,"schema":{"type":"string","title":"Test Case Id"}},{"name":"workspace_id","in":"path","required":true,"schema":{"type":"string","title":"Workspace Id"}},{"name":"project_id","in":"path","required":true,"schema":{"type":"string","title":"Project Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TestPlanUpdateRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TestPlanResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/workspaces/{workspace_id}/projects/{project_id}/tests/{test_case_id}/system-reset":{"post":{"tags":["tests"],"summary":"System Reset Test","description":"Discard user edits: flip authored_by provenance back to 'system'. The\njson_plan stays as-is until the next regeneration overwrites it. Heal-\neligibility is independent — a \"fixed\" test stays fixed across a reset; use\nPATCH .../heal-eligibility to re-enable healing.","operationId":"system_reset_test_api_v1_workspaces__workspace_id__projects__project_id__tests__test_case_id__system_reset_post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"test_case_id","in":"path","required":true,"schema":{"type":"string","title":"Test Case Id"}},{"name":"workspace_id","in":"path","required":true,"schema":{"type":"string","title":"Workspace Id"}},{"name":"project_id","in":"path","required":true,"schema":{"type":"string","title":"Project Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TestPlanResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/workspaces/{workspace_id}/projects/{project_id}/tests/{test_case_id}/plan/recompile":{"post":{"tags":["tests"],"summary":"Recompile Test Plan Route","description":"Recompile a user-edited plan into a runnable, AI-verified test.\n\nUnlike PATCH .../plan (which saves the edit and lets it ride into the next run),\nthis re-validates the edited plan against the crawled page, regenerates the\nrunnable script, and replays it through the AI verify gate before persisting.\nPinned steps/selectors/assertions survive verbatim — no hardening rewrite. A\ndeterministic replay failure (verdict \"drop\") rejects the edit rather than\nshipping it: the response carries verified=false / persisted=false and the\nreason, and the previously-live plan is left in place.","operationId":"recompile_test_plan_route_api_v1_workspaces__workspace_id__projects__project_id__tests__test_case_id__plan_recompile_post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"test_case_id","in":"path","required":true,"schema":{"type":"string","title":"Test Case Id"}},{"name":"workspace_id","in":"path","required":true,"schema":{"type":"string","title":"Workspace Id"}},{"name":"project_id","in":"path","required":true,"schema":{"type":"string","title":"Project Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TestPlanUpdateRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TestRecompileResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/workspaces/{workspace_id}/projects/{project_id}/tests/{test_case_id}/heal-eligibility":{"patch":{"tags":["tests"],"summary":"Set Test Heal Eligibility","description":"Set the \"fixed test\" toggle. self_heal_enabled=False marks the test fixed:\nit is barred from ALL automatic regeneration (auto-heal AND re-explore\nreconcile), though it can still be hand-edited. True re-enables healing. This\nis independent of provenance (authored_by) — a hand-edited test still heals\nunless the user marks it fixed here.","operationId":"set_test_heal_eligibility_api_v1_workspaces__workspace_id__projects__project_id__tests__test_case_id__heal_eligibility_patch","security":[{"HTTPBearer":[]}],"parameters":[{"name":"test_case_id","in":"path","required":true,"schema":{"type":"string","title":"Test Case Id"}},{"name":"workspace_id","in":"path","required":true,"schema":{"type":"string","title":"Workspace Id"}},{"name":"project_id","in":"path","required":true,"schema":{"type":"string","title":"Project Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HealEligibilityUpdateRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HealEligibilityResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/workspaces/{workspace_id}/projects/{project_id}/tests/{test_case_id}/quarantine":{"patch":{"tags":["tests"],"summary":"Set Test Quarantine","description":"Mute a persistently flaky test without losing its signal. A quarantined test\nstill runs and still records a result; its red just lands in the run's\nquarantined_count instead of failed_count, so it doesn't fail the run or the\nCLI's exit code. Distinct from deactivation (staff-only, stops the test running\nat all) and from deletion (destroys the history).","operationId":"set_test_quarantine_api_v1_workspaces__workspace_id__projects__project_id__tests__test_case_id__quarantine_patch","security":[{"HTTPBearer":[]}],"parameters":[{"name":"test_case_id","in":"path","required":true,"schema":{"type":"string","title":"Test Case Id"}},{"name":"workspace_id","in":"path","required":true,"schema":{"type":"string","title":"Workspace Id"}},{"name":"project_id","in":"path","required":true,"schema":{"type":"string","title":"Project Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuarantineUpdateRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuarantineResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/workspaces/{workspace_id}/projects/{project_id}/tests/bulk-delete":{"post":{"tags":["tests"],"summary":"Bulk Delete Tests","description":"Delete several tests in one transaction — same semantics as DELETE /tests/{id}\nper test. An unknown or cross-project id fails the whole request (404) before\nanything is deleted.","operationId":"bulk_delete_tests_api_v1_workspaces__workspace_id__projects__project_id__tests_bulk_delete_post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"workspace_id","in":"path","required":true,"schema":{"type":"string","title":"Workspace Id"}},{"name":"project_id","in":"path","required":true,"schema":{"type":"string","title":"Project Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BulkTestIdsRequest"}}}},"responses":{"204":{"description":"Successful Response"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/workspaces/{workspace_id}/projects/{project_id}/tests/bulk-groups":{"post":{"tags":["tests"],"summary":"Bulk Add Test Groups","description":"Add groups to several tests at once. Unlike PATCH /tests/{id}, which replaces a\ntest's whole group set, this only ever adds — the caller doesn't need to know what\neach selected test already carries.","operationId":"bulk_add_test_groups_api_v1_workspaces__workspace_id__projects__project_id__tests_bulk_groups_post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"workspace_id","in":"path","required":true,"schema":{"type":"string","title":"Workspace Id"}},{"name":"project_id","in":"path","required":true,"schema":{"type":"string","title":"Project Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BulkAddGroupsRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BulkTestsResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/workspaces/{workspace_id}/projects/{project_id}/tests/{test_case_id}/events":{"get":{"tags":["tests"],"summary":"List Test Events","description":"Quarantine, grouping and rename history for one test, newest first. Plan edits\nare not here: those are versions, and they are restorable.","operationId":"list_test_events_api_v1_workspaces__workspace_id__projects__project_id__tests__test_case_id__events_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"test_case_id","in":"path","required":true,"schema":{"type":"string","title":"Test Case Id"}},{"name":"workspace_id","in":"path","required":true,"schema":{"type":"string","title":"Workspace Id"}},{"name":"project_id","in":"path","required":true,"schema":{"type":"string","title":"Project Id"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":500,"minimum":1,"default":100,"title":"Limit"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/TestEventResponse"},"title":"Response List Test Events Api V1 Workspaces  Workspace Id  Projects  Project Id  Tests  Test Case Id  Events Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/workspaces/{workspace_id}/projects/{project_id}/tests/bulk-quarantine":{"post":{"tags":["tests"],"summary":"Bulk Set Test Quarantine","description":"Quarantine or release a selection. Tests already in the requested state are left\nalone rather than rejected, so a mixed selection takes one call.","operationId":"bulk_set_test_quarantine_api_v1_workspaces__workspace_id__projects__project_id__tests_bulk_quarantine_post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"workspace_id","in":"path","required":true,"schema":{"type":"string","title":"Workspace Id"}},{"name":"project_id","in":"path","required":true,"schema":{"type":"string","title":"Project Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BulkQuarantineRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BulkTestsResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/workspaces/{workspace_id}/projects/{project_id}/tests/{test_case_id}/versions":{"get":{"tags":["tests"],"summary":"List Test Case Versions","description":"Newest-first page of a test's plan versions (metadata only). Pass the\nresponse's ``next_cursor`` back as ``cursor`` to fetch the next older page.","operationId":"list_test_case_versions_api_v1_workspaces__workspace_id__projects__project_id__tests__test_case_id__versions_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"test_case_id","in":"path","required":true,"schema":{"type":"string","title":"Test Case Id"}},{"name":"workspace_id","in":"path","required":true,"schema":{"type":"string","title":"Workspace Id"}},{"name":"project_id","in":"path","required":true,"schema":{"type":"string","title":"Project Id"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"default":20,"title":"Limit"}},{"name":"cursor","in":"query","required":false,"schema":{"anyOf":[{"type":"integer"},{"type":"null"}],"description":"version_no to page from (exclusive); omit for newest","title":"Cursor"},"description":"version_no to page from (exclusive); omit for newest"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TestCaseVersionListResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/workspaces/{workspace_id}/projects/{project_id}/tests/{test_case_id}/versions/{version_no}":{"get":{"tags":["tests"],"summary":"Get Test Case Version","description":"One past version, including its full json_plan snapshot.","operationId":"get_test_case_version_api_v1_workspaces__workspace_id__projects__project_id__tests__test_case_id__versions__version_no__get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"test_case_id","in":"path","required":true,"schema":{"type":"string","title":"Test Case Id"}},{"name":"version_no","in":"path","required":true,"schema":{"type":"integer","title":"Version No"}},{"name":"workspace_id","in":"path","required":true,"schema":{"type":"string","title":"Workspace Id"}},{"name":"project_id","in":"path","required":true,"schema":{"type":"string","title":"Project Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TestCaseVersionDetail"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/workspaces/{workspace_id}/projects/{project_id}/tests/{test_case_id}/versions/{a}/diff/{b}":{"get":{"tags":["tests"],"summary":"Diff Test Case Versions","description":"Step-level diff of two versions' plans (a → b).","operationId":"diff_test_case_versions_api_v1_workspaces__workspace_id__projects__project_id__tests__test_case_id__versions__a__diff__b__get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"test_case_id","in":"path","required":true,"schema":{"type":"string","title":"Test Case Id"}},{"name":"a","in":"path","required":true,"schema":{"type":"integer","title":"A"}},{"name":"b","in":"path","required":true,"schema":{"type":"integer","title":"B"}},{"name":"workspace_id","in":"path","required":true,"schema":{"type":"string","title":"Workspace Id"}},{"name":"project_id","in":"path","required":true,"schema":{"type":"string","title":"Project Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VersionDiffResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/workspaces/{workspace_id}/projects/{project_id}/tests/{test_case_id}/restore":{"post":{"tags":["tests"],"summary":"Restore Test Case Version","description":"Restore a past version: set json_plan to that version's plan and APPEND\na new ``restore`` version equal to it (history is never rewritten). Flips\nauthored_by→user as provenance (a deliberate human choice); heal-eligibility\nis unchanged — restoring a plan doesn't freeze the test against self-heal.","operationId":"restore_test_case_version_api_v1_workspaces__workspace_id__projects__project_id__tests__test_case_id__restore_post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"test_case_id","in":"path","required":true,"schema":{"type":"string","title":"Test Case Id"}},{"name":"workspace_id","in":"path","required":true,"schema":{"type":"string","title":"Workspace Id"}},{"name":"project_id","in":"path","required":true,"schema":{"type":"string","title":"Project Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RestoreVersionRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RestoreVersionResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/workspaces/{workspace_id}/projects/{project_id}/tests/{test_case_id}/script":{"get":{"tags":["tests"],"summary":"Get Rendered Script","description":"Render the .spec.ts content from json_plan on demand.\n\nServes the UI's \"view script\" panel and `beryl runs local`, which fetches this\nbody and runs it with the caller's own ``@playwright/test``. A session-mode test\nrenders exactly as the cloud run core renders it — referencing ``auth-state.json``\n— and the response says which account's session to establish (``session_mode`` +\n``account_id``); the caller mints the files from POST\n``/test-accounts/{id}/session``. The project's captured customer session is still\nnever served here; only the test account's own, to an authenticated member.\n``requires_auth`` stays true for these so an older CLI skips them instead of\nrunning the spec logged out.","operationId":"get_rendered_script_api_v1_workspaces__workspace_id__projects__project_id__tests__test_case_id__script_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"test_case_id","in":"path","required":true,"schema":{"type":"string","title":"Test Case Id"}},{"name":"workspace_id","in":"path","required":true,"schema":{"type":"string","title":"Workspace Id"}},{"name":"project_id","in":"path","required":true,"schema":{"type":"string","title":"Project Id"}},{"name":"base_url","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Resolve the plan's relative gotos against this root instead of the environment's — lets a local run target localhost or a preview deploy.","title":"Base Url"},"description":"Resolve the plan's relative gotos against this root instead of the environment's — lets a local run target localhost or a preview deploy."},{"name":"environment_id","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Render against this environment, its root URL and its test account, instead of the project default, so a caller that reveals LOGIN_PASSWORD for an environment gets a matching login_email.","title":"Environment Id"},"description":"Render against this environment, its root URL and its test account, instead of the project default, so a caller that reveals LOGIN_PASSWORD for an environment gets a matching login_email."},{"name":"frames","in":"query","required":false,"schema":{"anyOf":[{"type":"boolean"},{"type":"null"}],"description":"Force per-step filmstrip capture on (true) or off (false), so a local run produces the frames/step-NNN.png files a run import needs for the replay. Omitted: the deployment's SAVE_TRACE_ARTIFACTS default.","title":"Frames"},"description":"Force per-step filmstrip capture on (true) or off (false), so a local run produces the frames/step-NNN.png files a run import needs for the replay. Omitted: the deployment's SAVE_TRACE_ARTIFACTS default."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Get Rendered Script Api V1 Workspaces  Workspace Id  Projects  Project Id  Tests  Test Case Id  Script Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/workspaces/{workspace_id}/projects/{project_id}/tests/export":{"post":{"tags":["tests"],"summary":"Export Tests","description":"Bundle the selected tests' rendered ``.spec.ts`` files into a ZIP, or return them\nas JSON with ``format=json``.\n\nEach test is rendered from its ``json_plan`` the same way GET\n``/tests/{id}/script`` renders it. Ids are intersected with this project's tests,\nso a foreign/unknown id is silently dropped; a test with no renderable plan is\nskipped. 404 when none of the requested ids resolve to a renderable test.","operationId":"export_tests_api_v1_workspaces__workspace_id__projects__project_id__tests_export_post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"workspace_id","in":"path","required":true,"schema":{"type":"string","title":"Workspace Id"}},{"name":"project_id","in":"path","required":true,"schema":{"type":"string","title":"Project Id"}},{"name":"format","in":"query","required":false,"schema":{"enum":["zip","json"],"type":"string","description":"zip: a downloadable ZIP. json: the files inline.","default":"zip","title":"Format"},"description":"zip: a downloadable ZIP. json: the files inline."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TestExportRequest"}}}},"responses":{"200":{"description":"ZIP of the rendered `.spec.ts` files, or with format=json the same files as JSON","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TestExportFiles"}},"application/zip":{"schema":{"type":"string","format":"binary"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/workspaces/{workspace_id}/projects/{project_id}/tests/{test_case_id}/history":{"get":{"tags":["tests"],"summary":"Get Test History","description":"Return the most recent ``limit`` executions of a TestCase, plus\nderived signals (current streak, flakiness) computed server-side.\n\nUsed by the frontend to render the P/F/F/P chip strip on every test\nrow. The data comes straight from ``test_results`` — there's no\nseparate history table; each row already IS the history. Executions are\nscoped to the SELECTED environment (``environment_id``, else the project's\ndefault env) so the sparkline reflects one environment.\n\nWorkspace scope is enforced via the ``get_project_in_workspace``\ndependency on the parent project; we additionally verify the test\nbelongs to that project to prevent cross-project leakage.","operationId":"get_test_history_api_v1_workspaces__workspace_id__projects__project_id__tests__test_case_id__history_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"test_case_id","in":"path","required":true,"schema":{"type":"string","title":"Test Case Id"}},{"name":"workspace_id","in":"path","required":true,"schema":{"type":"string","title":"Workspace Id"}},{"name":"project_id","in":"path","required":true,"schema":{"type":"string","title":"Project Id"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"default":20,"title":"Limit"}},{"name":"environment_id","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Environment Id"}},{"name":"include_artifacts","in":"query","required":false,"schema":{"type":"boolean","description":"Presign each entry's screenshot, DOM, trace and frame URLs. The webapp passes false and loads the selected run's from /results/{id}/artifacts.","default":true,"title":"Include Artifacts"},"description":"Presign each entry's screenshot, DOM, trace and frame URLs. The webapp passes false and loads the selected run's from /results/{id}/artifacts."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TestHistoryResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/workspaces/{workspace_id}/projects/{project_id}/runs":{"post":{"tags":["runs"],"summary":"Trigger Run","operationId":"trigger_run_api_v1_workspaces__workspace_id__projects__project_id__runs_post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"workspace_id","in":"path","required":true,"schema":{"type":"string","title":"Workspace Id"}},{"name":"project_id","in":"path","required":true,"schema":{"type":"string","title":"Project Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TriggerExecutionRequest"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TestRunResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"x-beryl-ci-token":true,"description":"Accepts a project-scoped CI token as well as a personal access token."},"get":{"tags":["runs"],"summary":"List Runs","operationId":"list_runs_api_v1_workspaces__workspace_id__projects__project_id__runs_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"workspace_id","in":"path","required":true,"schema":{"type":"string","title":"Workspace Id"}},{"name":"project_id","in":"path","required":true,"schema":{"type":"string","title":"Project Id"}},{"name":"environment_id","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Environment Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/TestRunResponse"},"title":"Response List Runs Api V1 Workspaces  Workspace Id  Projects  Project Id  Runs Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/workspaces/{workspace_id}/projects/{project_id}/runs/page":{"get":{"tags":["runs"],"summary":"List Runs Page","description":"One page of the project's runs, newest-first, for the paginated run history.\n\n``GET /runs`` keeps returning a bare (50-capped) array for the CLI; this route\nexists so the webapp can walk the full history a page at a time instead of\nre-fetching fifty runs on every poll.","operationId":"list_runs_page_api_v1_workspaces__workspace_id__projects__project_id__runs_page_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"workspace_id","in":"path","required":true,"schema":{"type":"string","title":"Workspace Id"}},{"name":"project_id","in":"path","required":true,"schema":{"type":"string","title":"Project Id"}},{"name":"page","in":"query","required":false,"schema":{"type":"integer","minimum":1,"default":1,"title":"Page"}},{"name":"page_size","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"default":8,"title":"Page Size"}},{"name":"environment_id","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Environment Id"}},{"name":"include_queued","in":"query","required":false,"schema":{"type":"boolean","description":"False leaves out runs still waiting in the queue (see /runs/queue).","default":true,"title":"Include Queued"},"description":"False leaves out runs still waiting in the queue (see /runs/queue)."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RunListPage"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/workspaces/{workspace_id}/projects/{project_id}/runs/queue":{"get":{"tags":["runs"],"summary":"Get Run Queue","description":"The project's active run (pending or running) and its queued runs in the order\nthey will start. A project runs one run at a time.","operationId":"get_run_queue_api_v1_workspaces__workspace_id__projects__project_id__runs_queue_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"workspace_id","in":"path","required":true,"schema":{"type":"string","title":"Workspace Id"}},{"name":"project_id","in":"path","required":true,"schema":{"type":"string","title":"Project Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RunQueueResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/workspaces/{workspace_id}/projects/{project_id}/runs/{run_id}":{"get":{"tags":["runs"],"summary":"Get Run","operationId":"get_run_api_v1_workspaces__workspace_id__projects__project_id__runs__run_id__get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"run_id","in":"path","required":true,"schema":{"type":"string","title":"Run Id"}},{"name":"workspace_id","in":"path","required":true,"schema":{"type":"string","title":"Workspace Id"}},{"name":"project_id","in":"path","required":true,"schema":{"type":"string","title":"Project Id"}},{"name":"results","in":"query","required":false,"schema":{"enum":["all","in_flight"],"type":"string","description":"'in_flight' embeds only running/healing/pending results, without artifact URLs; settled rows are paged from /results/page.","default":"all","title":"Results"},"description":"'in_flight' embeds only running/healing/pending results, without artifact URLs; settled rows are paged from /results/page."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TestRunResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"x-beryl-ci-token":true,"description":"Accepts a project-scoped CI token as well as a personal access token."}},"/api/v1/workspaces/{workspace_id}/projects/{project_id}/runs/{run_id}/results/page":{"get":{"tags":["runs"],"summary":"List Run Results Page","description":"One page of this run's SETTLED per-test results, in the order the run produced\nthem.\n\n``GET /runs/{run_id}`` still carries every result inline, in-flight ones included\n(the CLI reads it that way, and the header counters come off the run row); this\nroute exists so the run page can filter and page a 99-test run instead of\nrendering all of it. Rows still running, healing or queued are excluded: they are\nthe live picture, shown unfiltered in their own sections. ``status_totals``,\n``group_counts`` and ``ungrouped_count`` are counted over the run's settled rows\nrather than over the page, so the filter options keep meaning what they meant\nbefore pagination.\n\nAccepts a project-scoped CI token as well as a personal access token.","operationId":"list_run_results_page_api_v1_workspaces__workspace_id__projects__project_id__runs__run_id__results_page_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"run_id","in":"path","required":true,"schema":{"type":"string","title":"Run Id"}},{"name":"workspace_id","in":"path","required":true,"schema":{"type":"string","title":"Workspace Id"}},{"name":"project_id","in":"path","required":true,"schema":{"type":"string","title":"Project Id"}},{"name":"page","in":"query","required":false,"schema":{"type":"integer","minimum":1,"default":1,"title":"Page"}},{"name":"page_size","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"default":20,"title":"Page Size"}},{"name":"status","in":"query","required":false,"schema":{"anyOf":[{"type":"string","pattern":"^(passed|failed|errored|cancelled|quarantined)$"},{"type":"null"}],"description":"Bucket to filter by; omit for all. Same set as the Tests filter.","title":"Status"},"description":"Bucket to filter by; omit for all. Same set as the Tests filter."},{"name":"group","in":"query","required":false,"schema":{"anyOf":[{"type":"string","pattern":"^[^\\x00]*$"},{"type":"null"}],"description":"Group name to filter by, or the sentinel '__ungrouped__' for results whose test carries no group at all.","title":"Group"},"description":"Group name to filter by, or the sentinel '__ungrouped__' for results whose test carries no group at all."},{"name":"q","in":"query","required":false,"schema":{"anyOf":[{"type":"string","maxLength":200,"pattern":"^[^\\x00]*$"},{"type":"null"}],"description":"Case-insensitive substring match on the test title.","title":"Q"},"description":"Case-insensitive substring match on the test title."},{"name":"include_artifacts","in":"query","required":false,"schema":{"type":"boolean","description":"Presign each row's screenshot, DOM, trace and frame URLs. The run page passes false and loads them per result from /results/{id}/artifacts.","default":true,"title":"Include Artifacts"},"description":"Presign each row's screenshot, DOM, trace and frame URLs. The run page passes false and loads them per result from /results/{id}/artifacts."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RunResultsPage"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"x-beryl-ci-token":true}},"/api/v1/workspaces/{workspace_id}/projects/{project_id}/runs/{run_id}/cancel":{"post":{"tags":["runs"],"summary":"Cancel Run","description":"Stop the run.\n\nIdempotent. The run and its not-yet-started tests go terminal here, so this\nworks on an orphaned run no worker owns; a live worker stops dispatching at\nthe next test boundary. The one test already in flight finishes and keeps its\nreal verdict. Completed tests are kept untouched.","operationId":"cancel_run_api_v1_workspaces__workspace_id__projects__project_id__runs__run_id__cancel_post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"workspace_id","in":"path","required":true,"schema":{"type":"string","title":"Workspace Id"}},{"name":"project_id","in":"path","required":true,"schema":{"type":"string","title":"Project Id"}},{"name":"run_id","in":"path","required":true,"schema":{"type":"string","title":"Run Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CancelExecutionResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/workspaces/{workspace_id}/projects/{project_id}/results/{test_result_id}/artifacts":{"get":{"tags":["runs"],"summary":"Get Result Artifacts","operationId":"get_result_artifacts_api_v1_workspaces__workspace_id__projects__project_id__results__test_result_id__artifacts_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"test_result_id","in":"path","required":true,"schema":{"type":"string","title":"Test Result Id"}},{"name":"workspace_id","in":"path","required":true,"schema":{"type":"string","title":"Workspace Id"}},{"name":"project_id","in":"path","required":true,"schema":{"type":"string","title":"Project Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ResultArtifactsResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/workspaces/{workspace_id}/projects/{project_id}/results/{test_result_id}/explain":{"get":{"tags":["runs"],"summary":"Explain Test Failure","operationId":"explain_test_failure_api_v1_workspaces__workspace_id__projects__project_id__results__test_result_id__explain_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"test_result_id","in":"path","required":true,"schema":{"type":"string","title":"Test Result Id"}},{"name":"workspace_id","in":"path","required":true,"schema":{"type":"string","title":"Workspace Id"}},{"name":"project_id","in":"path","required":true,"schema":{"type":"string","title":"Project Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExplainFailureResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/workspaces/{workspace_id}/projects/{project_id}/runs/{run_id}/progress":{"get":{"tags":["runs"],"summary":"Run Progress","description":"Current progress of a run; with ``wait``, long-polls until it changes.\n\nThe watch primitive for the CLI and CI: responds immediately when the run\nis terminal or its version moved past ``since_version``, otherwise parks on\nthe event hub for up to ``wait`` seconds. Holds no DB or Redis resource\nwhile parked; the snapshot comes from the Redis scoreboard with the run row\nas fallback.\n\nAccepts a project-scoped CI token as well as a personal access token.","operationId":"run_progress_api_v1_workspaces__workspace_id__projects__project_id__runs__run_id__progress_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"run_id","in":"path","required":true,"schema":{"type":"string","title":"Run Id"}},{"name":"workspace_id","in":"path","required":true,"schema":{"type":"string","title":"Workspace Id"}},{"name":"project_id","in":"path","required":true,"schema":{"type":"string","title":"Project Id"}},{"name":"since_version","in":"query","required":false,"schema":{"type":"integer","default":0,"title":"Since Version"}},{"name":"wait","in":"query","required":false,"schema":{"type":"number","maximum":25.0,"minimum":0.0,"default":0.0,"title":"Wait"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RunProgressResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"x-beryl-ci-token":true}},"/api/v1/workspaces/{workspace_id}/projects/{project_id}/runs/{run_id}/stream":{"get":{"tags":["runs"],"summary":"Stream Run","operationId":"stream_run_api_v1_workspaces__workspace_id__projects__project_id__runs__run_id__stream_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"run_id","in":"path","required":true,"schema":{"type":"string","title":"Run Id"}},{"name":"workspace_id","in":"path","required":true,"schema":{"type":"string","title":"Workspace Id"}},{"name":"project_id","in":"path","required":true,"schema":{"type":"string","title":"Project Id"}}],"responses":{"200":{"description":"Server-sent event stream","content":{"text/event-stream":{"schema":{"type":"string"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"x-beryl-ci-token":true,"description":"Accepts a project-scoped CI token as well as a personal access token."}},"/api/v1/workspaces/{workspace_id}/projects/{project_id}/explorations/{exploration_id}/stream":{"get":{"tags":["runs"],"summary":"Stream Exploration","description":"Live SSE feed of one exploration: the agent's steps as it explores + authors,\nending on the handoff to a deterministic run. Replays the steps recorded so far\n(so a reconnect / late join sees the whole pass), then subscribes to live deltas.","operationId":"stream_exploration_api_v1_workspaces__workspace_id__projects__project_id__explorations__exploration_id__stream_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"exploration_id","in":"path","required":true,"schema":{"type":"string","title":"Exploration Id"}},{"name":"workspace_id","in":"path","required":true,"schema":{"type":"string","title":"Workspace Id"}},{"name":"project_id","in":"path","required":true,"schema":{"type":"string","title":"Project Id"}}],"responses":{"200":{"description":"Server-sent event stream","content":{"text/event-stream":{"schema":{"type":"string"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/workspaces/{workspace_id}/projects/{project_id}/runs/{run_id}/report":{"get":{"tags":["runs"],"summary":"Get Report","operationId":"get_report_api_v1_workspaces__workspace_id__projects__project_id__runs__run_id__report_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"workspace_id","in":"path","required":true,"schema":{"type":"string","title":"Workspace Id"}},{"name":"project_id","in":"path","required":true,"schema":{"type":"string","title":"Project Id"}},{"name":"run_id","in":"path","required":true,"schema":{"type":"string","title":"Run Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TestRunReportResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/workspaces/{workspace_id}/projects/{project_id}/runs/{run_id}/download":{"get":{"tags":["runs"],"summary":"Download Run","description":"Self-contained JSON bundle for one run: run metadata, per-test result\nsummaries, and presigned artifact URLs — everything needed to save or inspect\nthe run offline. Reuses the same presign path as the run-detail view so\nprivate-bucket artifacts resolve to fresh time-limited URLs.","operationId":"download_run_api_v1_workspaces__workspace_id__projects__project_id__runs__run_id__download_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"workspace_id","in":"path","required":true,"schema":{"type":"string","title":"Workspace Id"}},{"name":"project_id","in":"path","required":true,"schema":{"type":"string","title":"Project Id"}},{"name":"run_id","in":"path","required":true,"schema":{"type":"string","title":"Run Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RunDownloadResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/workspaces/{workspace_id}/projects/{project_id}/explorations":{"get":{"tags":["jobs"],"summary":"List Explorations","operationId":"list_explorations_api_v1_workspaces__workspace_id__projects__project_id__explorations_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"workspace_id","in":"path","required":true,"schema":{"type":"string","title":"Workspace Id"}},{"name":"project_id","in":"path","required":true,"schema":{"type":"string","title":"Project Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/ExplorationListItem"},"title":"Response List Explorations Api V1 Workspaces  Workspace Id  Projects  Project Id  Explorations Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/workspaces/{workspace_id}/projects/{project_id}/explorations/{exploration_id}":{"get":{"tags":["jobs"],"summary":"Get Exploration","operationId":"get_exploration_api_v1_workspaces__workspace_id__projects__project_id__explorations__exploration_id__get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"workspace_id","in":"path","required":true,"schema":{"type":"string","title":"Workspace Id"}},{"name":"project_id","in":"path","required":true,"schema":{"type":"string","title":"Project Id"}},{"name":"exploration_id","in":"path","required":true,"schema":{"type":"string","title":"Exploration Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExplorationDetail"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/workspaces/{workspace_id}/projects/{project_id}/explorations/{exploration_id}/cancel":{"post":{"tags":["jobs"],"summary":"Cancel Exploration","description":"Cancel an in-flight exploration.\n\nFlips the row running→cancelled (the scoped UPDATE is the cross-process signal:\nthe worker's claim heartbeat sees the terminal flip and stops the agent loop within\none heartbeat interval; the in-process event covers the worker-in-API case\nimmediately). Idempotent against a concurrent finish: losing the race to a terminal\nstate is a 409, same contract as run cancel.","operationId":"cancel_exploration_api_v1_workspaces__workspace_id__projects__project_id__explorations__exploration_id__cancel_post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"workspace_id","in":"path","required":true,"schema":{"type":"string","title":"Workspace Id"}},{"name":"project_id","in":"path","required":true,"schema":{"type":"string","title":"Project Id"}},{"name":"exploration_id","in":"path","required":true,"schema":{"type":"string","title":"Exploration Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExplorationListItem"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/workspaces/{workspace_id}/projects/{project_id}/explorations/{exploration_id}/steps":{"get":{"tags":["jobs"],"summary":"List Exploration Steps","operationId":"list_exploration_steps_api_v1_workspaces__workspace_id__projects__project_id__explorations__exploration_id__steps_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"workspace_id","in":"path","required":true,"schema":{"type":"string","title":"Workspace Id"}},{"name":"project_id","in":"path","required":true,"schema":{"type":"string","title":"Project Id"}},{"name":"exploration_id","in":"path","required":true,"schema":{"type":"string","title":"Exploration Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/ExplorationStepResponse"},"title":"Response List Exploration Steps Api V1 Workspaces  Workspace Id  Projects  Project Id  Explorations  Exploration Id  Steps Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/workspaces/{workspace_id}/projects/{project_id}/test-creation-jobs":{"post":{"tags":["jobs"],"summary":"Create Creation Job","description":"Queue a test-creation job. The prompt and document are sent to the LLM.\n\nAccepts a project-scoped CI token as well as a personal access token.","operationId":"create_creation_job_api_v1_workspaces__workspace_id__projects__project_id__test_creation_jobs_post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"workspace_id","in":"path","required":true,"schema":{"type":"string","title":"Workspace Id"}},{"name":"project_id","in":"path","required":true,"schema":{"type":"string","title":"Project Id"}}],"requestBody":{"content":{"multipart/form-data":{"schema":{"$ref":"#/components/schemas/Body_create_creation_job_api_v1_workspaces__workspace_id__projects__project_id__test_creation_jobs_post"}}}},"responses":{"202":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TestCreationJobItem"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"x-beryl-ci-token":true},"get":{"tags":["jobs"],"summary":"List Creation Jobs","operationId":"list_creation_jobs_api_v1_workspaces__workspace_id__projects__project_id__test_creation_jobs_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"workspace_id","in":"path","required":true,"schema":{"type":"string","title":"Workspace Id"}},{"name":"project_id","in":"path","required":true,"schema":{"type":"string","title":"Project Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/TestCreationJobItem"},"title":"Response List Creation Jobs Api V1 Workspaces  Workspace Id  Projects  Project Id  Test Creation Jobs Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"x-beryl-ci-token":true,"description":"Accepts a project-scoped CI token as well as a personal access token."}},"/api/v1/workspaces/{workspace_id}/projects/{project_id}/test-creation-jobs/{job_id}":{"get":{"tags":["jobs"],"summary":"Get Creation Job","operationId":"get_creation_job_api_v1_workspaces__workspace_id__projects__project_id__test_creation_jobs__job_id__get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"job_id","in":"path","required":true,"schema":{"type":"string","title":"Job Id"}},{"name":"workspace_id","in":"path","required":true,"schema":{"type":"string","title":"Workspace Id"}},{"name":"project_id","in":"path","required":true,"schema":{"type":"string","title":"Project Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TestCreationJobDetail"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"x-beryl-ci-token":true,"description":"Accepts a project-scoped CI token as well as a personal access token."},"delete":{"tags":["jobs"],"summary":"Delete Creation Job","description":"Delete the job. The flows and Tests it created stay.","operationId":"delete_creation_job_api_v1_workspaces__workspace_id__projects__project_id__test_creation_jobs__job_id__delete","security":[{"HTTPBearer":[]}],"parameters":[{"name":"job_id","in":"path","required":true,"schema":{"type":"string","title":"Job Id"}},{"name":"workspace_id","in":"path","required":true,"schema":{"type":"string","title":"Workspace Id"}},{"name":"project_id","in":"path","required":true,"schema":{"type":"string","title":"Project Id"}}],"responses":{"204":{"description":"Successful Response"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/workspaces/{workspace_id}/projects/{project_id}/test-creation-jobs/{job_id}/clone":{"post":{"tags":["jobs"],"summary":"Clone Creation Job","description":"Queue a new job with this job's prompt, document, environment, account and mode.\n\nAccepts a project-scoped CI token as well as a personal access token.","operationId":"clone_creation_job_api_v1_workspaces__workspace_id__projects__project_id__test_creation_jobs__job_id__clone_post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"job_id","in":"path","required":true,"schema":{"type":"string","title":"Job Id"}},{"name":"workspace_id","in":"path","required":true,"schema":{"type":"string","title":"Workspace Id"}},{"name":"project_id","in":"path","required":true,"schema":{"type":"string","title":"Project Id"}}],"responses":{"202":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TestCreationJobItem"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"x-beryl-ci-token":true}},"/api/v1/workspaces/{workspace_id}/projects/{project_id}/test-creation-jobs/{job_id}/retry":{"post":{"tags":["jobs"],"summary":"Retry Creation Job","description":"Queue a job that authors only what this one left without a test: its gaps and\nskipped scenarios, on the surfaces that miss them. The prompt and document are sent\nto the LLM.\n\nAccepts a project-scoped CI token as well as a personal access token.","operationId":"retry_creation_job_api_v1_workspaces__workspace_id__projects__project_id__test_creation_jobs__job_id__retry_post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"job_id","in":"path","required":true,"schema":{"type":"string","title":"Job Id"}},{"name":"workspace_id","in":"path","required":true,"schema":{"type":"string","title":"Workspace Id"}},{"name":"project_id","in":"path","required":true,"schema":{"type":"string","title":"Project Id"}}],"requestBody":{"content":{"application/json":{"schema":{"anyOf":[{"$ref":"#/components/schemas/TestCreationJobRetry"},{"type":"null"}],"title":"Body"}}}},"responses":{"202":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TestCreationJobItem"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"x-beryl-ci-token":true}},"/api/v1/workspaces/{workspace_id}/projects/{project_id}/config/variables":{"get":{"tags":["config"],"summary":"List Variables","description":"All variables for the project. Each item flags its scope: ``environment_id``\nnull = project-level (all environments), set = pinned to that environment.","operationId":"list_variables_api_v1_workspaces__workspace_id__projects__project_id__config_variables_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"workspace_id","in":"path","required":true,"schema":{"type":"string","title":"Workspace Id"}},{"name":"project_id","in":"path","required":true,"schema":{"type":"string","title":"Project Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/VariableResponse"},"title":"Response List Variables Api V1 Workspaces  Workspace Id  Projects  Project Id  Config Variables Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"post":{"tags":["config"],"summary":"Create Variable","description":"Create a plaintext variable. 409 if the key already exists in the same scope.","operationId":"create_variable_api_v1_workspaces__workspace_id__projects__project_id__config_variables_post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"workspace_id","in":"path","required":true,"schema":{"type":"string","title":"Workspace Id"}},{"name":"project_id","in":"path","required":true,"schema":{"type":"string","title":"Project Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VariableCreate"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VariableResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/workspaces/{workspace_id}/projects/{project_id}/config/variables/{variable_id}":{"put":{"tags":["config"],"summary":"Update Variable","description":"Update a variable's value.","operationId":"update_variable_api_v1_workspaces__workspace_id__projects__project_id__config_variables__variable_id__put","security":[{"HTTPBearer":[]}],"parameters":[{"name":"variable_id","in":"path","required":true,"schema":{"type":"string","title":"Variable Id"}},{"name":"workspace_id","in":"path","required":true,"schema":{"type":"string","title":"Workspace Id"}},{"name":"project_id","in":"path","required":true,"schema":{"type":"string","title":"Project Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VariableUpdate"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VariableResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"patch":{"tags":["config"],"summary":"Update Variable","description":"Update a variable's value.","operationId":"update_variable_api_v1_workspaces__workspace_id__projects__project_id__config_variables__variable_id__patch","security":[{"HTTPBearer":[]}],"parameters":[{"name":"variable_id","in":"path","required":true,"schema":{"type":"string","title":"Variable Id"}},{"name":"workspace_id","in":"path","required":true,"schema":{"type":"string","title":"Workspace Id"}},{"name":"project_id","in":"path","required":true,"schema":{"type":"string","title":"Project Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VariableUpdate"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VariableResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["config"],"summary":"Delete Variable","operationId":"delete_variable_api_v1_workspaces__workspace_id__projects__project_id__config_variables__variable_id__delete","security":[{"HTTPBearer":[]}],"parameters":[{"name":"variable_id","in":"path","required":true,"schema":{"type":"string","title":"Variable Id"}},{"name":"workspace_id","in":"path","required":true,"schema":{"type":"string","title":"Workspace Id"}},{"name":"project_id","in":"path","required":true,"schema":{"type":"string","title":"Project Id"}}],"responses":{"204":{"description":"Successful Response"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/workspaces/{workspace_id}/projects/{project_id}/config/secrets":{"get":{"tags":["config"],"summary":"List Secrets","description":"Secret METADATA only — id, key, scope, timestamps. Never the value.","operationId":"list_secrets_api_v1_workspaces__workspace_id__projects__project_id__config_secrets_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"workspace_id","in":"path","required":true,"schema":{"type":"string","title":"Workspace Id"}},{"name":"project_id","in":"path","required":true,"schema":{"type":"string","title":"Project Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/SecretResponse"},"title":"Response List Secrets Api V1 Workspaces  Workspace Id  Projects  Project Id  Config Secrets Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"post":{"tags":["config"],"summary":"Upsert Secret","description":"Create or overwrite a secret. The value is Fernet-encrypted at rest and the\nresponse carries metadata only — the plaintext is never returned.","operationId":"upsert_secret_api_v1_workspaces__workspace_id__projects__project_id__config_secrets_post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"workspace_id","in":"path","required":true,"schema":{"type":"string","title":"Workspace Id"}},{"name":"project_id","in":"path","required":true,"schema":{"type":"string","title":"Project Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecretCreate"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecretResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/workspaces/{workspace_id}/projects/{project_id}/config/secrets/{secret_id}/value":{"get":{"tags":["config"],"summary":"Reveal Secret","description":"The decrypted value, by secret id or key — the explicit read that lets the\naccount's own agent drive a real login while authoring. Member-gated and logged\nwith the requesting user; list/get remain metadata-only.","operationId":"reveal_secret_api_v1_workspaces__workspace_id__projects__project_id__config_secrets__secret_id__value_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"secret_id","in":"path","required":true,"schema":{"type":"string","title":"Secret Id"}},{"name":"workspace_id","in":"path","required":true,"schema":{"type":"string","title":"Workspace Id"}},{"name":"project_id","in":"path","required":true,"schema":{"type":"string","title":"Project Id"}},{"name":"environment_id","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Prefer the row scoped to this environment when the key exists at both scopes — matches what a run against that environment resolves.","title":"Environment Id"},"description":"Prefer the row scoped to this environment when the key exists at both scopes — matches what a run against that environment resolves."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecretValueResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/workspaces/{workspace_id}/projects/{project_id}/config/secrets/{secret_id}":{"delete":{"tags":["config"],"summary":"Delete Secret","operationId":"delete_secret_api_v1_workspaces__workspace_id__projects__project_id__config_secrets__secret_id__delete","security":[{"HTTPBearer":[]}],"parameters":[{"name":"secret_id","in":"path","required":true,"schema":{"type":"string","title":"Secret Id"}},{"name":"workspace_id","in":"path","required":true,"schema":{"type":"string","title":"Workspace Id"}},{"name":"project_id","in":"path","required":true,"schema":{"type":"string","title":"Project Id"}}],"responses":{"204":{"description":"Successful Response"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/workspaces/{workspace_id}/projects/{project_id}/config/signing/android":{"get":{"tags":["config"],"summary":"Get Android Signing","description":"Which key signs Android builds converted from an .aab, with its fingerprints.\nBeryl's key for the project is generated on first read.","operationId":"get_android_signing_api_v1_workspaces__workspace_id__projects__project_id__config_signing_android_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"workspace_id","in":"path","required":true,"schema":{"type":"string","title":"Workspace Id"}},{"name":"project_id","in":"path","required":true,"schema":{"type":"string","title":"Project Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AndroidSigningResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"put":{"tags":["config"],"summary":"Set Android Signing","description":"Sign converted builds with the customer's own key. The keystore is opened with\nthe passwords here, so a wrong one fails now; it is encrypted at rest and never\nreturned.","operationId":"set_android_signing_api_v1_workspaces__workspace_id__projects__project_id__config_signing_android_put","security":[{"HTTPBearer":[]}],"parameters":[{"name":"workspace_id","in":"path","required":true,"schema":{"type":"string","title":"Workspace Id"}},{"name":"project_id","in":"path","required":true,"schema":{"type":"string","title":"Project Id"}}],"requestBody":{"required":true,"content":{"multipart/form-data":{"schema":{"$ref":"#/components/schemas/Body_set_android_signing_api_v1_workspaces__workspace_id__projects__project_id__config_signing_android_put"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AndroidSigningResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["config"],"summary":"Clear Android Signing","description":"Forget the customer's keystore; converted builds go back to Beryl's key.","operationId":"clear_android_signing_api_v1_workspaces__workspace_id__projects__project_id__config_signing_android_delete","security":[{"HTTPBearer":[]}],"parameters":[{"name":"workspace_id","in":"path","required":true,"schema":{"type":"string","title":"Workspace Id"}},{"name":"project_id","in":"path","required":true,"schema":{"type":"string","title":"Project Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AndroidSigningResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/workspaces/{workspace_id}/projects/{project_id}/config/files":{"get":{"tags":["config"],"summary":"List Files","description":"File metadata for the project (size is null on list — not persisted).","operationId":"list_files_api_v1_workspaces__workspace_id__projects__project_id__config_files_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"workspace_id","in":"path","required":true,"schema":{"type":"string","title":"Workspace Id"}},{"name":"project_id","in":"path","required":true,"schema":{"type":"string","title":"Project Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/FileResponse"},"title":"Response List Files Api V1 Workspaces  Workspace Id  Projects  Project Id  Config Files Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"post":{"tags":["config"],"summary":"Upload File","description":"Upload a file to storage and persist its metadata (name, content-type, key).","operationId":"upload_file_api_v1_workspaces__workspace_id__projects__project_id__config_files_post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"workspace_id","in":"path","required":true,"schema":{"type":"string","title":"Workspace Id"}},{"name":"project_id","in":"path","required":true,"schema":{"type":"string","title":"Project Id"}}],"requestBody":{"required":true,"content":{"multipart/form-data":{"schema":{"$ref":"#/components/schemas/Body_upload_file_api_v1_workspaces__workspace_id__projects__project_id__config_files_post"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/FileResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/workspaces/{workspace_id}/projects/{project_id}/config/files/uploads":{"post":{"tags":["config"],"summary":"Create File Upload","description":"Start a direct-to-storage upload (any size up to the cap, iOS builds included):\nPUT the bytes to the returned URL, then call complete.","operationId":"create_file_upload_api_v1_workspaces__workspace_id__projects__project_id__config_files_uploads_post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"workspace_id","in":"path","required":true,"schema":{"type":"string","title":"Workspace Id"}},{"name":"project_id","in":"path","required":true,"schema":{"type":"string","title":"Project Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/FileUploadRequest"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/FileUploadResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/workspaces/{workspace_id}/projects/{project_id}/config/files/uploads/{file_id}/complete":{"post":{"tags":["config"],"summary":"Complete File Upload","description":"Confirm an upload. An iOS build is read here: its bundle id and version are\nrecorded, and a build that cannot run on a simulator is refused and deleted.","operationId":"complete_file_upload_api_v1_workspaces__workspace_id__projects__project_id__config_files_uploads__file_id__complete_post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"file_id","in":"path","required":true,"schema":{"type":"string","title":"File Id"}},{"name":"workspace_id","in":"path","required":true,"schema":{"type":"string","title":"Workspace Id"}},{"name":"project_id","in":"path","required":true,"schema":{"type":"string","title":"Project Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/FileResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/workspaces/{workspace_id}/projects/{project_id}/config/files/{file_id}/download":{"get":{"tags":["config"],"summary":"Download File","description":"Return a time-limited presigned GET URL for the file's blob.","operationId":"download_file_api_v1_workspaces__workspace_id__projects__project_id__config_files__file_id__download_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"file_id","in":"path","required":true,"schema":{"type":"string","title":"File Id"}},{"name":"workspace_id","in":"path","required":true,"schema":{"type":"string","title":"Workspace Id"}},{"name":"project_id","in":"path","required":true,"schema":{"type":"string","title":"Project Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/FileDownloadResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/workspaces/{workspace_id}/projects/{project_id}/config/files/{file_id}":{"delete":{"tags":["config"],"summary":"Delete File","description":"Delete the file row; best-effort removal of the underlying blob.","operationId":"delete_file_api_v1_workspaces__workspace_id__projects__project_id__config_files__file_id__delete","security":[{"HTTPBearer":[]}],"parameters":[{"name":"file_id","in":"path","required":true,"schema":{"type":"string","title":"File Id"}},{"name":"workspace_id","in":"path","required":true,"schema":{"type":"string","title":"Workspace Id"}},{"name":"project_id","in":"path","required":true,"schema":{"type":"string","title":"Project Id"}}],"responses":{"204":{"description":"Successful Response"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/workspaces/{workspace_id}/projects/{project_id}/ci/tokens":{"post":{"tags":["ci"],"summary":"Create Ci Token","operationId":"create_ci_token_api_v1_workspaces__workspace_id__projects__project_id__ci_tokens_post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"workspace_id","in":"path","required":true,"schema":{"type":"string","title":"Workspace Id"}},{"name":"project_id","in":"path","required":true,"schema":{"type":"string","title":"Project Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CiTokenCreateRequest"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CiTokenCreatedResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"get":{"tags":["ci"],"summary":"List Ci Tokens","operationId":"list_ci_tokens_api_v1_workspaces__workspace_id__projects__project_id__ci_tokens_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"workspace_id","in":"path","required":true,"schema":{"type":"string","title":"Workspace Id"}},{"name":"project_id","in":"path","required":true,"schema":{"type":"string","title":"Project Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/CiTokenResponse"},"title":"Response List Ci Tokens Api V1 Workspaces  Workspace Id  Projects  Project Id  Ci Tokens Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/workspaces/{workspace_id}/projects/{project_id}/ci/tokens/{token_id}":{"delete":{"tags":["ci"],"summary":"Revoke Ci Token","operationId":"revoke_ci_token_api_v1_workspaces__workspace_id__projects__project_id__ci_tokens__token_id__delete","security":[{"HTTPBearer":[]}],"parameters":[{"name":"token_id","in":"path","required":true,"schema":{"type":"string","title":"Token Id"}},{"name":"workspace_id","in":"path","required":true,"schema":{"type":"string","title":"Workspace Id"}},{"name":"project_id","in":"path","required":true,"schema":{"type":"string","title":"Project Id"}}],"responses":{"204":{"description":"Successful Response"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/workspaces/{workspace_id}/projects/{project_id}/ci/workflows":{"get":{"tags":["ci"],"summary":"List Ci Workflows","operationId":"list_ci_workflows_api_v1_workspaces__workspace_id__projects__project_id__ci_workflows_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"workspace_id","in":"path","required":true,"schema":{"type":"string","title":"Workspace Id"}},{"name":"project_id","in":"path","required":true,"schema":{"type":"string","title":"Project Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/CiWorkflowResponse"},"title":"Response List Ci Workflows Api V1 Workspaces  Workspace Id  Projects  Project Id  Ci Workflows Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"post":{"tags":["ci"],"summary":"Create Ci Workflow","operationId":"create_ci_workflow_api_v1_workspaces__workspace_id__projects__project_id__ci_workflows_post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"workspace_id","in":"path","required":true,"schema":{"type":"string","title":"Workspace Id"}},{"name":"project_id","in":"path","required":true,"schema":{"type":"string","title":"Project Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CiWorkflowWriteRequest"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CiWorkflowResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/workspaces/{workspace_id}/projects/{project_id}/ci/workflows/{workflow_id}":{"put":{"tags":["ci"],"summary":"Update Ci Workflow","operationId":"update_ci_workflow_api_v1_workspaces__workspace_id__projects__project_id__ci_workflows__workflow_id__put","security":[{"HTTPBearer":[]}],"parameters":[{"name":"workflow_id","in":"path","required":true,"schema":{"type":"string","title":"Workflow Id"}},{"name":"workspace_id","in":"path","required":true,"schema":{"type":"string","title":"Workspace Id"}},{"name":"project_id","in":"path","required":true,"schema":{"type":"string","title":"Project Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CiWorkflowWriteRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CiWorkflowResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["ci"],"summary":"Delete Ci Workflow","operationId":"delete_ci_workflow_api_v1_workspaces__workspace_id__projects__project_id__ci_workflows__workflow_id__delete","security":[{"HTTPBearer":[]}],"parameters":[{"name":"workflow_id","in":"path","required":true,"schema":{"type":"string","title":"Workflow Id"}},{"name":"workspace_id","in":"path","required":true,"schema":{"type":"string","title":"Workspace Id"}},{"name":"project_id","in":"path","required":true,"schema":{"type":"string","title":"Project Id"}}],"responses":{"204":{"description":"Successful Response"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/workspaces/{workspace_id}/mailboxes":{"post":{"tags":["mailboxes"],"summary":"Create Mailbox","description":"Add a mailbox to a project.\n\nMost projects need exactly one, created on demand by whatever first reads\n``{{mailbox_address}}``. Create a second only when a flow needs two genuinely\nseparate inboxes at the same time — both sides of an invite handshake. For an\naddress the site has not seen before, use a ``+tag`` alias of an existing mailbox\ninstead; it costs no row and receives into the same place.","operationId":"create_mailbox_api_v1_workspaces__workspace_id__mailboxes_post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"workspace_id","in":"path","required":true,"schema":{"type":"string","title":"Workspace Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MailboxCreate"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/app__email_inbox__schemas__MailboxResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"get":{"tags":["mailboxes"],"summary":"List Mailboxes","operationId":"list_mailboxes_api_v1_workspaces__workspace_id__mailboxes_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"workspace_id","in":"path","required":true,"schema":{"type":"string","title":"Workspace Id"}},{"name":"project_id","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Only this project's mailboxes","title":"Project Id"},"description":"Only this project's mailboxes"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/app__email_inbox__schemas__MailboxResponse"},"title":"Response List Mailboxes Api V1 Workspaces  Workspace Id  Mailboxes Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/workspaces/{workspace_id}/mailboxes/identities":{"get":{"tags":["mailboxes"],"summary":"List Minted Identities","operationId":"list_minted_identities_api_v1_workspaces__workspace_id__mailboxes_identities_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"workspace_id","in":"path","required":true,"schema":{"type":"string","title":"Workspace Id"}},{"name":"project_id","in":"query","required":true,"schema":{"type":"string","description":"The project whose minted addresses to list","title":"Project Id"},"description":"The project whose minted addresses to list"},{"name":"run_id","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Only this run's","title":"Run Id"},"description":"Only this run's"},{"name":"test_id","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Only this test's","title":"Test Id"},"description":"Only this test's"},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":500,"minimum":1,"default":100,"title":"Limit"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/MintedIdentityResponse"},"title":"Response List Minted Identities Api V1 Workspaces  Workspace Id  Mailboxes Identities Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/workspaces/{workspace_id}/mailboxes/{mailbox_id}":{"delete":{"tags":["mailboxes"],"summary":"Delete Mailbox","description":"Delete a mailbox and every email it holds.\n\nDestructive in a way an expiring inbox never was: the address is configured into the\nsite under test, so removing it breaks every test that signs in through it.","operationId":"delete_mailbox_api_v1_workspaces__workspace_id__mailboxes__mailbox_id__delete","security":[{"HTTPBearer":[]}],"parameters":[{"name":"workspace_id","in":"path","required":true,"schema":{"type":"string","title":"Workspace Id"}},{"name":"mailbox_id","in":"path","required":true,"schema":{"type":"string","title":"Mailbox Id"}}],"responses":{"204":{"description":"Successful Response"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/workspaces/{workspace_id}/mailboxes/{mailbox_id}/emails":{"get":{"tags":["mailboxes"],"summary":"List Mailbox Emails","operationId":"list_mailbox_emails_api_v1_workspaces__workspace_id__mailboxes__mailbox_id__emails_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"workspace_id","in":"path","required":true,"schema":{"type":"string","title":"Workspace Id"}},{"name":"mailbox_id","in":"path","required":true,"schema":{"type":"string","title":"Mailbox Id"}},{"name":"since","in":"query","required":false,"schema":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Since"}},{"name":"limit","in":"query","required":false,"schema":{"anyOf":[{"type":"integer","maximum":100,"minimum":1},{"type":"null"}],"description":"Return only the most recent N emails (newest first)","title":"Limit"},"description":"Return only the most recent N emails (newest first)"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InboxEmailsResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/workspaces/{workspace_id}/mailboxes/{mailbox_id}/emails/latest":{"get":{"tags":["mailboxes"],"summary":"Fetch Latest Mailbox Email","operationId":"fetch_latest_mailbox_email_api_v1_workspaces__workspace_id__mailboxes__mailbox_id__emails_latest_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"workspace_id","in":"path","required":true,"schema":{"type":"string","title":"Workspace Id"}},{"name":"mailbox_id","in":"path","required":true,"schema":{"type":"string","title":"Mailbox Id"}},{"name":"timeout_s","in":"query","required":false,"schema":{"type":"integer","maximum":50,"minimum":0,"description":"0 = do not block","default":30,"title":"Timeout S"},"description":"0 = do not block"},{"name":"since","in":"query","required":false,"schema":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Since"}},{"name":"stored_after","in":"query","required":false,"schema":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"description":"Only mail INGESTED after this. Prefer it over `since` for a run watermark: `since` filters on the sender's Date: header, so a caller whose clock runs fast can fence out mail that really did arrive. Clamped to server time","title":"Stored After"},"description":"Only mail INGESTED after this. Prefer it over `since` for a run watermark: `since` filters on the sender's Date: header, so a caller whose clock runs fast can fence out mail that really did arrive. Clamped to server time"},{"name":"from_contains","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"From Contains"}},{"name":"subject_contains","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Subject Contains"}},{"name":"recipient_contains","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Only mail delivered to an address containing this — how +tag aliases sharing this mailbox tell their mail apart","title":"Recipient Contains"},"description":"Only mail delivered to an address containing this — how +tag aliases sharing this mailbox tell their mail apart"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InboundEmailResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/workspaces/{workspace_id}/mailboxes/{mailbox_id}/emails/{email_id}/extract":{"post":{"tags":["mailboxes"],"summary":"Extract From Email","operationId":"extract_from_email_api_v1_workspaces__workspace_id__mailboxes__mailbox_id__emails__email_id__extract_post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"workspace_id","in":"path","required":true,"schema":{"type":"string","title":"Workspace Id"}},{"name":"mailbox_id","in":"path","required":true,"schema":{"type":"string","title":"Mailbox Id"}},{"name":"email_id","in":"path","required":true,"schema":{"type":"string","title":"Email Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmailExtractRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmailExtractResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/workspaces/{workspace_id}/projects/{project_id}/mailbox":{"get":{"tags":["accounts"],"summary":"Get Mailbox","description":"The project's durable mailbox, minting it if this is the first ask.\n\nGet-or-create rather than a plain read: an agent asking for the address always wants\na usable one, and there is nothing to configure about a mailbox.","operationId":"get_mailbox_api_v1_workspaces__workspace_id__projects__project_id__mailbox_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"workspace_id","in":"path","required":true,"schema":{"type":"string","title":"Workspace Id"}},{"name":"project_id","in":"path","required":true,"schema":{"type":"string","title":"Project Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/app__test_accounts__schemas__MailboxResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/workspaces/{workspace_id}/projects/{project_id}/test-accounts":{"get":{"tags":["accounts"],"summary":"List Test Accounts","operationId":"list_test_accounts_api_v1_workspaces__workspace_id__projects__project_id__test_accounts_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"workspace_id","in":"path","required":true,"schema":{"type":"string","title":"Workspace Id"}},{"name":"project_id","in":"path","required":true,"schema":{"type":"string","title":"Project Id"}},{"name":"environment_id","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Environment Id"}},{"name":"throwaway_limit","in":"query","required":false,"schema":{"type":"integer","maximum":500,"minimum":0,"description":"How many of the newest throwaway accounts test executions created","default":50,"title":"Throwaway Limit"},"description":"How many of the newest throwaway accounts test executions created"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/TestAccountResponse"},"title":"Response List Test Accounts Api V1 Workspaces  Workspace Id  Projects  Project Id  Test Accounts Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"post":{"tags":["accounts"],"summary":"Create Test Account","operationId":"create_test_account_api_v1_workspaces__workspace_id__projects__project_id__test_accounts_post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"workspace_id","in":"path","required":true,"schema":{"type":"string","title":"Workspace Id"}},{"name":"project_id","in":"path","required":true,"schema":{"type":"string","title":"Project Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TestAccountCreate"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TestAccountResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/workspaces/{workspace_id}/projects/{project_id}/test-accounts/captured":{"put":{"tags":["accounts"],"summary":"Capture Test Account","description":"Store a session captured with the Beryl Chrome extension as a captured account.\n\nOnly stores: prove it with `POST /test-accounts/{id}/check` once a probe is set.","operationId":"capture_test_account_api_v1_workspaces__workspace_id__projects__project_id__test_accounts_captured_put","security":[{"HTTPBearer":[]}],"parameters":[{"name":"workspace_id","in":"path","required":true,"schema":{"type":"string","title":"Workspace Id"}},{"name":"project_id","in":"path","required":true,"schema":{"type":"string","title":"Project Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TestAccountCapture"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TestAccountCaptureResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/workspaces/{workspace_id}/projects/{project_id}/test-accounts/{account_id}":{"get":{"tags":["accounts"],"summary":"Get Test Account","operationId":"get_test_account_api_v1_workspaces__workspace_id__projects__project_id__test_accounts__account_id__get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"account_id","in":"path","required":true,"schema":{"type":"string","title":"Account Id"}},{"name":"workspace_id","in":"path","required":true,"schema":{"type":"string","title":"Workspace Id"}},{"name":"project_id","in":"path","required":true,"schema":{"type":"string","title":"Project Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TestAccountResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"patch":{"tags":["accounts"],"summary":"Update Test Account","operationId":"update_test_account_api_v1_workspaces__workspace_id__projects__project_id__test_accounts__account_id__patch","security":[{"HTTPBearer":[]}],"parameters":[{"name":"account_id","in":"path","required":true,"schema":{"type":"string","title":"Account Id"}},{"name":"workspace_id","in":"path","required":true,"schema":{"type":"string","title":"Workspace Id"}},{"name":"project_id","in":"path","required":true,"schema":{"type":"string","title":"Project Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TestAccountUpdate"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TestAccountResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["accounts"],"summary":"Delete Test Account","operationId":"delete_test_account_api_v1_workspaces__workspace_id__projects__project_id__test_accounts__account_id__delete","security":[{"HTTPBearer":[]}],"parameters":[{"name":"account_id","in":"path","required":true,"schema":{"type":"string","title":"Account Id"}},{"name":"workspace_id","in":"path","required":true,"schema":{"type":"string","title":"Workspace Id"}},{"name":"project_id","in":"path","required":true,"schema":{"type":"string","title":"Project Id"}}],"responses":{"204":{"description":"Successful Response"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/workspaces/{workspace_id}/projects/{project_id}/test-accounts/{account_id}/signup":{"post":{"tags":["accounts"],"summary":"Signup Test Account","description":"Store the account's signup plan and sign it up on its environment now.\n\nBlocks for the length of a browser replay — the same cost as banking one test. A green\nreplay flips the account to READY; a failed one only condemns an account that was\nnever proven, so re-running a working account cannot destroy it.","operationId":"signup_test_account_api_v1_workspaces__workspace_id__projects__project_id__test_accounts__account_id__signup_post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"account_id","in":"path","required":true,"schema":{"type":"string","title":"Account Id"}},{"name":"workspace_id","in":"path","required":true,"schema":{"type":"string","title":"Workspace Id"}},{"name":"project_id","in":"path","required":true,"schema":{"type":"string","title":"Project Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TestAccountSignup"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TestAccountResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/workspaces/{workspace_id}/projects/{project_id}/test-accounts/{account_id}/login":{"put":{"tags":["accounts"],"summary":"Set Account Login","description":"Store the sign-in plan a session-mode run replays, plus the probe that proves it.\n\nWrite-then-check, not write-and-hope: this only stores. Run\n`POST /test-accounts/{id}/check` to prove it against the live app.","operationId":"set_account_login_api_v1_workspaces__workspace_id__projects__project_id__test_accounts__account_id__login_put","security":[{"HTTPBearer":[]}],"parameters":[{"name":"account_id","in":"path","required":true,"schema":{"type":"string","title":"Account Id"}},{"name":"workspace_id","in":"path","required":true,"schema":{"type":"string","title":"Workspace Id"}},{"name":"project_id","in":"path","required":true,"schema":{"type":"string","title":"Project Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TestAccountLoginWrite"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TestAccountResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"get":{"tags":["accounts"],"summary":"Get Account Login","description":"The stored sign-in plan, its probe, and the hash a safe overwrite must cite.\n\nReadable, not just writable: the login plan heals, so an agent whose only verb was\n'overwrite' would clobber a repair it never saw.","operationId":"get_account_login_api_v1_workspaces__workspace_id__projects__project_id__test_accounts__account_id__login_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"account_id","in":"path","required":true,"schema":{"type":"string","title":"Account Id"}},{"name":"workspace_id","in":"path","required":true,"schema":{"type":"string","title":"Workspace Id"}},{"name":"project_id","in":"path","required":true,"schema":{"type":"string","title":"Project Id"}},{"name":"surface","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Surface"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TestAccountLoginResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/workspaces/{workspace_id}/projects/{project_id}/test-accounts/{account_id}/session":{"post":{"tags":["accounts"],"summary":"Establish Account Session","operationId":"establish_account_session_api_v1_workspaces__workspace_id__projects__project_id__test_accounts__account_id__session_post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"account_id","in":"path","required":true,"schema":{"type":"string","title":"Account Id"}},{"name":"workspace_id","in":"path","required":true,"schema":{"type":"string","title":"Workspace Id"}},{"name":"project_id","in":"path","required":true,"schema":{"type":"string","title":"Project Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TestAccountSessionResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/workspaces/{workspace_id}/projects/{project_id}/test-accounts/{account_id}/check":{"post":{"tags":["accounts"],"summary":"Check Account Login","description":"Sign in now and prove the captured session is live in a fresh browser.\n\nBlocks for two browser replays. Green here is the same green a run gets, because it is\nthe same code path — that is the point of checking at all.","operationId":"check_account_login_api_v1_workspaces__workspace_id__projects__project_id__test_accounts__account_id__check_post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"account_id","in":"path","required":true,"schema":{"type":"string","title":"Account Id"}},{"name":"workspace_id","in":"path","required":true,"schema":{"type":"string","title":"Workspace Id"}},{"name":"project_id","in":"path","required":true,"schema":{"type":"string","title":"Project Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TestAccountCheckResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}}},"components":{"schemas":{"AccountDeleteRequest":{"properties":{"confirmation":{"type":"string","title":"Confirmation","description":"Must be 'DELETE' to confirm deletion"}},"type":"object","required":["confirmation"],"title":"AccountDeleteRequest"},"AccountDeleteResponse":{"properties":{"success":{"type":"boolean","title":"Success"},"deleted_workspaces":{"items":{"type":"string"},"type":"array","title":"Deleted Workspaces","description":"IDs of workspaces that were deleted"},"left_workspaces":{"items":{"type":"string"},"type":"array","title":"Left Workspaces","description":"IDs of workspaces user was removed from"},"message":{"type":"string","title":"Message"}},"type":"object","required":["success","message"],"title":"AccountDeleteResponse"},"AccountProfileResponse":{"properties":{"id":{"type":"string","title":"Id"},"name":{"type":"string","title":"Name"},"email":{"type":"string","title":"Email"},"is_verified":{"type":"boolean","title":"Is Verified"},"newsletter_subscribed":{"type":"boolean","title":"Newsletter Subscribed","default":true},"auth_provider":{"type":"string","enum":["google","credentials"],"title":"Auth Provider"},"created_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Created At"},"is_superadmin":{"type":"boolean","title":"Is Superadmin","default":false},"is_vibemonitor":{"type":"boolean","title":"Is Vibemonitor","default":false},"is_developer":{"type":"boolean","title":"Is Developer","default":false},"is_support":{"type":"boolean","title":"Is Support","default":false}},"type":"object","required":["id","name","email","is_verified","auth_provider"],"title":"AccountProfileResponse"},"AccountUpdateRequest":{"properties":{"name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Name"},"newsletter_subscribed":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Newsletter Subscribed"}},"type":"object","title":"AccountUpdateRequest"},"AndroidSigningResponse":{"properties":{"mode":{"type":"string","enum":["beryl_key","customer_keystore"],"title":"Mode","description":"Which key signs Android builds converted from a bundle."},"beryl_key":{"$ref":"#/components/schemas/SigningKeyInfo","description":"Beryl's key for this project. Register its fingerprints with Google Sign-In, Firebase or Play Integrity if the app uses them."},"customer_keystore":{"anyOf":[{"$ref":"#/components/schemas/SigningKeyInfo"},{"type":"null"}],"description":"The customer's own key, when they uploaded a keystore."}},"type":"object","required":["mode","beryl_key"],"title":"AndroidSigningResponse","description":"Fingerprints only: the keystores and their passwords are never serialized."},"AppBuildWarning":{"properties":{"surface":{"type":"string","title":"Surface"},"app_id":{"type":"string","title":"App Id","description":"The environment's app id for this surface"},"uploaded_app_ids":{"items":{"type":"string"},"type":"array","title":"Uploaded App Ids","description":"App ids of the uploaded builds this environment can install for this surface"},"message":{"type":"string","title":"Message"}},"type":"object","required":["surface","app_id","uploaded_app_ids","message"],"title":"AppBuildWarning"},"BlockingWorkspace":{"properties":{"id":{"type":"string","title":"Id"},"name":{"type":"string","title":"Name"},"member_count":{"type":"integer","title":"Member Count"},"action_required":{"type":"string","title":"Action Required","description":"Action required to unblock deletion, e.g., 'Transfer ownership or remove 3 members'"}},"type":"object","required":["id","name","member_count","action_required"],"title":"BlockingWorkspace"},"Body_create_creation_job_api_v1_workspaces__workspace_id__projects__project_id__test_creation_jobs_post":{"properties":{"prompt":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Prompt","description":"What to test: the instruction the agent follows, a line is enough. Required; a CI token that sends a document may omit it and gets 'Draft a test for each scenario in the attached document'."},"file":{"anyOf":[{"type":"string","contentMediaType":"application/octet-stream"},{"type":"null"}],"title":"File","description":"An optional document: Markdown, plain text, PDF or DOCX."},"text":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Text","description":"The optional document as pasted text."},"environment_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Environment Id","description":"Environment to explore; omit for the project default."},"interactive":{"type":"boolean","title":"Interactive","description":"False for CI: the job never pauses for input (e.g. a sign-in session); it skips what is blocked and finishes. Always false for a CI token.","default":true},"account":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Account","description":"Label of the test account to sign in as; omit for the environment's default account."}},"type":"object","title":"Body_create_creation_job_api_v1_workspaces__workspace_id__projects__project_id__test_creation_jobs_post"},"Body_set_android_signing_api_v1_workspaces__workspace_id__projects__project_id__config_signing_android_put":{"properties":{"keystore":{"type":"string","contentMediaType":"application/octet-stream","title":"Keystore","description":"A JKS or PKCS12 keystore."},"store_password":{"type":"string","title":"Store Password"},"key_alias":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Key Alias","description":"The key to sign with; required when the store holds several."},"key_password":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Key Password","description":"Defaults to the store password."}},"type":"object","required":["keystore","store_password"],"title":"Body_set_android_signing_api_v1_workspaces__workspace_id__projects__project_id__config_signing_android_put"},"Body_upload_file_api_v1_workspaces__workspace_id__projects__project_id__config_files_post":{"properties":{"file":{"type":"string","contentMediaType":"application/octet-stream","title":"File","description":"The file to upload."},"environment_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Environment Id","description":"Environment to pin to; omit for project-level."}},"type":"object","required":["file"],"title":"Body_upload_file_api_v1_workspaces__workspace_id__projects__project_id__config_files_post"},"BulkAddGroupsRequest":{"properties":{"test_case_ids":{"items":{"type":"string"},"type":"array","maxItems":500,"minItems":1,"title":"Test Case Ids"},"add":{"items":{"type":"string"},"type":"array","minItems":1,"title":"Add"}},"type":"object","required":["test_case_ids","add"],"title":"BulkAddGroupsRequest","description":"Add groups to each selected test. Additive: a test keeps the groups it already\ncarries. Unknown names are rejected (422), never minted."},"BulkQuarantineRequest":{"properties":{"test_case_ids":{"items":{"type":"string"},"type":"array","maxItems":500,"minItems":1,"title":"Test Case Ids"},"quarantined":{"type":"boolean","title":"Quarantined"}},"type":"object","required":["test_case_ids","quarantined"],"title":"BulkQuarantineRequest","description":"Quarantine or release a selection. Tests already in the requested state are\ncounted as unchanged rather than rejected, so a mixed selection is one call."},"BulkTestIdsRequest":{"properties":{"test_case_ids":{"items":{"type":"string"},"type":"array","maxItems":500,"minItems":1,"title":"Test Case Ids"}},"type":"object","required":["test_case_ids"],"title":"BulkTestIdsRequest","description":"The tests a bulk action applies to. Every id must belong to the project, or the\nwhole request is rejected before anything changes."},"BulkTestsResponse":{"properties":{"updated":{"type":"integer","title":"Updated","description":"Tests whose state actually changed."}},"type":"object","required":["updated"],"title":"BulkTestsResponse"},"CancelExecutionResponse":{"properties":{"id":{"type":"string","title":"Id"},"status":{"type":"string","title":"Status"},"cancel_requested_at":{"type":"string","format":"date-time","title":"Cancel Requested At"}},"type":"object","required":["id","status","cancel_requested_at"],"title":"CancelExecutionResponse"},"CiTokenCreateRequest":{"properties":{"name":{"type":"string","maxLength":100,"minLength":1,"title":"Name"}},"type":"object","required":["name"],"title":"CiTokenCreateRequest"},"CiTokenCreatedResponse":{"properties":{"id":{"type":"string","title":"Id"},"name":{"type":"string","title":"Name"},"token_prefix":{"type":"string","title":"Token Prefix"},"created_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Created At"},"last_used_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Last Used At"},"token":{"type":"string","title":"Token"}},"type":"object","required":["id","name","token_prefix","token"],"title":"CiTokenCreatedResponse"},"CiTokenResponse":{"properties":{"id":{"type":"string","title":"Id"},"name":{"type":"string","title":"Name"},"token_prefix":{"type":"string","title":"Token Prefix"},"created_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Created At"},"last_used_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Last Used At"}},"type":"object","required":["id","name","token_prefix"],"title":"CiTokenResponse"},"CiWorkflowGroupRef":{"properties":{"id":{"type":"string","title":"Id"},"name":{"type":"string","title":"Name"}},"type":"object","required":["id","name"],"title":"CiWorkflowGroupRef"},"CiWorkflowResponse":{"properties":{"id":{"type":"string","title":"Id"},"name":{"type":"string","title":"Name"},"environment_id":{"type":"string","title":"Environment Id"},"environment_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Environment Name"},"groups":{"items":{"$ref":"#/components/schemas/CiWorkflowGroupRef"},"type":"array","title":"Groups"},"created_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Created At"}},"type":"object","required":["id","name","environment_id","groups"],"title":"CiWorkflowResponse"},"CiWorkflowWriteRequest":{"properties":{"name":{"type":"string","maxLength":100,"minLength":1,"title":"Name"},"environment_id":{"type":"string","title":"Environment Id"},"group_ids":{"items":{"type":"string"},"type":"array","title":"Group Ids"}},"type":"object","required":["name","environment_id"],"title":"CiWorkflowWriteRequest"},"CreateProjectResponse":{"properties":{"project_id":{"type":"string","title":"Project Id"},"status":{"type":"string","title":"Status"},"auth_status":{"type":"string","title":"Auth Status"}},"type":"object","required":["project_id","status","auth_status"],"title":"CreateProjectResponse","description":"auth_status: \"ready\" = auth reused, crawl started; \"needs_capture\" = login needed."},"CreateTestProjectRequest":{"properties":{"root_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Root Url"},"name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Name"},"force_new_login":{"type":"boolean","title":"Force New Login","default":false},"requires_auth_choice":{"anyOf":[{"$ref":"#/components/schemas/RequiresAuthChoice"},{"type":"null"}]},"skip_exploration":{"type":"boolean","title":"Skip Exploration","default":false}},"type":"object","title":"CreateTestProjectRequest"},"CreateTokenRequest":{"properties":{"name":{"type":"string","maxLength":100,"minLength":1,"title":"Name"},"expires_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Expires At"}},"type":"object","required":["name"],"title":"CreateTokenRequest"},"CreateTokenResponse":{"properties":{"id":{"type":"string","title":"Id"},"name":{"type":"string","title":"Name"},"token_prefix":{"type":"string","title":"Token Prefix"},"last_used_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Last Used At"},"expires_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Expires At"},"revoked_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Revoked At"},"created_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Created At"},"token":{"type":"string","title":"Token","description":"The raw token, shown only once at creation"}},"type":"object","required":["id","name","token_prefix","token"],"title":"CreateTokenResponse"},"DeletionPreviewResponse":{"properties":{"can_delete":{"type":"boolean","title":"Can Delete"},"blocking_workspaces":{"items":{"$ref":"#/components/schemas/BlockingWorkspace"},"type":"array","title":"Blocking Workspaces"},"workspaces_to_delete":{"items":{"$ref":"#/components/schemas/WorkspacePreview"},"type":"array","title":"Workspaces To Delete"},"workspaces_to_leave":{"items":{"$ref":"#/components/schemas/WorkspacePreview"},"type":"array","title":"Workspaces To Leave"},"message":{"type":"string","title":"Message"}},"type":"object","required":["can_delete","blocking_workspaces","workspaces_to_delete","workspaces_to_leave","message"],"title":"DeletionPreviewResponse"},"EmailExtract":{"type":"string","enum":["code","link","pattern"],"title":"EmailExtract"},"EmailExtractRequest":{"properties":{"extract":{"$ref":"#/components/schemas/EmailExtract","description":"What to pull out of the email: code or link","default":"code"},"extract_pattern":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Extract Pattern","description":"Legacy, ignored: a model reads the email, no regex runs"}},"type":"object","title":"EmailExtractRequest"},"EmailExtractResponse":{"properties":{"value":{"type":"string","title":"Value"},"source":{"type":"string","title":"Source"}},"type":"object","required":["value","source"],"title":"EmailExtractResponse"},"EnvironmentCreateRequest":{"properties":{"name":{"type":"string","title":"Name","description":"Display name for the environment, e.g. 'Staging'."},"root_url":{"type":"string","title":"Root Url","description":"Target URL; validated + normalized to its scope prefix."},"requires_auth_choice":{"anyOf":[{"$ref":"#/components/schemas/RequiresAuthChoice"},{"type":"null"}],"description":"Auth mode; defaults to PUBLIC (test logged-out) when omitted."}},"type":"object","required":["name","root_url"],"title":"EnvironmentCreateRequest","description":"Create an additional environment (target URL + auth answers) on a project.\nA project already seeds one default environment at creation; this adds more\n(e.g. a staging target alongside production)."},"EnvironmentResponse":{"properties":{"id":{"type":"string","title":"Id"},"project_id":{"type":"string","title":"Project Id"},"name":{"type":"string","title":"Name"},"root_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Root Url"},"app_ids":{"additionalProperties":{"type":"string"},"type":"object","title":"App Ids","description":"App id per app surface ({'android': 'com.acme.shop', 'ios': 'com.acme.Shop'}): the app whose newest uploaded build that surface's tests run"},"app_build_warnings":{"items":{"$ref":"#/components/schemas/AppBuildWarning"},"type":"array","title":"App Build Warnings","description":"App surfaces whose app id no uploaded build has, so their tests cannot run until a matching build is uploaded or the app id is changed to an uploaded one"},"status":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Status"},"unsupported_auth_type":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Unsupported Auth Type"},"failure_code":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Failure Code"},"failure_message":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Failure Message"},"requires_auth_choice":{"$ref":"#/components/schemas/RequiresAuthChoice"},"auth_last_authorised_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Auth Last Authorised At"},"site_health_viewports":{"items":{"type":"string","enum":["phone","tablet_portrait","tablet_landscape","desktop","desktop_wide"]},"type":"array","title":"Site Health Viewports","description":"Screen sizes the Site Health visual checks run at"},"site_health_tracker":{"$ref":"#/components/schemas/TrackerSettings","description":"How Site Health findings are filed as issue tracker tickets"},"site_health_runs":{"$ref":"#/components/schemas/RunSettings","description":"When Site Health runs (schedule, CI) and which pages it checks"},"site_health_runs_reset_fields":{"items":{"type":"string"},"type":"array","title":"Site Health Runs Reset Fields","description":"Stored run settings that were invalid and fell back to defaults (* = all). Scheduled and CI runs stop until the run settings are saved again"},"site_health_tracker_reset_fields":{"items":{"type":"string"},"type":"array","title":"Site Health Tracker Reset Fields","description":"Stored tracker settings that were invalid and fell back to defaults (* = all). Filing, auto-close and the digest stop until the tracker settings are saved again"},"site_health_next_run_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Site Health Next Run At","description":"Next scheduled Site Health run; null when off"},"created_at":{"type":"string","format":"date-time","title":"Created At"},"updated_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Updated At"}},"type":"object","required":["id","project_id","name","requires_auth_choice","site_health_viewports","site_health_tracker","site_health_runs","created_at"],"title":"EnvironmentResponse","description":"One environment of a project — the concrete target URL + its auth + lifecycle.\n\nDeliberately carries no session/credential blob; ``auth_last_authorised_at`` is a\ndatetime hint only. failure_detail/termination_reason stay support-scoped and are\nabsent from this customer response."},"ExplainFailureResponse":{"properties":{"explanation":{"type":"string","title":"Explanation"},"what":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"What"},"failed_step_index":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Failed Step Index"},"steps":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Steps"},"structured_steps":{"anyOf":[{"items":{"$ref":"#/components/schemas/StepDetail"},"type":"array"},{"type":"null"}],"title":"Structured Steps"},"step_urls":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Step Urls"},"step_durations_ms":{"anyOf":[{"items":{"anyOf":[{"type":"integer"},{"type":"null"}]},"type":"array"},{"type":"null"}],"title":"Step Durations Ms"},"why":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Why"}},"type":"object","required":["explanation"],"title":"ExplainFailureResponse","description":"Plain-English breakdown of a single test execution for the replay page.\n\nPlan-derived fields come from the version that ran (the run item's pinned\n``TestCaseVersion``), so the steps match the frames even after an edit or heal.\n``what`` is the label of the step the run failed on and ``failed_step_index`` its\nflat index into ``steps``; both None when that step can't be located. ``why`` leads\nwith when the test last passed on this environment and on which version.\n``explanation`` mirrors ``why`` for older clients."},"ExplorationAbandonedFlow":{"properties":{"handle":{"type":"string","title":"Handle"},"reason":{"type":"string","title":"Reason"},"detail":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Detail"},"url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Url"},"area":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Area"}},"type":"object","required":["handle","reason"],"title":"ExplorationAbandonedFlow","description":"A flow the agent tried and gave up on, with why — from domain_model.abandoned."},"ExplorationAuthoredTest":{"properties":{"test_case_id":{"type":"string","title":"Test Case Id"},"title":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Title"}},"type":"object","required":["test_case_id"],"title":"ExplorationAuthoredTest","description":"A test this exploration banked — name + id so the UI links to the test detail."},"ExplorationDetail":{"properties":{"id":{"type":"string","title":"Id"},"status":{"type":"string","title":"Status"},"stop_reason":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Stop Reason"},"tests_authored":{"type":"integer","title":"Tests Authored","default":0},"tests_updated":{"type":"integer","title":"Tests Updated","default":0},"total_steps":{"type":"integer","title":"Total Steps","default":0},"elapsed_s":{"type":"integer","title":"Elapsed S","default":0},"tokens_spent":{"type":"integer","title":"Tokens Spent","default":0},"test_run_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Test Run Id"},"started_at":{"type":"string","format":"date-time","title":"Started At"},"completed_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Completed At"},"authored":{"items":{"$ref":"#/components/schemas/ExplorationAuthoredTest"},"type":"array","title":"Authored"},"abandoned":{"items":{"$ref":"#/components/schemas/ExplorationAbandonedFlow"},"type":"array","title":"Abandoned"},"coverage":{"additionalProperties":{"type":"integer"},"type":"object","title":"Coverage"},"frontier":{"$ref":"#/components/schemas/ExplorationFrontier"}},"type":"object","required":["id","status","started_at"],"title":"ExplorationDetail","description":"One exploration with its outcomes — the summary header + panels the detail\npage renders. Extends the list row with banked tests, abandoned flows,\ncoverage-by-kind, and the frontier."},"ExplorationFrontier":{"properties":{"visited_areas":{"items":{"type":"string"},"type":"array","title":"Visited Areas"},"unattempted_interactions":{"items":{"additionalProperties":{"type":"string"},"type":"object"},"type":"array","title":"Unattempted Interactions"},"unvisited_urls":{"items":{"type":"string"},"type":"array","title":"Unvisited Urls"}},"type":"object","title":"ExplorationFrontier","description":"What the agent covered and what it left — the map of explored vs unexplored.\n\n``visited_areas`` are the URL sections it reached; ``unattempted_interactions`` are\nhigh-value in-page controls (chat/form/modal/carousel) it perceived but never acted\non; ``unvisited_urls`` are links it discovered but never opened. All best-effort,\npersisted at exploration end (absent on older rows)."},"ExplorationListItem":{"properties":{"id":{"type":"string","title":"Id"},"status":{"type":"string","title":"Status"},"stop_reason":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Stop Reason"},"tests_authored":{"type":"integer","title":"Tests Authored","default":0},"tests_updated":{"type":"integer","title":"Tests Updated","default":0},"total_steps":{"type":"integer","title":"Total Steps","default":0},"elapsed_s":{"type":"integer","title":"Elapsed S","default":0},"tokens_spent":{"type":"integer","title":"Tokens Spent","default":0},"test_run_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Test Run Id"},"started_at":{"type":"string","format":"date-time","title":"Started At"},"completed_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Completed At"}},"type":"object","required":["id","status","started_at"],"title":"ExplorationListItem","description":"One row in a project's exploration history — the metadata a list needs,\nno steps or outcomes. Mirrors the ``explorations`` row + the run it authored."},"ExplorationStepResponse":{"properties":{"seq":{"type":"integer","title":"Seq"},"tool":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Tool"},"rationale":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Rationale"},"summary":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Summary"},"ok":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Ok"},"error":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Error"},"step_code":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Step Code"},"final_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Final Url"},"screenshot_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Screenshot Url"},"dom_snapshot_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Dom Snapshot Url"},"snapshot_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Snapshot Url"},"created_at":{"type":"string","format":"date-time","title":"Created At"}},"type":"object","required":["seq","created_at"],"title":"ExplorationStepResponse","description":"One persisted exploration step as plain JSON (not the SSE frame) — for a\nstatic/deep-linkable step trace. Asset keys are presigned to short-lived URLs."},"FeaturesResponse":{"properties":{"features":{"additionalProperties":{"type":"boolean"},"type":"object","title":"Features"}},"type":"object","required":["features"],"title":"FeaturesResponse","description":"Full set of workspace feature flags, with defaults applied."},"FeaturesUpdate":{"properties":{"features":{"additionalProperties":{"type":"boolean"},"type":"object","title":"Features"}},"type":"object","title":"FeaturesUpdate","description":"Partial update to workspace feature flags.\n\nOnly keys listed in ``KNOWN_FEATURE_KEYS`` are accepted; unknown keys 400."},"FileDownloadResponse":{"properties":{"url":{"type":"string","title":"Url","description":"Time-limited presigned GET URL for the file."}},"type":"object","required":["url"],"title":"FileDownloadResponse"},"FileResponse":{"properties":{"id":{"type":"string","title":"Id"},"name":{"type":"string","title":"Name"},"content_type":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Content Type"},"size":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Size","description":"Byte size; populated on upload, null on list (not persisted)."},"environment_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Environment Id","description":"Null = project-level; set = pinned to this environment."},"storage_key":{"type":"string","title":"Storage Key","description":"Opaque S3 object key for the blob."},"scope":{"type":"string","enum":["project","environment"],"title":"Scope","description":"'project' when environment_id is null, else 'environment'."},"kind":{"type":"string","enum":["fixture","android_build","ios_build"],"title":"Kind","description":"'fixture': a file an upload step attaches. 'android_build': an APK that android tests install. 'ios_build': a zipped or tarred simulator .app that ios tests install.","default":"fixture"},"app_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"App Id","description":"An app build's package name (android) or bundle id (ios)."},"app_version":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"App Version","description":"An app build's versionName (android) or short version (ios)."},"build_number":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Build Number","description":"An app build's versionCode (android) or build number (ios)."},"abis":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Abis","description":"Native ABIs an Android build ships; empty when it has none."},"app_id_warning":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"App Id Warning","description":"Set on a ready build when no environment it can run in has its app id for its surface, so no test installs it yet."},"status":{"type":"string","enum":["pending","converting","ready","failed"],"title":"Status","description":"'ready' is installable. 'converting': an Android App Bundle is being turned into an APK on a worker; 'failed': it could not be, failure_reason says why.","default":"ready"},"failure_reason":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Failure Reason"},"signer_sha1":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Signer Sha1","description":"SHA-1 of the certificate an Android build is signed with."},"signer_sha256":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Signer Sha256","description":"SHA-256 of the certificate an Android build is signed with."},"signer_source":{"anyOf":[{"type":"string","enum":["as_uploaded","beryl_key","customer_keystore"]},{"type":"null"}],"title":"Signer Source","description":"'as_uploaded': signed by the customer before upload; 'beryl_key': Beryl's key for this project; 'customer_keystore': the customer's keystore held by Beryl."},"note":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Note","description":"Set on an upload: what Beryl did or will do with the build (conversion, signing, environments that took its app id)."},"created_at":{"type":"string","format":"date-time","title":"Created At"}},"type":"object","required":["id","name","storage_key","scope","created_at"],"title":"FileResponse"},"FileUploadRequest":{"properties":{"name":{"type":"string","maxLength":255,"minLength":1,"title":"Name"},"size":{"type":"integer","exclusiveMinimum":0.0,"title":"Size","description":"Byte size of the file to upload."},"kind":{"type":"string","enum":["fixture","android_build","ios_build"],"title":"Kind","default":"fixture"},"content_type":{"type":"string","title":"Content Type","default":"application/octet-stream"},"environment_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Environment Id","description":"Environment to pin to; omit for project-level."}},"type":"object","required":["name","size"],"title":"FileUploadRequest"},"FileUploadResponse":{"properties":{"file_id":{"type":"string","title":"File Id"},"upload_url":{"type":"string","title":"Upload Url","description":"Presigned URL: PUT exactly `size` bytes here (any other length is refused by storage with a 403), then call complete."},"method":{"type":"string","const":"PUT","title":"Method","default":"PUT"},"headers":{"additionalProperties":{"type":"string"},"type":"object","title":"Headers","description":"Headers the PUT must carry exactly."},"expires_in":{"type":"integer","title":"Expires In","description":"Seconds the upload URL stays valid."}},"type":"object","required":["file_id","upload_url","headers","expires_in"],"title":"FileUploadResponse"},"FindingsGateFinding":{"properties":{"fingerprint":{"type":"string","title":"Fingerprint"},"title":{"type":"string","title":"Title"},"severity":{"type":"string","title":"Severity"},"page_path":{"type":"string","title":"Page Path"},"check":{"type":"string","title":"Check"},"first_seen_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"First Seen At"}},"type":"object","required":["fingerprint","title","severity","page_path","check"],"title":"FindingsGateFinding"},"FindingsGateResult":{"properties":{"mode":{"type":"string","title":"Mode"},"status":{"type":"string","enum":["passed","failed","unknown"],"title":"Status","description":"failed: Site Health has a finding first seen after the last green run or came back after it (every current finding when there is none yet); unknown: the gate could not be evaluated, e.g. Site Health is not recording findings because no issue tracker is connected; see reason."},"reason":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Reason"},"baseline_run_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Baseline Run Id","description":"The last green run the gate compared against."},"baseline_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Baseline At"},"new_count":{"type":"integer","title":"New Count","default":0},"new_findings":{"items":{"$ref":"#/components/schemas/FindingsGateFinding"},"type":"array","title":"New Findings","description":"The newest new findings, at most 20; new_count has the total."}},"type":"object","required":["mode","status"],"title":"FindingsGateResult","description":"The run's findings gate. Separate from the test verdicts, which it never changes."},"GroupScheduleResponse":{"properties":{"group_id":{"type":"string","title":"Group Id"},"group_name":{"type":"string","title":"Group Name"},"enabled":{"type":"boolean","title":"Enabled"},"frequency":{"type":"string","title":"Frequency","default":"daily"},"day_of_week":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Day Of Week"},"run_hour":{"type":"integer","title":"Run Hour","default":3},"run_minute":{"type":"integer","title":"Run Minute","default":0},"timezone":{"type":"string","title":"Timezone","default":"UTC"},"next_run_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Next Run At"},"last_run_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Last Run At"}},"type":"object","required":["group_id","group_name","enabled"],"title":"GroupScheduleResponse"},"HTTPValidationError":{"properties":{"detail":{"items":{"$ref":"#/components/schemas/ValidationError"},"type":"array","title":"Detail"}},"type":"object","title":"HTTPValidationError"},"HealAttemptResponse":{"properties":{"heal_job_id":{"type":"string","title":"Heal Job Id","description":"The heal job that ran on this result."},"status":{"type":"string","title":"Status","description":"How the heal ended: errored (it stopped without a verdict, including a repair whose replay still failed), regression_flagged (the intent is no longer met), churn_stopped (it would undo or repeat earlier heals), skipped (another environment's build), or healed (a repair was saved but this result stayed red)."},"reason":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Reason","description":"The agent's diagnosis followed by how the attempt ended, e.g. the replay's failure."}},"type":"object","required":["heal_job_id","status"],"title":"HealAttemptResponse"},"HealEligibilityResponse":{"properties":{"id":{"type":"string","title":"Id"},"self_heal_enabled":{"type":"boolean","title":"Self Heal Enabled"},"updated_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Updated At"}},"type":"object","required":["id","self_heal_enabled"],"title":"HealEligibilityResponse"},"HealEligibilityUpdateRequest":{"properties":{"self_heal_enabled":{"type":"boolean","title":"Self Heal Enabled"}},"type":"object","required":["self_heal_enabled"],"title":"HealEligibilityUpdateRequest"},"HealOutcomeResponse":{"properties":{"rationale":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Rationale","description":"The agent's own explanation of what drifted."},"version_no":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Version No","description":"The test version the heal wrote; diff it against the previous version to see what changed."}},"type":"object","title":"HealOutcomeResponse"},"InboundEmailResponse":{"properties":{"id":{"type":"string","title":"Id"},"recipient":{"type":"string","title":"Recipient"},"sender":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Sender"},"subject":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Subject"},"body_text":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Body Text"},"body_html":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Body Html"},"received_at":{"type":"string","format":"date-time","title":"Received At"}},"type":"object","required":["id","recipient","sender","subject","body_text","body_html","received_at"],"title":"InboundEmailResponse"},"InboxEmailsResponse":{"properties":{"emails":{"items":{"$ref":"#/components/schemas/InboundEmailResponse"},"type":"array","title":"Emails"}},"type":"object","required":["emails"],"title":"InboxEmailsResponse"},"LastExecutionSummary":{"properties":{"id":{"type":"string","title":"Id"},"status":{"type":"string","title":"Status"},"trigger_source":{"type":"string","title":"Trigger Source"},"total_tests":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Total Tests"},"passed_count":{"type":"integer","title":"Passed Count"},"failed_count":{"type":"integer","title":"Failed Count"},"errored_count":{"type":"integer","title":"Errored Count"},"cancelled_count":{"type":"integer","title":"Cancelled Count"},"started_at":{"type":"string","format":"date-time","title":"Started At"},"completed_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Completed At"}},"type":"object","required":["id","status","trigger_source","passed_count","failed_count","errored_count","cancelled_count","started_at"],"title":"LastExecutionSummary"},"LocalEmailTarget":{"properties":{"inbox_id":{"type":"string","title":"Inbox Id"},"address":{"type":"string","title":"Address"},"recipient_contains":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Recipient Contains"},"addresses":{"additionalProperties":{"type":"string"},"type":"object","title":"Addresses"}},"type":"object","required":["inbox_id","address"],"title":"LocalEmailTarget","description":"Where a LOCAL replay receives this plan's mail. Chosen server-side, since the\nrendered spec only shows THAT it awaits mail, never at which address."},"MailboxCreate":{"properties":{"project_id":{"type":"string","title":"Project Id","description":"The project this mailbox belongs to"},"label":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Label","description":"What this mailbox is for, e.g. 'invitee'"},"is_default":{"type":"boolean","title":"Is Default","description":"Make it the address {{mailbox_address}} resolves to","default":false}},"type":"object","required":["project_id"],"title":"MailboxCreate"},"MessageResponse":{"properties":{"message":{"type":"string","title":"Message"}},"type":"object","required":["message"],"title":"MessageResponse"},"MintedIdentityResponse":{"properties":{"id":{"type":"string","title":"Id"},"address":{"type":"string","title":"Address"},"source":{"type":"string","title":"Source"},"project_id":{"type":"string","title":"Project Id"},"mailbox_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Mailbox Id"},"environment_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Environment Id"},"test_case_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Test Case Id"},"test_run_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Test Run Id"},"test_result_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Test Result Id"},"minted_at":{"type":"string","format":"date-time","title":"Minted At"},"teardown_outcome":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Teardown Outcome"},"concluded_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Concluded At"}},"type":"object","required":["id","address","source","project_id","mailbox_id","environment_id","test_case_id","test_run_id","test_result_id","minted_at","teardown_outcome","concluded_at"],"title":"MintedIdentityResponse"},"PriorityMap":{"properties":{"high":{"type":"string","enum":["urgent","high","medium","low","none"],"title":"High","default":"high"},"medium":{"type":"string","enum":["urgent","high","medium","low","none"],"title":"Medium","default":"medium"},"low":{"type":"string","enum":["urgent","high","medium","low","none"],"title":"Low","default":"low"}},"additionalProperties":false,"type":"object","title":"PriorityMap"},"ProjectDetailResponse":{"properties":{"id":{"type":"string","title":"Id"},"root_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Root Url"},"name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Name"},"status":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Status"},"unsupported_auth_type":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Unsupported Auth Type"},"failure_code":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Failure Code"},"failure_message":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Failure Message"},"needs_auth_capture":{"type":"boolean","title":"Needs Auth Capture","default":false},"requires_auth_choice":{"$ref":"#/components/schemas/RequiresAuthChoice"},"auth_last_authorised_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Auth Last Authorised At"},"login_email_set":{"type":"boolean","title":"Login Email Set","default":false},"login_password_set":{"type":"boolean","title":"Login Password Set","default":false},"url_count":{"type":"integer","title":"Url Count","default":0},"nl_test_case_count":{"type":"integer","title":"Nl Test Case Count","default":0},"test_count":{"type":"integer","title":"Test Count","default":0},"last_execution":{"anyOf":[{"$ref":"#/components/schemas/LastExecutionSummary"},{"type":"null"}]},"current_exploration_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Current Exploration Id"},"current_exploration_status":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Current Exploration Status"},"skip_exploration":{"type":"boolean","title":"Skip Exploration","default":false},"auto_quarantine":{"type":"boolean","title":"Auto Quarantine","description":"Quarantine and release tests automatically at the end of each run: a test that failed quarantine_failures times in the last quarantine_days days with a pass in between is muted (straight failures never are); a muted test is released after quarantine_release_passes first-attempt passes in a row.","default":false},"quarantine_failures":{"type":"integer","title":"Quarantine Failures","default":3},"quarantine_days":{"type":"integer","title":"Quarantine Days","default":7},"quarantine_release_passes":{"type":"integer","title":"Quarantine Release Passes","default":5},"enabled_surfaces":{"items":{"type":"string"},"type":"array","title":"Enabled Surfaces","description":"Surfaces enabled for this project, in canonical order."},"findings_gate":{"type":"string","enum":["off","new_since_green"],"title":"Findings Gate","description":"Findings gate on each run: off, or new_since_green to report the gate failed when the environment's Site Health has a finding first seen after the last green run, unknown when Site Health is not recording findings (its issue tracker must be connected). Reported next to the test verdicts; it never changes one.","default":"off"},"self_heal":{"type":"boolean","title":"Self Heal","description":"Auto-heal failed tests during a run. Off by default: a failed test fails right away. When on, a test marked fixed (self_heal_enabled false) still never heals.","default":false},"heal_max_minutes":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Heal Max Minutes","description":"Minutes the heal agent may spend on one failed test (1-5); the replay that proves a repair comes on top. Null means the platform default."},"heal_max_minutes_limit":{"type":"integer","title":"Heal Max Minutes Limit","description":"Highest heal_max_minutes accepted, and the time a null uses.","default":5},"heal_max_per_run":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Heal Max Per Run","description":"Failed tests one run may heal; past it the rest fail without a heal. Null means no cap."},"created_at":{"type":"string","format":"date-time","title":"Created At"},"updated_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Updated At"}},"type":"object","required":["id","requires_auth_choice","created_at"],"title":"ProjectDetailResponse"},"ProjectListItem":{"properties":{"id":{"type":"string","title":"Id"},"root_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Root Url"},"name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Name"},"status":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Status"},"url_count":{"type":"integer","title":"Url Count","default":0},"nl_test_case_count":{"type":"integer","title":"Nl Test Case Count","default":0},"test_count":{"type":"integer","title":"Test Count","default":0},"last_execution":{"anyOf":[{"$ref":"#/components/schemas/LastExecutionSummary"},{"type":"null"}]},"current_exploration_status":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Current Exploration Status"},"created_at":{"type":"string","format":"date-time","title":"Created At"},"updated_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Updated At"}},"type":"object","required":["id","created_at"],"title":"ProjectListItem"},"ProjectReportResponse":{"properties":{"project_id":{"type":"string","title":"Project Id"},"runs":{"items":{"$ref":"#/components/schemas/ProjectReportRunSummary"},"type":"array","title":"Runs"},"tests":{"items":{"$ref":"#/components/schemas/ProjectReportTestRow"},"type":"array","title":"Tests"},"trend":{"items":{"$ref":"#/components/schemas/ProjectReportTrendPoint"},"type":"array","title":"Trend"},"summary":{"$ref":"#/components/schemas/ProjectReportSummaryStats"}},"type":"object","required":["project_id","summary"],"title":"ProjectReportResponse"},"ProjectReportRunSummary":{"properties":{"id":{"type":"string","title":"Id"},"status":{"type":"string","title":"Status"},"trigger_source":{"type":"string","title":"Trigger Source"},"started_at":{"type":"string","format":"date-time","title":"Started At"},"completed_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Completed At"},"duration_ms":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Duration Ms"},"total_tests":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Total Tests"},"passed_count":{"type":"integer","title":"Passed Count"},"failed_count":{"type":"integer","title":"Failed Count"},"errored_count":{"type":"integer","title":"Errored Count"},"cancelled_count":{"type":"integer","title":"Cancelled Count"},"quarantined_count":{"type":"integer","title":"Quarantined Count","default":0}},"type":"object","required":["id","status","trigger_source","started_at","passed_count","failed_count","errored_count","cancelled_count"],"title":"ProjectReportRunSummary","description":"One historical run, as it appears in the project report matrix header."},"ProjectReportSummaryStats":{"properties":{"runs_shown":{"type":"integer","title":"Runs Shown"},"runs_total":{"type":"integer","title":"Runs Total"},"avg_pass_rate":{"type":"number","title":"Avg Pass Rate"},"last_pass_rate":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Last Pass Rate"},"currently_passing_count":{"type":"integer","title":"Currently Passing Count"},"currently_failing_count":{"type":"integer","title":"Currently Failing Count"},"stable_tests_count":{"type":"integer","title":"Stable Tests Count"},"tests_added_in_window":{"items":{"type":"string"},"type":"array","title":"Tests Added In Window"},"tests_removed_in_window":{"items":{"type":"string"},"type":"array","title":"Tests Removed In Window"}},"type":"object","required":["runs_shown","runs_total","avg_pass_rate","currently_passing_count","currently_failing_count","stable_tests_count"],"title":"ProjectReportSummaryStats","description":"Top-of-page headline numbers."},"ProjectReportTestRow":{"properties":{"test_case_id":{"type":"string","title":"Test Case Id"},"test_number":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Test Number"},"flow_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Flow Id"},"nl_description":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Nl Description"},"is_active":{"type":"boolean","title":"Is Active"},"outcomes_by_run_id":{"additionalProperties":{"type":"string"},"type":"object","title":"Outcomes By Run Id"},"runs_in_window":{"type":"integer","title":"Runs In Window"},"pass_count":{"type":"integer","title":"Pass Count"},"fail_count":{"type":"integer","title":"Fail Count"},"error_count":{"type":"integer","title":"Error Count"},"flips":{"type":"integer","title":"Flips"},"pass_rate":{"type":"number","title":"Pass Rate"},"current_streak_status":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Current Streak Status"},"current_streak_length":{"type":"integer","title":"Current Streak Length","default":0}},"type":"object","required":["test_case_id","is_active","runs_in_window","pass_count","fail_count","error_count","flips","pass_rate"],"title":"ProjectReportTestRow","description":"One row in the test-vs-run matrix.\n\n``outcomes_by_run_id`` maps a run id → the status of THIS test in that\nrun. Missing keys mean \"this test did not run in that project execution\"\n(test was deactivated, deleted, or hadn't been generated yet). The\nfrontend renders a gap chip for those.\n\n``test_number`` is the user-facing label (\"Test 3\") and matches the\nordering used on the Tests tab — newest-first within the project. Tests\nthat are no longer in the project (deleted) return ``None``."},"ProjectReportTrendPoint":{"properties":{"run_id":{"type":"string","title":"Run Id"},"started_at":{"type":"string","format":"date-time","title":"Started At"},"pass_rate":{"type":"number","title":"Pass Rate"},"passed_count":{"type":"integer","title":"Passed Count"},"total_tests":{"type":"integer","title":"Total Tests"}},"type":"object","required":["run_id","started_at","pass_rate","passed_count","total_tests"],"title":"ProjectReportTrendPoint","description":"One bar/point on the pass-rate sparkline."},"ProjectWorkspaceResponse":{"properties":{"workspace_id":{"type":"string","title":"Workspace Id"},"workspace_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Workspace Name"}},"type":"object","required":["workspace_id"],"title":"ProjectWorkspaceResponse","description":"Owning workspace of a project, for resolving a workspace-less deep link.\n\nDeliberately minimal: id + name only. It answers \"which workspace do I switch\nto\", and is served only to a caller who is already a member of that workspace,\nso it leaks nothing a member can't already read."},"QuarantineResponse":{"properties":{"id":{"type":"string","title":"Id"},"quarantined":{"type":"boolean","title":"Quarantined"},"quarantined_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Quarantined At"},"quarantine_source":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Quarantine Source"},"updated_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Updated At"}},"type":"object","required":["id","quarantined"],"title":"QuarantineResponse"},"QuarantineUpdateRequest":{"properties":{"quarantined":{"type":"boolean","title":"Quarantined"}},"type":"object","required":["quarantined"],"title":"QuarantineUpdateRequest"},"ReExploreResponse":{"properties":{"exploration_id":{"type":"string","title":"Exploration Id"},"status":{"type":"string","title":"Status"},"already_running":{"type":"boolean","title":"Already Running"}},"type":"object","required":["exploration_id","status","already_running"],"title":"ReExploreResponse","description":"The exploration kicked off (or already in flight) by a re-explore request."},"RequiresAuthChoice":{"type":"string","enum":["public","gated"],"title":"RequiresAuthChoice","description":"Visitor's explicit onboarding answer to \"how do you want to test this site\".\nAuthoritative over captured-session inference. Defaults to PUBLIC (legacy NULL\nrows were backfilled to PUBLIC)."},"RestoreVersionRequest":{"properties":{"version_no":{"type":"integer","title":"Version No"}},"type":"object","required":["version_no"],"title":"RestoreVersionRequest"},"RestoreVersionResponse":{"properties":{"id":{"type":"string","title":"Id"},"json_plan":{"title":"Json Plan"},"authored_by":{"type":"string","title":"Authored By"},"current_version_no":{"type":"integer","title":"Current Version No"},"restored_from_version_no":{"type":"integer","title":"Restored From Version No"},"updated_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Updated At"}},"type":"object","required":["id","json_plan","authored_by","current_version_no","restored_from_version_no"],"title":"RestoreVersionResponse"},"ResultArtifactsResponse":{"properties":{"test_result_id":{"type":"string","title":"Test Result Id"},"screenshot_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Screenshot Url"},"dom_snapshot_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Dom Snapshot Url"},"trace_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Trace Url"},"frame_urls":{"items":{"type":"string"},"type":"array","title":"Frame Urls"}},"type":"object","required":["test_result_id"],"title":"ResultArtifactsResponse"},"ReusableAuthResponse":{"properties":{"available":{"type":"boolean","title":"Available"},"host":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Host"},"final_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Final Url"},"captured_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Captured At"}},"type":"object","required":["available"],"title":"ReusableAuthResponse","description":"Pre-check: does a fresh reusable login exist for this (workspace, domain)?\n``final_url`` / ``captured_at`` are display hints only; the secret blob is never returned."},"Role":{"type":"string","enum":["OWNER","USER","VIEWER"],"title":"Role"},"RunDownloadResponse":{"properties":{"id":{"type":"string","title":"Id"},"project_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Project Id"},"environment_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Environment Id","description":"Environment the run executed against."},"trigger_source":{"type":"string","title":"Trigger Source"},"status":{"type":"string","title":"Status"},"total_tests":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Total Tests"},"passed_count":{"type":"integer","title":"Passed Count"},"failed_count":{"type":"integer","title":"Failed Count"},"errored_count":{"type":"integer","title":"Errored Count"},"cancelled_count":{"type":"integer","title":"Cancelled Count"},"quarantined_count":{"type":"integer","title":"Quarantined Count","description":"Reds from quarantined tests; they don't gate the run.","default":0},"duration_ms":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Duration Ms","description":"Wall-clock run duration in ms; null until complete."},"triggered_by":{"anyOf":[{"$ref":"#/components/schemas/RunTriggeredBy"},{"type":"null"}],"description":"User who triggered the run; null for scheduled runs."},"schedule":{"anyOf":[{"$ref":"#/components/schemas/RunScheduleRef"},{"type":"null"}],"description":"Schedule that produced the run; null for manual runs."},"commit_sha":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Commit Sha"},"branch":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Branch"},"commit_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Commit Url"},"pr_number":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Pr Number"},"started_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Started At"},"completed_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Completed At"},"tests":{"items":{"$ref":"#/components/schemas/RunDownloadTestResult"},"type":"array","title":"Tests"}},"type":"object","required":["id","trigger_source","status","passed_count","failed_count","errored_count","cancelled_count"],"title":"RunDownloadResponse","description":"Self-contained JSON bundle for one run: metadata, per-test result summaries,\nand presigned artifact URLs — everything needed to save/inspect the run offline."},"RunDownloadTestResult":{"properties":{"test_case_id":{"type":"string","title":"Test Case Id"},"test_result_id":{"type":"string","title":"Test Result Id"},"name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Name","description":"The test's goal in plain English."},"status":{"type":"string","title":"Status"},"quarantined":{"type":"boolean","title":"Quarantined","description":"The test was quarantined for this result — a red here didn't fail the run.","default":false},"phase":{"type":"string","title":"Phase","description":"Section the outcome came from: 'setup' | 'main' | 'teardown'. A red in setup/teardown means the harness broke, not your app.","default":"main"},"error_message":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Error Message"},"duration_ms":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Duration Ms"},"started_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Started At"},"completed_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Completed At"},"steps":{"anyOf":[{"items":{"$ref":"#/components/schemas/StepDetail"},"type":"array"},{"type":"null"}],"title":"Steps","description":"Ordered plan steps — index, action kind, plain-English phrase, and the raw action fields."},"screenshot_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Screenshot Url","description":"Presigned screenshot URL (time-limited)."},"dom_snapshot_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Dom Snapshot Url","description":"Presigned URL for the DOM snapshot captured at failure; null if none."},"trace_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Trace Url","description":"Presigned URL for the Playwright trace zip; null if none captured."},"frame_urls":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Frame Urls","description":"Presigned per-step filmstrip frame URLs, in order."}},"type":"object","required":["test_case_id","test_result_id","status"],"title":"RunDownloadTestResult","description":"One test's result inside a run-download bundle, with presigned artifact URLs."},"RunListPage":{"properties":{"items":{"items":{"$ref":"#/components/schemas/TestRunResponse"},"type":"array","title":"Items"},"total":{"type":"integer","title":"Total","description":"Runs in the resolved scope, across all pages."},"page":{"type":"integer","title":"Page","description":"1-indexed page actually returned."},"page_size":{"type":"integer","title":"Page Size"}},"type":"object","required":["total","page","page_size"],"title":"RunListPage","description":"One offset page of a project's runs. Separate from ``GET /runs`` for the same\nCLI-compatibility reason as :class:`TestListPage`."},"RunProgressResponse":{"properties":{"status":{"type":"string","title":"Status"},"counters":{"additionalProperties":{"type":"integer"},"type":"object","title":"Counters"},"version":{"type":"integer","title":"Version"}},"type":"object","required":["status","counters","version"],"title":"RunProgressResponse"},"RunQueueResponse":{"properties":{"active":{"anyOf":[{"$ref":"#/components/schemas/TestRunResponse"},{"type":"null"}]},"queued":{"items":{"$ref":"#/components/schemas/TestRunResponse"},"type":"array","title":"Queued"}},"type":"object","title":"RunQueueResponse","description":"The project's active run and the runs waiting behind it, in start order."},"RunResultsPage":{"properties":{"items":{"items":{"$ref":"#/components/schemas/TestResultResponse"},"type":"array","title":"Items"},"total":{"type":"integer","title":"Total","description":"Results matching the filters, across all pages."},"page":{"type":"integer","title":"Page","description":"1-indexed page actually returned."},"page_size":{"type":"integer","title":"Page Size"},"status_totals":{"additionalProperties":{"type":"integer"},"type":"object","title":"Status Totals"},"group_counts":{"additionalProperties":{"type":"integer"},"type":"object","title":"Group Counts"},"ungrouped_count":{"type":"integer","title":"Ungrouped Count","default":0}},"type":"object","required":["total","page","page_size"],"title":"RunResultsPage","description":"One offset page of a single run's per-test results, plus the run-wide counts\nthe filter chips and the group dropdown need.\n\n``GET /runs/{run_id}`` keeps carrying every result inline for the CLI and the run\nheader; this route exists so the run page can filter and page a large run instead\nof rendering the whole thing."},"RunScheduleRef":{"properties":{"id":{"type":"string","title":"Id","description":"Id of the schedule that produced the run."},"label":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Label","description":"Human cadence label, e.g. 'Daily at 03:00 UTC'."},"group_names":{"items":{"type":"string"},"type":"array","title":"Group Names","description":"Groups the schedule targets; empty = every active test."}},"type":"object","required":["id"],"title":"RunScheduleRef","description":"The schedule that produced a scheduled run. Null on manual/onboarding runs."},"RunSettings":{"properties":{"schedule":{"type":"string","enum":["off","daily","weekly"],"title":"Schedule","description":"How often Site Health runs on its own","default":"off"},"schedule_hour":{"type":"integer","maximum":23.0,"minimum":0.0,"title":"Schedule Hour","default":9},"schedule_minute":{"type":"integer","maximum":59.0,"minimum":0.0,"title":"Schedule Minute","default":0},"schedule_day_of_week":{"type":"integer","maximum":6.0,"minimum":0.0,"title":"Schedule Day Of Week","description":"Weekly runs only; 0 = Monday","default":0},"schedule_timezone":{"type":"string","title":"Schedule Timezone","description":"IANA timezone","default":"UTC"},"ci_mode":{"type":"string","enum":["off","every_build","main_only","deploy_only"],"title":"Ci Mode","description":"Which CI builds `beryl health run --ci` checks; the rest skip and pass","default":"off"},"ci_fail_on":{"type":"string","enum":["high","medium","never"],"title":"Ci Fail On","description":"Lowest finding severity that fails the CI build; never = report only","default":"high"},"ci_files_tickets":{"type":"boolean","title":"Ci Files Tickets","description":"CI runs file tracker tickets; off = the findings go to the PR only","default":false},"pages":{"type":"string","enum":["homepage","paths","sitemap","crawl"],"title":"Pages","description":"Pages a run checks: homepage, paths (the list below), sitemap.xml, or a crawl from the homepage","default":"homepage"},"paths":{"items":{"type":"string"},"type":"array","title":"Paths","description":"Page paths checked in paths mode"},"crawl_depth":{"type":"integer","maximum":5.0,"minimum":1.0,"title":"Crawl Depth","description":"Link hops from the homepage","default":2},"max_pages":{"type":"integer","maximum":100.0,"minimum":1.0,"title":"Max Pages","description":"Most pages one run checks, homepage included","default":25},"include":{"items":{"type":"string"},"type":"array","title":"Include","description":"Path patterns (glob, e.g. /blog/*) a page must match; empty = every page"},"exclude":{"items":{"type":"string"},"type":"array","title":"Exclude","description":"Path patterns skipped"},"logged_in":{"items":{"type":"string"},"type":"array","title":"Logged In","description":"Path patterns checked signed in with the environment's saved test sign-in; the rest run logged out"},"retries":{"type":"integer","maximum":3.0,"minimum":0.0,"title":"Retries","description":"Extra attempts when a page check fails or times out","default":1}},"additionalProperties":false,"type":"object","title":"RunSettings"},"RunSettingsUpdate":{"properties":{"schedule":{"anyOf":[{"type":"string","enum":["off","daily","weekly"]},{"type":"null"}],"title":"Schedule"},"schedule_hour":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Schedule Hour"},"schedule_minute":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Schedule Minute"},"schedule_day_of_week":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Schedule Day Of Week"},"schedule_timezone":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Schedule Timezone"},"ci_mode":{"anyOf":[{"type":"string","enum":["off","every_build","main_only","deploy_only"]},{"type":"null"}],"title":"Ci Mode"},"ci_fail_on":{"anyOf":[{"type":"string","enum":["high","medium","never"]},{"type":"null"}],"title":"Ci Fail On"},"ci_files_tickets":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Ci Files Tickets"},"pages":{"anyOf":[{"type":"string","enum":["homepage","paths","sitemap","crawl"]},{"type":"null"}],"title":"Pages"},"paths":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Paths"},"crawl_depth":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Crawl Depth"},"max_pages":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Max Pages"},"include":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Include"},"exclude":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Exclude"},"logged_in":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Logged In"},"retries":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Retries"}},"additionalProperties":false,"type":"object","title":"RunSettingsUpdate","description":"PATCH semantics: only the fields present change."},"RunTriggeredBy":{"properties":{"id":{"type":"string","title":"Id","description":"Id of the user who triggered the run."},"name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Name","description":"Triggering user's display name."},"email":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Email","description":"Triggering user's email."}},"type":"object","required":["id"],"title":"RunTriggeredBy","description":"The user who kicked off a manual/support run. Null on the run when it was\nscheduled or system-initiated."},"ScheduleItemResponse":{"properties":{"id":{"type":"string","title":"Id"},"environment_id":{"type":"string","title":"Environment Id"},"environment_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Environment Name"},"group_ids":{"items":{"type":"string"},"type":"array","title":"Group Ids","default":[]},"group_names":{"items":{"type":"string"},"type":"array","title":"Group Names","default":[]},"frequency":{"type":"string","title":"Frequency","default":"daily"},"day_of_week":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Day Of Week"},"run_hour":{"type":"integer","title":"Run Hour","default":3},"run_minute":{"type":"integer","title":"Run Minute","default":0},"timezone":{"type":"string","title":"Timezone","default":"UTC"},"next_run_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Next Run At"},"last_run_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Last Run At"}},"type":"object","required":["id","environment_id"],"title":"ScheduleItemResponse"},"ScheduleResponse":{"properties":{"enabled":{"type":"boolean","title":"Enabled"},"frequency":{"type":"string","title":"Frequency","default":"daily"},"day_of_week":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Day Of Week"},"run_hour":{"type":"integer","title":"Run Hour","default":3},"run_minute":{"type":"integer","title":"Run Minute","default":0},"timezone":{"type":"string","title":"Timezone","default":"UTC"},"next_run_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Next Run At"},"last_run_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Last Run At"},"group_schedules":{"items":{"$ref":"#/components/schemas/GroupScheduleResponse"},"type":"array","title":"Group Schedules","default":[]}},"type":"object","required":["enabled"],"title":"ScheduleResponse"},"ScheduleWriteRequest":{"properties":{"environment_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Environment Id"},"frequency":{"type":"string","enum":["daily","weekly"],"title":"Frequency","default":"daily"},"day_of_week":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Day Of Week"},"run_hour":{"type":"integer","title":"Run Hour","default":3},"run_minute":{"type":"integer","title":"Run Minute","default":0},"timezone":{"type":"string","title":"Timezone","default":"UTC"},"group_ids":{"items":{"type":"string"},"type":"array","title":"Group Ids","default":[]}},"type":"object","title":"ScheduleWriteRequest","description":"Create or fully update one schedule. ``group_ids`` empty = every active test.\n``environment_id`` omitted = the project's default environment (create) or\nunchanged (update)."},"SecretCreate":{"properties":{"key":{"type":"string","maxLength":255,"minLength":1,"title":"Key","description":"Secret name, unique within the project + environment scope."},"value":{"type":"string","title":"Value","description":"Plaintext value — Fernet-encrypted at rest, never returned."},"environment_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Environment Id","description":"Environment to pin to; null = project-level (all environments)."}},"type":"object","required":["key","value"],"title":"SecretCreate"},"SecretResponse":{"properties":{"id":{"type":"string","title":"Id"},"key":{"type":"string","title":"Key"},"environment_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Environment Id","description":"Null = project-level; set = pinned to this environment."},"scope":{"type":"string","enum":["project","environment"],"title":"Scope","description":"'project' when environment_id is null, else 'environment'."},"created_at":{"type":"string","format":"date-time","title":"Created At"},"updated_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Updated At"}},"type":"object","required":["id","key","scope","created_at"],"title":"SecretResponse","description":"Metadata only — a secret's value is write-only and NEVER serialized here."},"SecretValueResponse":{"properties":{"id":{"type":"string","title":"Id"},"key":{"type":"string","title":"Key"},"value":{"type":"string","title":"Value"}},"type":"object","required":["id","key","value"],"title":"SecretValueResponse","description":"The decrypted value, returned ONLY by the explicit reveal route."},"SigningKeyInfo":{"properties":{"sha1":{"type":"string","title":"Sha1","description":"Hex SHA-1 of the signing certificate."},"sha256":{"type":"string","title":"Sha256","description":"Hex SHA-256 of the signing certificate."},"key_alias":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Key Alias"},"set_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Set At"}},"type":"object","required":["sha1","sha256"],"title":"SigningKeyInfo"},"SpaceAuditEventResponse":{"properties":{"id":{"type":"string","title":"Id"},"action":{"type":"string","title":"Action"},"actor_name":{"type":"string","title":"Actor Name"},"actor_email":{"type":"string","title":"Actor Email"},"detail":{"additionalProperties":true,"type":"object","title":"Detail"},"created_at":{"type":"string","format":"date-time","title":"Created At"}},"type":"object","required":["id","action","actor_name","actor_email","detail","created_at"],"title":"SpaceAuditEventResponse"},"StepDetail":{"properties":{"index":{"type":"integer","title":"Index"},"action":{"type":"string","title":"Action"},"phrase":{"type":"string","title":"Phrase"},"is_assertion":{"type":"boolean","title":"Is Assertion"},"phase":{"type":"string","title":"Phase","default":"main"},"raw":{"additionalProperties":true,"type":"object","title":"Raw"}},"type":"object","required":["index","action","phrase","is_assertion","raw"],"title":"StepDetail","description":"One structured step of a test plan, for the interactive replay list.\n\n``index`` aligns 1:1 with the captured filmstrip frames, so clicking a step seeks\nthe replay to its frame. ``phrase`` is the deterministic plain-English label,\n``action`` a coarse tag, ``is_assertion`` marks an EXPECT (a check, not an action),\n``phase`` the section it belongs to (setup/main/teardown), and ``raw`` carries the\nPlanStep fields for an expand-to-detail view.\n\n``index`` stays FLAT across the three phases — it is the ordinal codegen mints the\nfilmstrip frames from. Grouping by ``phase`` must not renumber it per section."},"TestAccountCapture":{"properties":{"environment_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Environment Id","description":"Defaults to the project's default environment"},"identity_label":{"type":"string","title":"Identity Label","description":"What a plan's auth_label names. Capturing an existing captured label replaces its session","default":"default"},"email":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Email","description":"The signed-in user's address, what {{login_email}} resolves to"},"is_default":{"type":"boolean","title":"Is Default","default":false},"session":{"additionalProperties":true,"type":"object","title":"Session","description":"The captured session blob: schema_version, final_url, cookies (CDP shape), local_storage, session_storage, indexed_db"}},"type":"object","required":["session"],"title":"TestAccountCapture"},"TestAccountCaptureResponse":{"properties":{"id":{"type":"string","title":"Id"},"environment_id":{"type":"string","title":"Environment Id"},"identity_label":{"type":"string","title":"Identity Label"},"type":{"type":"string","title":"Type"},"lifetime":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Lifetime"},"login_method":{"type":"string","title":"Login Method"},"status":{"type":"string","title":"Status"},"email":{"type":"string","title":"Email"},"has_password":{"type":"boolean","title":"Has Password"},"mailbox_address":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Mailbox Address"},"is_default":{"type":"boolean","title":"Is Default"},"last_error":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Last Error"},"signed_up_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Signed Up At"},"created_at":{"type":"string","format":"date-time","title":"Created At"},"has_login_plan":{"type":"boolean","title":"Has Login Plan","default":false},"app_sign_ins":{"items":{"type":"string"},"type":"array","title":"App Sign Ins","description":"App surfaces ('android', 'ios') this account has a stored sign-in for"},"session_support":{"type":"string","title":"Session Support","default":"unknown"},"session_error":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Session Error"},"login_verified_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Login Verified At"},"has_signup_plan":{"type":"boolean","title":"Has Signup Plan","default":false},"session_expires_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Session Expires At"},"test_run_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Test Run Id"},"test_case_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Test Case Id"},"test_result_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Test Result Id"},"mint_source":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Mint Source"},"teardown_outcome":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Teardown Outcome"},"ignored_cookie_domains":{"items":{"type":"string"},"type":"array","title":"Ignored Cookie Domains"}},"type":"object","required":["id","environment_id","identity_label","type","login_method","status","email","has_password","mailbox_address","is_default","last_error","signed_up_at","created_at"],"title":"TestAccountCaptureResponse"},"TestAccountCheckResponse":{"properties":{"account_id":{"type":"string","title":"Account Id"},"identity_label":{"type":"string","title":"Identity Label"},"proved":{"type":"boolean","title":"Proved"},"session_support":{"type":"string","title":"Session Support"},"error":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Error"},"checked_at":{"type":"string","format":"date-time","title":"Checked At"}},"type":"object","required":["account_id","identity_label","proved","session_support","checked_at"],"title":"TestAccountCheckResponse"},"TestAccountCreate":{"properties":{"type":{"type":"string","title":"Type","description":"provided = the customer's own dedicated account (email + password required); provisioned = Beryl signs one up through the app's signup flow using the project mailbox. A captured account comes from the Chrome plugin and cannot be created here"},"lifetime":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Lifetime","description":"provisioned only: permanent (kept and reused) or throwaway. Defaults to permanent"},"identity_label":{"type":"string","title":"Identity Label","description":"What a plan's auth_label names — 'default', 'admin', 'member'","default":"default"},"environment_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Environment Id","description":"Defaults to the project's default environment"},"email":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Email","description":"Required for provided. Omitted for provisioned: the address is derived from the project mailbox, +tagged with the identity label"},"password":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Password","description":"Required for provided; stored encrypted as a project secret and never returned. Omitted for provisioned; one is generated at signup time"},"login_method":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Login Method","description":"password | magic_link | otp. Defaults to password"},"is_default":{"type":"boolean","title":"Is Default","description":"Make this the account an authenticated plan gets when it names no auth_label. The first account created for an environment is always default","default":false}},"type":"object","required":["type"],"title":"TestAccountCreate"},"TestAccountLoginResponse":{"properties":{"account_id":{"type":"string","title":"Account Id"},"identity_label":{"type":"string","title":"Identity Label"},"plan":{"anyOf":[{},{"type":"null"}],"title":"Plan"},"probe":{"anyOf":[{},{"type":"null"}],"title":"Probe"},"login_plan_hash":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Login Plan Hash"},"session_support":{"type":"string","title":"Session Support"},"session_error":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Session Error"},"login_verified_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Login Verified At"}},"type":"object","required":["account_id","identity_label","plan","probe","login_plan_hash","session_support","session_error","login_verified_at"],"title":"TestAccountLoginResponse"},"TestAccountLoginWrite":{"properties":{"plan":{"title":"Plan","description":"The SIGN-IN ActionPlan, replayed once per run to mint the session every session-mode test rides. It must end logged in. Type {{login_email}} into the email field and {{login_password}} into the password field; an emailed code or magic link arrives at the account's own address, so an await_email step reads it unattended. Required, except for a captured account: that one takes only a probe"},"probe":{"title":"Probe","description":"The liveness probe: a tiny plan (a goto plus a POSITIVE assertion that only holds when signed in, e.g. expect visible on the account menu) replayed in a fresh browser carrying only the captured session. Without it a dead session runs every test logged-out and still reports green"},"base_hash":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Base Hash","description":"The login_plan_hash you read with `accounts get-login`. The write is rejected if the stored plan changed since — so a blind overwrite can never clobber a heal you never saw. Omit only when writing the first plan"},"surface":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Surface","description":"An app surface ('android', 'ios') to store this sign-in for: the same user signs in through the app's own screens, so plan and probe are plans for that device (device 'android' or 'ios', starting with a launch). Omit for the web sign-in"}},"type":"object","required":["probe"],"title":"TestAccountLoginWrite"},"TestAccountResponse":{"properties":{"id":{"type":"string","title":"Id"},"environment_id":{"type":"string","title":"Environment Id"},"identity_label":{"type":"string","title":"Identity Label"},"type":{"type":"string","title":"Type"},"lifetime":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Lifetime"},"login_method":{"type":"string","title":"Login Method"},"status":{"type":"string","title":"Status"},"email":{"type":"string","title":"Email"},"has_password":{"type":"boolean","title":"Has Password"},"mailbox_address":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Mailbox Address"},"is_default":{"type":"boolean","title":"Is Default"},"last_error":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Last Error"},"signed_up_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Signed Up At"},"created_at":{"type":"string","format":"date-time","title":"Created At"},"has_login_plan":{"type":"boolean","title":"Has Login Plan","default":false},"app_sign_ins":{"items":{"type":"string"},"type":"array","title":"App Sign Ins","description":"App surfaces ('android', 'ios') this account has a stored sign-in for"},"session_support":{"type":"string","title":"Session Support","default":"unknown"},"session_error":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Session Error"},"login_verified_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Login Verified At"},"has_signup_plan":{"type":"boolean","title":"Has Signup Plan","default":false},"session_expires_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Session Expires At"},"test_run_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Test Run Id"},"test_case_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Test Case Id"},"test_result_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Test Result Id"},"mint_source":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Mint Source"},"teardown_outcome":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Teardown Outcome"}},"type":"object","required":["id","environment_id","identity_label","type","login_method","status","email","has_password","mailbox_address","is_default","last_error","signed_up_at","created_at"],"title":"TestAccountResponse"},"TestAccountSessionResponse":{"properties":{"account_id":{"type":"string","title":"Account Id"},"identity_label":{"type":"string","title":"Identity Label"},"ok":{"type":"boolean","title":"Ok"},"error":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Error"},"unsupported":{"type":"boolean","title":"Unsupported","default":false},"session_support":{"type":"string","title":"Session Support"},"storage_state":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Storage State"},"init_scripts":{"items":{"type":"string"},"type":"array","title":"Init Scripts"},"secrets":{"items":{"type":"string"},"type":"array","title":"Secrets"}},"type":"object","required":["account_id","identity_label","ok","session_support"],"title":"TestAccountSessionResponse"},"TestAccountSignup":{"properties":{"plan":{"title":"Plan","description":"Omit to re-run the signup plan already stored on the account. The SIGNUP ActionPlan: the app's own sign-up form, ending logged in. Type {{login_email}} into the email field and {{login_password}} into the password field; both resolve at replay time, and an await_email step reads the project mailbox for a verification code. Stored on the account so the same identity can be signed up again on another environment"}},"type":"object","title":"TestAccountSignup"},"TestAccountUpdate":{"properties":{"email":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Email"},"password":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Password"},"login_method":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Login Method"},"is_default":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Is Default"},"status":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Status"}},"type":"object","title":"TestAccountUpdate"},"TestAttemptResponse":{"properties":{"id":{"type":"string","title":"Id"},"attempt_no":{"type":"integer","title":"Attempt No","description":"1-based, in execution order."},"status":{"type":"string","title":"Status"},"phase":{"type":"string","title":"Phase","default":"main"},"error_message":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Error Message"},"duration_ms":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Duration Ms"},"screenshot_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Screenshot Url","description":"Presigned URL for this attempt's failure screenshot; null if none."},"dom_snapshot_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Dom Snapshot Url"},"trace_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Trace Url"},"frame_urls":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Frame Urls"},"started_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Started At"},"completed_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Completed At"}},"type":"object","required":["id","attempt_no","status"],"title":"TestAttemptResponse","description":"One execution of a test inside a result. Attempt 1 is always present; 2..N exist\nonly when a retry ran. The failing attempt's artifacts are preserved in full — a\npass on attempt 2 is flake evidence, and this is the evidence."},"TestCaseVersionDetail":{"properties":{"test_case_id":{"type":"string","title":"Test Case Id"},"version_no":{"type":"integer","title":"Version No"},"source":{"type":"string","title":"Source"},"edited_by":{"type":"string","title":"Edited By"},"json_plan":{"title":"Json Plan"},"nl_snapshot":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Nl Snapshot"},"created_at":{"type":"string","format":"date-time","title":"Created At"},"is_current":{"type":"boolean","title":"Is Current","default":false},"id":{"type":"string","title":"Id","readOnly":true}},"type":"object","required":["test_case_id","version_no","source","edited_by","json_plan","created_at","id"],"title":"TestCaseVersionDetail"},"TestCaseVersionListResponse":{"properties":{"test_case_id":{"type":"string","title":"Test Case Id"},"current_version_no":{"type":"integer","title":"Current Version No"},"versions":{"items":{"$ref":"#/components/schemas/TestCaseVersionSummary"},"type":"array","title":"Versions"},"next_cursor":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Next Cursor"},"id":{"type":"string","title":"Id","readOnly":true}},"type":"object","required":["test_case_id","current_version_no","id"],"title":"TestCaseVersionListResponse"},"TestCaseVersionSummary":{"properties":{"version_no":{"type":"integer","title":"Version No"},"source":{"type":"string","title":"Source"},"edited_by":{"type":"string","title":"Edited By"},"nl_snapshot":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Nl Snapshot"},"created_at":{"type":"string","format":"date-time","title":"Created At"},"is_current":{"type":"boolean","title":"Is Current","default":false}},"type":"object","required":["version_no","source","edited_by","created_at"],"title":"TestCaseVersionSummary","description":"One row in the version-history timeline — metadata only, no full plan."},"TestCompilePolicy":{"properties":{"timeout_ms":{"type":"integer","title":"Timeout Ms"},"error_retries":{"type":"integer","title":"Error Retries"}},"type":"object","required":["timeout_ms","error_retries"],"title":"TestCompilePolicy"},"TestCompileRequest":{"properties":{"plan":{"additionalProperties":true,"type":"object","title":"Plan"},"title":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Title"},"base_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Base Url"},"environment_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Environment Id"},"frames":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Frames"}},"type":"object","required":["plan"],"title":"TestCompileRequest","description":"Render an UNBANKED plan to a runnable .spec.ts — the pre-create seam of the\nlocal-verify flow. Same validation as create; no row, no browser, no LLM."},"TestCompileResponse":{"properties":{"content":{"type":"string","title":"Content"},"plan_hash":{"type":"string","title":"Plan Hash"},"requires_auth":{"type":"boolean","title":"Requires Auth"},"uses_login_password":{"type":"boolean","title":"Uses Login Password"},"login_config_error":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Login Config Error"},"policy":{"$ref":"#/components/schemas/TestCompilePolicy"},"email":{"anyOf":[{"$ref":"#/components/schemas/LocalEmailTarget"},{"type":"null"}]},"inlined_login_steps":{"type":"integer","title":"Inlined Login Steps","default":0},"session_mode":{"type":"boolean","title":"Session Mode","default":false},"account_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Account Id"}},"type":"object","required":["content","plan_hash","requires_auth","uses_login_password","policy"],"title":"TestCompileResponse"},"TestCreateRequest":{"properties":{"title":{"type":"string","title":"Title"},"plan":{"additionalProperties":true,"type":"object","title":"Plan"},"verify":{"type":"boolean","title":"Verify","default":true},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Description"},"groups":{"items":{"type":"string"},"type":"array","title":"Groups","description":"Names of existing project groups to put this test in. A name with no matching group is a 422 — groups are created in project settings."},"access":{"type":"string","enum":["read","write"],"title":"Access","description":"'read' when the test only reads the app; 'write' when any step creates, edits, renames, deletes or toggles something. A writer must clean up in 'after'.","default":"read"},"plan_hash":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Plan Hash"}},"type":"object","required":["title","plan"],"title":"TestCreateRequest","description":"A customer-authored (bring-your-own-agent) test: a title + an ActionPlan.\n``verify=False`` skips the browser+AI replay gate entirely (zero LLM spend).\n``description`` is the durable NL intent healing anchors to — the same\n``nl_snapshot`` slot the agent path fills — persisted on the byo head\nrevision."},"TestCreateResponse":{"properties":{"id":{"type":"string","title":"Id"},"project_id":{"type":"string","title":"Project Id"},"nl_test_case_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Nl Test Case Id"},"discovered_url_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Discovered Url Id"},"nl_title":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Nl Title"},"nl_description":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Nl Description"},"flow_id":{"type":"string","title":"Flow Id","description":"The logical test this row belongs to. Every surface variant of one flow shares its title, groups and access."},"surface":{"type":"string","title":"Surface","description":"Where this variant runs: web-desktop, web-tablet or web-mobile."},"is_active":{"type":"boolean","title":"Is Active"},"authored_by":{"type":"string","title":"Authored By","default":"system"},"groups":{"items":{"type":"string"},"type":"array","title":"Groups"},"self_heal_enabled":{"type":"boolean","title":"Self Heal Enabled","default":true},"quarantined":{"type":"boolean","title":"Quarantined","default":false},"access":{"type":"string","title":"Access","description":"'read': the test only reads the app. 'write': it changes state.","default":"read"},"quarantined_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Quarantined At","description":"When the test was quarantined; null while it isn't."},"quarantine_source":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Quarantine Source","description":"Who quarantined it: 'user' or 'auto'. Null while it isn't."},"has_script":{"type":"boolean","title":"Has Script"},"retrying":{"type":"boolean","title":"Retrying","default":false},"environment_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Environment Id","description":"Environment the per-env status fields below resolve against."},"last_result_status":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Last Result Status","description":"Latest result status of this test in the selected environment."},"last_run_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Last Run At","description":"When this test last ran in the selected environment."},"last_result_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Last Result Id","description":"Id of this test's latest result in the selected environment."},"rehab_ready":{"type":"boolean","title":"Rehab Ready","description":"This quarantined test has passed cleanly its last quarantine_release_passes runs (the project's release threshold) in the selected environment, so it looks safe to un-quarantine. A suggestion only unless the project's auto_quarantine is on. Always false for a test that isn't quarantined.","default":false},"rehab_pass_streak":{"type":"integer","title":"Rehab Pass Streak","description":"Consecutive clean passes behind rehab_ready, capped at the threshold. 0 for a test that isn't quarantined.","default":0},"requires_auth":{"type":"boolean","title":"Requires Auth","description":"This test runs against an authenticated session rather than a public page. Derived from the same rule the runner uses to decide whether to inject the saved login, so it can't drift from actual behaviour. Broader than TestCompileResponse.requires_auth, which excludes plans that sign themselves in inline.","default":false},"created_at":{"type":"string","format":"date-time","title":"Created At"},"updated_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Updated At"},"verified":{"type":"boolean","title":"Verified","description":"True only when the server-side verify replay passed (verdict 'keep'). False for verify=false and for a 'flag' (the replay could not run): the test is saved but unproven."},"verdict":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Verdict","description":"The verify replay verdict: 'keep' or 'flag'. Null for verify=false."},"verify_message":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Verify Message","description":"Why a 'flag' did not verify."}},"type":"object","required":["id","project_id","discovered_url_id","flow_id","surface","is_active","has_script","created_at","verified"],"title":"TestCreateResponse"},"TestCreationJobDetail":{"properties":{"id":{"type":"string","title":"Id"},"status":{"type":"string","title":"Status"},"needs":{"anyOf":[{"$ref":"#/components/schemas/TestCreationJobNeed"},{"type":"null"}]},"environment_id":{"type":"string","title":"Environment Id"},"prompt":{"type":"string","title":"Prompt","description":"The user's instruction to the agent"},"document_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Document Name","description":"Name of the attached document; null when none was attached"},"cloned_from_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Cloned From Id"},"retry":{"type":"boolean","title":"Retry","description":"True when the job retries cloned_from_id: it authors only the scenarios that job left without a test","default":false},"interactive":{"type":"boolean","title":"Interactive","description":"False: the job never pauses for input; what it would wait on is skipped","default":true},"account_label":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Account Label","description":"Label of the test account the agent signs in as; null is the environment's default account"},"error":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Error"},"test_count":{"type":"integer","title":"Test Count","default":0},"surface_steps":{"items":{"$ref":"#/components/schemas/TestCreationJobStep"},"type":"array","title":"Surface Steps","description":"One step per enabled surface, run in order on its own workers"},"created_at":{"type":"string","format":"date-time","title":"Created At"},"started_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Started At"},"completed_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Completed At"},"document_text":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Document Text"},"skipped_flows":{"items":{"$ref":"#/components/schemas/TestCreationJobSkippedFlow"},"type":"array","title":"Skipped Flows","default":[]},"tests":{"items":{"$ref":"#/components/schemas/TestCreationJobTest"},"type":"array","title":"Tests","default":[]}},"type":"object","required":["id","status","environment_id","prompt","created_at"],"title":"TestCreationJobDetail"},"TestCreationJobItem":{"properties":{"id":{"type":"string","title":"Id"},"status":{"type":"string","title":"Status"},"needs":{"anyOf":[{"$ref":"#/components/schemas/TestCreationJobNeed"},{"type":"null"}]},"environment_id":{"type":"string","title":"Environment Id"},"prompt":{"type":"string","title":"Prompt","description":"The user's instruction to the agent"},"document_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Document Name","description":"Name of the attached document; null when none was attached"},"cloned_from_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Cloned From Id"},"retry":{"type":"boolean","title":"Retry","description":"True when the job retries cloned_from_id: it authors only the scenarios that job left without a test","default":false},"interactive":{"type":"boolean","title":"Interactive","description":"False: the job never pauses for input; what it would wait on is skipped","default":true},"account_label":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Account Label","description":"Label of the test account the agent signs in as; null is the environment's default account"},"error":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Error"},"test_count":{"type":"integer","title":"Test Count","default":0},"surface_steps":{"items":{"$ref":"#/components/schemas/TestCreationJobStep"},"type":"array","title":"Surface Steps","description":"One step per enabled surface, run in order on its own workers"},"created_at":{"type":"string","format":"date-time","title":"Created At"},"started_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Started At"},"completed_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Completed At"}},"type":"object","required":["id","status","environment_id","prompt","created_at"],"title":"TestCreationJobItem"},"TestCreationJobNeed":{"properties":{"kind":{"type":"string","title":"Kind"},"reason":{"type":"string","title":"Reason"},"surface":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Surface"}},"type":"object","required":["kind","reason"],"title":"TestCreationJobNeed"},"TestCreationJobRetry":{"properties":{"prompt":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Prompt","description":"The instruction to retry with; omit to reuse the job's own"},"document_text":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Document Text","description":"The document to retry with; omit to reuse the job's own"}},"type":"object","title":"TestCreationJobRetry"},"TestCreationJobSkippedFlow":{"properties":{"handle":{"type":"string","title":"Handle"},"reason":{"type":"string","title":"Reason"},"detail":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Detail"},"advice":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Advice","description":"What the customer can do about this skip reason"}},"type":"object","required":["handle","reason"],"title":"TestCreationJobSkippedFlow"},"TestCreationJobStep":{"properties":{"surface":{"type":"string","title":"Surface"},"status":{"type":"string","title":"Status"},"authored":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Authored"},"gaps":{"items":{"type":"string"},"type":"array","title":"Gaps","description":"Drafted flows this surface could not author"},"warnings":{"items":{"type":"string"},"type":"array","title":"Warnings","description":"Degraded parts of a step that otherwise finished, e.g. app memory not saved"},"error":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Error"}},"type":"object","required":["surface","status"],"title":"TestCreationJobStep"},"TestCreationJobTest":{"properties":{"id":{"type":"string","title":"Id"},"flow_id":{"type":"string","title":"Flow Id"},"title":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Title"},"surface":{"type":"string","title":"Surface"}},"type":"object","required":["id","flow_id","surface"],"title":"TestCreationJobTest"},"TestEventResponse":{"properties":{"id":{"type":"string","title":"Id"},"action":{"type":"string","title":"Action"},"actor_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Actor Name"},"actor_email":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Actor Email"},"source":{"type":"string","title":"Source"},"detail":{"additionalProperties":true,"type":"object","title":"Detail"},"created_at":{"type":"string","format":"date-time","title":"Created At"}},"type":"object","required":["id","action","source","created_at"],"title":"TestEventResponse"},"TestExportFile":{"properties":{"filename":{"type":"string","title":"Filename"},"content":{"type":"string","title":"Content"}},"type":"object","required":["filename","content"],"title":"TestExportFile"},"TestExportFiles":{"properties":{"files":{"items":{"$ref":"#/components/schemas/TestExportFile"},"type":"array","title":"Files"}},"type":"object","required":["files"],"title":"TestExportFiles","description":"The export as JSON: what the ZIP would hold, one entry per file."},"TestExportRequest":{"properties":{"test_case_ids":{"items":{"type":"string"},"type":"array","title":"Test Case Ids","description":"Ids of the tests to include in the export."}},"type":"object","required":["test_case_ids"],"title":"TestExportRequest","description":"Select which tests to bundle into the export of rendered .spec.ts files."},"TestFlowListPage":{"properties":{"items":{"items":{"$ref":"#/components/schemas/TestFlowResponse"},"type":"array","title":"Items"},"total":{"type":"integer","title":"Total","description":"Flows matching the filters, across all pages."},"page":{"type":"integer","title":"Page"},"page_size":{"type":"integer","title":"Page Size"},"status_totals":{"additionalProperties":{"type":"integer"},"type":"object","title":"Status Totals"},"group_counts":{"additionalProperties":{"type":"integer"},"type":"object","title":"Group Counts"},"ungrouped_count":{"type":"integer","title":"Ungrouped Count","default":0}},"type":"object","required":["total","page","page_size"],"title":"TestFlowListPage"},"TestFlowResponse":{"properties":{"id":{"type":"string","title":"Id"},"title":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Title"},"access":{"type":"string","title":"Access"},"groups":{"items":{"type":"string"},"type":"array","title":"Groups"},"status":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Status","description":"Rolled up over the flow's active surface tests in the selected environment: failing (any un-quarantined surface failed or errored), else quarantined (any surface quarantined), else passed (every surface passed). Null when a surface hasn't run or was cancelled."},"created_at":{"type":"string","format":"date-time","title":"Created At"},"tests":{"items":{"$ref":"#/components/schemas/TestResponse"},"type":"array","title":"Tests","description":"One test per surface, in surface order."}},"type":"object","required":["id","access","created_at"],"title":"TestFlowResponse"},"TestGroupResponse":{"properties":{"id":{"type":"string","title":"Id"},"name":{"type":"string","title":"Name"},"test_count":{"type":"integer","title":"Test Count","default":0},"created_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Created At"}},"type":"object","required":["id","name"],"title":"TestGroupResponse"},"TestGroupWriteRequest":{"properties":{"name":{"type":"string","title":"Name"}},"type":"object","required":["name"],"title":"TestGroupWriteRequest"},"TestHistoryEntry":{"properties":{"test_result_id":{"type":"string","title":"Test Result Id"},"test_run_id":{"type":"string","title":"Test Run Id"},"trigger_source":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Trigger Source","description":"The parent run's trigger source; 'local' means the browser ran on the customer's machine and the result was imported"},"status":{"type":"string","title":"Status"},"phase":{"type":"string","title":"Phase","description":"Section the outcome came from: 'setup' | 'main' | 'teardown'. A setup/teardown red is a harness break and is excluded from this test's streak and pass-rate.","default":"main"},"started_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Started At"},"completed_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Completed At"},"duration_ms":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Duration Ms"},"error_message":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Error Message"},"screenshot_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Screenshot Url"},"dom_snapshot_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Dom Snapshot Url"},"trace_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Trace Url"},"frame_urls":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Frame Urls"},"heal":{"anyOf":[{"$ref":"#/components/schemas/HealOutcomeResponse"},{"type":"null"}],"description":"Set when Beryl healed this result and it re-ran green."},"heal_attempt":{"anyOf":[{"$ref":"#/components/schemas/HealAttemptResponse"},{"type":"null"}],"description":"Set when Beryl tried to heal this red and it stayed red."},"heal_skip_reason":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Heal Skip Reason","description":"Why Beryl did not try to heal this red automatically."}},"type":"object","required":["test_result_id","test_run_id","status"],"title":"TestHistoryEntry","description":"One historical execution of a single TestCase.\n\nNewest-first ordering is the responsibility of the producer\n(``GET /tests/{test_case_id}/history``). Each entry carries enough to\nrender a hoverable chip — status, timing, plus links to the run\npage and artifact URLs."},"TestHistoryResponse":{"properties":{"test_case_id":{"type":"string","title":"Test Case Id"},"total_runs":{"type":"integer","title":"Total Runs"},"history":{"items":{"$ref":"#/components/schemas/TestHistoryEntry"},"type":"array","title":"History"},"current_streak":{"anyOf":[{"$ref":"#/components/schemas/TestHistoryStreak"},{"type":"null"}]},"stability":{"anyOf":[{"$ref":"#/components/schemas/TestHistoryStability"},{"type":"null"}]},"id":{"type":"string","title":"Id","readOnly":true}},"type":"object","required":["test_case_id","total_runs","id"],"title":"TestHistoryResponse"},"TestHistoryStability":{"properties":{"pass_rate":{"type":"number","title":"Pass Rate"},"flips":{"type":"integer","title":"Flips"},"window":{"type":"integer","title":"Window"}},"type":"object","required":["pass_rate","flips","window"],"title":"TestHistoryStability","description":"Flakiness signal computed over the last N runs.\n\n- ``pass_rate``: fraction of runs in the window that passed (0.0-1.0)\n- ``flips``: number of P→F or F→P transitions in the window. A\n  stable test has 0-1 flips; a flaky test has many.\n- ``window``: number of runs the metrics were computed over (≤ limit)"},"TestHistoryStreak":{"properties":{"status":{"type":"string","title":"Status"},"length":{"type":"integer","title":"Length"},"since":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Since"}},"type":"object","required":["status","length"],"title":"TestHistoryStreak","description":"How long this test has been in its current pass/fail state.\n\nFor terminal statuses only. ``length`` counts how many consecutive\nmost-recent runs share ``status`` (e.g. failing 3× in a row).\n``since`` is the started_at of the first run in that streak — i.e.\nthe moment the streak began."},"TestListPage":{"properties":{"items":{"items":{"$ref":"#/components/schemas/TestResponse"},"type":"array","title":"Items"},"total":{"type":"integer","title":"Total","description":"Tests matching the filters, across all pages."},"page":{"type":"integer","title":"Page","description":"1-indexed page actually returned."},"page_size":{"type":"integer","title":"Page Size"},"status_totals":{"additionalProperties":{"type":"integer"},"type":"object","title":"Status Totals"},"group_counts":{"additionalProperties":{"type":"integer"},"type":"object","title":"Group Counts"},"ungrouped_count":{"type":"integer","title":"Ungrouped Count","default":0}},"type":"object","required":["total","page","page_size"],"title":"TestListPage","description":"One offset page of a project's tests, plus the counts a numbered pager needs.\n\nA separate endpoint from ``GET /tests`` rather than a shape change to it: the\npublished CLI reads that route as a bare array and needs the unpaged list to\nresolve ``--group`` before triggering a run."},"TestPlanResponse":{"properties":{"id":{"type":"string","title":"Id"},"json_plan":{"title":"Json Plan"},"authored_by":{"type":"string","title":"Authored By"},"self_heal_enabled":{"type":"boolean","title":"Self Heal Enabled","default":true},"current_version_no":{"type":"integer","title":"Current Version No","default":0},"updated_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Updated At"}},"type":"object","required":["id","json_plan","authored_by"],"title":"TestPlanResponse"},"TestPlanUpdateRequest":{"properties":{"json_plan":{"additionalProperties":true,"type":"object","title":"Json Plan"},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Description"}},"type":"object","required":["json_plan"],"title":"TestPlanUpdateRequest"},"TestRecompileResponse":{"properties":{"id":{"type":"string","title":"Id"},"json_plan":{"title":"Json Plan"},"authored_by":{"type":"string","title":"Authored By"},"self_heal_enabled":{"type":"boolean","title":"Self Heal Enabled","default":true},"current_version_no":{"type":"integer","title":"Current Version No","default":0},"updated_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Updated At"},"verified":{"type":"boolean","title":"Verified"},"verdict":{"type":"string","title":"Verdict"},"persisted":{"type":"boolean","title":"Persisted"},"verify_message":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Verify Message"},"error_context":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Error Context"},"screenshot_b64":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Screenshot B64"},"validation_warnings":{"items":{"type":"string"},"type":"array","title":"Validation Warnings"}},"type":"object","required":["id","json_plan","authored_by","verified","verdict","persisted"],"title":"TestRecompileResponse","description":"A plan edit that went through the recompile loop (re-validate -> codegen ->\nAI verify). ``persisted`` is False only when the replay deterministically failed\n(the edit was rejected, not shipped); the live ``json_plan`` is then unchanged."},"TestResponse":{"properties":{"id":{"type":"string","title":"Id"},"project_id":{"type":"string","title":"Project Id"},"nl_test_case_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Nl Test Case Id"},"discovered_url_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Discovered Url Id"},"nl_title":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Nl Title"},"nl_description":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Nl Description"},"flow_id":{"type":"string","title":"Flow Id","description":"The logical test this row belongs to. Every surface variant of one flow shares its title, groups and access."},"surface":{"type":"string","title":"Surface","description":"Where this variant runs: web-desktop, web-tablet or web-mobile."},"is_active":{"type":"boolean","title":"Is Active"},"authored_by":{"type":"string","title":"Authored By","default":"system"},"groups":{"items":{"type":"string"},"type":"array","title":"Groups"},"self_heal_enabled":{"type":"boolean","title":"Self Heal Enabled","default":true},"quarantined":{"type":"boolean","title":"Quarantined","default":false},"access":{"type":"string","title":"Access","description":"'read': the test only reads the app. 'write': it changes state.","default":"read"},"quarantined_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Quarantined At","description":"When the test was quarantined; null while it isn't."},"quarantine_source":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Quarantine Source","description":"Who quarantined it: 'user' or 'auto'. Null while it isn't."},"has_script":{"type":"boolean","title":"Has Script"},"retrying":{"type":"boolean","title":"Retrying","default":false},"environment_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Environment Id","description":"Environment the per-env status fields below resolve against."},"last_result_status":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Last Result Status","description":"Latest result status of this test in the selected environment."},"last_run_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Last Run At","description":"When this test last ran in the selected environment."},"last_result_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Last Result Id","description":"Id of this test's latest result in the selected environment."},"rehab_ready":{"type":"boolean","title":"Rehab Ready","description":"This quarantined test has passed cleanly its last quarantine_release_passes runs (the project's release threshold) in the selected environment, so it looks safe to un-quarantine. A suggestion only unless the project's auto_quarantine is on. Always false for a test that isn't quarantined.","default":false},"rehab_pass_streak":{"type":"integer","title":"Rehab Pass Streak","description":"Consecutive clean passes behind rehab_ready, capped at the threshold. 0 for a test that isn't quarantined.","default":0},"requires_auth":{"type":"boolean","title":"Requires Auth","description":"This test runs against an authenticated session rather than a public page. Derived from the same rule the runner uses to decide whether to inject the saved login, so it can't drift from actual behaviour. Broader than TestCompileResponse.requires_auth, which excludes plans that sign themselves in inline.","default":false},"created_at":{"type":"string","format":"date-time","title":"Created At"},"updated_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Updated At"}},"type":"object","required":["id","project_id","discovered_url_id","flow_id","surface","is_active","has_script","created_at"],"title":"TestResponse"},"TestResultResponse":{"properties":{"id":{"type":"string","title":"Id"},"test_run_id":{"type":"string","title":"Test Run Id"},"test_case_id":{"type":"string","title":"Test Case Id"},"status":{"type":"string","title":"Status"},"phase":{"type":"string","title":"Phase","description":"Which section of the test the outcome came from: 'setup' (reaching the start state — e.g. an expired login), 'main' (the test itself), or 'teardown' (cleanup). A failure in setup or teardown is the harness breaking, not a regression in your app, and is excluded from the new-failure count.","default":"main"},"quarantined":{"type":"boolean","title":"Quarantined","description":"The test was quarantined when this result was produced: it ran and its outcome was recorded, but a red here did not fail the run.","default":false},"teardown_outcome":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Teardown Outcome","description":"What happened to the plan's 'after' section: 'clean' (ran and passed), 'skipped' (never reached), 'failed' (its own step failed), 'unverified' (the body failed first), 'none' (the plan has no 'after'). Null on older rows."},"previous_run_status":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Previous Run Status"},"failing_since":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Failing Since"},"title":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Title"},"error_message":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Error Message"},"failed_step_index":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Failed Step Index","description":"0-based index, over before + steps + after, of the step the test was on when it failed; null when it failed in `after` or before any step ran."},"duration_ms":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Duration Ms"},"screenshot_s3_key":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Screenshot S3 Key"},"dom_snapshot_s3_key":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Dom Snapshot S3 Key"},"trace_s3_key":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Trace S3 Key"},"frame_s3_keys":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Frame S3 Keys"},"screenshot_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Screenshot Url","description":"Presigned URL for the failure screenshot; null if none captured."},"dom_snapshot_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Dom Snapshot Url","description":"Presigned URL for the DOM snapshot captured at failure; null if none."},"trace_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Trace Url","description":"Presigned URL for the Playwright trace zip; null if none captured."},"frame_urls":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Frame Urls","description":"Ordered presigned URLs for the per-step filmstrip frames."},"attempt_count":{"type":"integer","title":"Attempt Count","description":"How many attempts this status took. 1 = passed/failed first try.","default":1},"flaky":{"type":"boolean","title":"Flaky","description":"Passed, but only after a retry — a transient failure the retry absorbed. The failing attempt's evidence is kept in `attempts`.","default":false},"attempts":{"anyOf":[{"items":{"$ref":"#/components/schemas/TestAttemptResponse"},"type":"array"},{"type":"null"}],"title":"Attempts","description":"Per-attempt evidence, in execution order. Only populated when more than one attempt ran; a first-try outcome is fully described by this row."},"heal":{"anyOf":[{"$ref":"#/components/schemas/HealOutcomeResponse"},{"type":"null"}],"description":"Set when Beryl healed this result: its steps were rewritten with the intent unchanged, proved in a browser, and it re-ran green in this run."},"heal_attempt":{"anyOf":[{"$ref":"#/components/schemas/HealAttemptResponse"},{"type":"null"}],"description":"Set when Beryl tried to heal this red and the test stayed red: how the heal ended and why."},"heal_skip_reason":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Heal Skip Reason","description":"Why Beryl did not try to heal this red automatically; null when a heal ran or the result passed."},"started_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Started At"},"completed_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Completed At"}},"type":"object","required":["id","test_run_id","test_case_id","status"],"title":"TestResultResponse"},"TestRunReportResponse":{"properties":{"id":{"type":"string","title":"Id"},"test_run_id":{"type":"string","title":"Test Run Id"},"content":{"additionalProperties":true,"type":"object","title":"Content"},"generated_at":{"type":"string","format":"date-time","title":"Generated At"}},"type":"object","required":["id","test_run_id","content","generated_at"],"title":"TestRunReportResponse"},"TestRunResponse":{"properties":{"id":{"type":"string","title":"Id"},"project_id":{"type":"string","title":"Project Id"},"environment_id":{"type":"string","title":"Environment Id","description":"Environment the run executed against."},"trigger_source":{"type":"string","title":"Trigger Source"},"status":{"type":"string","title":"Status"},"total_tests":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Total Tests"},"passed_count":{"type":"integer","title":"Passed Count"},"failed_count":{"type":"integer","title":"Failed Count"},"errored_count":{"type":"integer","title":"Errored Count"},"cancelled_count":{"type":"integer","title":"Cancelled Count"},"quarantined_count":{"type":"integer","title":"Quarantined Count","description":"Reds from quarantined tests. Counted separately from failed/errored so they don't gate the run; the five counters are disjoint.","default":0},"cancel_requested_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Cancel Requested At"},"queue_position":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Queue Position","description":"1-based place in the project's run queue while status is queued; a project runs one run at a time, in trigger order. Null otherwise."},"waiting_for_run_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Waiting For Run Id","description":"The project's active run a queued run waits on; null otherwise."},"queued_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Queued At","description":"When a run that had to wait was triggered; null if it never queued."},"summary":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Summary"},"exploration_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Exploration Id"},"triggered_by":{"anyOf":[{"$ref":"#/components/schemas/RunTriggeredBy"},{"type":"null"}],"description":"User who triggered the run; null for scheduled/system runs."},"schedule":{"anyOf":[{"$ref":"#/components/schemas/RunScheduleRef"},{"type":"null"}],"description":"Schedule that produced the run; null for manual/onboarding runs."},"duration_ms":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Duration Ms","description":"Wall-clock run duration in ms; null until the run completes."},"billed_ms":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Billed Ms","description":"Cloud-billable browser time in ms (every attempt's duration, retries included, plus the run's one-time session sign-in and any concluded self-heal browser time). Null while the run is in flight and for runs that never meter (local imports, support runs)."},"new_failures_count":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"New Failures Count","description":"Tests failing/erroring this run that passed or were absent last run."},"fixed_count":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Fixed Count","description":"Tests passing this run that failed or errored last run."},"findings_gate":{"anyOf":[{"$ref":"#/components/schemas/FindingsGateResult"},{"type":"null"}],"description":"Findings gate result, frozen when the run finished; null when the project's gate was off, the run is still in flight, or the run ended failed without finishing its tests."},"target_url_override":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Target Url Override","description":"Per-run base-URL override the run executed against (from `runs trigger --url-override`); null when the run used the environment's default base URL."},"commit_sha":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Commit Sha","description":"Commit of your app the run tested; null when the trigger sent none."},"branch":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Branch","description":"Branch of your app the run tested; null when the trigger sent none."},"commit_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Commit Url","description":"Link to the commit; null when the trigger sent none."},"pr_number":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Pr Number","description":"Pull/merge request number; null when the trigger sent none."},"started_at":{"type":"string","format":"date-time","title":"Started At"},"completed_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Completed At"},"first_test_started_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"First Test Started At","description":"When the run's first test started. started_at is when the run was triggered, so the gap between the two is time spent waiting to start. Null until a test starts, and on run lists."},"expected_run_ms":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Expected Run Ms","description":"Typical running time in ms (first test start to run end) of recent completed cloud runs on the same environment with the same test count. Set only on an in-flight run whose first test has started, and null when there isn't enough history."},"test_results":{"items":{"$ref":"#/components/schemas/TestResultResponse"},"type":"array","title":"Test Results"}},"type":"object","required":["id","project_id","environment_id","trigger_source","status","passed_count","failed_count","errored_count","cancelled_count","started_at"],"title":"TestRunResponse"},"TestUpdateRequest":{"properties":{"title":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Title"},"groups":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Groups"},"access":{"anyOf":[{"type":"string","enum":["read","write"]},{"type":"null"}],"title":"Access"},"intent":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Intent","description":"What the test proves, in plain language: the target heal judges against. Shared by every surface of the test; the plan is not regenerated."}},"type":"object","title":"TestUpdateRequest","description":"Partial update of a test's own metadata. An omitted field is left alone; a\npresent ``groups`` REPLACES the whole set (send [] to clear)."},"TokenResponse":{"properties":{"id":{"type":"string","title":"Id"},"name":{"type":"string","title":"Name"},"token_prefix":{"type":"string","title":"Token Prefix"},"last_used_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Last Used At"},"expires_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Expires At"},"revoked_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Revoked At"},"created_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Created At"}},"type":"object","required":["id","name","token_prefix"],"title":"TokenResponse"},"TrackerSettings":{"properties":{"provider":{"anyOf":[{"type":"string","const":"linear"},{"type":"null"}],"title":"Provider","description":"Issue tracker Site Health files tickets in; null = not connected for this environment"},"team_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Team Id","description":"Tracker team the tickets go to"},"team_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Team Name"},"project_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Project Id","description":"Tracker project inside the team; optional"},"project_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Project Name"},"labels":{"items":{"type":"string"},"type":"array","title":"Labels","description":"Label names put on every ticket; missing labels are created"},"priority_map":{"$ref":"#/components/schemas/PriorityMap","description":"Finding severity to tracker priority"},"auto_file_threshold":{"type":"string","enum":["high","medium","low"],"title":"Auto File Threshold","description":"Lowest severity filed as a ticket automatically; the rest go to the digest","default":"high"},"digest":{"type":"string","enum":["off","daily","weekly"],"title":"Digest","description":"How often findings that were not filed are summarized","default":"weekly"},"digest_target":{"type":"string","enum":["ticket","slack"],"title":"Digest Target","description":"ticket = one digest ticket kept up to date; slack = the workspace's Slack alert channel","default":"ticket"},"auto_close":{"type":"boolean","title":"Auto Close","description":"Close a ticket when a later run no longer sees it","default":true},"reopen_on_regression":{"type":"boolean","title":"Reopen On Regression","description":"Reopen the same ticket when a fixed finding comes back; false files a new one","default":true},"reopen_if_closed_while_failing":{"type":"boolean","title":"Reopen If Closed While Failing","description":"Reopen a ticket closed in the tracker while the check still fails","default":true},"max_tickets_per_run":{"type":"integer","maximum":100.0,"minimum":0.0,"title":"Max Tickets Per Run","description":"New tickets one run may file; the rest go to the digest","default":10},"assignee_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Assignee Id","description":"Tracker user (a person or an agent user) new tickets are assigned to"},"min_consecutive_runs_manual":{"type":"integer","maximum":10.0,"minimum":1.0,"title":"Min Consecutive Runs Manual","description":"Runs in a row a finding must show in before a manual run files it","default":1},"min_consecutive_runs_scheduled":{"type":"integer","maximum":10.0,"minimum":1.0,"title":"Min Consecutive Runs Scheduled","description":"Runs in a row a finding must show in before a scheduled or CI run files it","default":2},"paused":{"type":"boolean","title":"Paused","description":"Stop all ticket creation and updates without disconnecting","default":false}},"additionalProperties":false,"type":"object","title":"TrackerSettings"},"TrackerSettingsUpdate":{"properties":{"provider":{"anyOf":[{"type":"string","const":"linear"},{"type":"null"}],"title":"Provider"},"team_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Team Id"},"team_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Team Name"},"project_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Project Id"},"project_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Project Name"},"labels":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Labels"},"priority_map":{"anyOf":[{"$ref":"#/components/schemas/PriorityMap"},{"type":"null"}]},"auto_file_threshold":{"anyOf":[{"type":"string","enum":["high","medium","low"]},{"type":"null"}],"title":"Auto File Threshold"},"digest":{"anyOf":[{"type":"string","enum":["off","daily","weekly"]},{"type":"null"}],"title":"Digest"},"digest_target":{"anyOf":[{"type":"string","enum":["ticket","slack"]},{"type":"null"}],"title":"Digest Target"},"auto_close":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Auto Close"},"reopen_on_regression":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Reopen On Regression"},"reopen_if_closed_while_failing":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Reopen If Closed While Failing"},"max_tickets_per_run":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Max Tickets Per Run"},"assignee_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Assignee Id"},"min_consecutive_runs_manual":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Min Consecutive Runs Manual"},"min_consecutive_runs_scheduled":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Min Consecutive Runs Scheduled"},"paused":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Paused"}},"additionalProperties":false,"type":"object","title":"TrackerSettingsUpdate","description":"PATCH semantics: only the fields present change. Send `provider: null` to\nstop filing for the environment."},"TriggerExecutionRequest":{"properties":{"target_url_override":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Target Url Override"},"test_case_ids":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Test Case Ids"},"environment_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Environment Id","description":"Environment to run against; defaults to the project's default env."},"max_retries":{"anyOf":[{"type":"integer","maximum":3.0,"minimum":0.0},{"type":"null"}],"title":"Max Retries","description":"How many times to retry a test that fails or errors, for this run only. 0 disables retries. Omit to use the deployment default."},"extra_headers":{"anyOf":[{"additionalProperties":{"type":"string"},"type":"object"},{"type":"null"}],"title":"Extra Headers","description":"Custom HTTP request headers sent on every navigation of this run, e.g. an x-vercel-protection-bypass token to reach a protected preview deploy. Header values are treated as secrets and never returned on any run response."},"commit_sha":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Commit Sha","description":"Commit of your app this run tests, e.g. $GITHUB_SHA. Optional."},"branch":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Branch","description":"Branch of your app this run tests, e.g. main. Optional."},"commit_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Commit Url","description":"http(s) link to the commit in your repo host. Optional."},"pr_number":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Pr Number","description":"Pull/merge request number the commit belongs to. Optional."}},"type":"object","title":"TriggerExecutionRequest"},"UpdateEnvironmentRequest":{"properties":{"name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Name"},"root_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Root Url"},"app_ids":{"anyOf":[{"additionalProperties":{"type":"string"},"type":"object"},{"type":"null"}],"title":"App Ids","description":"App ids to set per app surface ({'android': 'com.acme.shop', 'ios': 'com.acme.Shop'}); only the surfaces present change, and an empty string clears one"},"requires_auth_choice":{"anyOf":[{"$ref":"#/components/schemas/RequiresAuthChoice"},{"type":"null"}]},"site_health_viewports":{"anyOf":[{"items":{"type":"string","enum":["phone","tablet_portrait","tablet_landscape","desktop","desktop_wide"]},"type":"array"},{"type":"null"}],"title":"Site Health Viewports","description":"Screen sizes for the Site Health visual checks; an empty list resets to all five"},"site_health_tracker":{"anyOf":[{"$ref":"#/components/schemas/TrackerSettingsUpdate"},{"type":"null"}],"description":"Issue tracker settings to change; only the fields present change"},"site_health_runs":{"anyOf":[{"$ref":"#/components/schemas/RunSettingsUpdate"},{"type":"null"}],"description":"Site Health schedule, CI and page list settings to change; only the fields present change"}},"type":"object","title":"UpdateEnvironmentRequest","description":"Partial edit of an environment. Every field optional — only the ones present\nare applied (PATCH semantics)."},"UpdateScheduleRequest":{"properties":{"enabled":{"type":"boolean","title":"Enabled"},"frequency":{"type":"string","enum":["daily","weekly"],"title":"Frequency","default":"daily"},"day_of_week":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Day Of Week"},"run_hour":{"type":"integer","title":"Run Hour","default":3},"run_minute":{"type":"integer","title":"Run Minute","default":0},"timezone":{"type":"string","title":"Timezone","default":"UTC"}},"type":"object","required":["enabled"],"title":"UpdateScheduleRequest"},"UpdateTestProjectRequest":{"properties":{"name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Name"},"auto_quarantine":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Auto Quarantine"},"quarantine_failures":{"anyOf":[{"type":"integer","maximum":50.0,"minimum":1.0},{"type":"null"}],"title":"Quarantine Failures"},"quarantine_days":{"anyOf":[{"type":"integer","maximum":90.0,"minimum":1.0},{"type":"null"}],"title":"Quarantine Days"},"quarantine_release_passes":{"anyOf":[{"type":"integer","maximum":50.0,"minimum":1.0},{"type":"null"}],"title":"Quarantine Release Passes"},"self_heal":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Self Heal","description":"Auto-heal failed tests during a run. Off by default: a failed test fails right away. When on, a test marked fixed (self_heal_enabled false) still never heals."},"heal_max_minutes":{"anyOf":[{"type":"integer","maximum":5.0,"minimum":1.0},{"type":"null"}],"title":"Heal Max Minutes","description":"Minutes the heal agent may spend on one failed test (1-5); the replay that proves a repair comes on top. Null means the platform default. Send null to go back to it."},"heal_max_per_run":{"anyOf":[{"type":"integer","maximum":1000.0,"minimum":1.0},{"type":"null"}],"title":"Heal Max Per Run","description":"Failed tests one run may heal; past it the rest fail without a heal. Null means no cap. Send null to remove the cap."},"enabled_surfaces":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Enabled Surfaces","description":"Surfaces enabled for this project, replacing the current set. Non-empty; any of web-desktop, web-tablet, web-mobile, android, ios."},"add_surfaces":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Add Surfaces","description":"Surfaces to turn on, merged into the current set server-side. Cannot be combined with enabled_surfaces."},"remove_surfaces":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Remove Surfaces","description":"Surfaces to turn off, removed from the current set server-side; at least one must stay enabled. Cannot be combined with enabled_surfaces."},"findings_gate":{"anyOf":[{"type":"string","enum":["off","new_since_green"]},{"type":"null"}],"title":"Findings Gate","description":"Findings gate on each run: off, or new_since_green to report the gate failed when the environment's Site Health has a finding first seen after the last green run, unknown when Site Health is not recording findings (its issue tracker must be connected). Reported next to the test verdicts; it never changes one."}},"type":"object","title":"UpdateTestProjectRequest","description":"Partial edit of a project's user-owned fields (PATCH semantics)."},"ValidationError":{"properties":{"loc":{"items":{"anyOf":[{"type":"string"},{"type":"integer"}]},"type":"array","title":"Location"},"msg":{"type":"string","title":"Message"},"type":{"type":"string","title":"Error Type"},"input":{"title":"Input"},"ctx":{"type":"object","title":"Context"}},"type":"object","required":["loc","msg","type"],"title":"ValidationError"},"VariableCreate":{"properties":{"key":{"type":"string","maxLength":255,"minLength":1,"title":"Key","description":"Variable name, unique within the project + environment scope."},"value":{"type":"string","title":"Value","description":"Plaintext value — NOT secret, returned as-is."},"environment_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Environment Id","description":"Environment to pin to; null = project-level (all environments)."}},"type":"object","required":["key","value"],"title":"VariableCreate"},"VariableResponse":{"properties":{"id":{"type":"string","title":"Id"},"key":{"type":"string","title":"Key"},"value":{"type":"string","title":"Value","description":"Plaintext value — variables are not secret."},"environment_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Environment Id","description":"Null = project-level; set = pinned to this environment."},"scope":{"type":"string","enum":["project","environment"],"title":"Scope","description":"'project' when environment_id is null, else 'environment'."},"created_at":{"type":"string","format":"date-time","title":"Created At"},"updated_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Updated At"}},"type":"object","required":["id","key","value","scope","created_at"],"title":"VariableResponse"},"VariableUpdate":{"properties":{"value":{"type":"string","title":"Value","description":"New plaintext value for this variable."}},"type":"object","required":["value"],"title":"VariableUpdate"},"VersionDiffResponse":{"properties":{"test_case_id":{"type":"string","title":"Test Case Id"},"from_version_no":{"type":"integer","title":"From Version No"},"to_version_no":{"type":"integer","title":"To Version No"},"steps":{"items":{"$ref":"#/components/schemas/VersionStepDiff"},"type":"array","title":"Steps"},"identical":{"type":"boolean","title":"Identical","default":false},"id":{"type":"string","title":"Id","readOnly":true}},"type":"object","required":["test_case_id","from_version_no","to_version_no","id"],"title":"VersionDiffResponse"},"VersionStepDiff":{"properties":{"op":{"type":"string","title":"Op"},"index":{"type":"integer","title":"Index"},"a":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"A"},"b":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"B"}},"type":"object","required":["op","index"],"title":"VersionStepDiff","description":"One entry in a step-level plan diff.\n\n``op`` is ``added`` (only in B), ``removed`` (only in A), ``changed``\n(same index, different step), or ``unchanged``. ``index`` is the step's\nposition; ``a``/``b`` are the step bodies on each side (None where absent)."},"WorkspaceCreate":{"properties":{"name":{"type":"string","title":"Name"},"domain":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Domain"},"visible_to_org":{"type":"boolean","title":"Visible To Org","default":false}},"type":"object","required":["name"],"title":"WorkspaceCreate"},"WorkspacePreview":{"properties":{"id":{"type":"string","title":"Id"},"name":{"type":"string","title":"Name"},"user_role":{"$ref":"#/components/schemas/Role"}},"type":"object","required":["id","name","user_role"],"title":"WorkspacePreview"},"WorkspaceResponse":{"properties":{"id":{"type":"string","title":"Id"},"name":{"type":"string","title":"Name"},"domain":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Domain"},"visible_to_org":{"type":"boolean","title":"Visible To Org"},"is_paid":{"type":"boolean","title":"Is Paid"},"autofix_enabled":{"type":"boolean","title":"Autofix Enabled","default":true},"created_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Created At"}},"type":"object","required":["id","name","visible_to_org","is_paid"],"title":"WorkspaceResponse"},"WorkspaceUpdate":{"properties":{"name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Name"},"visible_to_org":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Visible To Org"},"autofix_enabled":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Autofix Enabled"}},"type":"object","title":"WorkspaceUpdate"},"WorkspaceWithMembership":{"properties":{"id":{"type":"string","title":"Id"},"name":{"type":"string","title":"Name"},"domain":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Domain"},"visible_to_org":{"type":"boolean","title":"Visible To Org"},"is_paid":{"type":"boolean","title":"Is Paid"},"autofix_enabled":{"type":"boolean","title":"Autofix Enabled","default":true},"created_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Created At"},"user_role":{"$ref":"#/components/schemas/Role"}},"type":"object","required":["id","name","visible_to_org","is_paid","user_role"],"title":"WorkspaceWithMembership"},"app__email_inbox__schemas__MailboxResponse":{"properties":{"id":{"type":"string","title":"Id"},"address":{"type":"string","title":"Address"},"project_id":{"type":"string","title":"Project Id"},"is_default":{"type":"boolean","title":"Is Default"},"label":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Label"},"created_at":{"type":"string","format":"date-time","title":"Created At"}},"type":"object","required":["id","address","project_id","is_default","label","created_at"],"title":"MailboxResponse"},"app__test_accounts__schemas__MailboxResponse":{"properties":{"id":{"type":"string","title":"Id"},"address":{"type":"string","title":"Address"},"created_at":{"type":"string","format":"date-time","title":"Created At"}},"type":"object","required":["id","address","created_at"],"title":"MailboxResponse"}},"securitySchemes":{"HTTPBearer":{"type":"http","scheme":"bearer","description":"Send `Authorization: Bearer <token>`. Every route accepts a personal access token (`beryl_pat_...`, created under Account, API tokens in the webapp or with `beryl tokens create`) and the webapp's own session token. Routes marked as accepting a CI token also take a project-scoped CI token (`beryl_ci_...`), which is limited to the one project it was created for."}}},"tags":[{"name":"workspaces","description":"Workspaces you belong to. Every project lives in one."},{"name":"projects","description":"Projects: the app under test, its groups and its reusable sign-in."},{"name":"environments","description":"Environments of a project: the base URLs a suite runs against."},{"name":"tests","description":"Tests: versioned action plans, their history, quarantine and groups."},{"name":"jobs","description":"Test creation jobs: the cloud agent authors tests from a document."},{"name":"runs","description":"Runs: trigger a suite, follow progress, read results and artifacts."},{"name":"accounts","description":"Test accounts the runner signs in as, and the project mailbox."},{"name":"mailboxes","description":"Workspace mailboxes that receive test-account email."},{"name":"config","description":"Project variables, secrets and files available to tests."},{"name":"ci","description":"Project-scoped CI tokens and CI workflows."},{"name":"tokens","description":"Personal access tokens for the API, CLI and MCP server."},{"name":"account","description":"The signed-in user's profile."}]}