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 PENDINGQueued, waiting to start RUNNINGBrowser is executing your goal COMPLETEDFinished (check result for data) FAILEDInfrastructure error occurred CANCELLEDManually stopped
Cancellation is only supported for runs created via /run-async or /run-sse. Runs created via the synchronous /run endpoint cannot be cancelled because the request blocks until completion.
The Run Object
When you fetch a run, you get back the following object:
{
"run_id" : "abc123" ,
"status" : "COMPLETED" ,
"result" : { ... },
"error" : null ,
"streaming_url" : "https://tf-abc123.fra0-tinyfish.unikraft.app/stream/0"
}
Field Description run_idUnique identifier for this run statusCurrent lifecycle status resultYour extracted data (when COMPLETED) errorError details (when FAILED) streaming_urlURL to watch the browser live
Searching and Filtering Runs
GET /v1/runs supports filtering, text search, sorting, and pagination to help you find specific runs.
Query Parameters
Parameter Type Description statusstring Filter by status: PENDING, RUNNING, COMPLETED, FAILED, CANCELLED goalstring Search runs by goal text (case-insensitive partial match) created_afterISO 8601 Only return runs created after this timestamp created_beforeISO 8601 Only return runs created before this timestamp sort_directionasc | descSort order by creation date (default: desc) cursorstring Pagination cursor from a previous response limitnumber Results per page, 1–100 (default: 20)
Examples
Search by goal text:
curl "https://agent.tinyfish.ai/v1/runs?goal=linkedin" \
-H "X-API-Key: YOUR_API_KEY"
Filter by status and date range:
curl "https://agent.tinyfish.ai/v1/runs?status=COMPLETED&created_after=2026-01-01T00:00:00Z&created_before=2026-02-01T00:00:00Z" \
-H "X-API-Key: YOUR_API_KEY"
Oldest first with pagination:
curl "https://agent.tinyfish.ai/v1/runs?sort_direction=asc&limit=10" \
-H "X-API-Key: YOUR_API_KEY"
The response includes a pagination object with total, next_cursor, and has_more:
{
"data" : [ ... ],
"pagination" : {
"total" : 142 ,
"next_cursor" : "eyJpZCI6..." ,
"has_more" : true
}
}
Pass next_cursor as the cursor parameter to fetch the next page.
Watching Runs Live
Every run includes a streaming_url 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://tf-abc123.fra0-tinyfish.unikraft.app/stream/0"
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 } ` };
}
}
Cancelling Runs
You can cancel a run that is PENDING or RUNNING by sending a POST request to /v1/runs/{id}/cancel. This works for runs created via /run-async or /run-sse only.
const response = await fetch ( `https://agent.tinyfish.ai/v1/runs/ ${ run_id } /cancel` , {
method: "POST" ,
headers: {
"X-API-Key" : process . env . TINYFISH_API_KEY ,
},
});
const result = await response . json ();
// result.status: CANCELLED, COMPLETED, or FAILED
// result.cancelled_at: timestamp if cancelled
// result.message: additional context (e.g. "Run already cancelled")
The cancel endpoint is idempotent — calling it on an already-cancelled or completed run returns the current state without error.
Scenario Response status cancelled_atmessageRun cancelled CANCELLEDTimestamp nullAlready cancelled CANCELLEDTimestamp "Run already cancelled"Already completed COMPLETEDnull"Run already finished"
Only runs created via the API (/run-async or /run-sse) can be cancelled using this endpoint. Runs created through the dashboard UI or via the synchronous /run endpoint cannot be cancelled.
Endpoints Choose sync, async, or streaming
Error Codes Handle errors gracefully