> ## Documentation Index
> Fetch the complete documentation index at: https://docs.autosana.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Runs API

> Trigger flow execution, poll for results, and retrieve run results programmatically

All requests require an API key in the `X-API-Key` header. See [API Reference](/api-reference) for authentication details.

***

## Run Flows

Trigger flow execution. Returns a `batch_id` to poll via [Run Status](#run-status).

<Note>
  **POST** `/api/v1/flows/run` — Returns `200 OK`
</Note>

### Request Body

<ParamField body="bundle_id" type="string">
  App bundle identifier (mobile). Required if `app_id` is not provided.
</ParamField>

<ParamField body="platform" type="string">
  `ios` or `android`. Required with `bundle_id`.
</ParamField>

<ParamField body="app_id" type="string">
  Web app identifier. Required if `bundle_id` is not provided.
</ParamField>

<ParamField body="app_build_id" type="string">
  Optional. Pin the run to a specific build (UUID) instead of the app's active build — useful for testing a particular CI/CD build. The build must belong to the resolved app, otherwise the request returns `404`.
</ParamField>

<ParamField body="suite_ids" type="string[]">
  Suite UUIDs to run. At least one of `suite_ids` or `flow_ids` is required.
</ParamField>

<ParamField body="flow_ids" type="string[]">
  Flow UUIDs to run. At least one of `suite_ids` or `flow_ids` is required.

  When provided, suite auth instructions and suite-scoped variables are resolved automatically unless `resolve_suite_context` is set to `false`. See [Suite context for individual flows](#suite-context-for-individual-flows) below.
</ParamField>

<ParamField body="resolve_suite_context" type="boolean" default="true">
  When running individual flows via `flow_ids`, whether to look up the flow's suite and run auth instructions first. Defaults to `true`. Set to `false` to run the flow without suite auth or suite-scoped variables — useful for unauthenticated smoke tests or flows that handle login themselves.
</ParamField>

<ParamField body="suite_overrides" type="object">
  Optional. When a flow belongs to multiple suites, pass a JSON object mapping each ambiguous `flow_id` to the `suite_id` whose auth instructions and variables should be used, e.g. `{"<flow_id>": "<suite_id>"}`. Ignored when `resolve_suite_context` is `false`.
</ParamField>

<ParamField body="variables" type="string | object">
  Key-value variables to attach to the build being run (the pinned `app_build_id` if provided, otherwise the active build) and inject into flow instructions via `${env:KEY}`. Accepts a string (`"KEY1=VALUE1,KEY2=VALUE2"`) or a JSON object (`{"KEY1": "VALUE1"}`). See [Build Variables](/variables#build-variables).
</ParamField>

<ParamField body="web_browser" type="string">
  For web apps: which browser to run the flow in. One of:

  * `chrome` — real Google Chrome (default). Includes proprietary codecs (H.264, AAC) and Widevine DRM. Use this unless you have a specific reason to pick another browser.
  * `chromium` — open-source Chromium. No proprietary codecs, no DRM, deterministic and vendor-neutral.
  * `firefox` — Mozilla Firefox stable.
  * `edge` — Microsoft Edge stable.

  Aliases accepted: `Chrome` / `Google Chrome` → `chrome`; `msedge` / `Microsoft Edge` → `edge`. Ignored for mobile runs.
</ParamField>

### Suite context for individual flows

When you trigger a single flow via `flow_ids`, Autosana resolves the suite it belongs to and runs that suite's **Auth Instructions** first — the same behavior as running the flow manually from the dashboard.

```bash theme={null}
# Runs auth instructions first, then the flow (default)
curl -X POST https://backend.autosana.ai/api/v1/flows/run \
  -H "X-API-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "app_id": "your-app-id",
    "flow_ids": ["660e8400-e29b-41d4-a716-446655440001"]
  }'

# Skip suite auth — run only the flow instructions
curl -X POST https://backend.autosana.ai/api/v1/flows/run \
  -H "X-API-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "app_id": "your-app-id",
    "flow_ids": ["660e8400-e29b-41d4-a716-446655440001"],
    "resolve_suite_context": false
  }'
```

<Tip>
  If a flow belongs to multiple suites, the request returns `400` unless you pass `suite_overrides` mapping that flow to one of its suite UUIDs, e.g. `{"660e8400-e29b-41d4-a716-446655440001": "550e8400-e29b-41d4-a716-446655440000"}`.
</Tip>

### Example Request

```bash theme={null}
curl -X POST https://backend.autosana.ai/api/v1/flows/run \
  -H "X-API-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "bundle_id": "com.company.app",
    "platform": "android",
    "suite_ids": ["550e8400-e29b-41d4-a716-446655440000"],
    "variables": "PR_NUMBER=42,BRANCH=feature/login"
  }'
```

### Example Response

```json theme={null}
{
  "status": "success",
  "batch_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
  "flow_group_run_ids": ["f1a2b3c4-d5e6-7890-abcd-ef1234567890"],
  "flow_run_count": 5
}
```

***

## Run Status

Poll execution status for a batch triggered by [Run Flows](#run-flows).

<Note>
  **GET** `/api/v1/runs/status` — Returns `200 OK`
</Note>

### Query Parameters

<ParamField query="batch_id" type="string" required>
  The `batch_id` from `/api/v1/flows/run`.
</ParamField>

### Example Request

```bash theme={null}
curl -X GET "https://backend.autosana.ai/api/v1/runs/status?batch_id=BATCH_ID" \
  -H "X-API-Key: YOUR_API_KEY"
```

### Example Response

```json theme={null}
{
  "batch_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
  "is_complete": true,
  "timestamp": "2025-01-31T12:34:56.789Z",
  "app": {
    "id": "com.company.app",
    "name": "My App",
    "platform": "android",
    "url": "https://storage.example.com/builds/app.apk"
  },
  "git": {
    "commit_sha": "abc123",
    "branch": "main"
  },
  "summary": {
    "total_groups": 2,
    "passed_groups": 1,
    "failed_groups": 1,
    "total_flows": 10,
    "passed_flows": 8,
    "failed_flows": 2,
    "error_flows": 0,
    "terminated_flows": 0,
    "skipped_flows": 0
  },
  "run_groups": [
    {
      "name": "Login Suite",
      "status": "passed",
      "url": "https://autosana.ai/runs/groups/group-uuid-1",
      "source": "ci",
      "actor": { "id": "990e8400-e29b-41d4-a716-446655440088", "name": "Ada Lovelace", "type": "user" },
      "runs": [
        {
          "id": "run-uuid-1",
          "name": "Login with valid credentials",
          "status": "passed",
          "url": "https://autosana.ai/runs/flow/run-uuid-1",
          "summary": "Successfully logged in and verified the dashboard loaded."
        }
      ]
    },
    {
      "name": "Checkout Suite",
      "status": "failed",
      "url": "https://autosana.ai/runs/groups/group-uuid-2",
      "source": "schedule",
      "actor": { "id": "f8d8fb05-6292-4daa-9bf4-b0cc3b40a366", "name": "Autosana", "type": "system" },
      "runs": [
        {
          "id": "run-uuid-2",
          "name": "Checkout with expired card",
          "status": "failed",
          "url": "https://autosana.ai/runs/flow/run-uuid-2"
        }
      ]
    }
  ]
}
```

Each run group also includes `source` (how it was triggered: `ci`, `dashboard`, `schedule`, or `mcp`) and `actor` (who triggered it, as `{ id, name, type }`, where `type` is `user` or `system`). Both may be `null` for older runs.

***

## Get Run Results

Get full details of a run, including metadata, summary, and all actions with screenshot URLs. Use the `id` from individual runs in the [Run Status](#run-status) response.

<Note>
  **GET** `/api/v1/runs/{run_id}` — Returns `200 OK`
</Note>

### Path Parameters

<ParamField path="run_id" type="string" required>
  UUID of the run. Available in the `runs[].id` field from [Run Status](#run-status).
</ParamField>

### Example Request

```bash theme={null}
curl -X GET "https://backend.autosana.ai/api/v1/runs/run-uuid-1" \
  -H "X-API-Key: YOUR_API_KEY"
```

### Example Response

```json theme={null}
{
  "run_id": "run-uuid-1",
  "flow_name": "Login with valid credentials",
  "platform": "web",
  "status": "passed",
  "started_at": "2025-01-31T12:34:50.000000+00:00",
  "completed_at": "2025-01-31T12:35:01.000000+00:00",
  "source": "ci",
  "actor": { "id": "990e8400-e29b-41d4-a716-446655440088", "name": "Ada Lovelace", "type": "user" },
  "summary": "Successfully logged in and verified the dashboard loaded.",
  "issues": [
    {
      "type": "ux",
      "severity": "minor",
      "title": "No loading indicator on login",
      "description": "After tapping 'Sign In', there is no visual loading state before the dashboard appears.",
      "actions": [4,5]
    }
  ],
  "url": "https://autosana.ai/runs/flow/run-uuid-1",
  "performance_data_url": "https://storage.example.com/perf/run-uuid-1.json",
  "device_log_url": "https://storage.example.com/logs/run-uuid-1/device.log?token=...",
  "network_log_url": "https://storage.example.com/logs/run-uuid-1/network.jsonl?token=...",
  "actions": [
    {
      "id": "action-uuid-1",
      "position": 1,
      "type": "tap",
      "status": "passed",
      "description": "Tap the 'Sign In' button",
      "value": null,
      "screenshot_url": "https://storage-path/screenshot1.png",
      "annotated_screenshot_url": "https://example.com/screenshot1_annotated.png",
      "executed_at": "2025-01-31T12:34:56.789000+00:00"
    },
    {
      "id": "action-uuid-2",
      "position": 2,
      "type": "send_keys",
      "status": "passed",
      "description": "Type email into the email field",
      "value": "user@example.com",
      "screenshot_url": "https://storage-path/screenshot2.png",
      "annotated_screenshot_url": "https://example.com/screenshot2_annotated.png",
      "executed_at": "2025-01-31T12:34:58.789000+00:00"
    },
    {
      "id": "action-uuid-3",
      "position": 3,
      "type": "pass",
      "status": "passed",
      "description": "Login completed successfully — dashboard is visible",
      "value": null,
      "screenshot_url": "https://storage-path/screenshot3.png",
      "annotated_screenshot_url": null,
      "executed_at": "2025-01-31T12:35:00.789000+00:00"
    }
  ]
}
```

### Artifact URLs

<ResponseField name="performance_data_url" type="string | null">
  Time-series performance metrics (memory, CPU, web vitals) as JSON.
</ResponseField>

<ResponseField name="device_log_url" type="string | null">
  Device log (Android `logcat` / iOS syslog) or browser console log (web), as plain text or JSONL.
</ResponseField>

<ResponseField name="network_log_url" type="string | null">
  HTTP requests captured during the run, as JSONL — one entry per request with `method`, `url`, `status`, `resource_type`, `duration_ms`, `response_size`, etc. Failed requests (DNS, abort, CORS) appear with `status: 0` and an `error` string.

  Web runs only. `null` for mobile — use the `platform` field to disambiguate.
</ResponseField>

Any of these may be `null` if the artifact wasn't produced for that run.

***

## Polling

Poll `/api/v1/runs/status` every 10-15 seconds until `is_complete` is `true`.

```bash theme={null}
while true; do
  RESPONSE=$(curl -s "https://backend.autosana.ai/api/v1/runs/status?batch_id=$BATCH_ID" \
    -H "X-API-Key: YOUR_API_KEY")

  if [ "$(echo "$RESPONSE" | jq -r '.is_complete')" = "true" ]; then
    echo "$RESPONSE" | jq '.summary'
    break
  fi

  sleep 15
done
```
