Test-Lab.aiDocs
API Reference

Run Tests API

Use the Test-Lab API to trigger test plan execution programmatically. Run single tests, batch multiple plans, or trigger all tests for a project with CI/CD build tracking.

Run Tests API

The Run Tests endpoint lets you trigger test plan execution programmatically from your CI/CD pipeline, scripts, or any HTTP client. You can run a single test plan, batch multiple plans in one request, or trigger every plan in a project — all with optional build ID tracking for traceability.

POST https://test-lab.ai/api/v1/run

Authentication

Authorization: Bearer tl_xxxxx

Request Body

FieldTypeRequiredDescription
testPlanIdsnumber[] | stringOne of theseRun one or more test plans (e.g. [1,2,3] or "1,2,3")
projectIdnumberOne of theseRun all test plans for a project
labelstringOne of theseRun all test plans tagged with this label name
testTypestringNo"quickTest" or "deepTest" (default: plan's default)
buildIdstringNoCI build/commit identifier (max 100 chars)
cookiesarrayNoAuthentication cookies to inject (see below)
preferScriptbooleanNoWhen true, each plan runs as its saved Playwright script (deterministic, no LLM cost). Plans without a generated script fall back to an AI run automatically.
triggerPipelinePreStepsbooleanNoDefault false. When false, plans configured as a pipeline pre-step (referenced by another plan as a pre-step) are silently excluded from batch runs and reported with status: "skipped". Pre-steps usually expect input parameters or specific browser state and produce false-failures when run solo. Pass true to include them — useful when you explicitly want to smoke-test a login pre-step on its own with default credentials.

Exactly one of testPlanIds, projectId, or label must be provided. Every selector is scoped to the API key's account; the API never resolves plans, projects, or labels belonging to other accounts.

FieldTypeRequiredDescription
namestringYesCookie name
valuestringYesCookie value
domainstringYesDomain (e.g. .example.com)

Cookies can also be configured at the project or test plan level in the dashboard. Runtime cookies override stored cookies.

Examples

Test Plans

Using an array:

curl -X POST https://test-lab.ai/api/v1/run \
  -H "Authorization: Bearer tl_xxxxx" \
  -H "Content-Type: application/json" \
  -d '{
    "testPlanIds": [ID_1, ID_2, ID_3],
    "testType": "deepTest"
  }'

Using a comma-separated string:

curl -X POST https://test-lab.ai/api/v1/run \
  -H "Authorization: Bearer tl_xxxxx" \
  -H "Content-Type: application/json" \
  -d '{
    "testPlanIds": "ID_1,ID_2,ID_3"
  }'

Response (multiple plans):

{
  "jobs": [
    {
      "jobId": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
      "status": "running",
      "testPlanId": YOUR_TEST_PLAN_ID,
      "testPlanName": "Login Flow",
      "testType": "deepTest"
    },
    {
      "jobId": "yyyyyyyy-yyyy-yyyy-yyyy-yyyyyyyyyyyy",
      "status": "running",
      "testPlanId": ID_2,
      "testPlanName": "Signup Flow",
      "testType": "deepTest"
    }
  ],
  "triggered": 2,
  "failed": 0
}

All Plans for a Project

curl -X POST https://test-lab.ai/api/v1/run \
  -H "Authorization: Bearer tl_xxxxx" \
  -H "Content-Type: application/json" \
  -d '{
    "projectId": YOUR_PROJECT_ID
  }'

All Plans with a Label

Run every test plan tagged with a given label. Labels are account-scoped and matched by name (the same string you'd see on the plan in the dashboard).

curl -X POST https://test-lab.ai/api/v1/run \
  -H "Authorization: Bearer tl_xxxxx" \
  -H "Content-Type: application/json" \
  -d '{
    "label": "smoke"
  }'

Useful for grouping smoke tests, regression suites, or environment-specific subsets without hardcoding plan IDs in CI.

Run as Script (Cheaper, Deterministic)

When a test plan has a generated Playwright script (Save as Script from a passing AI run), the API can run that script instead of spinning up an AI agent. Add "preferScript": true:

curl -X POST https://test-lab.ai/api/v1/run \
  -H "Authorization: Bearer tl_xxxxx" \
  -H "Content-Type: application/json" \
  -d '{
    "projectId": YOUR_PROJECT_ID,
    "preferScript": true,
    "buildId": "abc123"
  }'

Each plan in the request is checked individually. Plans with an active or stale script run as scripts; plans without a script fall back to a normal AI run, so flipping the flag never silently breaks a plan that hasn't been scriptified yet. Script runs do not consume LLM credits.

Pipelines (plans with pre-steps)

A plan with pre-steps configured in the dashboard runs as a pipeline automatically — pre-steps execute first, then the main test, all sharing browser state (cookies, localStorage, current URL). No special API parameter needed; just include the master plan in testPlanIds (or its projectId / label).

Behavior with preferScript: true:

  • If every step in the pipeline (every pre-step + the main test) has a saved script for the chosen device, the whole pipeline runs deterministically as a script pipeline. State chains between steps via Playwright storageState. No LLM cost.
  • If any step is missing a script, the entire pipeline falls back to AI mode (all steps run as AI, including those that do have scripts). Mixing script + AI mid-pipeline can't share state cleanly across the boundary, so we keep the whole chain on one execution mode.

Response shape: the jobs[] entry returned for a pipeline run carries the main plan's job ID (the last position in the chain). Pre-step jobs share the same pipeline_id and run_group_id and can be looked up by querying jobs with that group ID. testType is script for the script-pipeline branch, otherwise the main plan's recipe.

Pre-step plans listed alongside their masters: the triggerPipelinePreSteps flag (covered above) controls plans that ARE pre-steps (i.e. referenced by another plan). The default false skips them when listed in a batch. This is independent from the pipeline-execution behavior described here, which kicks in for plans that HAVE pre-steps.

With Build ID (CI Integration)

curl -X POST https://test-lab.ai/api/v1/run \
  -H "Authorization: Bearer tl_xxxxx" \
  -H "Content-Type: application/json" \
  -d '{
    "testPlanIds": [YOUR_TEST_PLAN_ID],
    "buildId": "abc123"
  }'

With Authentication Cookies

curl -X POST https://test-lab.ai/api/v1/run \
  -H "Authorization: Bearer tl_xxxxx" \
  -H "Content-Type: application/json" \
  -d '{
    "testPlanIds": [YOUR_TEST_PLAN_ID],
    "cookies": [
      { "name": "session", "value": "abc123xyz", "domain": ".myapp.com" }
    ]
  }'

Response

The endpoint always returns the same array shape, regardless of which selector you used:

FieldTypeDescription
jobsarrayArray of job objects
jobs[].jobIdstringUUID of each job
jobs[].statusstringStatus of each job (running, queued, pending, error, or skipped)
jobs[].testPlanIdnumberTest plan ID
jobs[].testPlanNamestringTest plan name
jobs[].testTypestringTest mode (quickTest, deepTest, or script)
jobs[].errorstringError if the job failed to start, or the reason a plan was skipped
triggerednumberCount of successfully triggered jobs (excludes error and skipped)
failednumberCount of failed jobs
skippednumberCount of plans excluded from this run (e.g. pre-step plans when triggerPipelinePreSteps is not set)
buildIdstringBuild ID if provided

Error Responses

Invalid API Key

{
  "error": "Invalid API key"
}

Status: 401

Insufficient Credits

{
  "error": "Insufficient credits. Please top up to continue running tests."
}

Status: 402

Test Plan Not Found

{
  "error": "No test plans found"
}

Status: 404

Invalid Parameters

{
  "error": "One of testPlanIds, projectId, or label is required"
}

Status: 400

Code Examples

JavaScript/Node.js

const response = await fetch('https://test-lab.ai/api/v1/run', {
  method: 'POST',
  headers: {
    'Authorization': `Bearer ${process.env.TESTLAB_API_KEY}`,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    testPlanIds: [YOUR_TEST_PLAN_ID],
    testType: 'quickTest',
    buildId: process.env.GITHUB_SHA,
  }),
});

const data = await response.json();
console.log('Triggered:', data.triggered, 'jobs');

Python

import requests
import os

response = requests.post(
    'https://test-lab.ai/api/v1/run',
    headers={
        'Authorization': f'Bearer {os.environ["TESTLAB_API_KEY"]}',
        'Content-Type': 'application/json',
    },
    json={
        'testPlanIds': [YOUR_TEST_PLAN_ID],
        'testType': 'quickTest',
        'buildId': os.environ.get('GITHUB_SHA'),
    }
)

data = response.json()
print(f'Triggered: {data["triggered"]} jobs')

Next Steps

On this page