Skip to content

Reference REST API Tests

Tests API

Create test suites and cases, trigger runs in AI, replay or hybrid mode, and poll run status and step results over the REST API.

These endpoints create test suites and cases, trigger runs, and read run status and step results. Authentication, error shapes and rate limits are covered in the REST API overview.

ID format: The {suite_id}, {case_id}, {run_id}, and {suite_run_id} path parameters are string public IDs (the public_id field in responses, e.g. "suite_abc123"), not the numeric id. App references in query and body fields generally take the app’s public_id as well — Create Suite additionally accepts a legacy numeric app_id. One exception on run IDs: the AI suite-run cancel endpoint takes the numeric ID.

Test Suites

List Suites

GET /api/v1/tests/suites

Auth: Bearer token required. Viewer role or above.

Query parameters:

ParameterTypeDescription
app_idstringFilter suites by app public ID (e.g. ?app_id=app_xyz789)
tagsstringComma-separated tag names to filter by (e.g. ?tags=smoke,profiles)
matchstringany (default) — suite has at least one tag; all — suite has every tag

Response:

[
  {
    "id": 1,
    "public_id": "suite_abc123",
    "name": "Login Flow",
    "description": "Tests for the login feature",
    "app_id": 1,
    "app_public_id": "app_xyz789",
    "app_name": "My App",
    "platform": "ios",
    "case_count": 5,
    "reset_strategy": "clear_data",
    "context": null,
    "variables": {},
    "last_run_status": "passed",
    "last_run_at": "2025-01-20T14:00:00",
    "created_at": "2025-01-15T10:30:00",
    "updated_at": "2025-01-20T14:00:00",
    "tags": [{"name": "profiles", "display_name": "Profiles"}]
  }
]

Create Suite

POST /api/v1/tests/suites

Auth: Bearer token required. Developer role or above.

Request body:

FieldTypeRequiredDescription
namestringYesSuite name
descriptionstringNoSuite description
app_public_idstringNoAssociated app public ID (preferred)
app_idintNoAssociated app numeric ID (legacy alternative to app_public_id)
platformstringNoios or android
tagsstring[]NoOptional list of tags. Each tag must match ^[a-z0-9_-]{1,50}$. Auto-creates new tags within the org (case-insensitive uniqueness; first-seen casing becomes display_name).

Response includes tags: [{name, display_name}] reflecting the suite’s current tags.

Export Suite as YAML

Downloads the suite and all its cases as a YAML file. Includes step mappings, source recordings, and device dimensions for portable hybrid replay.

GET /api/v1/tests/suites/{suite_id}/export-yaml

Auth: Bearer token required. Viewer role or above.

Response: YAML file download (text/yaml).

Import Suite from YAML

Creates a test suite from an uploaded YAML file. Optionally links to an app.

POST /api/v1/tests/suites/import-yaml

Auth: Bearer token required. Developer role or above.

Body: multipart/form-data with a file field containing the YAML file.

Query parameters:

ParameterTypeDescription
app_idstring(Optional) App public ID to link the suite to

If app_id is not provided but the YAML contains an appId field, the import attempts to match an existing app by package name.

Response:

{
  "public_id": "my-suite-abc123",
  "name": "My Test Suite",
  "case_count": 5
}

Get Suite

Returns the suite with all its test cases.

GET /api/v1/tests/suites/{suite_id}

Auth: Bearer token required. Viewer role or above.

Update Suite

PATCH /api/v1/tests/suites/{suite_id}

Auth: Bearer token required. Developer role or above.

Request body:

FieldTypeRequiredDescription
namestringNoSuite name
descriptionstringNoSuite description
reset_strategystringNoOne of relaunch, clear_data, reinstall
contextstringNoAdditional context passed to the AI agent
variablesobjectNoKey-value variables available during test execution
visual_regression_warn_pctintNoWarn-tier threshold for visual regression (% changed pixels). null disables the warn tier. See Visual regression.
visual_regression_fail_pctintNoFail-tier threshold for visual regression (% changed pixels). null disables the fail tier. See Visual regression.
tagsstring[]NoWhen present, replaces the suite’s tag set wholesale. An empty array clears all tags. Omit to leave existing tags unchanged.

Delete Suite

DELETE /api/v1/tests/suites/{suite_id}

Auth: Bearer token required. Developer role or above.


List Org Tags

GET /api/v1/tests/tags

Auth: Bearer token required. Viewer role or above.

Lists every tag in the user’s organization with usage counts. Used by autocomplete UIs.

Response: 200 OK

[
  { "name": "smoke", "display_name": "smoke", "suite_count": 7 },
  { "name": "profiles", "display_name": "Profiles", "suite_count": 3 }
]

Sorted by suite_count DESC, name ASC. Tags with zero suites are included.


Test Cases

Create Test Case (in a suite)

POST /api/v1/tests/suites/{suite_id}/cases

Auth: Bearer token required. Developer role or above.

Request body:

FieldTypeRequiredDescription
namestringYesTest case name
stepsarrayYesArray of step objects or strings
assertionsarrayNoVerification assertions
modestringNoai or recorded (default: recorded)
source_recordingarrayNoRaw recording actions for hybrid replay
source_device_widthintNoDevice width used during recording
source_device_heightintNoDevice height used during recording

Response:

{
  "id": 1,
  "suite_id": 1,
  "name": "Login with valid credentials",
  "mode": "ai",
  "steps": [...],
  "assertions": [...],
  "step_count": 5,
  "has_source_recording": true,
  "source_recording_summary": {
    "total_actions": 12,
    "gesture_counts": {"tap": 3, "swipe": 1}
  },
  "source_gesture_list": [...],
  "step_gesture_groups": [...],
  "source_device_width": 390,
  "source_device_height": 844,
  "context": null,
  "created_at": "2025-01-15T10:30:00",
  "updated_at": "2025-01-15T10:30:00"
}

List Test Cases (in a suite)

A suite’s cases are returned embedded in the suite object — fetch them with Get Suite (GET /api/v1/tests/suites/{suite_id}). There is no separate list endpoint.

Get Test Case

Returns the test case. Works for both suite-attached and standalone test cases. To fetch a case’s run history, use GET /api/v1/tests/cases/{case_id}/runs.

GET /api/v1/tests/cases/{case_id}

Auth: Bearer token required. Viewer role or above.

Update Test Case

PATCH /api/v1/tests/cases/{case_id}

Auth: Bearer token required. Developer role or above.

Request body:

FieldTypeRequiredDescription
namestringNoTest case name
stepsarrayNoUpdated steps
assertionsarrayNoUpdated assertions
contextstringNoAdditional context for the AI
app_idstringNoAssociated app public ID. Only settable on standalone cases — returns 400 if the case is attached to a suite (the suite owns the app linkage).
sub_flow_idsarrayNoOrdered list of reusable case IDs to run before this case’s own steps
source_recordingarrayNoRaw recording actions for hybrid replay
fuzzy_matchbooleanNoEnable fuzzy coordinate matching during replay
is_reusablebooleanNoMark case as a reusable sub-flow. Setting true requires no parent suite — returns 400 if the case is attached to a suite.

Delete Test Case

DELETE /api/v1/tests/cases/{case_id}

Auth: Bearer token required. Developer role or above.

Copy Test Case

Copy a test case to another suite.

POST /api/v1/tests/suites/{suite_id}/cases/{case_id}/copy

Auth: Bearer token required. Developer role or above.

Request body:

FieldTypeRequiredDescription
target_suite_idstringYesDestination suite public ID

Create Standalone Test Case

Create a test case that is not attached to any suite. If a standalone case with the same name already exists for the app, it is updated in place instead of duplicated.

POST /api/v1/tests/cases

Auth: Bearer token required. Developer role or above.

Request body:

FieldTypeRequiredDescription
namestringYesTest case name
app_idstringYesApp public ID the case belongs to
stepsarrayYesArray of step objects or strings
assertionsarrayNoVerification assertions
modestringNoai or recorded (default: recorded)
contextstringNoAdditional context for the AI
source_recordingarrayNoRaw recording actions for hybrid replay
source_device_widthintNoDevice width used during recording
source_device_heightintNoDevice height used during recording
source_platformstringNoios, android, tvos, or androidtv (defaults to the app’s platform)
fuzzy_matchbooleanNoEnable fuzzy coordinate matching during replay (default: true)

Response: The created (or updated) test case object, same shape as Create Test Case (in a suite).

Errors:

  • 404 — App not found in your organization.

List Standalone Test Cases

List test cases that are not attached to any suite.

GET /api/v1/tests/cases

Auth: Bearer token required. Viewer role or above.

Query parameters:

ParameterTypeDescription
reusablebooleantrue — only reusable sub-flows; false — only non-reusable; omit for all

Response: Array of test case objects (most recent first), each including recent_run_statuses for the last 10 runs.


Test Case Runs

List Runs for a Test Case

GET /api/v1/tests/cases/{case_id}/runs

Auth: Bearer token required. Viewer role or above.

Returns all runs for the specified test case, ordered by most recent first.

Create a Run Record

POST /api/v1/tests/cases/{case_id}/run

Auth: Bearer token required. Viewer role or above.

Creates a run record for the case in pending status — it does not execute the test. To actually execute a test, use Run AI Test (POST /api/v1/ai/test/run) or the CI endpoints.

Response:

{
  "id": 1,
  "public_id": "tr7abc123x",
  "test_case_id": 1,
  "status": "pending",
  "started_at": "2025-01-20T14:00:00",
  "finished_at": null,
  "result": null,
  "reasoning_log": null,
  "error_message": null,
  "duration_ms": null,
  "model_used": null,
  "tokens_used": null,
  "cost_micro": null
}

List Baselines for a Test Case

GET /api/v1/tests/cases/{case_id}/baselines

Auth: Bearer token required. Viewer role or above.

Returns all baseline image records for the test case.

Get Baseline Image

GET /api/v1/tests/cases/{case_id}/baselines/step_{step_index}.jpg

Auth: Bearer token required. Viewer role or above.

Returns the baseline screenshot for the specified step as a JPEG image.


Test Runs (run-level operations)

Update Test Run

PATCH /api/v1/tests/runs/{run_id}

Auth: Bearer token required.

Query parameters:

ParameterTypeRequiredDescription
statusstringYesOne of pending, running, passed, failed, error
result_jsonstringNoJSON-encoded result data
error_messagestringNoError message if failed
duration_msintNoExecution duration in milliseconds

Get Test Run

GET /api/v1/tests/runs/{run_id}

Auth: Bearer token required.

Cancel Test Run

Cancel a running AI test execution.

POST /api/v1/tests/runs/{run_id}/cancel

Auth: Bearer token required.

Response:

{
  "status": "cancellation_requested"
}

Errors:

  • 400 — Run is not active or already finished.

Suite Runs

Get Suite Run

Get details of a suite run including all linked test runs.

GET /api/v1/tests/suite-runs/{suite_run_id}

Auth: Bearer token required.

Response:

{
  "id": 1,
  "suite_id": 1,
  "session_id": "uuid-string",
  "status": "passed",
  "reset_strategy": "clear_data",
  "started_at": "2025-01-20T14:00:00",
  "finished_at": "2025-01-20T14:05:00",
  "duration_ms": 300000,
  "error_message": null,
  "test_runs": [
    {
      "id": 1,
      "test_case_id": 1,
      "status": "passed",
      "duration_ms": 15000,
      "error_message": null
    }
  ]
}

Last updated 8 Sep 2026 Something wrong on this page? Tell us

Search the docs