List and filter runs
Retrieve a paginated list of test runs with filtering by unit, procedure, date range, outcome, and station.
Access
| API Key | Access Level | Description |
|---|---|---|
| User | Full | Users can read runs |
| Station | Limited | Stations cannot read runs |
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 versions.
Filter by unit serial numbers.
Filter by component part numbers.
Filter by revision identifiers.
Filter by batch numbers.
Filter for runs with duration greater than or equal to this value (ISO 8601 duration).
^P(?:(\d+W)|(?!.*W)(?=\d|T\d)(\d+Y)?(\d+M)?(\d+D)?(T(?=\d)(\d+H)?(\d+M)?(\d+([.,]\d+)?S)?)?)$durationFilter for runs with duration less than or equal to this value (ISO 8601 duration).
^P(?:(\d+W)|(?!.*W)(?=\d|T\d)(\d+Y)?(\d+M)?(\d+D)?(T(?=\d)(\d+H)?(\d+M)?(\d+([.,]\d+)?S)?)?)$durationFilter for runs started at or after this time.
^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z|([+-](?:[01]\d|2[0-3]):[0-5]\d)))$date-timeFilter for runs started at or before this time.
^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z|([+-](?:[01]\d|2[0-3]):[0-5]\d)))$date-timeFilter for runs ended at or after this time.
^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z|([+-](?:[01]\d|2[0-3]):[0-5]\d)))$date-timeFilter for runs ended at or before this time.
^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z|([+-](?:[01]\d|2[0-3]):[0-5]\d)))$date-timeFilter for runs created at or after this time.
^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z|([+-](?:[01]\d|2[0-3]):[0-5]\d)))$date-timeFilter for runs created at or before this time.
^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z|([+-](?:[01]\d|2[0-3]):[0-5]\d)))$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.
-9007199254740991 <= value <= 9007199254740991Field to sort results by.
"started_at""started_at" | "created_at" | "duration" | "outcome" | "serial_number" | "part_number" | "revision_number"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"],
batch_numbers="BATCH-2024-Q1-001,BATCH-2024-Q1-002",
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"
},
"created_by_station": {
"id": "550e8400-e29b-41d4-a716-446655440002",
"name": "Test Station 01"
},
"operated_by": {
"id": "550e8400-e29b-41d4-a716-446655440001",
"name": "John Doe",
"email": "john.doe@example.com"
},
"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"
}
},
"batch": {
"id": "550e8400-e29b-41d4-a716-446655440005",
"number": "BATCH-2024-Q1-001"
}
}
}
],
"meta": {
"has_more": true,
"next_cursor": 100
}
}{
"message": "Bad request",
"code": "BAD_REQUEST",
"issues": []
}{
"message": "Unauthorized",
"code": "UNAUTHORIZED",
"issues": []
}{
"message": "Internal server error",
"code": "INTERNAL_SERVER_ERROR",
"issues": []
}How is this guide?