{"openapi":"3.1.0","info":{"title":"Empirical API","version":"1.0.0","description":"Programmatic access to Empirical test runs, snoozes, and more.","contact":{"name":"Empirical","url":"https://empirical.run"}},"servers":[{"url":"https://api.empirical.run"}],"security":[{"Bearer":[]}],"tags":[{"name":"Analytics","description":"Aggregated test-run, test-count and test-case analytics for a project."}],"components":{"securitySchemes":{"Bearer":{"type":"http","scheme":"bearer"}},"schemas":{"ErrorResponse":{"type":"object","properties":{"data":{"nullable":true,"description":"Always null for error responses."},"error":{"type":"object","properties":{"message":{"type":"string","description":"Human-readable error message."}},"required":["message"],"description":"Error details."}},"required":["data","error"]},"AnalyticsTestRunsResponse":{"type":"object","properties":{"data":{"type":"object","properties":{"daily":{"type":"array","items":{"$ref":"#/components/schemas/AnalyticsDaily"}},"summary":{"$ref":"#/components/schemas/AnalyticsRunsSummary"}},"required":["daily","summary"],"description":"Response payload."}},"required":["data"]},"AnalyticsDaily":{"type":"object","properties":{"date":{"type":"string","description":"Date in YYYY-MM-DD format."},"run_count":{"type":"number","description":"Total number of test runs on this date."},"passed_runs":{"type":"number","description":"Number of passed test runs."},"failed_runs":{"type":"number","description":"Number of failed test runs."},"error_runs":{"type":"number","description":"Number of test runs that errored."},"cancelled_runs":{"type":"number","description":"Number of cancelled test runs."},"rerun_count":{"type":"number","description":"Number of reruns on this date."},"total_tests":{"type":"number","description":"Total number of tests executed."},"passed_tests":{"type":"number","description":"Number of passed tests."},"failed_tests":{"type":"number","description":"Number of failed tests."},"failed_tests_after_snooze":{"type":"number","description":"Number of failed tests after applying snoozes."},"flaky_tests":{"type":"number","description":"Number of flaky tests."}},"required":["date","run_count","passed_runs","failed_runs","error_runs","cancelled_runs","rerun_count","total_tests","passed_tests","failed_tests","failed_tests_after_snooze","flaky_tests"]},"AnalyticsRunsSummary":{"type":"object","properties":{"total_runs":{"type":"number","description":"Total number of test runs in the period."},"passed_runs":{"type":"number","description":"Number of passed test runs."},"failed_runs":{"type":"number","description":"Number of failed test runs."},"error_runs":{"type":"number","description":"Number of test runs that errored."},"pass_rate":{"type":"number","description":"Pass rate as a percentage (0-100)."},"avg_tests_per_run":{"type":"number","description":"Average number of tests per run."},"rerun_count":{"type":"number","description":"Total number of reruns."},"rerun_rate":{"type":"number","description":"Rerun rate as a percentage (0-100)."}},"required":["total_runs","passed_runs","failed_runs","error_runs","pass_rate","avg_tests_per_run","rerun_count","rerun_rate"]},"AnalyticsTestCountResponse":{"type":"object","properties":{"data":{"type":"object","properties":{"daily":{"type":"array","items":{"$ref":"#/components/schemas/TestCountByDayEntry"}},"summary":{"$ref":"#/components/schemas/TestCountSummary"}},"required":["daily","summary"],"description":"Response payload."}},"required":["data"]},"TestCountByDayEntry":{"type":"object","properties":{"date":{"type":"string","description":"Date in YYYY-MM-DD format."},"test_count":{"type":"number","description":"Number of distinct test cases that ran on this date (skipped tests excluded)."}},"required":["date","test_count"]},"TestCountSummary":{"type":"object","properties":{"latest_count":{"type":"number","description":"Test count on the most recent day in the window."},"first_count":{"type":"number","description":"Test count on the first day in the window."},"change":{"type":"number","description":"Absolute change between `first_count` and `latest_count`."},"change_percent":{"type":"number","description":"Percentage change (0-100) between first and latest day."}},"required":["latest_count","first_count","change","change_percent"]},"AnalyticsErrorResponse":{"type":"object","properties":{"error":{"type":"string","description":"Human-readable error message."}},"required":["error"]},"AnalyticsTestCasesResponse":{"type":"object","properties":{"data":{"type":"object","properties":{"test_cases":{"type":"array","items":{"$ref":"#/components/schemas/AnalyticsTestCase"}},"summary":{"$ref":"#/components/schemas/AnalyticsTestCasesSummary"}},"required":["test_cases","summary"],"description":"Response payload."}},"required":["data"]},"AnalyticsTestCase":{"type":"object","properties":{"test_case_id":{"type":"string","description":"Unique identifier for the test case."},"test_name":{"type":"string","description":"Name of the test case."},"file_path":{"type":"string","description":"File path of the test case."},"project_name":{"type":"string","description":"Name of the project the test belongs to."},"tags":{"type":"array","items":{"type":"string"},"description":"Array of tags associated with the test case."},"last_run_at":{"type":"string","description":"ISO 8601 timestamp of the last time this test was run."},"metrics":{"type":"object","properties":{"total_runs":{"type":"number","description":"Total number of runs for this test case."},"pass_count":{"type":"number","description":"Number of times the test passed."},"fail_count":{"type":"number","description":"Number of times the test failed."},"flaky_count":{"type":"number","description":"Number of times the test was flaky."},"pass_rate":{"type":"number","description":"Pass rate as a percentage (0-100)."},"fail_rate":{"type":"number","description":"Fail rate as a percentage (0-100)."},"flaky_rate":{"type":"number","description":"Flaky rate as a percentage (0-100)."}},"required":["total_runs","pass_count","fail_count","flaky_count","pass_rate","fail_rate","flaky_rate"],"description":"Aggregated metrics for this test case."},"history":{"type":"array","items":{"$ref":"#/components/schemas/TestCaseHistoryEntry"},"description":"History of test executions for this test case."}},"required":["test_case_id","test_name","file_path","project_name","tags","last_run_at","metrics","history"]},"TestCaseHistoryEntry":{"type":"object","properties":{"timestamp":{"type":"string","description":"ISO 8601 timestamp of the history entry."},"status":{"type":"string","description":"Test status for this entry: `pass`, `fail`, `flaky`, or `skip`."},"test_run_id":{"type":"string","description":"ID of the test run this entry belongs to."},"environment_id":{"type":"string","description":"ID of the environment the test ran in."},"executed_at":{"type":"string","description":"ISO 8601 timestamp of when the test executed."},"duration_total":{"type":"number","description":"Total duration in milliseconds."},"retries":{"type":"number","description":"Number of retries for this test execution."}},"required":["timestamp","status","test_run_id","environment_id","executed_at","duration_total","retries"]},"AnalyticsTestCasesSummary":{"type":"object","properties":{"total_test_cases":{"type":"number","description":"Total number of test cases."},"test_cases_with_history":{"type":"number","description":"Number of test cases that have execution history."}},"required":["total_test_cases","test_cases_with_history"]}},"parameters":{}},"paths":{"/api/v1/analytics/test-runs":{"get":{"tags":["Analytics"],"operationId":"listTestRunsAnalyticsV1","summary":"Test-run analytics","description":"Returns daily test-run statistics and a period summary for the scoped project.\n\n**Superseded by** `/api/v2/analytics/test-runs`.","x-empirical-visibility":"external","x-empirical-maturity":"ga","deprecated":true,"x-empirical-deprecated-since":"2026-06-01","x-empirical-superseded-by":"/api/v2/analytics/test-runs","parameters":[{"schema":{"type":"integer","minimum":1,"maximum":90,"description":"Number of days to include (1-90). Ignored when both `start_date` and `end_date` are provided."},"required":false,"description":"Number of days to include (1-90). Ignored when both `start_date` and `end_date` are provided.","name":"days","in":"query"},{"schema":{"type":"string","description":"Start of a custom date range (ISO 8601)."},"required":false,"description":"Start of a custom date range (ISO 8601).","name":"start_date","in":"query"},{"schema":{"type":"string","description":"End of a custom date range (ISO 8601)."},"required":false,"description":"End of a custom date range (ISO 8601).","name":"end_date","in":"query"},{"schema":{"type":"integer","minimum":1,"description":"Filter to a single environment by ID."},"required":false,"description":"Filter to a single environment by ID.","name":"environment_id","in":"query"},{"schema":{"type":"string","description":"Filter to test runs on this git branch."},"required":false,"description":"Filter to test runs on this git branch.","name":"branch","in":"query"}],"responses":{"200":{"description":"Daily test-run stats and a period summary.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AnalyticsTestRunsResponse"}}}},"400":{"description":"Invalid request.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/api/v1/analytics/test-count":{"get":{"tags":["Analytics"],"operationId":"getTestCountAnalyticsV1","summary":"Test-count analytics","description":"Returns the number of distinct test cases run per day for the scoped project.\n\n**Superseded by** `/api/v2/analytics/test-count`.","x-empirical-visibility":"external","x-empirical-maturity":"ga","deprecated":true,"x-empirical-deprecated-since":"2026-06-01","x-empirical-superseded-by":"/api/v2/analytics/test-count","parameters":[{"schema":{"type":"integer","minimum":1,"maximum":90,"description":"Number of days to include (1-90). Ignored when both `start_date` and `end_date` are provided."},"required":false,"description":"Number of days to include (1-90). Ignored when both `start_date` and `end_date` are provided.","name":"days","in":"query"},{"schema":{"type":"string","description":"Start of a custom date range (ISO 8601)."},"required":false,"description":"Start of a custom date range (ISO 8601).","name":"start_date","in":"query"},{"schema":{"type":"string","description":"End of a custom date range (ISO 8601)."},"required":false,"description":"End of a custom date range (ISO 8601).","name":"end_date","in":"query"},{"schema":{"type":"string","description":"Filter to a single environment by ID."},"required":false,"description":"Filter to a single environment by ID.","name":"environment_id","in":"query"}],"responses":{"200":{"description":"Daily distinct test counts and a period summary.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AnalyticsTestCountResponse"}}}},"400":{"description":"Invalid request.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Analytics backend error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AnalyticsErrorResponse"}}}}}}},"/api/v1/analytics/test-cases":{"get":{"tags":["Analytics"],"operationId":"listTestCasesAnalyticsV1","summary":"Test-case analytics with history","description":"Returns aggregated test-case metrics including per-test execution history. The v2 endpoint omits history.\n\n**Superseded by** `/api/v2/analytics/test-cases`.","x-empirical-visibility":"external","x-empirical-maturity":"ga","deprecated":true,"x-empirical-deprecated-since":"2026-06-01","x-empirical-superseded-by":"/api/v2/analytics/test-cases","parameters":[{"schema":{"type":"integer","minimum":1,"maximum":90,"description":"Number of days to include (1-90). Ignored when both `start_date` and `end_date` are provided."},"required":false,"description":"Number of days to include (1-90). Ignored when both `start_date` and `end_date` are provided.","name":"days","in":"query"},{"schema":{"type":"string","description":"Start of a custom date range (ISO 8601)."},"required":false,"description":"Start of a custom date range (ISO 8601).","name":"start_date","in":"query"},{"schema":{"type":"string","description":"End of a custom date range (ISO 8601)."},"required":false,"description":"End of a custom date range (ISO 8601).","name":"end_date","in":"query"},{"schema":{"type":"string","description":"Filter to a single environment by ID."},"required":false,"description":"Filter to a single environment by ID.","name":"environment_id","in":"query"},{"schema":{"type":"string","description":"Free-text search over test name and file path."},"required":false,"description":"Free-text search over test name and file path.","name":"search","in":"query"},{"schema":{"type":"string","description":"Comma-separated list of tags to filter by."},"required":false,"description":"Comma-separated list of tags to filter by.","name":"tags","in":"query"},{"schema":{"type":"string","enum":["fail_rate","flaky_rate","last_run"],"description":"Field to order results by. One of `fail_rate`, `flaky_rate`, `last_run`. Defaults to `fail_rate`."},"required":false,"description":"Field to order results by. One of `fail_rate`, `flaky_rate`, `last_run`. Defaults to `fail_rate`.","name":"order_by","in":"query"},{"schema":{"type":"string","enum":["asc","desc"],"description":"Sort direction, `asc` or `desc`. Defaults to `desc`."},"required":false,"description":"Sort direction, `asc` or `desc`. Defaults to `desc`.","name":"order","in":"query"},{"schema":{"type":"integer","minimum":1,"maximum":500,"description":"Maximum number of test cases to return (1-500)."},"required":false,"description":"Maximum number of test cases to return (1-500).","name":"limit","in":"query"},{"schema":{"type":"integer","minimum":1,"maximum":100,"description":"Maximum number of history entries to return per test case (1-100)."},"required":false,"description":"Maximum number of history entries to return per test case (1-100).","name":"limit_history","in":"query"},{"schema":{"type":"string","description":"Filter to a single test case by ID."},"required":false,"description":"Filter to a single test case by ID.","name":"test_case_id","in":"query"},{"schema":{"type":"string","enum":["true","false"],"description":"When `false`, include inactive test cases. Defaults to active-only."},"required":false,"description":"When `false`, include inactive test cases. Defaults to active-only.","name":"is_active","in":"query"}],"responses":{"200":{"description":"Test cases with metrics and history.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AnalyticsTestCasesResponse"}}}},"400":{"description":"Invalid request.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Analytics backend error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AnalyticsErrorResponse"}}}}}}}}}