Skip to main content
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:
StatusMeaning
PENDINGQueued, waiting to start
RUNNINGBrowser is executing your goal
COMPLETEDFinished (check result for data)
FAILEDInfrastructure error occurred
CANCELLEDManually stopped

The Run Object

When you fetch a run, you get back the following object:
{
  "run_id": "abc123",
  "status": "COMPLETED",
  "result": { ... },
  "error": null,
  "streamingUrl": "https://stream.mino.ai/session/abc123"
}
FieldDescription
run_idUnique identifier for this run
statusCurrent lifecycle status
resultYour extracted data (when COMPLETED)
errorError details (when FAILED)
streamingUrlURL to watch the browser live

Watching Runs Live

Every run includes a streamingUrl where you can watch the browser execute in real-time. This is useful for debugging, demos, or showing users what’s happening behind the scenes. Embed the URL in an iframe to display the live browser view in your app:
<iframe
  src="https://stream.mino.ai/session/abc123"
  width="800"
  height="600"
/>
The streaming URL is valid for 24 hours after the run completes.

Understanding COMPLETED Status

COMPLETED means the infrastructure worked, not that your goal succeeded.
Always check the result field: Goal succeeded:
{
  "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.
{
  "status": "COMPLETED",
  "result": {
    "status": "failure",
    "reason": "Could not find any products on the page"
  }
}

Handling Run Results

Use this pattern to handle both infrastructure failures and goal failures in your code.
async function handleTinyFishResponse(run: TinyFishRun) {
  switch (run.status) {
    case "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 "FAILED":
      return {
        success: false,
        error: run.error?.message || "Automation failed",
        retryable: true,
      };

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

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