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

# Runs

> The lifecycle of a TinyFish Web Agent automation

A run is a single execution of an automation. When you call any TinyFish Web Agent endpoint, you create a run that moves through a lifecycle from start to finish.

## Run Lifecycle

Every run moves through these statuses:

| Status | Meaning |
| - | - |
| `PENDING` | Queued, waiting to start |
| `RUNNING` | Browser is executing your goal |
| `COMPLETED` | Finished (check result for data) |
| `FAILED` | Infrastructure error occurred |
| `CANCELLED` | Manually stopped |

> [!NOTE]
>
> Cancellation is only supported for runs created via `/run-async`, `/run-batch`, or `/run-sse`. Runs created via the synchronous `/run` endpoint cannot be cancelled because the request blocks until completion. Request/response shape and idempotency behavior: [Runs Reference](https://docs.tinyfish.ai/agent/api/runs.md#cancel-a-run-by-id).

In an organization, which runs a key can list and cancel depends on the kind of key; see [Who sees what](https://docs.tinyfish.ai/key-concepts/organizations.md#who-sees-what).

***

## Watching Runs Live

Every run includes a `streaming_url` where you can watch the browser execute in real time — useful for debugging, demos, or showing users what's happening behind the scenes. It's available while the run is active; once the run reaches a terminal status, switch to `video_url` from the run object to access the recording instead.

***

## Understanding COMPLETED Status

> [!WARNING]
>
> `COMPLETED` means the infrastructure worked, not that your goal succeeded.

Always check the `result` field:

**Goal succeeded:**

```json theme={null}
{
  "status": "COMPLETED",
  "result": {
    "products": [
      { "name": "Widget", "price": 29.99 }
    ]
  }
}
```

**Infrastructure worked, goal failed:**

The browser worked fine, but TinyFish Web Agent couldn't achieve your goal.

```json theme={null}
{
  "status": "COMPLETED",
  "result": {
    "status": "failure",
    "reason": "Could not find any products on the page"
  }
}
```

A run's `error` field covers the other case — when the infrastructure itself fails, `error.category` tells you how to react: `SYSTEM_FAILURE` is a TinyFish issue (retry after `retry_after`), `AGENT_FAILURE` means the input needs fixing, `BILLING_FAILURE` means the run was rejected at the billing check before it started — add money at [agent.tinyfish.ai/wallet](https://agent.tinyfish.ai/wallet) (minimum top-up \$10), or add credits on a legacy account — and `UNKNOWN` should be treated as retryable. Full run object and error object field list: [Runs Reference](https://docs.tinyfish.ai/agent/api/runs.md#get-a-run-by-id).

Runs can also use [vault credentials](https://docs.tinyfish.ai/key-concepts/credentials.md) for authenticated automation. Pass `use_vault: true` and optionally `credential_item_ids` when creating a run to let TinyFish log into sites using your connected password manager.

***

## Agent Mode and Limits

`agent_config` controls how the agent behaves (`mode`) and how far it's allowed to go (`max_steps`,
`max_duration_seconds`) — see [Agent Mode, Max Steps, and Max Duration](https://docs.tinyfish.ai/agent/explanation/agent-modes.md)
for when to use each.

***

## Handling Run Results

Use this pattern to handle both infrastructure failures and goal failures in your code.

```typescript theme={null}
import { TinyFish, RunStatus } from "@tiny-fish/sdk";
import type { Run } from "@tiny-fish/sdk";

const client = new TinyFish();

// Fetch a run by ID, then handle the result
const run = await client.runs.get(runId);
const result = await handleRunResult(run);

async function handleRunResult(run: Run) {
  switch (run.status) {
    case RunStatus.COMPLETED:
      if (!run.result) {
        return { success: false, error: "No result returned" };
      }

      // Check for goal-level failure in result
      if (run.result.status === "failure" || run.result.error) {
        return {
          success: false,
          error: run.result.reason || run.result.error || "Goal not achieved",
        };
      }

      return { success: true, data: run.result };

    case RunStatus.FAILED:
      return {
        success: false,
        error: run.error?.message || "Automation failed",
        retryable: true,
      };

    case RunStatus.CANCELLED:
      return { success: false, error: "Run was cancelled" };

    default:
      return { success: false, error: `Unexpected status: ${run.status}` };
  }
}
```

***

## Related

> [card] [Runs Reference](https://docs.tinyfish.ai/agent/api/runs.md)
>
> List, get, cancel, batch, and per-step screenshots/HTML — full schema

> [card] [Endpoints](https://docs.tinyfish.ai/agent/api/agent/endpoints.md)
>
> Choose sync, async, batch, or streaming

> [card] [Agent Mode, Max Steps, and Max Duration](https://docs.tinyfish.ai/agent/explanation/agent-modes.md)
>
> Default vs Strict mode, step and time limits

> [card] [Error Codes](https://docs.tinyfish.ai/error-codes.md)
>
> Handle errors gracefully

> [card] [Vault Credentials](https://docs.tinyfish.ai/key-concepts/credentials.md)
>
> Use password manager credentials in runs


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.