{"openapi":"3.1.0","info":{"title":"Assertline API","version":"1","description":"Find recorded tests, run them and read the verdict. Listed operations are stable: fields are added, never renamed or removed. Every answer is JSON with `ok`. The same operations are available to assistants as MCP tools at POST /api/mcp."},"servers":[{"url":"https://app.assertline.com/api"}],"security":[{"bearer":[]}],"paths":{"/auth/me":{"get":{"operationId":"whoami","summary":"Who you are connected as","description":"The organization the key belongs to, its plan and what kind of credential is in use. Call it first to check that the key works.","x-mcp-tool":"whoami","x-key-kinds":["org","ci","worker"],"parameters":[],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok"],"properties":{"ok":{"const":true}},"additionalProperties":true},"example":{"ok":true,"type":"apikey","org":{"id":"4a788ccd-9b2e-42d7-837b-95a0784f3f0b","name":"Northwind Store","plan":"pro"},"role":"member"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"default":{"$ref":"#/components/responses/Error"}}}},"/projects":{"get":{"operationId":"listProjects","summary":"List projects","description":"Every project of the organization. A project groups the recorded tests of one application.","x-mcp-tool":"list_projects","x-key-kinds":["org","ci"],"parameters":[],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok"],"properties":{"ok":{"const":true}},"additionalProperties":true},"example":{"ok":true,"projects":[{"id":"c90e5906-4a97-429a-a47b-f240aa8da758","name":"Shop","description":null,"created_at":"2026-11-13T03:20:33.215Z","updated_at":"2026-11-13T03:20:33.215Z"}]}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"default":{"$ref":"#/components/responses/Error"}}}},"/sessions":{"get":{"operationId":"listTests","summary":"List the recorded tests of a project","description":"A recorded test is called a session in the API. `status` is `recording` while it is being recorded and `completed` once it can be run.","x-mcp-tool":"list_tests","x-key-kinds":["org","ci"],"parameters":[{"name":"projectId","in":"query","required":true,"description":"The project, from the list of projects.","schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok"],"properties":{"ok":{"const":true}},"additionalProperties":true},"example":{"ok":true,"sessions":[{"id":"a07f0795-8535-4c72-a6b6-17dd2bac4474","project_id":"c90e5906-4a97-429a-a47b-f240aa8da758","title":"Checkout","status":"completed","created_at":"2026-11-13T03:20:33.271Z","completed_at":"2026-11-13T03:20:33.350Z","action_count":2,"default_environment_id":null,"default_environment_name":null}]}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"default":{"$ref":"#/components/responses/Error"}}}},"/sessions/{sessionId}":{"get":{"operationId":"getTest","summary":"One recorded test with its steps","description":"The test and its steps in order. `action_type` says what a step does (`navigate`, `click`, `fill`, `assert-text-visible`, `assert-network-request`, …). Secret values are never returned: a step holds a `{{NAME}}` placeholder and `secret_names` lists the names.","x-mcp-tool":"get_test","x-key-kinds":["org","ci"],"parameters":[{"name":"sessionId","in":"path","required":true,"description":"The test, from the list of tests.","schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok"],"properties":{"ok":{"const":true}},"additionalProperties":true},"example":{"ok":true,"session":{"id":"a07f0795-8535-4c72-a6b6-17dd2bac4474","project_id":"c90e5906-4a97-429a-a47b-f240aa8da758","title":"Checkout","status":"completed","tags":["smoke"],"default_environment_id":null,"action_count":2,"secret_names":[]},"actions":[{"id":"fa84b128-ebd8-45ea-ae44-6fa24d31d9ae","sequence":1,"action_type":"navigate","url":"https://example.com","value":null,"locator_value_1":null,"warn_only":false}]}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"default":{"$ref":"#/components/responses/Error"}}}},"/sessions/{sessionId}/run":{"post":{"operationId":"runTest","summary":"Run a test","description":"Starts a run and answers at once with the run in status `queued`; read the run until its status is `completed` (passed) or `failed`. `auto` uses a computer of the organization when one is connected and online, otherwise Assertline's hosted browsers (Pro). Refusals: 403 `PLAN_REQUIRED` (hosted runs need Pro), 402 `CREDITS_REQUIRED` (included minutes and credits are used up), 409 `NO_WORKER` (nothing connected to run on), 422 `VARIABLES_UNRESOLVED` (a variable of the test has no value).","x-mcp-tool":"run_test","x-key-kinds":["org","ci","worker"],"parameters":[{"name":"sessionId","in":"path","required":true,"description":"The test to run.","schema":{"type":"string","format":"uuid"}}],"responses":{"201":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok"],"properties":{"ok":{"const":true}},"additionalProperties":true},"example":{"ok":true,"run":{"id":"5473ca7d-ada7-4f2f-a656-751e13c6e31b","session_id":"a07f0795-8535-4c72-a6b6-17dd2bac4474","status":"queued","triggered_by":"dashboard","environment_id":null,"device_profile":"desktop","expected_steps":2,"started_at":null,"completed_at":null}}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"default":{"$ref":"#/components/responses/Error"}},"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"properties":{"execution":{"type":"string","enum":["auto","local","hosted"],"default":"auto","description":"Where to run: `auto`, `local` (a connected computer of the organization) or `hosted` (Assertline's browsers)."},"environmentId":{"type":"string","format":"uuid","description":"The environment whose variables the run uses. Default: the test's own default environment."},"device":{"type":"string","default":"desktop","description":"A device profile id from the list of devices, for phone and tablet sizes."}}}}}}}},"/runs":{"get":{"operationId":"listRuns","summary":"List runs of a test or a project","description":"Newest first, with the number of passed, failed and warned steps. For one test (`sessionId`) or for every test of a project (`projectId`).","x-mcp-tool":"list_runs","x-key-kinds":["org","ci"],"parameters":[{"name":"sessionId","in":"query","required":false,"description":"Runs of this test.","schema":{"type":"string","format":"uuid"}},{"name":"projectId","in":"query","required":false,"description":"Runs of every test of this project.","schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok"],"properties":{"ok":{"const":true}},"additionalProperties":true},"example":{"ok":true,"runs":[{"id":"5473ca7d-ada7-4f2f-a656-751e13c6e31b","session_id":"a07f0795-8535-4c72-a6b6-17dd2bac4474","status":"completed","device_profile":"desktop","expected_steps":2,"failure_reason":null,"result_count":2,"passed_count":2,"failed_count":0,"warned_count":0,"started_at":"2026-11-13T03:21:02.000Z","completed_at":"2026-11-13T03:21:09.000Z"}]}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"default":{"$ref":"#/components/responses/Error"}}}},"/runs/{runId}":{"get":{"operationId":"getRun","summary":"The status of a run","description":"`status` is one of `queued`, `running`, `completed`, `failed`. `completed` means every step reported and none failed: the test passed. `failed` means a step failed, or the run itself broke, in which case `failure_reason` says why. The results say which step and why.","x-mcp-tool":"get_run","x-key-kinds":["org","ci","worker"],"parameters":[{"name":"runId","in":"path","required":true,"description":"The run.","schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok"],"properties":{"ok":{"const":true}},"additionalProperties":true},"example":{"ok":true,"run":{"id":"5473ca7d-ada7-4f2f-a656-751e13c6e31b","session_id":"a07f0795-8535-4c72-a6b6-17dd2bac4474","status":"queued","device_profile":"desktop","expected_steps":2,"failure_reason":null,"result_count":0,"started_at":null,"completed_at":null}}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"default":{"$ref":"#/components/responses/Error"}}}},"/runs/{runId}/results":{"get":{"operationId":"getRunResults","summary":"The step results of a run","description":"One result per step, in order. `status` is one of `passed`, `failed`, `warned`, `skipped`; `error_message` says why a step failed. A site that refused the automated browser is reported as a failed step that names the protection, never as a pass.","x-mcp-tool":"get_run_results","x-key-kinds":["org","ci","worker"],"parameters":[{"name":"runId","in":"path","required":true,"description":"The run.","schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok"],"properties":{"ok":{"const":true}},"additionalProperties":true},"example":{"ok":true,"results":[{"id":"0b8c1c44-1c7e-4e0f-9b1e-2f5d6a7c8e90","run_id":"5473ca7d-ada7-4f2f-a656-751e13c6e31b","sequence":1,"status":"passed","action_type":"navigate","url":"https://example.com","error_message":null,"selector_used":null,"execution_time_ms":812,"screenshot_storage":"cloud","screenshot_url":"https://…","created_at":"2026-11-13T03:21:03.000Z"}]}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"default":{"$ref":"#/components/responses/Error"}}}},"/runs/batch":{"post":{"operationId":"runBatch","summary":"Run every test with a tag","description":"Starts one run for each completed test that carries the tag (or the story), all against the named environment, and answers with the batch id. Tests are tagged in the dashboard. Read the batch until its status is no longer `running`.","x-mcp-tool":"run_batch","x-key-kinds":["org","ci"],"parameters":[],"responses":{"201":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok"],"properties":{"ok":{"const":true}},"additionalProperties":true},"example":{"ok":true,"batchId":"bfdd1d7a-1176-4f5e-a2b2-c971207bf8e5","queued":["a07f0795-8535-4c72-a6b6-17dd2bac4474"],"skipped":[],"dashboardUrl":"https://app.assertline.com"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"default":{"$ref":"#/components/responses/Error"}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"properties":{"tag":{"type":"string","description":"Run the tests with this tag. Give `tag` or `story`, not both."},"story":{"type":"string","description":"Run the tests linked to this story id."},"environmentName":{"type":"string","description":"The name of the environment to run against, from the list of environments."},"projectIds":{"type":"array","items":{"type":"string","format":"uuid"},"description":"Only tests of these projects. Default: every project."},"device":{"type":"string","default":"desktop","description":"A device profile id."}},"required":["environmentName"]}}}}},"get":{"operationId":"listBatches","summary":"List batches","description":"The batches of the organization, newest first.","x-mcp-tool":"list_batches","x-key-kinds":["org","ci"],"parameters":[],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok"],"properties":{"ok":{"const":true}},"additionalProperties":true},"example":{"ok":true,"batches":[{"id":"bfdd1d7a-1176-4f5e-a2b2-c971207bf8e5","tag":"smoke","story":null,"environment_name":"staging","status":"running","triggered_by":"cli","created_at":"2026-11-13T03:24:43.767Z","completed_at":null}]}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"default":{"$ref":"#/components/responses/Error"}}}},"/runs/batch/{batchId}":{"get":{"operationId":"getBatch","summary":"A batch and its runs","description":"The batch with one entry per run. The batch status is `running` until every run finished.","x-mcp-tool":"get_batch","x-key-kinds":["org","ci"],"parameters":[{"name":"batchId","in":"path","required":true,"description":"The batch.","schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok"],"properties":{"ok":{"const":true}},"additionalProperties":true},"example":{"ok":true,"batch":{"id":"bfdd1d7a-1176-4f5e-a2b2-c971207bf8e5","tag":"smoke","environment_name":"staging","status":"running","created_at":"2026-11-13T03:24:43.767Z","completed_at":null,"device_profile":"desktop"},"runs":[{"id":"448a3aeb-8629-4dc7-bace-55c9be827851","session_id":"a07f0795-8535-4c72-a6b6-17dd2bac4474","status":"queued","expected_steps":2,"failure_reason":null,"session_title":"Checkout","project_name":"Shop"}],"skipped":[]}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"default":{"$ref":"#/components/responses/Error"}}}},"/environments":{"get":{"operationId":"listEnvironments","summary":"List environments","description":"The environments (for example staging and production) whose variables a run can use. Variable values are not part of this answer.","x-mcp-tool":"list_environments","x-key-kinds":["org","ci","worker"],"parameters":[],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok"],"properties":{"ok":{"const":true}},"additionalProperties":true},"example":{"ok":true,"environments":[{"id":"cc08642b-e249-463e-8229-61d8bd482fa3","name":"staging","created_at":"2026-11-13T03:20:44.534Z"}]}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"default":{"$ref":"#/components/responses/Error"}}}},"/devices":{"get":{"operationId":"listDevices","summary":"List device profiles","description":"The screen sizes a run can use: desktop, and phone and tablet profiles.","x-mcp-tool":"list_devices","x-key-kinds":["org","ci","worker"],"parameters":[],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok"],"properties":{"ok":{"const":true}},"additionalProperties":true},"example":{"ok":true,"default":"desktop","devices":[{"id":"desktop","label":"Desktop","kind":"desktop","viewport":{"width":1920,"height":1080}},{"id":"iphone-15","label":"iPhone 15","kind":"phone","viewport":{"width":393,"height":659}}]}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"default":{"$ref":"#/components/responses/Error"}}}},"/orgs/current/entitlements":{"get":{"operationId":"getPlan","summary":"The plan, its limits and this month's usage","description":"What the organization's plan includes, how much of it is used this month, and the prepaid credit balance. Use it to tell whether a hosted run can start.","x-mcp-tool":"get_plan_and_usage","x-key-kinds":["org","ci"],"parameters":[],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok"],"properties":{"ok":{"const":true}},"additionalProperties":true},"example":{"ok":true,"entitlements":{"plan":"pro","label":"Pro","features":{"hostedRuns":true,"ci":true,"batches":true},"caps":{"seats":null,"projects":null,"retentionDays":365,"concurrentHostedRuns":3},"included":{"hostedMinutes":200,"storageGb":10},"usage":{"hostedMinutes":0,"storageGb":0},"credits":{"balanceUsd":10,"includedRemainingMinutes":200,"hostedRunsAllowed":true}}}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"default":{"$ref":"#/components/responses/Error"}}}}},"components":{"securitySchemes":{"bearer":{"type":"http","scheme":"bearer","description":"An API key created in the dashboard under Settings, API keys. A `ci` key can read and run and nothing else; an `org` key acts as a member of the organization."}},"schemas":{"Error":{"type":"object","required":["ok","error"],"properties":{"ok":{"const":false},"error":{"type":"string","description":"What went wrong, in words."},"code":{"type":"string","description":"A stable code when there is one: PLAN_REQUIRED, CAP_REACHED, CREDITS_REQUIRED, NO_WORKER, KEY_SCOPE, VARIABLES_UNRESOLVED."},"hint":{"type":"string"}}}},"responses":{"Unauthorized":{"description":"No key, or a key that is not valid any more.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"Error":{"description":"A refusal or a failure. 400 bad input, 402 credits needed, 403 the plan or the key does not allow it, 404 not found in this organization, 409 nothing to run on, 422 a variable has no value, 429 too many requests.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}}