{"openapi":"3.1.1","info":{"title":"Stably Public API","description":"Interact with your Stably tests from anywhere","version":"1.0.0"},"components":{"securitySchemes":{"apiKey":{"type":"http","scheme":"bearer"}},"schemas":{}},"paths":{"/v1/testSuite/{testSuiteId}/run":{"post":{"summary":"Start a test suite run","tags":["testSuite"],"description":"Run a test suite","requestBody":{"required":true,"content":{"application/json":{"schema":{"x-fastify-zod-openapi-optional":true,"anyOf":[{"type":"object","properties":{"numberOfWorkers":{"type":"number","minimum":0,"maximum":100},"retries":{"type":"number"},"repeats":{"type":"number"},"operationDelayMs":{"type":"number"},"testTimeoutMs":{"type":"number"},"testMatch":{"type":"object","properties":{"glob":{"type":"string"},"regex":{"type":"string"}}},"setupTestId":{"type":"string"},"teardownTestId":{"type":"string"},"beforeEachTestId":{"type":"string"},"afterEachTestId":{"type":"string"},"notificationProfile":{"type":"string","enum":["PROJECT","SUITE","DISABLED"]},"environment":{"description":"Environment used to run the test suite","example":"PRODUCTION","type":"string","enum":["PRODUCTION","STAGING","DEVELOPMENT"]},"variableOverrides":{"description":"Variable overrides for the test suite","example":{"TEST_VAR":"test","TEST_VAR_2":{"value":"test","sensitive":true},"JSON_VAR":{"value":{"attribute":"value","anotherAttribute":"anotherValue"}}},"type":"object","propertyNames":{"type":"string"},"additionalProperties":{"anyOf":[{"type":"string"},{"type":"object","properties":{"sensitive":{"default":false,"type":"boolean"},"value":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"object","propertyNames":{},"additionalProperties":{}},{"type":"array","items":{}},{"type":"null"}]}},"required":["value"]}]}},"metadata":{"type":"object","properties":{"git":{"type":"object","properties":{"branch":{"type":"string"}},"required":["branch"]},"note":{"description":"Note to be added to the test suite run","example":"This is a note","type":"string"}}},"urlReplacements":{"type":"array","items":{"type":"object","properties":{"original":{"type":"string"},"replacement":{"type":"string"}},"required":["original","replacement"]}}},"required":[]},{"type":"null"}]}}}},"parameters":[{"schema":{"type":"string","description":"Test suite id"},"in":"path","name":"testSuiteId","required":true,"description":"Test suite id"}],"security":[{"apiKey":[]}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"projectId":{"type":"string","description":"Id of the project that contains the test suite"},"testSuiteRunId":{"type":"string","description":"Id of the suite run"},"testSuiteName":{"type":"string","description":"Name of the test suite"},"options":{"type":"object","properties":{"numberOfWorkers":{"type":"number","minimum":0,"maximum":100},"retries":{"type":"number"},"repeats":{"type":"number"},"operationDelayMs":{"type":"number"},"testTimeoutMs":{"type":"number"},"testMatch":{"type":"object","properties":{"glob":{"type":"string"},"regex":{"type":"string"}},"additionalProperties":false},"setupTestId":{"type":"string"},"teardownTestId":{"type":"string"},"beforeEachTestId":{"type":"string"},"afterEachTestId":{"type":"string"},"notificationProfile":{"type":"string","enum":["PROJECT","SUITE","DISABLED"]},"environment":{"type":"string","enum":["ALL","PRODUCTION","STAGING","DEVELOPMENT","NONE"]},"variableOverrides":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{"type":"object","properties":{"value":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"object","propertyNames":{},"additionalProperties":{}},{"type":"array","items":{}},{"type":"null"}]},"sensitive":{"type":"boolean"}},"required":["value","sensitive"],"additionalProperties":false}},"metadata":{"type":"object","properties":{"git":{"type":"object","properties":{"branch":{"type":"string"}},"required":["branch"],"additionalProperties":false},"note":{"description":"Note to be added to the test suite run","example":"This is a note","type":"string"}},"additionalProperties":false}},"additionalProperties":false,"description":"Applied options"}},"required":["projectId","testSuiteRunId","testSuiteName","options"],"additionalProperties":false,"description":"Test suite run was started"}}}},"401":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"],"additionalProperties":false,"description":"Unauthorized"}}}},"404":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"],"additionalProperties":false,"description":"Test suite not found"}}}}}}},"/v1/testSuiteRun/{testSuiteRunId}/status":{"get":{"summary":"Get the status of a test suite run","tags":["testSuite"],"description":"Get the status of a test suite run","parameters":[{"schema":{"type":"string","description":"Test suite run id"},"in":"path","name":"testSuiteRunId","required":true,"description":"Test suite run id"}],"security":[{"apiKey":[]}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string","enum":["RUNNING","FINISHED"],"description":"Status of the test suite run"}},"required":["status"],"additionalProperties":false,"description":"Test suite run status"}}}},"401":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"],"additionalProperties":false,"description":"Unauthorized"}}}},"404":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"],"additionalProperties":false,"description":"No task found"}}}}}}},"/v1/testSuiteRun/{testSuiteRunId}/result":{"get":{"summary":"Get the result of a test suite run","tags":["testSuite"],"description":"Get the result of a test suite run","parameters":[{"schema":{"type":"string","description":"Test suite run id"},"in":"path","name":"testSuiteRunId","required":true,"description":"Test suite run id"}],"security":[{"apiKey":[]}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"projectId":{"type":"string","description":"Id of the project that contains the test suite"},"testSuiteRunId":{"type":"string","description":"Id of the suite run"},"testSuiteName":{"type":"string","description":"Name of the test suite"},"results":{"type":"array","items":{"type":"object","properties":{"runId":{"type":"string","description":"Id of the test run"},"testId":{"type":"string","description":"Id of the test that was run by the test suite"},"testName":{"type":"string","description":"Name of the test that was run by the test suite"},"status":{"type":"string","enum":["PASSED","FAILED","RUNNING","ERROR","FLAKY","CANCELLED","SKIPPED","QUEUED","RETRYING"],"description":"Status of the test run"}},"required":["runId","testId","testName","status"],"additionalProperties":false}}},"required":["projectId","testSuiteRunId","testSuiteName","results"],"additionalProperties":false,"description":"Test suite results"}}}},"401":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"],"additionalProperties":false,"description":"Unauthorized"}}}}}}},"/v1/testSuiteRun/cancel":{"post":{"summary":"Cancel test suite runs","tags":["testSuite"],"description":"Cancel test suite runs. Provide either testSuiteId to cancel all in-flight and queued runs for a test suite, or testSuiteRunId to cancel a specific run.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"where":{"anyOf":[{"type":"object","properties":{"testSuiteId":{"type":"string","description":"Cancel all in-flight and queued runs for this test suite"}},"required":["testSuiteId"]},{"type":"object","properties":{"testSuiteRunId":{"type":"string","description":"Cancel a specific test suite run"}},"required":["testSuiteRunId"]}],"description":"Specify either testSuiteId or testSuiteRunId to identify runs to cancel"}},"required":["where"]}}}},"security":[{"apiKey":[]}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"cancelled":{"type":"array","items":{"type":"object","properties":{"testSuiteRunId":{"type":"string","description":"Id of the cancelled test suite run"}},"required":["testSuiteRunId"],"additionalProperties":false},"description":"List of cancelled test suite runs"}},"required":["cancelled"],"additionalProperties":false,"description":"Test suite runs were cancelled"}}}},"401":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"],"additionalProperties":false,"description":"Unauthorized"}}}}}}},"/v1/testSuiteRun/{testSuiteRunId}/trace":{"get":{"summary":"Get trace download URL","tags":["testSuite"],"description":"Get a presigned URL for downloading the Playwright trace zip of a test run attempt","parameters":[{"schema":{"description":"Attempt id. If omitted, the first attempt is used.","type":"string"},"in":"query","name":"attemptId","description":"Attempt id. If omitted, the first attempt is used."},{"schema":{"type":"string","description":"Test suite run id"},"in":"path","name":"testSuiteRunId","required":true,"description":"Test suite run id"}],"security":[{"apiKey":[]}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"presignedUrl":{"type":"string","description":"Presigned URL to download the trace zip"},"expiresInSeconds":{"type":"number","description":"URL expiration time in seconds"}},"required":["presignedUrl","expiresInSeconds"],"additionalProperties":false,"description":"Trace download URL"}}}},"401":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"],"additionalProperties":false,"description":"Unauthorized"}}}},"404":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"],"additionalProperties":false,"description":"Test suite run or attempt not found"}}}}}}},"/v1/tcms/project/{projectId}/overview":{"get":{"summary":"Get TCMS overview","tags":["tcms"],"description":"Get TCMS overview for a project","parameters":[{"schema":{"type":"string"},"in":"query","name":"search"},{"schema":{"type":"string"},"in":"query","name":"suiteId"},{"schema":{"type":"array","items":{"type":"string","enum":["ACTIVE","DRAFT","DEPRECATED"]}},"in":"query","name":"status"},{"schema":{"type":"array","items":{"type":"string","enum":["CRITICAL","HIGH","MEDIUM","LOW"]}},"in":"query","name":"priority"},{"schema":{"type":"array","items":{"type":"string"}},"in":"query","name":"tags"},{"schema":{"type":"string"},"in":"path","name":"projectId","required":true}],"security":[{"apiKey":[]}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"cases":{"type":"array","items":{}},"suites":{"type":"array","items":{}},"suiteTree":{"type":"array","items":{}},"stats":{},"tags":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"}},"required":["id","name"],"additionalProperties":false}},"recentRuns":{"type":"array","items":{}}},"required":["cases","suites","suiteTree","stats","tags","recentRuns"],"additionalProperties":false}}}},"401":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"],"additionalProperties":false}}}}}}},"/v1/tcms/project/{projectId}/cases":{"post":{"summary":"Upsert TCMS case","tags":["tcms"],"description":"Create or update a TCMS case","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"mode":{"default":"commit","type":"string","enum":["commit","draft"]},"draftKey":{"type":"string"},"case":{"type":"object","properties":{"id":{"type":"string"},"title":{"type":"string","minLength":1},"description":{"type":"string"},"priority":{"type":"string","enum":["CRITICAL","HIGH","MEDIUM","LOW"]},"status":{"type":"string","enum":["ACTIVE","DRAFT","DEPRECATED"]},"tags":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","minLength":1},"name":{"type":"string","minLength":1}},"required":["id","name"]}},"owners":{"type":"array","items":{"type":"string"}},"suiteIds":{"type":"array","items":{"type":"string"}}},"required":["title"]}},"required":["case"]}}}},"parameters":[{"schema":{"type":"string"},"in":"path","name":"projectId","required":true}],"security":[{"apiKey":[]}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"case":{}},"required":["case"],"additionalProperties":false}}}},"401":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"],"additionalProperties":false}}}}}}},"/v1/tcms/project/{projectId}/cases/{caseId}/link":{"post":{"summary":"Link case to Playwright test","tags":["tcms"],"description":"Link a TCMS case to a Playwright test","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"testIdentifier":{"type":"string","minLength":1},"mode":{"default":"LINK","type":"string","enum":["LINK","UNLINK"]}},"required":["testIdentifier"]}}}},"parameters":[{"schema":{"type":"string"},"in":"path","name":"projectId","required":true},{"schema":{"type":"string"},"in":"path","name":"caseId","required":true}],"security":[{"apiKey":[]}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"result":{}},"required":["result"],"additionalProperties":false}}}},"401":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"],"additionalProperties":false}}}}}}},"/v1/tcms/project/{projectId}/suites":{"post":{"summary":"Upsert TCMS suite","tags":["tcms"],"description":"Create or update a TCMS suite","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"mode":{"default":"commit","type":"string","enum":["commit","draft"]},"draftKey":{"type":"string"},"suite":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string","minLength":1},"description":{"type":"string"},"caseIds":{"type":"array","items":{"type":"string"}}},"required":["name"]}},"required":["suite"]}}}},"parameters":[{"schema":{"type":"string"},"in":"path","name":"projectId","required":true}],"security":[{"apiKey":[]}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"suite":{}},"required":["suite"],"additionalProperties":false}}}},"401":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"],"additionalProperties":false}}}}}}},"/v1/tcms/project/{projectId}/runs":{"post":{"summary":"Record TCMS suite run","tags":["tcms"],"description":"Create a TCMS suite run record","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"suiteId":{"type":"string"},"status":{"type":"string","enum":["QUEUED","RUNNING","PASSED","FAILED","PARTIAL","CANCELED"]},"notes":{"type":"string"},"triggeredBy":{"type":"string"},"playwrightSuiteRunId":{"type":"string"},"caseStatuses":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{"type":"string","enum":["QUEUED","RUNNING","PASSED","FAILED","PARTIAL","CANCELED"]}}},"required":["suiteId","status"]}}}},"parameters":[{"schema":{"type":"string"},"in":"path","name":"projectId","required":true}],"security":[{"apiKey":[]}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"runId":{"type":"string"}},"required":["runId"],"additionalProperties":false}}}},"401":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"],"additionalProperties":false}}}}}}},"/v1/projects/{projectId}/runs":{"post":{"summary":"Start a test run","tags":["runner"],"description":"Start a test run","requestBody":{"required":true,"content":{"application/json":{"schema":{"x-fastify-zod-openapi-optional":true,"anyOf":[{"type":"object","properties":{"playwrightProjectName":{"description":"Playwright project name(s) to run. Maps to --project CLI flag.","anyOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}]},"runGroupName":{"deprecated":true,"description":"Deprecated. Use playwrightProjectName instead.","anyOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}]},"envOverrides":{"type":"object","properties":{},"additionalProperties":{"type":"string"}},"environment":{"description":"Name of the environment to use for this run (e.g. \"Staging\", \"Production\"). When omitted, falls back to the project's default environment.","type":"string"},"environmentName":{"deprecated":true,"description":"Deprecated. Use environment instead.","type":"string"},"autofix":{"description":"When true, automatically attempt to fix failing tests after the run completes.","type":"boolean"},"branch":{"description":"Git branch to run tests against. When omitted, uses the project's default branch.","example":"staging/dev","type":"string","minLength":1,"maxLength":255}}},{"type":"null"}]}}}},"parameters":[{"schema":{"type":"string"},"in":"path","name":"projectId","required":true}],"security":[{"apiKey":[]}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"runId":{"type":"string","description":"ID to use for polling the run status and results"}},"required":["runId"],"additionalProperties":false}}}},"400":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"],"additionalProperties":false,"description":"Bad request"}}}},"500":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"],"additionalProperties":false,"description":"Internal server error"}}}}}}},"/v1/projects/{projectId}/runs/{runId}":{"get":{"summary":"Get test run status and results","tags":["runner"],"description":"Get the status and results of a test run","parameters":[{"schema":{"type":"string"},"in":"path","name":"projectId","required":true},{"schema":{"type":"string"},"in":"path","name":"runId","required":true}],"security":[{"apiKey":[]}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string","enum":["QUEUED","RUNNING","PASSED","FAILED","TIMEDOUT","CANCELLED","INTERRUPTED"],"description":"Overall status of the test run"},"startedAt":{"description":"ISO timestamp when the run started (null for queued runs)","type":"string"},"finishedAt":{"description":"ISO timestamp when the run finished","type":"string"},"branchName":{"description":"Git branch name associated with this run","type":"string"},"results":{"description":"Test results (only present when status is not running)","type":"object","properties":{"testCases":{"type":"array","items":{"type":"object","properties":{"title":{"type":"string","description":"Test case title"},"status":{"type":"string","enum":["QUEUED","RUNNING","PASSED","FAILED","TIMEDOUT","SKIPPED","INTERRUPTED","FLAKY"],"description":"Test case status"},"durationMs":{"description":"Test duration in milliseconds","type":"number"}},"required":["title","status"],"additionalProperties":false}}},"required":["testCases"],"additionalProperties":false}},"required":["status"],"additionalProperties":false}}}},"404":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"],"additionalProperties":false,"description":"Run not found"}}}}}}},"/v1/projects/{projectId}/runs/cancel":{"post":{"summary":"Cancel a test run","tags":["runner"],"description":"Cancel a test run. The run must be in QUEUED or RUNNING status. If the run has a container, the container will be stopped.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"where":{"type":"object","properties":{"runId":{"type":"string","description":"ID of the run to cancel"}},"required":["runId"]}},"required":["where"]}}}},"parameters":[{"schema":{"type":"string"},"in":"path","name":"projectId","required":true}],"security":[{"apiKey":[]}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"cancelled":{"type":"array","items":{"type":"object","properties":{"runId":{"type":"string","description":"ID of the cancelled run"}},"required":["runId"],"additionalProperties":false},"description":"List of cancelled runs"}},"required":["cancelled"],"additionalProperties":false,"description":"Run was cancelled"}}}},"400":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"],"additionalProperties":false,"description":"Bad request"}}}},"401":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"],"additionalProperties":false,"description":"Unauthorized"}}}}}}},"/internal/v1/cli/exchange-token":{"post":{"tags":["CLI Internal"],"description":"Exchange a full OAuth token for a smaller org-scoped token","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"accessToken":{"type":"string","description":"The full OAuth access token to exchange"},"orgId":{"type":"string","description":"Organization ID to scope the token to"}},"required":["accessToken","orgId"]}}}},"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"accessToken":{"type":"string"},"expiresInSeconds":{"type":"number"}},"required":["accessToken","expiresInSeconds"],"additionalProperties":false}}}},"401":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"],"additionalProperties":false}}}},"403":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"],"additionalProperties":false}}}}}}},"/openapi.json":{"get":{"responses":{"200":{"description":"Default Response"}}}}},"servers":[{"url":"https://api.stably.ai","description":"Production Server"}]}