TofuPilotTofuPilot
REST API v1.0/Runs

List runs by serial number

Retrieve all test runs associated with a specific unit identified by serial number. Returns comprehensive run data including metadata, phases, and measurements.

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
/v1/runs
AuthorizationBearer <token>

In: header

Query Parameters

serial_numberstring

Unique serial number of the unit to retrieve test runs for. Returns all runs associated with this specific unit.

Response Body

from tofupilot import TofuPilotClient

client = TofuPilotClient()
result = client.get_runs_by_serial_number(
    serial_number="SN-2024-001234"
)
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": "BAD_REQUEST",
  "message": "Part number is required but not provided and no automatic parsing is configured. Provide a part_number parameter or configure serial number parsing in organization settings.",
  "issues": []
}
{
  "code": "UNAUTHORIZED",
  "message": "Authorization not provided",
  "issues": []
}
{
  "code": "FORBIDDEN",
  "message": "Insufficient access",
  "issues": []
}
{
  "code": "NOT_FOUND",
  "message": "Procedure with ID {procedureId} does not exist. Create the procedure first in the app.",
  "issues": []
}
{
  "code": "INTERNAL_SERVER_ERROR",
  "message": "Internal server error",
  "issues": []
}

How is this guide?