TofuPilotTofuPilot
REST API v2.0 (Preview)/Runs

List test 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

This API version might be subject to breaking changes as we stabilize until release planned for Aug 2025.

Access

API KeyAccess LevelDescription
UserFullUsers can get runs from any procedure of their organization
StationLimitedStations can only get runs from procedures they were previously linked to from the app

Endpoint

GET
/v2/runs
AuthorizationBearer <token>

In: header

Query Parameters

include?array<string>

Relations to include in the response. If not specified, no relations are included.

Default[]
ids?array<string>

Filter by specific run IDs.

outcome?array<string>

Filter by run outcomes.

procedure_ids?array<string>

Filter by procedure IDs.

serial_numbers?array<string>

Filter by unit serial numbers.

started_after?string

Filter for runs started at or after this time.

Formatdate-time
started_before?string

Filter for runs started at or before this time.

Formatdate-time
created_by_user_ids?array<string>

Filter by user IDs who created the runs.

created_by_station_ids?array<string>

Filter by station IDs that created the runs.

limit?integer

Maximum number of runs to return. Default is 50. Use -1 for no limit.

Default50
Range-1 <= value
offset?integer

Number of runs to skip for pagination.

Default0
Range0 <= value
sort_by?string

Field to sort results by. Available options: started_at, created_at, duration. Default is started_at.

Default"started_at"
Value in"started_at" | "created_at" | "duration"
sort_order?string

Sort order direction. Default is desc.

Default"desc"
Value in"asc" | "desc"

Response Body

from tofupilot import TofuPilotClient

client = TofuPilotClient()
result = client.get_runs_by_serial_number(
    include=["phases","measurements"],
    ids=["550e8400-e29b-41d4-a716-446655440000"],
    outcome=["PASS","FAIL"],
    procedure_ids=["550e8400-e29b-41d4-a716-446655440000"],
    serial_numbers=["SN-001234","SN-005678"],
    started_after="2024-01-15T10:30:00Z",
    started_before="2024-01-15T11:30:00Z",
    created_by_user_ids=["550e8400-e29b-41d4-a716-446655440000"],
    created_by_station_ids=["550e8400-e29b-41d4-a716-446655440000"],
    limit=50,
    offset=0,
    sort_by="started_at",
    sort_order="desc"
)
print(result)
[
  {
    "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",
    "created_by_user": {
      "id": "550e8400-e29b-41d4-a716-446655440001",
      "name": "John Doe",
      "image": "https://example.com/user-avatar.jpg",
      "image_uploaded": {
        "s3Key": "uploads/user-123/avatar.jpg"
      }
    },
    "created_by_station": {
      "id": "550e8400-e29b-41d4-a716-446655440002",
      "name": "Test Station 01",
      "image": "https://example.com/station-01.jpg"
    },
    "procedure": {
      "id": "550e8400-e29b-41d4-a716-446655440003",
      "name": "PCB Functional Test"
    },
    "unit": {
      "id": "550e8400-e29b-41d4-a716-446655440004",
      "serial_number": "SN-2024-001234",
      "batch": {
        "id": "550e8400-e29b-41d4-a716-446655440005",
        "number": "BATCH-2024-Q1-001"
      },
      "revision": {
        "id": "550e8400-e29b-41d4-a716-446655440006",
        "identifier": "REV-A",
        "image": {
          "s3Key": "uploads/revisions/rev-a.jpg"
        },
        "component": {
          "id": "550e8400-e29b-41d4-a716-446655440007",
          "part_number": "PCB-MAIN-001",
          "name": "Main Control Board"
        }
      }
    },
    "phases": [
      {
        "id": "550e8400-e29b-41d4-a716-446655440008",
        "name": "Power On Test",
        "outcome": "PASS",
        "started_at": "2024-01-15T10:35:00Z",
        "ended_at": "2024-01-15T10:36:30Z",
        "duration": "PT1M30S",
        "docstring": "Verifies that the board powers on correctly and all voltage rails are within spec.",
        "measurements": [
          {
            "id": "550e8400-e29b-41d4-a716-446655440009",
            "name": "Input Voltage",
            "outcome": "PASS",
            "units": "V",
            "measured_value": 12.05,
            "lower_limit": 11.4,
            "upper_limit": 12.6
          }
        ]
      }
    ],
    "procedure_version": {
      "id": "550e8400-e29b-41d4-a716-446655440010",
      "value": "v2.1.0"
    },
    "attachments": [
      {
        "id": "550e8400-e29b-41d4-a716-446655440011",
        "name": "test-results.pdf",
        "size": 1048576,
        "content_type": "application/pdf"
      }
    ],
    "file_import": {
      "id": "550e8400-e29b-41d4-a716-446655440012",
      "upload": {
        "id": "550e8400-e29b-41d4-a716-446655440013",
        "name": "openhtf-results.json",
        "size": 524288,
        "content_type": "application/json"
      }
    },
    "logs": [
      {
        "id": "550e8400-e29b-41d4-a716-446655440014",
        "level": "INFO",
        "timestamp": "2024-01-15T10:35:15Z",
        "message": "Successfully connected to test equipment on port COM3",
        "source_file": "test_equipment.py",
        "line_number": 142
      }
    ]
  }
]
{
  "code": "INTERNAL_SERVER_ERROR",
  "message": "Internal server error",
  "issues": []
}

How is this guide?