List and filter runs
Retrieve a paginated list of test runs with optional filtering by unit, procedure, date range, outcome, and other criteria. Supports sorting and includes run metadata.
API v2 Preview
The TofuPilot API v2.0 is currently in public preview and is subject to change as we stabilize until release (planned for Oct 2025).
Access
| API Key | Access Level | Description | 
|---|---|---|
| User | Full | Users can get runs from any procedure | 
| Station | Limited | Stations can only get runs from procedures to which they are currently linked. | 
Endpoint
/v2/runsAPI key for authentication. Use format: Bearer YOUR_API_KEY
In: header
Query Parameters
Search query to filter runs by run ID (partial match) or unit serial number.
Filter by specific run IDs.
Filter by run outcomes.
Filter by procedure IDs.
Filter by procedure version values.
Filter by unit serial numbers.
Filter by component part numbers.
Filter by revision identifiers.
Filter for runs with duration greater than or equal to this value (ISO 8601 duration).
durationFilter for runs with duration less than or equal to this value (ISO 8601 duration).
durationFilter for runs started at or after this time.
date-timeFilter for runs started at or before this time.
date-timeFilter for runs ended at or after this time.
date-timeFilter for runs ended at or before this time.
date-timeFilter for runs created at or after this time.
date-timeFilter for runs created at or before this time.
date-timeFilter by user IDs who created the runs.
Filter by station IDs that created the runs.
Filter by user IDs who operated the runs.
Maximum number of runs to return per page.
501 <= value <= 100Offset position for pagination. Use the next_cursor from the previous response to get the next page.
Field to sort results by.
"started_at""started_at" | "created_at" | "duration"Sort order direction.
"desc""asc" | "desc"Response Body
from tofupilot.v2 import TofuPilot
from datetime import datetime, timedelta, timezone
# Initialize the TofuPilot client
client = TofuPilot()
# Execute the operation
result = client.runs.list(
    limit=20,
    search_query="SN-001234",
    ids=["550e8400-e29b-41d4-a716-446655440000"],
    outcomes=["PASS", "FAIL"],
    procedure_ids=["550e8400-e29b-41d4-a716-446655440000"],
    procedure_versions=["v1.0.0", "v2.0.0"],
    serial_numbers=["SN-001234", "SN-005678"],
    part_numbers=["PCB-V1.2", "PCB-V1.3"],
    revision_numbers=["REV-A", "REV-B"],
    duration_min="PT5M",
    duration_max="PT30M",
    started_after=datetime.fromisoformat("2024-01-15T10:30:00Z"),
    started_before=datetime.fromisoformat("2024-01-15T11:30:00Z"),
    ended_after=datetime.fromisoformat("2024-01-15T10:30:00Z"),
    ended_before=datetime.fromisoformat("2024-01-15T11:30:00Z"),
    created_after=datetime.fromisoformat("2024-01-15T10:30:00Z"),
    created_before=datetime.fromisoformat("2024-01-15T11:30:00Z"),
    created_by_user_ids=["550e8400-e29b-41d4-a716-446655440000"],
    created_by_station_ids=["550e8400-e29b-41d4-a716-446655440000"],
    operated_by_ids=["550e8400-e29b-41d4-a716-446655440001"],
    cursor=50,
    sort_by="started_at",
    sort_order="desc"
)
# Handle response
print(result){
  "data": [
    {
      "id": "550e8400-e29b-41d4-a716-446655440000",
      "created_at": "2024-01-15T10:30:00Z",
      "started_at": "2024-01-15T10:35:00Z",
      "ended_at": "2024-01-15T10:37:30Z",
      "duration": "PT2M30S",
      "outcome": "PASS",
      "docstring": "Test run for production validation",
      "created_by_user": {
        "id": "550e8400-e29b-41d4-a716-446655440001",
        "name": "John Doe",
        "email": "john.doe@example.com",
        "image": "https://example.com/user-avatar.jpg"
      },
      "created_by_station": {
        "id": "550e8400-e29b-41d4-a716-446655440002",
        "name": "Test Station 01",
        "image": "https://example.com/station-01.jpg"
      },
      "operated_by": {
        "id": "550e8400-e29b-41d4-a716-446655440001",
        "name": "John Doe",
        "email": "john.doe@example.com",
        "image": "https://example.com/operator-avatar.jpg"
      },
      "procedure": {
        "id": "550e8400-e29b-41d4-a716-446655440003",
        "name": "PCB Functional Test",
        "version": {
          "id": "550e8400-e29b-41d4-a716-446655440010",
          "tag": "v2.1.0"
        }
      },
      "unit": {
        "id": "550e8400-e29b-41d4-a716-446655440004",
        "serial_number": "SN-2024-001234",
        "part": {
          "id": "550e8400-e29b-41d4-a716-446655440007",
          "number": "PCB-MAIN-001",
          "name": "Main Control Board",
          "revision": {
            "id": "550e8400-e29b-41d4-a716-446655440006",
            "number": "REV-A",
            "image": "https://example.com/revision-image.jpg"
          }
        },
        "batch": {
          "id": "550e8400-e29b-41d4-a716-446655440005",
          "number": "BATCH-2024-Q1-001"
        }
      }
    }
  ],
  "meta": {
    "has_more": true,
    "next_cursor": 100
  }
}{
  "code": "INTERNAL_SERVER_ERROR",
  "message": "Internal server error",
  "issues": []
}How is this guide?