{"openapi":"3.1.0","info":{"title":"TofuPilot APIv2","description":"TofuPilot REST API for managing runs, units, procedures, and more.","version":"2.0.0"},"servers":[{"url":"https://www.tofupilot.app/api"}],"tags":[{"name":"Runs"},{"name":"Logs"},{"name":"Phases"},{"name":"Measurements"},{"name":"Procedures"},{"name":"Units"},{"name":"Parts"},{"name":"Batches"},{"name":"Stations"},{"name":"Deployments"},{"name":"Attachments"},{"name":"Users"},{"name":"Revisions"},{"name":"Versions"},{"name":"Imports"}],"externalDocs":{"url":"https://tofupilot.com/docs/api/rest-api/runs/create"},"paths":{"/v2/procedures":{"post":{"operationId":"procedure-create","summary":"Create procedure","description":"Create a procedure to group and track related runs.","tags":["Procedures"],"security":[{"api_key":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":60,"description":"Name of the procedure. Must be unique within the organization.","example":"Battery Test Procedure"}},"required":["name"]}}}},"responses":{"200":{"description":"Procedure created successfully","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","description":"Unique identifier for the created procedure.","example":"550e8400-e29b-41d4-a716-446655440000"}},"required":["id"],"additionalProperties":false}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorUNAUTHORIZED"}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorINTERNALSERVERERROR"}}}}},"x-access":[{"level":"full","authType":"user","description":"Users can create procedures"},{"level":"unauthorized","authType":"station","description":"Stations cannot create procedures"}],"x-speakeasy-name-override":"create"},"get":{"operationId":"procedure-list","summary":"List and filter procedures","description":"List procedures with filtering and search. Includes creator and linked repository. Cursor-paginated.","tags":["Procedures"],"security":[{"api_key":[]}],"parameters":[{"name":"limit","in":"query","required":false,"schema":{"default":50,"description":"Maximum number of procedures to return per page.","example":20,"type":"integer","minimum":1,"maximum":100},"description":"Maximum number of procedures to return per page."},{"name":"cursor","in":"query","required":false,"schema":{"type":"number","description":"Offset position for pagination. Use the next_cursor from the previous response to get the next page.","example":50}},{"name":"search_query","in":"query","required":false,"schema":{"type":"string","maxLength":100,"description":"Search text to filter procedures by ID (6+ characters) or name.","example":"battery test"}},{"name":"created_after","in":"query","required":false,"schema":{"type":"string","format":"date-time","pattern":"^(?:(?:\\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)))$","description":"Only return procedures created after this timestamp (ISO 8601).","example":"2024-01-01T00:00:00.000Z"}},{"name":"created_before","in":"query","required":false,"schema":{"type":"string","format":"date-time","pattern":"^(?:(?:\\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)))$","description":"Only return procedures created before this timestamp (ISO 8601).","example":"2024-12-31T23:59:59.999Z"}}],"responses":{"200":{"description":"Procedures retrieved successfully","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","description":"Unique identifier for the procedure.","example":"550e8400-e29b-41d4-a716-446655440000"},"name":{"type":"string","description":"Name of the procedure.","example":"Battery Test Procedure"},"created_at":{"type":"string","format":"date-time","pattern":"^(?:(?:\\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))$","description":"ISO 8601 timestamp when the procedure was created.","example":"2024-01-15T10:30:00.000Z"},"created_by_user":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","description":"Unique identifier for the user who created the procedure.","example":"550e8400-e29b-41d4-a716-446655440001"},"name":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Name of the user who created the procedure.","example":"John Doe"},"email":{"type":"string","format":"email","pattern":"^(?!\\.)(?!.*\\.\\.)([A-Za-z0-9_'+\\-\\.]*)[A-Za-z0-9_+-]@([A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$","description":"Email of the user who created the procedure.","example":"john.doe@company.com"}},"required":["id","name","email"],"additionalProperties":false,"description":"User who created the procedure."},"linkedRepository":{"anyOf":[{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","description":"Unique identifier for the linked repository.","example":"550e8400-e29b-41d4-a716-446655440004"},"name":{"type":"string","description":"Name of the repository.","example":"my-repo"},"fullName":{"type":"string","description":"Full name of the repository (owner/repo).","example":"org/my-repo"},"provider":{"type":"string","enum":["github","gitlab"]}},"required":["id","name","fullName","provider"],"additionalProperties":false},{"type":"null"}],"description":"Linked repository for this procedure."}},"required":["id","name","created_at","created_by_user","linkedRepository"],"additionalProperties":false}},"meta":{"type":"object","properties":{"has_more":{"type":"boolean","description":"Whether there are more results available for pagination.","example":true},"next_cursor":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}],"description":"Cursor value to fetch the next page of results. Use this value as the cursor parameter in the next request. Null if no more results available.","example":100}},"required":["has_more","next_cursor"],"additionalProperties":false}},"required":["data","meta"],"additionalProperties":false}}}},"400":{"description":"Procedure {id} has no created_by_user","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBADREQUEST"}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorUNAUTHORIZED"}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorINTERNALSERVERERROR"}}}}},"x-access":[{"level":"full","authType":"user","description":"Users can read procedures"},{"level":"limited","authType":"station","description":"Stations cannot read procedures"}],"x-speakeasy-name-override":"list"}},"/v2/procedures/{id}":{"get":{"operationId":"procedure-get","summary":"Get procedure","description":"Get a procedure by ID, with recent runs, linked stations, and version history.","tags":["Procedures"],"security":[{"api_key":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"Unique identifier of the procedure to retrieve."}],"responses":{"200":{"description":"Procedure retrieved successfully","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","description":"Unique identifier for the procedure.","example":"550e8400-e29b-41d4-a716-446655440000"},"name":{"type":"string","description":"Procedure name.","example":"PCB Functional Test"},"created_at":{"type":"string","format":"date-time","pattern":"^(?:(?:\\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))$","description":"ISO 8601 timestamp when the procedure was created.","example":"2024-01-15T10:30:00Z"},"created_by_user":{"anyOf":[{"type":"object","properties":{"id":{"type":"string","description":"User ID.","example":"550e8400-e29b-41d4-a716-446655440001"},"name":{"anyOf":[{"type":"string","description":"User display name.","example":"John Doe"},{"type":"null"}]},"email":{"anyOf":[{"type":"string","description":"User email address.","example":"john.doe@example.com"},{"type":"null"}]}},"required":["id","name","email"],"additionalProperties":false},{"type":"null"}],"description":"User who created this procedure."},"runs_count":{"type":"number","description":"Total number of runs for this procedure.","example":42},"recent_runs":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","description":"Run ID.","example":"550e8400-e29b-41d4-a716-446655440003"},"started_at":{"type":"string","format":"date-time","pattern":"^(?:(?:\\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))$","description":"ISO 8601 timestamp when the run started.","example":"2024-01-15T10:35:00Z"},"outcome":{"type":"string","enum":["PASS","FAIL","ERROR","TIMEOUT","ABORTED"],"description":"Run outcome.","example":"PASS"},"unit":{"anyOf":[{"type":"object","properties":{"serial_number":{"type":"string","description":"Unit serial number.","example":"SN-001234"}},"required":["serial_number"],"additionalProperties":false},{"type":"null"}],"description":"Unit information."}},"required":["id","started_at","outcome","unit"],"additionalProperties":false},"description":"List of recent runs for this procedure."},"stations":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","description":"Station ID.","example":"550e8400-e29b-41d4-a716-446655440004"},"name":{"type":"string","description":"Station name.","example":"Test Station 01"}},"required":["id","name"],"additionalProperties":false},"description":"Stations linked to this procedure."}},"required":["id","name","created_at","created_by_user","runs_count","recent_runs","stations"],"additionalProperties":false}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorUNAUTHORIZED"}}}},"404":{"description":"Procedure not found: {id}","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorNOTFOUND"}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorINTERNALSERVERERROR"}}}}},"x-access":[{"level":"full","authType":"user","description":"Users can read procedures"},{"level":"limited","authType":"station","description":"Stations cannot read procedures"}],"x-speakeasy-name-override":"get"},"delete":{"operationId":"procedure-delete","summary":"Delete procedure","description":"Delete a procedure and all its runs, phases, measurements, and attachments. Irreversible.","tags":["Procedures"],"security":[{"api_key":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"Unique identifier of the procedure to delete."}],"responses":{"200":{"description":"Procedure deleted successfully","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","description":"Unique identifier of the deleted procedure.","example":"550e8400-e29b-41d4-a716-446655440000"}},"required":["id"],"additionalProperties":false}}}},"400":{"description":"Failed to delete procedure: {error}","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBADREQUEST"}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorUNAUTHORIZED"}}}},"404":{"description":"Procedure with ID {id} not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorNOTFOUND"}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorINTERNALSERVERERROR"}}}}},"x-access":[{"level":"full","authType":"user","description":"Users can delete procedures"},{"level":"unauthorized","authType":"station","description":"Stations cannot delete procedures"}],"x-speakeasy-name-override":"delete"},"patch":{"operationId":"procedure-update","summary":"Update procedure","description":"Update a procedure's name or configuration. Only provided fields are changed.","tags":["Procedures"],"security":[{"api_key":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"Unique identifier of the procedure to update."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"description":"New name for the procedure.","example":"Updated Battery Test Procedure","type":"string","minLength":1,"maxLength":60},"productionBranch":{"description":"Branch treated as production. Pushes to this branch deploy as production; every other branch deploys as preview. Null = no branch promoted to production.","example":"main","anyOf":[{"type":"string","minLength":1,"maxLength":255},{"type":"null"}]},"autoPushEnabled":{"description":"Master switch for auto-pushing builds to linked stations. Build artifacts are always recorded; this only gates the station fan-out.","example":true,"type":"boolean"},"excludedBranchPatterns":{"description":"Branches matching any of these patterns (exact name or minimatch glob, e.g. \"renovate/*\") skip preview deployments. Empty array = no exclusions.","example":["renovate/*","wip/*"],"type":"array","items":{"type":"string","minLength":1,"maxLength":255}},"rootDirectory":{"description":"Path within the linked repo to the directory holding this procedure's `pyproject.toml` (and `procedure.yaml` for framework procedures). Empty/null = repo root.","example":"stations/boot_test","anyOf":[{"type":"string","maxLength":256},{"type":"null"}]},"entryPoint":{"description":"Entry-point path inside the procedure's package dir, relative to it. Forwarded to the CLI through the deployment manifest. Empty/null = use the framework default (openhtf/plain → main.py, pytest → \".\", yaml → procedure.yaml auto-discovery).","example":"main.py","anyOf":[{"type":"string","maxLength":256},{"type":"null"}]}}}}}},"responses":{"200":{"description":"Procedure updated successfully","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","description":"Unique identifier of the updated procedure.","example":"550e8400-e29b-41d4-a716-446655440000"}},"required":["id"],"additionalProperties":false}}}},"400":{"description":"Failed to update procedure: {error}","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBADREQUEST"}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorUNAUTHORIZED"}}}},"404":{"description":"Procedure with ID {id} not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorNOTFOUND"}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorINTERNALSERVERERROR"}}}}},"x-access":[{"level":"full","authType":"user","description":"Users can update procedures"},{"level":"unauthorized","authType":"station","description":"Stations cannot update procedures"}],"x-speakeasy-name-override":"update"}},"/v2/procedures/{procedure_id}/versions/{tag}":{"get":{"operationId":"procedure-getVersion","summary":"Get procedure version","description":"Get a procedure version by tag, with its metadata and configuration.","tags":["Versions"],"security":[{"api_key":[]}],"parameters":[{"name":"procedure_id","in":"path","required":true,"schema":{"type":"string"},"description":"ID of the procedure that owns this version."},{"name":"tag","in":"path","required":true,"schema":{"type":"string"},"description":"Version tag to retrieve."}],"responses":{"200":{"description":"Procedure version retrieved successfully","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","description":"Unique identifier for the procedure version.","example":"550e8400-e29b-41d4-a716-446655440000"},"tag":{"type":"string","description":"Version tag.","example":"v1.0.0"},"created_at":{"type":"string","format":"date-time","pattern":"^(?:(?:\\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))$","description":"ISO 8601 timestamp when the procedure version was created.","example":"2024-01-15T10:30:00Z"},"created_by_user":{"description":"User who created this procedure version.","anyOf":[{"type":"object","properties":{"id":{"type":"string","description":"User ID.","example":"550e8400-e29b-41d4-a716-446655440001"},"name":{"anyOf":[{"type":"string","description":"User display name.","example":"John Doe"},{"type":"null"}]}},"required":["id","name"],"additionalProperties":false},{"type":"null"}]},"created_by_station":{"description":"Station that created this procedure version.","anyOf":[{"type":"object","properties":{"id":{"type":"string","description":"Station ID.","example":"550e8400-e29b-41d4-a716-446655440002"},"name":{"type":"string","description":"Station name.","example":"Assembly Station 01"}},"required":["id","name"],"additionalProperties":false},{"type":"null"}]},"procedure":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","description":"Procedure ID.","example":"550e8400-e29b-41d4-a716-446655440003"},"name":{"type":"string","description":"Procedure name.","example":"PCB Assembly Test"}},"required":["id","name"],"additionalProperties":false,"description":"Procedure this version belongs to."},"run_count":{"type":"integer","minimum":0,"maximum":9007199254740991,"description":"Number of runs using this procedure version.","example":42}},"required":["id","tag","created_at","procedure","run_count"],"additionalProperties":false}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorUNAUTHORIZED"}}}},"404":{"description":"Procedure version not found: {id}","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorNOTFOUND"}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorINTERNALSERVERERROR"}}}}},"x-access":[{"level":"full","authType":"user","description":"Users can read procedureversions"},{"level":"limited","authType":"station","description":"Stations cannot read procedureversions"}],"x-speakeasy-group":"procedures.versions","x-speakeasy-name-override":"get"},"delete":{"operationId":"procedure-deleteVersion","summary":"Delete procedure version","description":"Delete a procedure version by tag. Irreversible.","tags":["Versions"],"security":[{"api_key":[]}],"parameters":[{"name":"procedure_id","in":"path","required":true,"schema":{"type":"string"},"description":"ID of the procedure that owns this version"},{"name":"tag","in":"path","required":true,"schema":{"type":"string"},"description":"Version tag to delete"}],"responses":{"200":{"description":"Procedure version deleted successfully","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","description":"ID of the deleted procedure version","example":"550e8400-e29b-41d4-a716-446655440000"}},"required":["id"],"additionalProperties":false}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorUNAUTHORIZED"}}}},"404":{"description":"Procedure version not found: {id}","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorNOTFOUND"}}}},"409":{"description":"Cannot delete procedure version with associated runs. Found {runCount} runs.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorCONFLICT"}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorINTERNALSERVERERROR"}}}}},"x-access":[{"level":"full","authType":"user","description":"Users can delete procedureversions"},{"level":"unauthorized","authType":"station","description":"Stations cannot delete procedureversions"}],"x-speakeasy-group":"procedures.versions","x-speakeasy-name-override":"delete"}},"/v2/procedures/{procedure_id}/versions":{"post":{"operationId":"procedure-createVersion","summary":"Create procedure version","description":"Create a version of a procedure. Versions snapshot procedure configuration over time.","tags":["Versions"],"security":[{"api_key":[]}],"parameters":[{"name":"procedure_id","in":"path","required":true,"schema":{"type":"string"},"description":"The ID of the procedure this version belongs to"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"tag":{"type":"string","minLength":1,"maxLength":60,"pattern":"^[a-zA-Z0-9_.:+-]+$","description":"The version tag","example":"v1.0.0"}},"required":["tag"]}}}},"responses":{"200":{"description":"Procedure version created successfully","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","description":"Unique identifier for the created procedure version","example":"550e8400-e29b-41d4-a716-446655440000"}},"required":["id"],"additionalProperties":false}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorUNAUTHORIZED"}}}},"404":{"description":"Procedure not found: {procedureId}","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorNOTFOUND"}}}},"409":{"description":"A version with this tag already exists for the procedure","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorCONFLICT"}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorINTERNALSERVERERROR"}}}}},"x-access":[{"level":"full","authType":"user","description":"Users can create procedureversions"},{"level":"limited","authType":"station","description":"Stations cannot create procedureversions"}],"x-speakeasy-group":"procedures.versions","x-speakeasy-name-override":"create"}},"/v2/runs":{"post":{"operationId":"run-create","summary":"Create run","description":"Create a run linked to a procedure and unit. Existing procedures and units are reused automatically.","tags":["Runs"],"security":[{"api_key":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"outcome":{"type":"string","enum":["PASS","FAIL","ERROR","TIMEOUT","ABORTED"],"description":"Overall test result. Use PASS when test succeeds, FAIL when test fails but script execution completed successfully, ERROR when script execution fails, TIMEOUT when test exceeds time limit, ABORTED for manual script interruption.","example":"PASS"},"procedure_id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","description":"Procedure ID. Create the procedure in the app first, then find the auto-generated ID on the procedure page.","example":"550e8400-e29b-41d4-a716-446655440000"},"deployment_id":{"anyOf":[{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","description":"Deployment ID this run was executed from. Set by the CLI when running a pulled deployment so the run is linked back to the exact build it ran. Validated against the procedure; left null for ad-hoc or local runs.","example":"550e8400-e29b-41d4-a716-446655440000"},{"type":"null"}]},"procedure_version":{"anyOf":[{"type":"string","minLength":1,"maxLength":60,"pattern":"^[a-zA-Z0-9_.:+-]+$","description":"Specific version of the test procedure used for the run. Matched case-insensitively. If none exist, a procedure with this procedure version will be created. If no procedure version is specified, the run will not be linked to any specific version.","example":"v1.2.3"},{"type":"null"}]},"operated_by":{"type":"string","maxLength":254,"format":"email","pattern":"^(?!\\.)(?!.*\\.\\.)([A-Za-z0-9_'+\\-\\.]*)[A-Za-z0-9_+-]@([A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$","description":"Email address of the operator who executed the test run. Honored only for API-key callers (user keys and station keys); browser session callers are auto-stamped with the session user and this field is ignored. If the email does not match a member of the calling organization, it is silently dropped and the run is recorded with no operator. The run is linked to this user (when resolved) to track who performed the test.","example":"john.doe@example.com"},"started_at":{"type":"string","format":"date-time","pattern":"^(?:(?:\\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)))$","description":"ISO 8601 timestamp when the test run began execution. This timestamp will be used to track when the test execution started and for historical analysis of test runs. A separate created_at timestamp is stored internally server side to track upload date.","example":"2024-01-15T10:30:00Z"},"ended_at":{"type":"string","format":"date-time","pattern":"^(?:(?:\\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)))$","description":"ISO 8601 timestamp when the test run finished execution.","example":"2024-01-15T10:35:30Z"},"serial_number":{"type":"string","minLength":1,"maxLength":60,"pattern":"^[a-zA-Z0-9_.:+-]+$","description":"Unique serial number of the unit under test. Matched case-insensitively. If no unit with this serial number exists, one will be created.","example":"SN-001234"},"part_number":{"type":"string","minLength":1,"maxLength":60,"pattern":"^[a-zA-Z0-9_.:+-]+$","description":"Component part number for the unit. Matched case-insensitively. This field is required if the part number cannot be extracted from the serial number (as set in the settings). This field takes precedence over extraction from serial number. A component with the provided or extracted part number will be created if one does not exist.","example":"PCB-V1.2"},"revision_number":{"type":"string","minLength":1,"maxLength":60,"pattern":"^[a-zA-Z0-9_.:+-]+$","description":"Hardware revision identifier for the unit. Matched case-insensitively. If none exist, a revision with this number will be created. If no revision is specified, the unit will be linked to the default revision of the part number.","example":"REV-1.0"},"batch_number":{"type":"string","minLength":1,"maxLength":60,"pattern":"^[a-zA-Z0-9_.:+-]+$","description":"Production batch identifier for grouping units manufactured together. Matched case-insensitively. If none exist, a batch with this batch number will be created. If no batch number is specified, the unit will not be linked to any batch.","example":"BATCH-2024-01"},"sub_units":{"description":"Array of sub-unit serial numbers that are part of this main unit. Matched case-insensitively. Each sub-unit must already exist and will be linked as a sub-component of the main unit under test. If no sub-units are specified, the unit will be created without sub-unit relationships.","example":["SUB-001","SUB-002"],"type":"array","items":{"type":"string","minLength":1,"maxLength":60,"pattern":"^[a-zA-Z0-9_.:+-]+$"}},"docstring":{"type":"string","maxLength":50000,"description":"Additional notes or documentation about this test run.","example":"Test run for production validation"},"phases":{"type":"array","items":{"type":"object","properties":{"name":{"type":"string","maxLength":100,"description":"Name identifier for the test phase. Each phase should have a descriptive name that identifies the specific stage of testing being performed. Analytics at phase level are computed using this name as unique identifier.","example":"Power On Test"},"outcome":{"type":"string","enum":["PASS","FAIL","SKIP","ERROR"],"description":"Overall result of the phase execution. Use PASS when phase succeeds, FAIL when phase fails but execution completed successfully, ERROR when phase execution fails, SKIP when phase was not executed.","example":"PASS"},"started_at":{"type":"string","format":"date-time","pattern":"^(?:(?:\\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)))$","description":"ISO 8601 timestamp when the phase execution began.","example":"2024-01-15T10:30:00Z"},"ended_at":{"type":"string","format":"date-time","pattern":"^(?:(?:\\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)))$","description":"ISO 8601 timestamp when the phase execution completed.","example":"2024-01-15T10:35:00Z"},"docstring":{"anyOf":[{"type":"string","maxLength":50000,"description":"Additional notes or documentation about this test phase.","example":"Initial power-on sequence validation"},{"type":"null"}]},"measurements":{"anyOf":[{"type":"array","items":{"type":"object","properties":{"name":{"type":"string","maxLength":100,"description":"Name identifier for the measurement. Each measurement should have a descriptive name that identifies the specific data point being captured. Analytics at measurement level are computed using this name as unique identifier.","example":"Voltage Output"},"outcome":{"type":"string","enum":["PASS","FAIL","UNSET"],"description":"Result of the measurement validation. Use PASS when measurement meets all criteria, FAIL when measurement is outside acceptable limits or validation fails, UNSET when no validation was performed.","example":"PASS"},"x_axis":{"anyOf":[{"type":"object","properties":{"data":{"type":"array","items":{"type":"number"},"description":"Array of numeric data points for this axis.","example":[0,1,2,3,4]},"units":{"description":"Unit for this axis.","example":"V","anyOf":[{"type":"string"},{"type":"null"}]},"name":{"description":"Name of this data series.","example":"Frequency","anyOf":[{"type":"string"},{"type":"null"}]},"description":{"description":"Description of this data series.","example":"Output voltage over time","anyOf":[{"type":"string"},{"type":"null"}]},"validators":{"description":"Validators for this specific axis/series.","anyOf":[{"type":"array","items":{"type":"object","properties":{"outcome":{"description":"Pre-computed validation result from test framework. Server stores as-is, does not re-evaluate.","anyOf":[{"type":"string","enum":["PASS","FAIL","UNSET"]},{"type":"null"}]},"operator":{"description":"Comparison operator: \">\", \">=\", \"<\", \"<=\", \"==\", \"!=\", \"matches\", \"in\", \"range\"","example":">=","anyOf":[{"type":"string"},{"type":"null"}]},"expected_value":{"description":"Expected value for comparison. Type depends on operator.","example":3,"anyOf":[{"anyOf":[{"type":"boolean"},{"type":"number"},{"type":"string"},{"type":"array","items":{"type":"number"}},{"type":"array","items":{"type":"string"}}]},{"type":"null"}]},"expression":{"description":"Original expression string for display/audit purposes.","example":"3.0 <= x <= 3.6","anyOf":[{"type":"string"},{"type":"null"}]},"is_decisive":{"description":"Whether this validator is decisive (if it fails, measurement fails). False for marginal/warning validators. Defaults to true.","anyOf":[{"type":"boolean"},{"type":"null"}]}},"description":"Structured validator specification with operator and expected value."}},{"type":"null"}]},"aggregations":{"description":"Aggregations computed over this axis data (min, max, avg, etc.).","anyOf":[{"type":"array","items":{"type":"object","properties":{"type":{"type":"string","description":"Aggregation function: \"min\", \"max\", \"avg\", \"sum\", \"count\", \"std\", \"median\", \"percentile_95\", etc.","example":"avg"},"outcome":{"description":"Computed result of aggregation validation. Server stores as-is.","anyOf":[{"type":"string","enum":["PASS","FAIL","UNSET"]},{"type":"null"}]},"value":{"description":"Computed aggregation value.","example":3.3,"anyOf":[{"anyOf":[{"type":"number"},{"type":"string"},{"type":"boolean"}]},{"type":"null"}]},"unit":{"description":"Unit for the aggregated value.","example":"V","anyOf":[{"type":"string"},{"type":"null"}]},"validators":{"description":"Validators applied to the aggregated value.","anyOf":[{"type":"array","items":{"type":"object","properties":{"outcome":{"description":"Pre-computed validation result from test framework. Server stores as-is, does not re-evaluate.","anyOf":[{"type":"string","enum":["PASS","FAIL","UNSET"]},{"type":"null"}]},"operator":{"description":"Comparison operator: \">\", \">=\", \"<\", \"<=\", \"==\", \"!=\", \"matches\", \"in\", \"range\"","example":">=","anyOf":[{"type":"string"},{"type":"null"}]},"expected_value":{"description":"Expected value for comparison. Type depends on operator.","example":3,"anyOf":[{"anyOf":[{"type":"boolean"},{"type":"number"},{"type":"string"},{"type":"array","items":{"type":"number"}},{"type":"array","items":{"type":"string"}}]},{"type":"null"}]},"expression":{"description":"Original expression string for display/audit purposes.","example":"3.0 <= x <= 3.6","anyOf":[{"type":"string"},{"type":"null"}]},"is_decisive":{"description":"Whether this validator is decisive (if it fails, measurement fails). False for marginal/warning validators. Defaults to true.","anyOf":[{"type":"boolean"},{"type":"null"}]}},"description":"Structured validator specification with operator, expected value, and outcome."}},{"type":"null"}]}},"required":["type"],"description":"Aggregation specification with computed value and optional validators."}},{"type":"null"}]}},"required":["data"],"description":"Data series with numeric data, unit, and optional validators/aggregations."},{"type":"null"}],"description":"X-axis data series for multi-dimensional measurements. Use with y_axis for structured multi-dimensional data with per-axis validators/aggregations."},"y_axis":{"anyOf":[{"type":"array","items":{"type":"object","properties":{"data":{"type":"array","items":{"type":"number"},"description":"Array of numeric data points for this axis.","example":[0,1,2,3,4]},"units":{"description":"Unit for this axis.","example":"V","anyOf":[{"type":"string"},{"type":"null"}]},"name":{"description":"Name of this data series.","example":"Frequency","anyOf":[{"type":"string"},{"type":"null"}]},"description":{"description":"Description of this data series.","example":"Output voltage over time","anyOf":[{"type":"string"},{"type":"null"}]},"validators":{"description":"Validators for this specific axis/series.","anyOf":[{"type":"array","items":{"type":"object","properties":{"outcome":{"description":"Pre-computed validation result from test framework. Server stores as-is, does not re-evaluate.","anyOf":[{"type":"string","enum":["PASS","FAIL","UNSET"]},{"type":"null"}]},"operator":{"description":"Comparison operator: \">\", \">=\", \"<\", \"<=\", \"==\", \"!=\", \"matches\", \"in\", \"range\"","example":">=","anyOf":[{"type":"string"},{"type":"null"}]},"expected_value":{"description":"Expected value for comparison. Type depends on operator.","example":3,"anyOf":[{"anyOf":[{"type":"boolean"},{"type":"number"},{"type":"string"},{"type":"array","items":{"type":"number"}},{"type":"array","items":{"type":"string"}}]},{"type":"null"}]},"expression":{"description":"Original expression string for display/audit purposes.","example":"3.0 <= x <= 3.6","anyOf":[{"type":"string"},{"type":"null"}]},"is_decisive":{"description":"Whether this validator is decisive (if it fails, measurement fails). False for marginal/warning validators. Defaults to true.","anyOf":[{"type":"boolean"},{"type":"null"}]}},"description":"Structured validator specification with operator and expected value."}},{"type":"null"}]},"aggregations":{"description":"Aggregations computed over this axis data (min, max, avg, etc.).","anyOf":[{"type":"array","items":{"type":"object","properties":{"type":{"type":"string","description":"Aggregation function: \"min\", \"max\", \"avg\", \"sum\", \"count\", \"std\", \"median\", \"percentile_95\", etc.","example":"avg"},"outcome":{"description":"Computed result of aggregation validation. Server stores as-is.","anyOf":[{"type":"string","enum":["PASS","FAIL","UNSET"]},{"type":"null"}]},"value":{"description":"Computed aggregation value.","example":3.3,"anyOf":[{"anyOf":[{"type":"number"},{"type":"string"},{"type":"boolean"}]},{"type":"null"}]},"unit":{"description":"Unit for the aggregated value.","example":"V","anyOf":[{"type":"string"},{"type":"null"}]},"validators":{"description":"Validators applied to the aggregated value.","anyOf":[{"type":"array","items":{"type":"object","properties":{"outcome":{"description":"Pre-computed validation result from test framework. Server stores as-is, does not re-evaluate.","anyOf":[{"type":"string","enum":["PASS","FAIL","UNSET"]},{"type":"null"}]},"operator":{"description":"Comparison operator: \">\", \">=\", \"<\", \"<=\", \"==\", \"!=\", \"matches\", \"in\", \"range\"","example":">=","anyOf":[{"type":"string"},{"type":"null"}]},"expected_value":{"description":"Expected value for comparison. Type depends on operator.","example":3,"anyOf":[{"anyOf":[{"type":"boolean"},{"type":"number"},{"type":"string"},{"type":"array","items":{"type":"number"}},{"type":"array","items":{"type":"string"}}]},{"type":"null"}]},"expression":{"description":"Original expression string for display/audit purposes.","example":"3.0 <= x <= 3.6","anyOf":[{"type":"string"},{"type":"null"}]},"is_decisive":{"description":"Whether this validator is decisive (if it fails, measurement fails). False for marginal/warning validators. Defaults to true.","anyOf":[{"type":"boolean"},{"type":"null"}]}},"description":"Structured validator specification with operator, expected value, and outcome."}},{"type":"null"}]}},"required":["type"],"description":"Aggregation specification with computed value and optional validators."}},{"type":"null"}]}},"required":["data"],"description":"Data series with numeric data, unit, and optional validators/aggregations."}},{"type":"null"}],"description":"Y-axis data series (one or more) for multi-dimensional measurements. Each series can have its own validators and aggregations."},"measured_value":{"anyOf":[{"anyOf":[{"type":"number"},{"type":"string"},{"type":"boolean"},{"type":"array","items":{"type":"array","items":{"type":"number"}}},{"anyOf":[{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{}},{"type":"array","items":{}}]}],"description":"The actual value captured. [LEGACY for multi-dim] For multi-dimensional with per-axis validators/aggregations, use x_axis/y_axis instead.","example":3.3},{"type":"null"}]},"units":{"anyOf":[{"anyOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}]},{"type":"null"}],"description":"[LEGACY for multi-dim] Units of measurement. For structured multi-dimensional, use units within x_axis/y_axis instead.","example":"V"},"lower_limit":{"type":"number","deprecated":true,"description":"Use validators with operator \">=\" instead. Will be converted to a validator automatically.","example":3},"upper_limit":{"type":"number","deprecated":true,"description":"Use validators with operator \"<=\" instead. Will be converted to a validator automatically.","example":3.6},"validators":{"anyOf":[{"description":"Validators for this measurement. Use structured ValidatorSpec objects with operator and expected_value.","example":[{"operator":">=","expected_value":3,"outcome":"PASS"},{"operator":"<=","expected_value":3.6,"outcome":"PASS"}],"type":"array","items":{"type":"object","properties":{"outcome":{"description":"Pre-computed validation result from test framework. Server stores as-is, does not re-evaluate.","anyOf":[{"type":"string","enum":["PASS","FAIL","UNSET"]},{"type":"null"}]},"operator":{"description":"Comparison operator: \">\", \">=\", \"<\", \"<=\", \"==\", \"!=\", \"matches\", \"in\", \"range\"","example":">=","anyOf":[{"type":"string"},{"type":"null"}]},"expected_value":{"description":"Expected value for comparison. Type depends on operator.","example":3,"anyOf":[{"anyOf":[{"type":"boolean"},{"type":"number"},{"type":"string"},{"type":"array","items":{"type":"number"}},{"type":"array","items":{"type":"string"}}]},{"type":"null"}]},"expression":{"description":"Original expression string for display/audit purposes.","example":"3.0 <= x <= 3.6","anyOf":[{"type":"string"},{"type":"null"}]},"is_decisive":{"description":"Whether this validator is decisive (if it fails, measurement fails). False for marginal/warning validators. Defaults to true.","anyOf":[{"type":"boolean"},{"type":"null"}]}},"description":"Structured validator specification with operator and expected value."}},{"type":"null"}]},"aggregations":{"anyOf":[{"type":"array","items":{"type":"object","properties":{"type":{"type":"string","description":"Aggregation function: \"min\", \"max\", \"avg\", \"sum\", \"count\", \"std\", \"median\", \"percentile_95\", etc.","example":"avg"},"outcome":{"description":"Computed result of aggregation validation. Server stores as-is.","anyOf":[{"type":"string","enum":["PASS","FAIL","UNSET"]},{"type":"null"}]},"value":{"description":"Computed aggregation value.","example":3.3,"anyOf":[{"anyOf":[{"type":"number"},{"type":"string"},{"type":"boolean"}]},{"type":"null"}]},"unit":{"description":"Unit for the aggregated value.","example":"V","anyOf":[{"type":"string"},{"type":"null"}]},"validators":{"description":"Validators applied to the aggregated value.","anyOf":[{"type":"array","items":{"type":"object","properties":{"outcome":{"description":"Pre-computed validation result from test framework. Server stores as-is, does not re-evaluate.","anyOf":[{"type":"string","enum":["PASS","FAIL","UNSET"]},{"type":"null"}]},"operator":{"description":"Comparison operator: \">\", \">=\", \"<\", \"<=\", \"==\", \"!=\", \"matches\", \"in\", \"range\"","example":">=","anyOf":[{"type":"string"},{"type":"null"}]},"expected_value":{"description":"Expected value for comparison. Type depends on operator.","example":3,"anyOf":[{"anyOf":[{"type":"boolean"},{"type":"number"},{"type":"string"},{"type":"array","items":{"type":"number"}},{"type":"array","items":{"type":"string"}}]},{"type":"null"}]},"expression":{"description":"Original expression string for display/audit purposes.","example":"3.0 <= x <= 3.6","anyOf":[{"type":"string"},{"type":"null"}]},"is_decisive":{"description":"Whether this validator is decisive (if it fails, measurement fails). False for marginal/warning validators. Defaults to true.","anyOf":[{"type":"boolean"},{"type":"null"}]}},"description":"Structured validator specification with operator, expected value, and outcome."}},{"type":"null"}]}},"required":["type"],"description":"Aggregation specification with computed value and optional validators."},"description":"Aggregations computed over measurement values (min, max, avg, etc.). Each aggregation can have its own validators.","example":[{"type":"avg","value":3.3,"outcome":"PASS"}]},{"type":"null"}]},"docstring":{"anyOf":[{"type":"string","maxLength":50000,"description":"Additional notes or documentation about this measurement.","example":"Main power rail voltage measurement after stabilization"},{"type":"null"}]}},"required":["name","outcome"]},"description":"Array of measurements collected during this phase. Each measurement captures specific test data points with values, limits, and validation results. If no measurements are specified, the phase will be created without measurement data."},{"type":"null"}]},"retry_count":{"default":0,"description":"Zero-based retry attempt index for this phase. 0 = first attempt, 1 = first retry, etc. When a phase is retried, all attempts are stored with the same name and increasing retry_count.","example":0,"type":"integer","minimum":0,"maximum":9007199254740991}},"required":["name","outcome","started_at","ended_at"]},"description":"Array of test phases with measurements and results. Each phase represents a distinct stage of the test execution with timing information, outcome status, and optional measurements. If no phases are specified, the run will be created without phase-level organization of test data."},"logs":{"type":"array","items":{"type":"object","properties":{"level":{"type":"string","enum":["DEBUG","INFO","WARNING","ERROR","CRITICAL"],"description":"Severity level of the log message following standard system logging levels. Use DEBUG for detailed diagnostic information, INFO for general execution information, WARNING for unexpected events or potential issues, ERROR for serious problems that prevented function execution, CRITICAL for severe errors that may cause program termination.","example":"INFO"},"timestamp":{"type":"string","format":"date-time","pattern":"^(?:(?:\\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)))$","description":"ISO 8601 timestamp when the log message was generated.","example":"2024-01-15T10:30:15Z"},"message":{"description":"Content of the log message. Contains the actual log text describing the event, error, or information being logged. Messages longer than 10,000 characters will be truncated; empty messages become \"(empty)\".","example":"Starting voltage measurement sequence","type":"string"},"source_file":{"description":"Name or path of the source file where the log message originated. Helps identify the code location that generated the log entry. Paths longer than 200 characters keep the trailing 200 (leading characters are dropped); empty values become \"unknown\".","example":"voltage_test.py","type":"string"},"line_number":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Line number in the source file where the log message was generated. Used for debugging and tracing log origins.","example":42}},"required":["level","timestamp","message","source_file","line_number"]},"description":"Array of log messages generated during the test execution. Each log entry captures events, errors, and diagnostic information with severity levels and source code references. If no logs are specified, the run will be created without log entries."},"metadata":{"description":"Custom metadata to attach to the run (max 50 keys). Plain object of key/value pairs; values can be string, number, or boolean. Type is detected from the value.","example":{"fixture":"station-3","temperature_c":24.5,"rerun":false},"type":"object","propertyNames":{"type":"string","minLength":1,"maxLength":40,"pattern":"^[a-zA-Z0-9_.:+-]+$"},"additionalProperties":{"anyOf":[{"type":"string","maxLength":50000},{"type":"number"},{"type":"boolean"}]}},"unit_metadata":{"description":"Custom metadata to upsert on the unit under test (max 50 keys per unit). PATCH semantics: keys not present here are preserved on the unit.","example":{"vendor":"Acme"},"type":"object","propertyNames":{"type":"string","minLength":1,"maxLength":40,"pattern":"^[a-zA-Z0-9_.:+-]+$"},"additionalProperties":{"anyOf":[{"type":"string","maxLength":50000},{"type":"number"},{"type":"boolean"}]}}},"required":["outcome","procedure_id","started_at","ended_at","serial_number"]}}}},"responses":{"200":{"description":"Run created successfully","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","description":"Unique identifier of the created run. For a file that yields several runs (a multi-part STDF/ATDF datalog or a multi-report WSXF/TestStand document), this is the first run; see `ids` for the full set.","example":"550e8400-e29b-41d4-a716-446655440000"},"ids":{"description":"All run identifiers created from the file. Present when the import produced more than one run; a single-run import omits it (use `id`).","type":"array","items":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"}}},"required":["id"],"additionalProperties":false}}}},"400":{"description":"Bad request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBADREQUEST"}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorUNAUTHORIZED"}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorFORBIDDEN"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorNOTFOUND"}}}},"422":{"description":"Part number extraction failed for serial number {serial_number}. Provide a part_number parameter explicitly or fix the regex pattern in organization settings.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorUNPROCESSABLECONTENT"}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorINTERNALSERVERERROR"}}}}},"x-access":[{"level":"full","authType":"user","description":"Users can create runs"},{"level":"limited","authType":"station","description":"Stations cannot create runs"}],"x-speakeasy-name-override":"create"},"get":{"operationId":"run-list","summary":"List and filter runs","description":"List runs with filtering by unit, procedure, date range, outcome, and station. Cursor-paginated.","tags":["Runs"],"security":[{"api_key":[]}],"parameters":[{"name":"search_query","in":"query","required":false,"schema":{"type":"string","description":"Search query to filter runs by run ID (partial match) or unit serial number.","example":"SN-001234"}},{"name":"ids","in":"query","required":false,"schema":{"description":"Filter by specific run IDs.","example":["550e8400-e29b-41d4-a716-446655440000"],"type":"array","items":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"}}},{"name":"outcomes","in":"query","required":false,"schema":{"description":"Filter by run outcomes.","example":["PASS","FAIL"],"type":"array","items":{"type":"string","enum":["PASS","FAIL","ERROR","TIMEOUT","ABORTED"]}}},{"name":"procedure_ids","in":"query","required":false,"schema":{"description":"Filter by procedure IDs.","example":["550e8400-e29b-41d4-a716-446655440000"],"type":"array","items":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"}}},{"name":"procedure_versions","in":"query","required":false,"schema":{"description":"Filter by procedure versions.","example":["v1.0.0","v2.0.0"],"type":"array","items":{"type":"string"}}},{"name":"deployment_ids","in":"query","required":false,"schema":{"description":"Filter by deployment IDs the run executed from.","example":["550e8400-e29b-41d4-a716-446655440000"],"type":"array","items":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"}}},{"name":"environments","in":"query","required":false,"schema":{"description":"Filter by deployment environment (production, preview, development).","example":["production"],"type":"array","items":{"type":"string","enum":["production","preview","development"]}}},{"name":"serial_numbers","in":"query","required":false,"schema":{"description":"Filter by unit serial numbers.","example":["SN-001234","SN-005678"],"type":"array","items":{"type":"string"}}},{"name":"samples","in":"query","required":false,"schema":{"description":"Filter by the unit's reference-sample classification. Omit to include all units (production + references). Pass ['golden'] for known-good references only, ['failing'] for known-faulty references only, or both.","example":["golden"],"type":"array","items":{"type":"string","enum":["golden","failing","ignored"]}}},{"name":"part_numbers","in":"query","required":false,"schema":{"description":"Filter by component part numbers.","example":["PCB-V1.2","PCB-V1.3"],"type":"array","items":{"type":"string"}}},{"name":"revision_numbers","in":"query","required":false,"schema":{"description":"Filter by revision identifiers.","example":["REV-A","REV-B"],"type":"array","items":{"type":"string"}}},{"name":"batch_numbers","in":"query","required":false,"schema":{"description":"Filter by batch numbers.","example":["BATCH-2024-Q1-001","BATCH-2024-Q1-002"],"type":"array","items":{"type":"string"}}},{"name":"duration_min","in":"query","required":false,"schema":{"type":"string","format":"duration","pattern":"^P(?:(\\d+W)|(?!.*W)(?=\\d|T\\d)(\\d+Y)?(\\d+M)?(\\d+D)?(T(?=\\d)(\\d+H)?(\\d+M)?(\\d+([.,]\\d+)?S)?)?)$","description":"Filter for runs with duration greater than or equal to this value (ISO 8601 duration).","example":"PT5M"}},{"name":"duration_max","in":"query","required":false,"schema":{"type":"string","format":"duration","pattern":"^P(?:(\\d+W)|(?!.*W)(?=\\d|T\\d)(\\d+Y)?(\\d+M)?(\\d+D)?(T(?=\\d)(\\d+H)?(\\d+M)?(\\d+([.,]\\d+)?S)?)?)$","description":"Filter for runs with duration less than or equal to this value (ISO 8601 duration).","example":"PT30M"}},{"name":"started_after","in":"query","required":false,"schema":{"type":"string","format":"date-time","pattern":"^(?:(?:\\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)))$","description":"Filter for runs started at or after this time.","example":"2024-01-15T10:30:00Z"}},{"name":"started_before","in":"query","required":false,"schema":{"type":"string","format":"date-time","pattern":"^(?:(?:\\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)))$","description":"Filter for runs started at or before this time.","example":"2024-01-15T11:30:00Z"}},{"name":"ended_after","in":"query","required":false,"schema":{"type":"string","format":"date-time","pattern":"^(?:(?:\\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)))$","description":"Filter for runs ended at or after this time.","example":"2024-01-15T10:30:00Z"}},{"name":"ended_before","in":"query","required":false,"schema":{"type":"string","format":"date-time","pattern":"^(?:(?:\\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)))$","description":"Filter for runs ended at or before this time.","example":"2024-01-15T11:30:00Z"}},{"name":"created_after","in":"query","required":false,"schema":{"type":"string","format":"date-time","pattern":"^(?:(?:\\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)))$","description":"Filter for runs created at or after this time.","example":"2024-01-15T10:30:00Z"}},{"name":"created_before","in":"query","required":false,"schema":{"type":"string","format":"date-time","pattern":"^(?:(?:\\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)))$","description":"Filter for runs created at or before this time.","example":"2024-01-15T11:30:00Z"}},{"name":"created_by_user_ids","in":"query","required":false,"schema":{"description":"Filter by user IDs who created the runs.","example":["550e8400-e29b-41d4-a716-446655440000"],"type":"array","items":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"}}},{"name":"created_by_station_ids","in":"query","required":false,"schema":{"description":"Filter by station IDs that created the runs.","example":["550e8400-e29b-41d4-a716-446655440000"],"type":"array","items":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"}}},{"name":"operated_by_ids","in":"query","required":false,"schema":{"description":"Filter by user IDs who operated the runs.","example":["550e8400-e29b-41d4-a716-446655440001"],"type":"array","items":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"}}},{"name":"limit","in":"query","required":false,"schema":{"default":50,"description":"Maximum number of runs to return per page.","example":20,"type":"integer","minimum":1,"maximum":100},"description":"Maximum number of runs to return per page."},{"name":"cursor","in":"query","required":false,"schema":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Offset position for pagination. Use the next_cursor from the previous response to get the next page.","example":50}},{"name":"sort_by","in":"query","required":false,"schema":{"default":"started_at","description":"Field to sort results by.","example":"started_at","enum":["started_at","created_at","duration","outcome","serial_number","part_number","revision_number"],"type":"string"}},{"name":"sort_order","in":"query","required":false,"schema":{"default":"desc","description":"Sort order direction.","example":"desc","enum":["asc","desc"],"type":"string"}},{"name":"metadata","in":"query","required":false,"content":{"application/json":{"schema":{"description":"Filter runs by custom metadata. Supports up to 5 keys per request. Per-key operators: string `{in: [...]}`/`{contains: \"...\"}`, number `{gte, lte, gt, lt, eq}`, bool `{eq: true|false}`.","example":{"fixture":{"in":["station-3"]}},"type":"object","propertyNames":{"type":"string","minLength":1,"maxLength":40,"pattern":"^[a-zA-Z0-9_.:+-]+$"},"additionalProperties":{"anyOf":[{"type":"object","properties":{"in":{"minItems":1,"maxItems":50,"type":"array","items":{"type":"string","minLength":1}},"contains":{"type":"string","minLength":1,"maxLength":50000}},"additionalProperties":false},{"type":"object","properties":{"gte":{"type":"number"},"lte":{"type":"number"},"gt":{"type":"number"},"lt":{"type":"number"},"eq":{"type":"number"}},"additionalProperties":false},{"type":"object","properties":{"eq":{"type":"boolean"}},"required":["eq"],"additionalProperties":false}]}}}},"description":"Filter runs by custom metadata. Supports up to 5 keys per request. Per-key operators: string `{in: [...]}`/`{contains: \"...\"}`, number `{gte, lte, gt, lt, eq}`, bool `{eq: true|false}`."},{"name":"include_metadata","in":"query","required":false,"schema":{"description":"When true, includes the run metadata array in the response. Defaults to false to keep payloads small.","example":false,"default":false,"type":"boolean"},"description":"When true, includes the run metadata array in the response. Defaults to false to keep payloads small."}],"responses":{"200":{"description":"Runs retrieved successfully","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","description":"Unique identifier for the run.","example":"550e8400-e29b-41d4-a716-446655440000"},"created_at":{"type":"string","format":"date-time","pattern":"^(?:(?:\\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))$","description":"ISO 8601 timestamp when the run was created.","example":"2024-01-15T10:30:00Z"},"started_at":{"type":"string","format":"date-time","pattern":"^(?:(?:\\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))$","description":"ISO 8601 timestamp when the run execution started.","example":"2024-01-15T10:35:00Z"},"ended_at":{"type":"string","format":"date-time","pattern":"^(?:(?:\\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))$","description":"ISO 8601 timestamp when the run execution ended.","example":"2024-01-15T10:37:30Z"},"duration":{"type":"string","description":"ISO 8601 duration of the run (computed from started_at and ended_at).","example":"PT2M30S"},"outcome":{"type":"string","enum":["PASS","FAIL","ERROR","TIMEOUT","ABORTED"],"description":"Final result of the run execution.","example":"PASS"},"docstring":{"description":"Additional notes or documentation about this test run.","example":"Test run for production validation","anyOf":[{"type":"string"},{"type":"null"}]},"created_by_user":{"description":"User whose API key was used to create this run. Only returned if `all` or `created_by` is included.","anyOf":[{"type":"object","properties":{"id":{"type":"string","description":"User ID.","example":"550e8400-e29b-41d4-a716-446655440001"},"name":{"anyOf":[{"type":"string","description":"User display name.","example":"John Doe"},{"type":"null"}]},"email":{"anyOf":[{"type":"string","description":"User email address.","example":"john.doe@example.com"},{"type":"null"}]}},"required":["id","name","email"],"additionalProperties":false},{"type":"null"}]},"created_by_station":{"description":"Station whose API key was used to create this run. Only returned if `all` or `created_by` is included.","anyOf":[{"type":"object","properties":{"id":{"type":"string","description":"Station ID.","example":"550e8400-e29b-41d4-a716-446655440002"},"name":{"type":"string","description":"Station name.","example":"Test Station 01"}},"required":["id","name"],"additionalProperties":false},{"type":"null"}]},"operated_by":{"description":"User who operated this run. Only returned if `all` or `operated_by` is included.","anyOf":[{"type":"object","properties":{"id":{"type":"string","description":"Operator ID.","example":"550e8400-e29b-41d4-a716-446655440001"},"name":{"anyOf":[{"type":"string","description":"Operator display name.","example":"John Doe"},{"type":"null"}]},"email":{"anyOf":[{"type":"string","description":"Operator email address.","example":"john.doe@example.com"},{"type":"null"}]}},"required":["id","name","email"],"additionalProperties":false},{"type":"null"}]},"procedure":{"type":"object","properties":{"id":{"type":"string","description":"Procedure ID.","example":"550e8400-e29b-41d4-a716-446655440003"},"name":{"type":"string","description":"Procedure name.","example":"PCB Functional Test"},"version":{"anyOf":[{"type":"object","properties":{"id":{"type":"string","description":"Procedure version ID.","example":"550e8400-e29b-41d4-a716-446655440010"},"tag":{"type":"string","description":"Version tag.","example":"v2.1.0"}},"required":["id","tag"],"additionalProperties":false},{"type":"null"}],"description":"Version of the procedure used for this run.","example":{"id":"550e8400-e29b-41d4-a716-446655440010","tag":"v2.1.0"}}},"required":["id","name","version"],"additionalProperties":false,"description":"Test procedure associated with this run."},"unit":{"type":"object","properties":{"id":{"type":"string","description":"Unit ID.","example":"550e8400-e29b-41d4-a716-446655440004"},"serial_number":{"type":"string","description":"Unit serial number.","example":"SN-2024-001234"},"sample":{"anyOf":[{"type":"string","enum":["golden","failing","ignored"]},{"type":"null"}],"description":"Reference-sample classification of the unit. 'golden' = known-good reference, 'failing' = known-faulty reference, 'ignored' = bench-check unit excluded from analytics and alerts, null = production unit.","example":null},"part":{"type":"object","properties":{"id":{"type":"string","description":"Part ID.","example":"550e8400-e29b-41d4-a716-446655440007"},"number":{"type":"string","description":"Part number.","example":"PCB-MAIN-001"},"name":{"type":"string","description":"Part name.","example":"Main Control Board"},"revision":{"type":"object","properties":{"id":{"type":"string","description":"Revision ID.","example":"550e8400-e29b-41d4-a716-446655440006"},"number":{"type":"string","description":"Revision number.","example":"REV-A"}},"required":["id","number"],"additionalProperties":false,"description":"Revision information for this unit.","example":{"id":"550e8400-e29b-41d4-a716-446655440006","number":"REV-A"}}},"required":["id","number","name","revision"],"additionalProperties":false,"description":"Part information with revision details."},"batch":{"description":"Batch information for this unit.","example":{"id":"550e8400-e29b-41d4-a716-446655440005","number":"BATCH-2024-Q1-001"},"anyOf":[{"type":"object","properties":{"id":{"type":"string","description":"Batch ID.","example":"550e8400-e29b-41d4-a716-446655440005"},"number":{"type":"string","description":"Batch number.","example":"BATCH-2024-Q1-001"}},"required":["id","number"],"additionalProperties":false},{"type":"null"}]}},"required":["id","serial_number","sample","part"],"additionalProperties":false,"description":"Unit under test information."},"metadata":{"description":"Custom metadata key/value pairs on the run. Only present when the request sets `include_metadata=true`.","type":"object","propertyNames":{"type":"string","minLength":1,"maxLength":40,"pattern":"^[a-zA-Z0-9_.:+-]+$"},"additionalProperties":{"anyOf":[{"type":"string","maxLength":50000},{"type":"number"},{"type":"boolean"}]},"example":{"vendor":"Acme","lot_size":500,"qualified":true}}},"required":["id","created_at","started_at","ended_at","duration","outcome","procedure","unit"],"additionalProperties":false}},"meta":{"type":"object","properties":{"has_more":{"type":"boolean","description":"Whether there are more results available for pagination.","example":true},"next_cursor":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}],"description":"Cursor value to fetch the next page of results. Use this value as the cursor parameter in the next request. Null if no more results available.","example":100}},"required":["has_more","next_cursor"],"additionalProperties":false}},"required":["data","meta"],"additionalProperties":false,"description":"Paginated list of test runs matching the filter criteria."}}}},"400":{"description":"{message}","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBADREQUEST"}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorUNAUTHORIZED"}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorINTERNALSERVERERROR"}}}}},"x-access":[{"level":"full","authType":"user","description":"Users can read runs"},{"level":"limited","authType":"station","description":"Stations cannot read runs"}],"x-speakeasy-name-override":"list"},"delete":{"operationId":"run-delete","summary":"Delete runs","description":"Delete runs by ID. Also removes their phases, measurements, and attachments. Irreversible.","tags":["Runs"],"security":[{"api_key":[]}],"parameters":[{"name":"ids","in":"query","required":true,"schema":{"type":"array","items":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","description":"Unique identifier of the run to delete","example":"550e8400-e29b-41d4-a716-446655440000"},"description":"Run IDs to delete.","example":["550e8400-e29b-41d4-a716-446655440000","6ba7b810-9dad-11d1-80b4-00c04fd430c8"]},"style":"form","explode":true,"description":"Run IDs to delete."}],"responses":{"200":{"description":"Runs deleted successfully","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"array","items":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","description":"ID of a successfully deleted run","example":"550e8400-e29b-41d4-a716-446655440000"},"description":"IDs of runs that were successfully deleted","example":["550e8400-e29b-41d4-a716-446655440000","6ba7b810-9dad-11d1-80b4-00c04fd430c8"]}},"required":["id"],"additionalProperties":false,"description":"Response for successful run deletion"}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorUNAUTHORIZED"}}}},"404":{"description":"No runs found with IDs: {runIds}","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorNOTFOUND"}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorINTERNALSERVERERROR"}}}}},"x-access":[{"level":"full","authType":"user","description":"Users can delete runs"},{"level":"unauthorized","authType":"station","description":"Stations cannot delete runs"}],"x-speakeasy-name-override":"delete"}},"/v2/runs/{id}":{"get":{"operationId":"run-get","summary":"Get run","description":"Get a run by ID, with its metadata, phases, measurements, and logs.","tags":["Runs"],"security":[{"api_key":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"ID of the run to retrieve."}],"responses":{"200":{"description":"Runs retrieved successfully","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","description":"Unique identifier for the run.","example":"550e8400-e29b-41d4-a716-446655440000"},"created_at":{"type":"string","format":"date-time","pattern":"^(?:(?:\\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))$","description":"ISO 8601 timestamp when the run was created.","example":"2024-01-15T10:30:00Z"},"started_at":{"type":"string","format":"date-time","pattern":"^(?:(?:\\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))$","description":"ISO 8601 timestamp when the run execution started.","example":"2024-01-15T10:35:00Z"},"ended_at":{"type":"string","format":"date-time","pattern":"^(?:(?:\\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))$","description":"ISO 8601 timestamp when the run execution ended.","example":"2024-01-15T10:37:30Z"},"duration":{"type":"string","description":"ISO 8601 duration of the run (computed from started_at and ended_at).","example":"PT2M30S"},"outcome":{"type":"string","enum":["PASS","FAIL","ERROR","TIMEOUT","ABORTED"],"description":"Final result of the run execution.","example":"PASS"},"docstring":{"description":"Additional notes or documentation about this test run.","example":"Test run for production validation","anyOf":[{"type":"string"},{"type":"null"}]},"created_by_user":{"description":"User whose API key was used to create this run. Only returned if `all` or `created_by` is included.","anyOf":[{"type":"object","properties":{"id":{"type":"string","description":"User ID.","example":"550e8400-e29b-41d4-a716-446655440001"},"name":{"anyOf":[{"type":"string","description":"User display name.","example":"John Doe"},{"type":"null"}]},"email":{"anyOf":[{"type":"string","description":"User email address.","example":"john.doe@example.com"},{"type":"null"}]}},"required":["id","name","email"],"additionalProperties":false},{"type":"null"}]},"created_by_station":{"description":"Station whose API key was used to create this run. Only returned if `all` or `created_by` is included.","anyOf":[{"type":"object","properties":{"id":{"type":"string","description":"Station ID.","example":"550e8400-e29b-41d4-a716-446655440002"},"name":{"anyOf":[{"type":"string","description":"Station name.","example":"Test Station 01"},{"type":"null"}]}},"required":["id","name"],"additionalProperties":false},{"type":"null"}]},"operated_by":{"description":"User who operated this run. Only returned if `all` or `operated_by` is included.","anyOf":[{"type":"object","properties":{"id":{"type":"string","description":"Operator ID.","example":"550e8400-e29b-41d4-a716-446655440001"},"name":{"anyOf":[{"type":"string","description":"Operator display name.","example":"John Doe"},{"type":"null"}]},"email":{"anyOf":[{"type":"string","description":"Operator email address.","example":"john.doe@example.com"},{"type":"null"}]}},"required":["id","name","email"],"additionalProperties":false},{"type":"null"}]},"procedure":{"type":"object","properties":{"id":{"type":"string","description":"Procedure ID.","example":"550e8400-e29b-41d4-a716-446655440003"},"name":{"type":"string","description":"Procedure name.","example":"PCB Functional Test"},"version":{"anyOf":[{"type":"object","properties":{"id":{"type":"string","description":"Procedure version ID.","example":"550e8400-e29b-41d4-a716-446655440010"},"tag":{"type":"string","description":"Version tag.","example":"v2.1.0"}},"required":["id","tag"],"additionalProperties":false},{"type":"null"}],"description":"Version of the procedure used for this run.","example":{"id":"550e8400-e29b-41d4-a716-446655440010","tag":"v2.1.0"}}},"required":["id","name","version"],"additionalProperties":false,"description":"Test procedure associated with this run."},"unit":{"type":"object","properties":{"id":{"type":"string","description":"Unit ID.","example":"550e8400-e29b-41d4-a716-446655440004"},"serial_number":{"type":"string","description":"Unit serial number.","example":"SN-2024-001234"},"sample":{"anyOf":[{"type":"string","enum":["golden","failing","ignored"]},{"type":"null"}],"description":"Reference-sample classification of the unit. 'golden' = known-good reference, 'failing' = known-faulty reference, 'ignored' = bench-check unit excluded from analytics and alerts, null = production unit.","example":null},"part":{"type":"object","properties":{"id":{"type":"string","description":"Part ID.","example":"550e8400-e29b-41d4-a716-446655440007"},"number":{"type":"string","description":"Part number.","example":"PCB-MAIN-001"},"name":{"type":"string","description":"Part name.","example":"Main Control Board"},"revision":{"type":"object","properties":{"id":{"type":"string","description":"Revision ID.","example":"550e8400-e29b-41d4-a716-446655440006"},"number":{"type":"string","description":"Revision number.","example":"REV-A"}},"required":["id","number"],"additionalProperties":false,"description":"Revision information for this unit.","example":{"id":"550e8400-e29b-41d4-a716-446655440006","number":"REV-A"}}},"required":["id","number","name","revision"],"additionalProperties":false,"description":"Part information with revision details."},"batch":{"description":"Batch information for this unit.","example":{"id":"550e8400-e29b-41d4-a716-446655440005","number":"BATCH-2024-Q1-001"},"anyOf":[{"type":"object","properties":{"id":{"type":"string","description":"Batch ID.","example":"550e8400-e29b-41d4-a716-446655440005"},"number":{"type":"string","description":"Batch number.","example":"BATCH-2024-Q1-001"}},"required":["id","number"],"additionalProperties":false},{"type":"null"}]}},"required":["id","serial_number","sample","part"],"additionalProperties":false,"description":"Unit under test information."},"phases":{"description":"Array of execution phases in this run. Only returned if `all` or `phases` is included.","type":"array","items":{"type":"object","properties":{"id":{"type":"string","description":"Phase ID.","example":"550e8400-e29b-41d4-a716-446655440008"},"name":{"type":"string","description":"Phase name.","example":"Power On Test"},"outcome":{"type":"string","enum":["PASS","FAIL","SKIP","ERROR"],"description":"Phase execution result.","example":"PASS"},"started_at":{"type":"string","format":"date-time","pattern":"^(?:(?:\\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))$","description":"ISO 8601 timestamp when the phase started.","example":"2024-01-15T10:35:00Z"},"ended_at":{"type":"string","format":"date-time","pattern":"^(?:(?:\\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))$","description":"ISO 8601 timestamp when the phase ended.","example":"2024-01-15T10:36:30Z"},"duration":{"type":"string","description":"ISO 8601 duration of the phase (computed from started_at and ended_at).","example":"PT1M30S"},"retry_count":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Zero-based retry attempt index. 0 = first attempt, 1 = first retry, etc.","example":0},"docstring":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Phase documentation string.","example":"Verifies that the board powers on correctly and all voltage rails are within spec."},"measurements":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","description":"Measurement ID.","example":"550e8400-e29b-41d4-a716-446655440009"},"name":{"type":"string","description":"Measurement name.","example":"Input Voltage"},"outcome":{"type":"string","enum":["PASS","FAIL","UNSET"],"description":"Measurement validation result.","example":"PASS"},"units":{"description":"Units of measurement. Not present for multi-dimensional measurements (units are per data series).","example":"V","anyOf":[{"type":"string"},{"type":"null"}]},"validators":{"anyOf":[{"type":"array","items":{"type":"object","properties":{"outcome":{"type":"string","enum":["PASS","FAIL","UNSET"],"description":"Validation result: PASS, FAIL, or UNSET.","example":"PASS"},"operator":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Comparison operator used for validation.","example":">="},"expected_value":{"anyOf":[{"anyOf":[{"type":"null"},{"type":"boolean"},{"type":"number"},{"type":"string"},{"type":"array","items":{"type":"number"}},{"type":"array","items":{"type":"string"}}]},{"type":"null"}],"description":"Expected value for comparison. Type depends on measurement type.","example":3},"expression":{"type":"string","description":"Human-readable expression string for display.","example":"x >= 3.0"},"is_decisive":{"anyOf":[{"type":"boolean"},{"type":"null"}],"description":"Whether this validator is decisive (if it fails, measurement fails). False for marginal/warning validators."},"is_expression_only":{"type":"boolean","description":"True if validator only has expression (no structured operator/expected_value)."},"analytics_expression":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Synthetic expression from operator+expected_value for analytics tooltip. Null if expression-only."},"has_custom_expression":{"type":"boolean","description":"True if user provided a custom expression (shown in italic with analytics tooltip)."}},"required":["outcome","operator","expected_value","expression","is_decisive","is_expression_only","analytics_expression","has_custom_expression"],"additionalProperties":false,"description":"Validator result with outcome and comparison details."}},{"type":"null"}],"description":"Structured validation rules with outcome and expected values."},"aggregations":{"description":"Aggregations computed over this measurement.","anyOf":[{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","description":"Unique identifier for the aggregation."},"type":{"type":"string","description":"Aggregation type (e.g., MIN, MAX, MEAN, RANGE, STD_DEV).","example":"MEAN"},"outcome":{"anyOf":[{"type":"string","enum":["PASS","FAIL","UNSET"]},{"type":"null"}],"description":"Aggregation validation result: PASS, FAIL, UNSET, or null if no validators.","example":"PASS"},"value":{"anyOf":[{"anyOf":[{"type":"number"},{"type":"string"},{"type":"boolean"}]},{"type":"null"}],"description":"Computed aggregation value. Type depends on aggregation type.","example":42.5},"unit":{"description":"Unit of measurement for the aggregated value.","example":"V","anyOf":[{"type":"string"},{"type":"null"}]},"validators":{"description":"Validators applied to the aggregated value.","anyOf":[{"type":"array","items":{"type":"object","properties":{"outcome":{"type":"string","enum":["PASS","FAIL","UNSET"],"description":"Validation result: PASS, FAIL, or UNSET.","example":"PASS"},"operator":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Comparison operator used for validation.","example":">="},"expected_value":{"anyOf":[{"anyOf":[{"type":"null"},{"type":"boolean"},{"type":"number"},{"type":"string"},{"type":"array","items":{"type":"number"}},{"type":"array","items":{"type":"string"}}]},{"type":"null"}],"description":"Expected value for comparison. Type depends on measurement type.","example":3},"expression":{"type":"string","description":"Human-readable expression string for display.","example":"x >= 3.0"},"is_decisive":{"anyOf":[{"type":"boolean"},{"type":"null"}],"description":"Whether this validator is decisive (if it fails, measurement fails). False for marginal/warning validators."},"is_expression_only":{"type":"boolean","description":"True if validator only has expression (no structured operator/expected_value)."},"analytics_expression":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Synthetic expression from operator+expected_value for analytics tooltip. Null if expression-only."},"has_custom_expression":{"type":"boolean","description":"True if user provided a custom expression (shown in italic with analytics tooltip)."}},"required":["outcome","operator","expected_value","expression","is_decisive","is_expression_only","analytics_expression","has_custom_expression"],"additionalProperties":false,"description":"Validator result with outcome and comparison details."}},{"type":"null"}]}},"required":["id","type","outcome","value"],"additionalProperties":false,"description":"Aggregation result with computed value and optional validators."}},{"type":"null"}]},"measured_value":{"description":"The actual measured value.","example":12.05,"anyOf":[{"type":"number"},{"type":"string"},{"type":"boolean"},{"type":"array","items":{"type":"array","items":{"type":"number"}}},{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{}},{"type":"array","items":{}}]},"data_series":{"description":"Multi-dimensional measurement data series.","type":"array","items":{"type":"object","properties":{"data":{"type":"array","items":{"type":"number"},"description":"Array of numeric data points for this series.","example":[0,1,2,3,4]},"units":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Unit for this data series.","example":"V"},"name":{"description":"Name of this data series.","example":"Frequency","anyOf":[{"type":"string"},{"type":"null"}]},"description":{"description":"Description of this data series.","example":"Output voltage over time","anyOf":[{"type":"string"},{"type":"null"}]},"validators":{"description":"Validators for this data series.","anyOf":[{"type":"array","items":{"type":"object","properties":{"outcome":{"type":"string","enum":["PASS","FAIL","UNSET"],"description":"Validation result: PASS, FAIL, or UNSET.","example":"PASS"},"operator":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Comparison operator used for validation.","example":">="},"expected_value":{"anyOf":[{"anyOf":[{"type":"null"},{"type":"boolean"},{"type":"number"},{"type":"string"},{"type":"array","items":{"type":"number"}},{"type":"array","items":{"type":"string"}}]},{"type":"null"}],"description":"Expected value for comparison. Type depends on measurement type.","example":3},"expression":{"type":"string","description":"Human-readable expression string for display.","example":"x >= 3.0"},"is_decisive":{"anyOf":[{"type":"boolean"},{"type":"null"}],"description":"Whether this validator is decisive (if it fails, measurement fails). False for marginal/warning validators."},"is_expression_only":{"type":"boolean","description":"True if validator only has expression (no structured operator/expected_value)."},"analytics_expression":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Synthetic expression from operator+expected_value for analytics tooltip. Null if expression-only."},"has_custom_expression":{"type":"boolean","description":"True if user provided a custom expression (shown in italic with analytics tooltip)."}},"required":["outcome","operator","expected_value","expression","is_decisive","is_expression_only","analytics_expression","has_custom_expression"],"additionalProperties":false,"description":"Validator result with outcome and comparison details."}},{"type":"null"}]},"aggregations":{"description":"Aggregations computed over this data series.","anyOf":[{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","description":"Unique identifier for the aggregation."},"type":{"type":"string","description":"Aggregation type (e.g., MIN, MAX, MEAN, RANGE, STD_DEV).","example":"MEAN"},"outcome":{"anyOf":[{"type":"string","enum":["PASS","FAIL","UNSET"]},{"type":"null"}],"description":"Aggregation validation result: PASS, FAIL, UNSET, or null if no validators.","example":"PASS"},"value":{"anyOf":[{"anyOf":[{"type":"number"},{"type":"string"},{"type":"boolean"}]},{"type":"null"}],"description":"Computed aggregation value. Type depends on aggregation type.","example":42.5},"unit":{"description":"Unit of measurement for the aggregated value.","example":"V","anyOf":[{"type":"string"},{"type":"null"}]},"validators":{"description":"Validators applied to the aggregated value.","anyOf":[{"type":"array","items":{"type":"object","properties":{"outcome":{"type":"string","enum":["PASS","FAIL","UNSET"],"description":"Validation result: PASS, FAIL, or UNSET.","example":"PASS"},"operator":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Comparison operator used for validation.","example":">="},"expected_value":{"anyOf":[{"anyOf":[{"type":"null"},{"type":"boolean"},{"type":"number"},{"type":"string"},{"type":"array","items":{"type":"number"}},{"type":"array","items":{"type":"string"}}]},{"type":"null"}],"description":"Expected value for comparison. Type depends on measurement type.","example":3},"expression":{"type":"string","description":"Human-readable expression string for display.","example":"x >= 3.0"},"is_decisive":{"anyOf":[{"type":"boolean"},{"type":"null"}],"description":"Whether this validator is decisive (if it fails, measurement fails). False for marginal/warning validators."},"is_expression_only":{"type":"boolean","description":"True if validator only has expression (no structured operator/expected_value)."},"analytics_expression":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Synthetic expression from operator+expected_value for analytics tooltip. Null if expression-only."},"has_custom_expression":{"type":"boolean","description":"True if user provided a custom expression (shown in italic with analytics tooltip)."}},"required":["outcome","operator","expected_value","expression","is_decisive","is_expression_only","analytics_expression","has_custom_expression"],"additionalProperties":false,"description":"Validator result with outcome and comparison details."}},{"type":"null"}]}},"required":["id","type","outcome","value"],"additionalProperties":false,"description":"Aggregation result with computed value and optional validators."}},{"type":"null"}]}},"required":["data","units"],"additionalProperties":false}}},"required":["id","name","outcome","validators"],"additionalProperties":false},"description":"Array of measurements taken during this phase."}},"required":["id","name","outcome","started_at","ended_at","duration","retry_count","measurements"],"additionalProperties":false}},"attachments":{"description":"Files attached to this run, including both regular attachments and test reports. Only returned if `all` or `attachments` is included.","type":"array","items":{"type":"object","properties":{"id":{"type":"string","description":"Attachment ID.","example":"550e8400-e29b-41d4-a716-446655440011"},"name":{"type":"string","description":"File name.","example":"test-results.pdf"},"size":{"anyOf":[{"type":"number"},{"type":"null"}],"description":"File size in bytes.","example":1048576},"content_type":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"MIME type of the file.","example":"application/pdf"},"is_report":{"type":"boolean","description":"Whether this attachment is a test report (from file import) or a regular attachment.","example":false},"download_url":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Presigned URL for downloading the file. This URL is temporary and will expire.","example":"https://s3.amazonaws.com/bucket/file?X-Amz-Algorithm=..."}},"required":["id","name","size","content_type","is_report"],"additionalProperties":false}},"logs":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"level":{"type":"string","enum":["DEBUG","INFO","WARNING","ERROR","CRITICAL"]},"timestamp":{"type":"string","format":"date-time","pattern":"^(?:(?:\\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))$"},"message":{"type":"string"},"source_file":{"type":"string"},"line_number":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991}},"required":["id","level","timestamp","message","source_file","line_number"],"additionalProperties":false}},"sub_units":{"description":"Array of sub-units that had parent changes during this run. Only returned if `all` or `sub_units` is included.","example":[{"id":"550e8400-e29b-41d4-a716-446655440000","serial_number":"SN-SUB-001","part_number":"PART-001","part_name":"Motor Assembly"},{"id":"550e8400-e29b-41d4-a716-446655440001","serial_number":"SN-SUB-002","part_number":"PART-002","part_name":null}],"type":"array","items":{"type":"object","properties":{"id":{"type":"string","description":"Unit ID.","example":"550e8400-e29b-41d4-a716-446655440000"},"serial_number":{"type":"string","description":"Unit serial number.","example":"SN-SUB-001"},"part_number":{"type":"string","description":"Part number of the sub-unit.","example":"PART-001"},"part_name":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Part name of the sub-unit.","example":"Motor Assembly"}},"required":["id","serial_number","part_number","part_name"],"additionalProperties":false}},"metadata":{"description":"Custom metadata key/value pairs on the run.","type":"object","propertyNames":{"type":"string","minLength":1,"maxLength":40,"pattern":"^[a-zA-Z0-9_.:+-]+$"},"additionalProperties":{"anyOf":[{"type":"string","maxLength":50000},{"type":"number"},{"type":"boolean"}]},"example":{"vendor":"Acme","lot_size":500,"qualified":true}}},"required":["id","created_at","started_at","ended_at","duration","outcome","procedure","unit"],"additionalProperties":false,"description":"Single test run details."}}}},"400":{"description":"{message}","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBADREQUEST"}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorUNAUTHORIZED"}}}},"404":{"description":"Run with ID {id} not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorNOTFOUND"}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorINTERNALSERVERERROR"}}}}},"x-access":[{"level":"full","authType":"user","description":"Users can read runs"},{"level":"limited","authType":"station","description":"Stations cannot read runs"}],"x-speakeasy-name-override":"get"},"patch":{"operationId":"run-update","summary":"Update run","description":"Link uploaded files to a run. Upload files via Initialize and Finalize first, then call this to attach them.","tags":["Runs"],"security":[{"api_key":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"Unique identifier of the run to update."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"attachments":{"description":"Array of upload IDs to attach to the run.","example":["550e8400-e29b-41d4-a716-446655440000"],"type":"array","items":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"}}}}}}},"responses":{"200":{"description":"Run attachments updated successfully","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","description":"Unique identifier of the updated run.","example":"550e8400-e29b-41d4-a716-446655440000"}},"required":["id"],"additionalProperties":false}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorUNAUTHORIZED"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorNOTFOUND"}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorINTERNALSERVERERROR"}}}}},"x-access":[{"level":"full","authType":"user","description":"Users can update runs"},{"level":"limited","authType":"station","description":"Stations cannot update runs"}],"x-speakeasy-name-override":"update"}},"/v2/runs/{id}/attachments":{"post":{"operationId":"run-createAttachment","summary":"Attach file to run","description":"Attach a file to a run. Returns an upload ID and pre-signed URL; PUT the file to the URL, then call Finalize upload to commit.","tags":["Runs"],"security":[{"api_key":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"Unique identifier of the run to attach the file to."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":255,"description":"File name including extension (e.g. \"report.pdf\"). Used to determine content type and display name.","example":"test_report.pdf"}},"required":["name"]}}}},"responses":{"200":{"description":"Run attachment created successfully","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","description":"Unique identifier of the created attachment. Use this to reference the attachment in subsequent API calls.","example":"550e8400-e29b-41d4-a716-446655440000"},"upload_url":{"type":"string","description":"Temporary pre-signed URL to upload the file directly to storage. Send a PUT request with the raw file bytes and appropriate Content-Type header. The URL expires after 60 seconds.","example":"https://storage.example.com/org/file.pdf?X-Amz-Signature=abc123"}},"required":["id","upload_url"],"additionalProperties":false}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorUNAUTHORIZED"}}}},"404":{"description":"Run not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorNOTFOUND"}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorINTERNALSERVERERROR"}}}}},"x-access":[{"level":"full","authType":"user","description":"Users can update runs"},{"level":"limited","authType":"station","description":"Stations cannot update runs"}],"x-speakeasy-name-override":"create"}},"/v2/runs/{id}/metadata":{"patch":{"operationId":"run-updateMetadata","summary":"Update run metadata","description":"Upsert custom metadata on a run as a key/value object. Omitted keys are preserved; pass `null` to delete a key.","tags":["Runs"],"security":[{"api_key":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"Unique identifier of the run to update."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"metadata":{"description":"Custom metadata to upsert on the run. Plain object of key/value pairs. PATCH semantics: keys not present here are preserved. Pass `null` as a value to delete a key.","example":{"fixture":"station-3","last_temp":null},"type":"object","propertyNames":{"type":"string","minLength":1,"maxLength":40,"pattern":"^[a-zA-Z0-9_.:+-]+$"},"additionalProperties":{"anyOf":[{"anyOf":[{"type":"string","maxLength":50000},{"type":"number"},{"type":"boolean"}]},{"type":"null"}]}}}}}}},"responses":{"200":{"description":"Run metadata updated successfully","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","description":"Unique identifier of the updated run.","example":"550e8400-e29b-41d4-a716-446655440000"}},"required":["id"],"additionalProperties":false}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorUNAUTHORIZED"}}}},"404":{"description":"Could not find run with ID: {runId}","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorNOTFOUND"}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorINTERNALSERVERERROR"}}}}},"x-access":[{"level":"full","authType":"user","description":"Users can update runs"},{"level":"limited","authType":"station","description":"Stations cannot update runs"}],"x-speakeasy-name-override":"updateMetadata"}},"/v2/attachments":{"post":{"operationId":"attachment-initialize","summary":"Initialize upload","description":"Get a pre-signed URL to upload a file. Returns the upload ID and URL. PUT the file to the URL, then call Finalize upload.","tags":["Attachments"],"security":[{"api_key":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","description":"File name including extension (e.g. \"report.pdf\")"}},"required":["name"]}}}},"responses":{"200":{"description":"Upload URL generated successfully","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","description":"ID of the created upload"},"upload_url":{"type":"string","description":"Pre-signed URL to upload the file directly to S3"}},"required":["id","upload_url"],"additionalProperties":false}}}},"400":{"description":"Invalid file type: {fileType}","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBADREQUEST"}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorUNAUTHORIZED"}}}},"403":{"description":"You must belong to an organization to upload a file","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorFORBIDDEN"}}}},"404":{"description":"Upload not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorNOTFOUND"}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorINTERNALSERVERERROR"}}}},"502":{"description":"Failed to generate upload URL","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBADGATEWAY"}}}}},"x-access":[{"level":"full","authType":"user","description":"Users can create uploads"},{"level":"full","authType":"station","description":"Stations can create uploads"}],"x-speakeasy-name-override":"initialize"}},"/v2/attachments/{id}/finalize":{"post":{"operationId":"attachment-finalize","summary":"Finalize upload","description":"Finalize a file upload after uploading to the pre-signed URL. Validates the file and records its metadata.","tags":["Attachments"],"security":[{"api_key":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"ID of the upload to finalize"}],"responses":{"200":{"description":"Upload metadata updated successfully","content":{"application/json":{"schema":{"type":"object","properties":{"url":{"type":"string","description":"Signed URL for accessing the uploaded file","example":"https://s3.amazonaws.com/bucket/file.pdf?..."}},"required":["url"],"additionalProperties":false}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorUNAUTHORIZED"}}}},"404":{"description":"Upload not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorNOTFOUND"}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorINTERNALSERVERERROR"}}}}},"x-access":[{"level":"full","authType":"user","description":"Users can create uploads"},{"level":"full","authType":"station","description":"Stations can create uploads"}],"x-speakeasy-name-override":"finalize"}},"/v2/units":{"post":{"operationId":"unit-create","summary":"Create unit","description":"Create a unit with a serial number and link it to a part revision.","tags":["Units"],"security":[{"api_key":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"serial_number":{"type":"string","minLength":1,"maxLength":60,"pattern":"^[a-zA-Z0-9_.:+-]+$","description":"Unique serial number identifier for the unit. Must be unique within the organization.","example":"SN-001234"},"part_number":{"type":"string","minLength":1,"maxLength":60,"pattern":"^[a-zA-Z0-9_.:+-]+$","description":"Component part number that defines what type of unit this is. If the part does not exist, it will be created.","example":"PCB-V1.2"},"revision_number":{"type":"string","minLength":1,"maxLength":60,"pattern":"^[a-zA-Z0-9_.:+-]+$","description":"Hardware revision identifier for the specific version of the part. If the revision does not exist, it will be created.","example":"REV-1.0"},"sample":{"description":"Sample classification. 'golden' marks a known-good reference unit; 'failing' marks a known-faulty reference unit; 'ignored' marks a bench-check unit excluded from analytics and alerts. All are excluded from production analytics aggregates (FPY, Cpk, throughput) by default. Omit or null for regular production units.","example":"golden","anyOf":[{"type":"string","enum":["golden","failing","ignored"]},{"type":"null"}]},"metadata":{"description":"Custom metadata to attach to the unit (max 50 keys per unit). Plain object of key/value pairs; values can be string, number, or boolean. Type is detected from the value.","example":{"vendor":"Acme","lot_size":500,"qualified":true},"type":"object","propertyNames":{"type":"string","minLength":1,"maxLength":40,"pattern":"^[a-zA-Z0-9_.:+-]+$"},"additionalProperties":{"anyOf":[{"type":"string","maxLength":50000},{"type":"number"},{"type":"boolean"}]}}},"required":["serial_number","part_number","revision_number"]}}}},"responses":{"200":{"description":"Unit created successfully","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","description":"Unique identifier for the created unit.","example":"550e8400-e29b-41d4-a716-446655440000"}},"required":["id"],"additionalProperties":false}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorUNAUTHORIZED"}}}},"404":{"description":"Revision {revision_number} not found for part {part_number}","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorNOTFOUND"}}}},"409":{"description":"Unit with serial number {serial_number} already exists in the organization","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorCONFLICT"}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorINTERNALSERVERERROR"}}}}},"x-access":[{"level":"full","authType":"user","description":"Users can create units"},{"level":"full","authType":"station","description":"Stations can create units"}],"x-speakeasy-name-override":"create"},"get":{"operationId":"unit-list","summary":"List and filter units","description":"List units with filtering by serial number, part number, and batch. Cursor-paginated.","tags":["Units"],"security":[{"api_key":[]}],"parameters":[{"name":"search_query","in":"query","required":false,"schema":{"type":"string","description":"Search query to filter units by serial number.","example":"SN-001234"}},{"name":"ids","in":"query","required":false,"schema":{"description":"Filter by specific unit IDs.","example":["550e8400-e29b-41d4-a716-446655440000"],"type":"array","items":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"}}},{"name":"serial_numbers","in":"query","required":false,"schema":{"description":"Filter by unit serial numbers.","example":["SN-001234","SN-005678"],"type":"array","items":{"type":"string"}}},{"name":"part_numbers","in":"query","required":false,"schema":{"description":"Filter by component part numbers.","example":["PCB-V1.2","PCB-V1.3"],"type":"array","items":{"type":"string"}}},{"name":"revision_numbers","in":"query","required":false,"schema":{"description":"Filter by revision numbers.","example":["1.0","1.1"],"type":"array","items":{"type":"string"}}},{"name":"batch_numbers","in":"query","required":false,"schema":{"description":"Filter by batch numbers. Use empty string (\"\") alone to filter for units without a batch.","example":["BATCH-2024-01","BATCH-2024-02"],"type":"array","items":{"type":"string"}}},{"name":"procedure_ids","in":"query","required":false,"schema":{"description":"Filter by procedure IDs of runs on the unit.","example":["550e8400-e29b-41d4-a716-446655440000"],"type":"array","items":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"}}},{"name":"outcomes","in":"query","required":false,"schema":{"description":"Filter by outcomes of runs on the unit.","example":["FAIL","ERROR"],"type":"array","items":{"type":"string","enum":["PASS","FAIL","ERROR","TIMEOUT","ABORTED"]}}},{"name":"started_after","in":"query","required":false,"schema":{"type":"string","format":"date-time","pattern":"^(?:(?:\\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)))$","description":"Filter for units with runs started at or after this time.","example":"2024-01-15T10:30:00Z"}},{"name":"started_before","in":"query","required":false,"schema":{"type":"string","format":"date-time","pattern":"^(?:(?:\\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)))$","description":"Filter for units with runs started at or before this time.","example":"2024-01-15T11:30:00Z"}},{"name":"latest_only","in":"query","required":false,"schema":{"default":false,"description":"When true, procedure/outcome/started filters apply only to the latest run per unit.","example":true,"type":"boolean"}},{"name":"run_count_min","in":"query","required":false,"schema":{"type":"integer","minimum":0,"maximum":9007199254740991,"description":"Filter for units with at least this many test runs.","example":2}},{"name":"run_count_max","in":"query","required":false,"schema":{"type":"integer","minimum":0,"maximum":9007199254740991,"description":"Filter for units with at most this many test runs.","example":5}},{"name":"created_after","in":"query","required":false,"schema":{"type":"string","format":"date-time","pattern":"^(?:(?:\\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)))$","description":"Filter for units created at or after this time.","example":"2024-01-15T10:30:00Z"}},{"name":"created_before","in":"query","required":false,"schema":{"type":"string","format":"date-time","pattern":"^(?:(?:\\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)))$","description":"Filter for units created at or before this time.","example":"2024-01-15T11:30:00Z"}},{"name":"created_by_user_ids","in":"query","required":false,"schema":{"description":"Filter by user IDs who created the units.","example":["550e8400-e29b-41d4-a716-446655440000"],"type":"array","items":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"}}},{"name":"created_by_station_ids","in":"query","required":false,"schema":{"description":"Filter by station IDs that created the units.","example":["550e8400-e29b-41d4-a716-446655440000"],"type":"array","items":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"}}},{"name":"exclude_units_with_parent","in":"query","required":false,"schema":{"default":false,"description":"Exclude sub-units (units that have a parent). Shows only top-level units.","example":true,"type":"boolean"}},{"name":"samples","in":"query","required":false,"schema":{"description":"Filter by reference-sample classification. Omit to include all units (production + references). Pass ['golden'] for known-good references only, ['failing'] for known-faulty references only, or any combination.","example":["golden"],"type":"array","items":{"type":"string","enum":["golden","failing","ignored"]}}},{"name":"limit","in":"query","required":false,"schema":{"default":50,"description":"Maximum number of units to return.","example":50,"type":"integer","minimum":1,"maximum":100},"description":"Maximum number of units to return."},{"name":"cursor","in":"query","required":false,"schema":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Cursor for pagination. Use next_cursor from previous response to fetch next page.","example":50}},{"name":"sort_by","in":"query","required":false,"schema":{"default":"created_at","description":"Field to sort results by. last_run_at sorts by most recent test run date. last_run_procedure sorts by procedure name of the last run.","example":"created_at","type":"string","enum":["serial_number","created_at","last_run_at","part_number","last_run_procedure"]}},{"name":"sort_order","in":"query","required":false,"schema":{"default":"desc","description":"Sort order direction.","example":"desc","type":"string","enum":["asc","desc"]}},{"name":"metadata","in":"query","required":false,"content":{"application/json":{"schema":{"description":"Filter units by custom metadata. Supports up to 5 keys per request. Per-key operators: string `{in: [...]}`/`{contains: \"...\"}`, number `{gte, lte, gt, lt, eq}`, bool `{eq: true|false}`.","example":{"vendor":{"in":["Acme"]},"lot_size":{"gte":100}},"type":"object","propertyNames":{"type":"string","minLength":1,"maxLength":40,"pattern":"^[a-zA-Z0-9_.:+-]+$"},"additionalProperties":{"anyOf":[{"type":"object","properties":{"in":{"minItems":1,"maxItems":50,"type":"array","items":{"type":"string","minLength":1}},"contains":{"type":"string","minLength":1,"maxLength":50000}},"additionalProperties":false},{"type":"object","properties":{"gte":{"type":"number"},"lte":{"type":"number"},"gt":{"type":"number"},"lt":{"type":"number"},"eq":{"type":"number"}},"additionalProperties":false},{"type":"object","properties":{"eq":{"type":"boolean"}},"required":["eq"],"additionalProperties":false}]}}}},"description":"Filter units by custom metadata. Supports up to 5 keys per request. Per-key operators: string `{in: [...]}`/`{contains: \"...\"}`, number `{gte, lte, gt, lt, eq}`, bool `{eq: true|false}`."},{"name":"include_metadata","in":"query","required":false,"schema":{"description":"When true, includes the unit metadata array in the response. Defaults to false to keep payloads small.","example":false,"default":false,"type":"boolean"},"description":"When true, includes the unit metadata array in the response. Defaults to false to keep payloads small."}],"responses":{"200":{"description":"Units retrieved successfully","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","description":"Unique identifier for the unit.","example":"550e8400-e29b-41d4-a716-446655440000"},"serial_number":{"type":"string","description":"Human-readable serial number assigned to the unit.","example":"SN-2024-001234"},"created_at":{"type":"string","format":"date-time","pattern":"^(?:(?:\\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))$","description":"ISO 8601 timestamp when the unit was created.","example":"2024-01-15T10:30:00Z"},"sample":{"anyOf":[{"type":"string","enum":["golden","failing","ignored"]},{"type":"null"}],"description":"Reference-sample classification. 'golden' = known-good reference, 'failing' = known-faulty reference, 'ignored' = bench-check unit excluded from analytics and alerts, null = production unit.","example":null},"created_by_user":{"description":"User who created this unit. Null if created by a station or system.","anyOf":[{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","description":"Unique identifier for the user.","example":"550e8400-e29b-41d4-a716-446655440001"},"name":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Display name of the user who created this unit.","example":"John Doe"}},"required":["id","name"],"additionalProperties":false},{"type":"null"}]},"created_by_station":{"description":"Station that created this unit. Null if created by a user.","anyOf":[{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","description":"Unique identifier for the station.","example":"550e8400-e29b-41d4-a716-446655440002"},"name":{"type":"string","description":"Name of the station that created this unit.","example":"Assembly Station 01"}},"required":["id","name"],"additionalProperties":false},{"type":"null"}]},"batch":{"description":"Production batch this unit belongs to. Null if not part of a batch.","anyOf":[{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","description":"Unique identifier for the batch.","example":"550e8400-e29b-41d4-a716-446655440005"},"number":{"type":"string","description":"Human-readable batch number.","example":"BATCH-2024-Q1-001"}},"required":["id","number"],"additionalProperties":false},{"type":"null"}]},"parent":{"description":"Parent unit in the assembly hierarchy. Null if this is a top-level unit.","anyOf":[{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","description":"Unique identifier for the parent unit.","example":"550e8400-e29b-41d4-a716-446655440004"},"serial_number":{"type":"string","description":"Serial number of the parent unit.","example":"SN-2024-001233"}},"required":["id","serial_number"],"additionalProperties":false},{"type":"null"}]},"children":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","description":"Unique identifier for the child unit.","example":"550e8400-e29b-41d4-a716-446655440006"},"serial_number":{"type":"string","description":"Serial number of the child unit.","example":"SN-2024-001235"}},"required":["id","serial_number"],"additionalProperties":false},"description":"Child units assembled into this unit. Limited to 10 results; use Get Unit endpoint for complete list."},"part":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","description":"Unique identifier for the part.","example":"550e8400-e29b-41d4-a716-446655440008"},"number":{"type":"string","description":"Part number.","example":"PCB-MAIN-001"},"name":{"type":"string","description":"Human-readable part name.","example":"Main Control Board"},"revision":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","description":"Unique identifier for the revision.","example":"550e8400-e29b-41d4-a716-446655440007"},"number":{"type":"string","description":"Revision number (e.g., version) of the part.","example":"REV-A"}},"required":["id","number"],"additionalProperties":false,"description":"Revision information for this part. Every unit must have a specific revision."}},"required":["id","number","name","revision"],"additionalProperties":false,"description":"Part information with the specific revision this unit is built from."},"last_run":{"description":"Most recent test run performed on this unit. Null if no runs have been executed.","anyOf":[{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","description":"Unique identifier for the run.","example":"550e8400-e29b-41d4-a716-446655440009"},"outcome":{"type":"string","enum":["PASS","FAIL","ERROR","TIMEOUT","ABORTED"],"description":"Final result of the test run execution.","example":"PASS"},"started_at":{"type":"string","format":"date-time","pattern":"^(?:(?:\\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))$","description":"ISO 8601 timestamp when the run execution started.","example":"2024-01-15T10:25:00Z"},"ended_at":{"anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\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))$"},{"type":"null"}],"description":"ISO 8601 timestamp when the run execution completed. Null if still running.","example":"2024-01-15T10:30:00Z"},"procedure":{"anyOf":[{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","description":"Unique identifier for the procedure.","example":"550e8400-e29b-41d4-a716-446655440010"},"name":{"type":"string","description":"Name of the test procedure that was executed.","example":"PCB Assembly Test"}},"required":["id","name"],"additionalProperties":false},{"type":"null"}],"description":"Test procedure that was executed. Null if run had no associated procedure."}},"required":["id","outcome","started_at","ended_at","procedure"],"additionalProperties":false},{"type":"null"}]},"metadata":{"description":"Custom metadata key/value pairs on the unit. Only present when the request sets `include_metadata=true`.","type":"object","propertyNames":{"type":"string","minLength":1,"maxLength":40,"pattern":"^[a-zA-Z0-9_.:+-]+$"},"additionalProperties":{"anyOf":[{"type":"string","maxLength":50000},{"type":"number"},{"type":"boolean"}]},"example":{"vendor":"Acme","lot_size":500,"qualified":true}}},"required":["id","serial_number","created_at","sample","children","part"],"additionalProperties":false}},"meta":{"type":"object","properties":{"has_more":{"type":"boolean","description":"Whether there are more results available for pagination.","example":true},"next_cursor":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}],"description":"Cursor value to fetch the next page of results. Use this value as the cursor parameter in the next request. Null if no more results available.","example":100}},"required":["has_more","next_cursor"],"additionalProperties":false}},"required":["data","meta"],"additionalProperties":false}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorUNAUTHORIZED"}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorINTERNALSERVERERROR"}}}}},"x-access":[{"level":"full","authType":"user","description":"Users can read units"},{"level":"full","authType":"station","description":"Stations can read units"}],"x-speakeasy-name-override":"list"},"delete":{"operationId":"unit-delete","summary":"Delete units","description":"Delete units by serial number. Sub-units are unlinked, not deleted. Irreversible.","tags":["Units"],"security":[{"api_key":[]}],"parameters":[{"name":"serial_numbers","in":"query","required":true,"schema":{"type":"array","items":{"type":"string","minLength":1,"maxLength":60,"pattern":"^[a-zA-Z0-9_.:+-]+$","description":"Serial number of the unit to delete","example":"UNIT-001"},"description":"Array of unit serial numbers to delete.","example":["UNIT-001","UNIT-002"]},"style":"form","explode":true,"description":"Array of unit serial numbers to delete."}],"responses":{"200":{"description":"Units deleted successfully","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"array","items":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","description":"ID of a successfully deleted unit","example":"550e8400-e29b-41d4-a716-446655440000"},"description":"IDs of units that were successfully deleted","example":["550e8400-e29b-41d4-a716-446655440000","6ba7b810-9dad-11d1-80b4-00c04fd430c8"]}},"required":["id"],"additionalProperties":false,"description":"Response for successful unit deletion"}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorUNAUTHORIZED"}}}},"404":{"description":"No units found with serial numbers: {serialNumbers}","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorNOTFOUND"}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorINTERNALSERVERERROR"}}}}},"x-access":[{"level":"full","authType":"user","description":"Users can delete units"},{"level":"unauthorized","authType":"station","description":"Stations cannot delete units"}],"x-speakeasy-name-override":"delete"}},"/v2/units/{serial_number}":{"get":{"operationId":"unit-get","summary":"Get unit","description":"Get a unit by serial number, with its part, parent/child links, and run history.","tags":["Units"],"security":[{"api_key":[]}],"parameters":[{"name":"serial_number","in":"path","required":true,"schema":{"type":"string"},"description":"Serial number of the unit to retrieve."}],"responses":{"200":{"description":"Units retrieved successfully","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","description":"Unique identifier for the unit.","example":"550e8400-e29b-41d4-a716-446655440000"},"serial_number":{"type":"string","description":"Unit serial number.","example":"SN-2024-001234"},"created_at":{"type":"string","format":"date-time","pattern":"^(?:(?:\\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))$","description":"ISO 8601 timestamp when the unit was created.","example":"2024-01-15T10:30:00Z"},"sample":{"anyOf":[{"type":"string","enum":["golden","failing","ignored"]},{"type":"null"}],"description":"Reference-sample classification. 'golden' = known-good reference, 'failing' = known-faulty reference, 'ignored' = bench-check unit excluded from analytics and alerts, null = production unit.","example":null},"created_by_user":{"description":"User who created this unit.","anyOf":[{"type":"object","properties":{"id":{"type":"string","description":"User ID.","example":"550e8400-e29b-41d4-a716-446655440001"},"name":{"anyOf":[{"type":"string","description":"User display name.","example":"John Doe"},{"type":"null"}]}},"required":["id","name"],"additionalProperties":false},{"type":"null"}]},"created_by_station":{"description":"Station that created this unit.","anyOf":[{"type":"object","properties":{"id":{"type":"string","description":"Station ID.","example":"550e8400-e29b-41d4-a716-446655440002"},"name":{"type":"string","description":"Station name.","example":"Assembly Station 01"}},"required":["id","name"],"additionalProperties":false},{"type":"null"}]},"part":{"type":"object","properties":{"id":{"type":"string","description":"Part ID.","example":"550e8400-e29b-41d4-a716-446655440007"},"number":{"type":"string","description":"Part number.","example":"PCB-MAIN-001"},"name":{"type":"string","description":"Part name.","example":"Main Control Board"},"revision":{"type":"object","properties":{"id":{"type":"string","description":"Revision ID.","example":"550e8400-e29b-41d4-a716-446655440006"},"number":{"type":"string","description":"Revision number.","example":"REV-A"}},"required":["id","number"],"additionalProperties":false,"description":"Revision information for this unit.","example":{"id":"550e8400-e29b-41d4-a716-446655440006","number":"REV-A"}}},"required":["id","number","name","revision"],"additionalProperties":false,"description":"Part information with revision details for this unit. Every unit must have a part and revision.","example":{"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":{"description":"Batch information for this unit.","anyOf":[{"type":"object","properties":{"id":{"type":"string","description":"Batch ID.","example":"550e8400-e29b-41d4-a716-446655440005"},"number":{"type":"string","description":"Batch number.","example":"BATCH-2024-Q1-001"}},"required":["id","number"],"additionalProperties":false},{"type":"null"}]},"parent":{"anyOf":[{"type":"object","properties":{"id":{"type":"string","description":"Unit ID.","example":"550e8400-e29b-41d4-a716-446655440004"},"serial_number":{"type":"string","description":"Unit serial number.","example":"SN-2024-001234"},"part":{"anyOf":[{"type":"object","properties":{"id":{"type":"string","description":"Part ID.","example":"550e8400-e29b-41d4-a716-446655440003"},"number":{"type":"string","description":"Part number.","example":"PCB-MAIN-V2"},"name":{"type":"string","description":"Part name.","example":"Main PCB Assembly"},"revision":{"anyOf":[{"type":"object","properties":{"id":{"type":"string","description":"Revision ID.","example":"550e8400-e29b-41d4-a716-446655440002"},"number":{"type":"string","description":"Revision number.","example":"Rev-A"}},"required":["id","number"],"additionalProperties":false},{"type":"null"}],"description":"Part revision information."}},"required":["id","number","name","revision"],"additionalProperties":false},{"type":"null"}],"description":"Part information for the parent unit."}},"required":["id","serial_number","part"],"additionalProperties":false},{"type":"null"}],"description":"Parent unit information with part details and processed images."},"children":{"description":"Child units with part details.","type":"array","items":{"type":"object","properties":{"id":{"type":"string","description":"Unit ID.","example":"550e8400-e29b-41d4-a716-446655440005"},"serial_number":{"type":"string","description":"Unit serial number.","example":"SN-2024-001235"},"part":{"anyOf":[{"type":"object","properties":{"id":{"type":"string","description":"Part ID.","example":"550e8400-e29b-41d4-a716-446655440006"},"number":{"type":"string","description":"Part number.","example":"PCB-SUB-V1"},"name":{"type":"string","description":"Part name.","example":"Sub Assembly PCB"},"revision":{"anyOf":[{"type":"object","properties":{"id":{"type":"string","description":"Revision ID.","example":"550e8400-e29b-41d4-a716-446655440007"},"number":{"type":"string","description":"Revision number.","example":"Rev-B"}},"required":["id","number"],"additionalProperties":false},{"type":"null"}],"description":"Part revision information."}},"required":["id","number","name","revision"],"additionalProperties":false},{"type":"null"}],"description":"Part information for the child unit."}},"required":["id","serial_number","part"],"additionalProperties":false}},"created_during":{"description":"Run that created this unit.","anyOf":[{"type":"object","properties":{"id":{"type":"string","description":"Run ID.","example":"550e8400-e29b-41d4-a716-446655440009"},"created_at":{"type":"string","format":"date-time","pattern":"^(?:(?:\\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))$","description":"ISO 8601 timestamp when the run was created.","example":"2024-01-15T10:20:00Z"},"started_at":{"type":"string","format":"date-time","pattern":"^(?:(?:\\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))$","description":"ISO 8601 timestamp when the run started.","example":"2024-01-15T10:25:00Z"},"ended_at":{"type":"string","format":"date-time","pattern":"^(?:(?:\\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))$","description":"ISO 8601 timestamp when the run ended.","example":"2024-01-15T10:30:00Z"},"duration":{"type":"string","description":"ISO 8601 duration of the run (computed from started_at and ended_at).","example":"PT5M"},"outcome":{"type":"string","enum":["PASS","FAIL","ERROR","TIMEOUT","ABORTED"],"description":"Final result of the run execution.","example":"PASS"},"procedure":{"type":"object","properties":{"id":{"type":"string","description":"Procedure ID.","example":"550e8400-e29b-41d4-a716-446655440011"},"name":{"type":"string","description":"Procedure name.","example":"PCB Assembly Procedure"}},"required":["id","name"],"additionalProperties":false,"description":"Procedure information."}},"required":["id","created_at","started_at","ended_at","duration","outcome","procedure"],"additionalProperties":false},{"type":"null"}]},"attachments":{"description":"Files attached to this unit.","type":"array","items":{"type":"object","properties":{"id":{"type":"string","description":"Attachment ID.","example":"550e8400-e29b-41d4-a716-446655440011"},"name":{"type":"string","description":"File name.","example":"calibration-cert.pdf"},"size":{"anyOf":[{"type":"number"},{"type":"null"}],"description":"File size in bytes.","example":1048576},"content_type":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"MIME type of the file.","example":"application/pdf"},"download_url":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Presigned URL for downloading the file. This URL is temporary and will expire.","example":"https://s3.amazonaws.com/bucket/file?X-Amz-Algorithm=..."}},"required":["id","name","size","content_type","download_url"],"additionalProperties":false}},"metadata":{"description":"Custom metadata key/value pairs on the unit.","type":"object","propertyNames":{"type":"string","minLength":1,"maxLength":40,"pattern":"^[a-zA-Z0-9_.:+-]+$"},"additionalProperties":{"anyOf":[{"type":"string","maxLength":50000},{"type":"number"},{"type":"boolean"}]},"example":{"vendor":"Acme","lot_size":500,"qualified":true}}},"required":["id","serial_number","created_at","sample","part","parent"],"additionalProperties":false}}}},"400":{"description":"{message}","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBADREQUEST"}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorUNAUTHORIZED"}}}},"404":{"description":"Unit not found: {serial_number}","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorNOTFOUND"}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorINTERNALSERVERERROR"}}}}},"x-access":[{"level":"full","authType":"user","description":"Users can read units"},{"level":"full","authType":"station","description":"Stations can read units"}],"x-speakeasy-name-override":"get"},"patch":{"operationId":"unit-update","summary":"Update unit","description":"Update a unit: serial number, part revision, batch, and file attachments.","tags":["Units"],"security":[{"api_key":[]}],"parameters":[{"name":"serial_number","in":"path","required":true,"schema":{"type":"string"},"description":"Serial number of the unit to update."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"new_serial_number":{"type":"string","minLength":1,"maxLength":60,"pattern":"^[a-zA-Z0-9_.:+-]+$","description":"New serial number for the unit.","example":"UNIT-12345-NEW"},"part_number":{"type":"string","minLength":1,"maxLength":60,"pattern":"^[a-zA-Z0-9_.:+-]+$","description":"New part number for the unit.","example":"PCB-V2.0"},"revision_number":{"type":"string","minLength":1,"maxLength":60,"pattern":"^[a-zA-Z0-9_.:+-]+$","description":"New revision number for the unit.","example":"REV-B"},"batch_number":{"anyOf":[{"type":"string","minLength":1,"maxLength":60,"pattern":"^[a-zA-Z0-9_.:+-]+$"},{"type":"null"}],"description":"New batch number for the unit. Set to null to remove batch.","example":"BATCH-2024-02"},"attachments":{"description":"Array of upload IDs to attach to the unit.","example":["550e8400-e29b-41d4-a716-446655440000"],"type":"array","items":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"}},"sample":{"description":"Sample classification. 'golden' marks a known-good reference unit; 'failing' marks a known-faulty reference unit; 'ignored' marks a bench-check unit excluded from analytics and alerts. All are excluded from production analytics by default. Set to null to clear and treat as a production unit.","example":"golden","anyOf":[{"type":"string","enum":["golden","failing","ignored"]},{"type":"null"}]},"metadata":{"description":"Custom metadata to upsert on the unit. Plain object of key/value pairs. PATCH semantics: keys not present here are preserved. Pass `null` as a value to delete a key.","example":{"vendor":"Acme","lot_size":null},"type":"object","propertyNames":{"type":"string","minLength":1,"maxLength":40,"pattern":"^[a-zA-Z0-9_.:+-]+$"},"additionalProperties":{"anyOf":[{"anyOf":[{"type":"string","maxLength":50000},{"type":"number"},{"type":"boolean"}]},{"type":"null"}]}}}}}}},"responses":{"200":{"description":"Unit updated successfully","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","description":"Unique identifier of the updated unit.","example":"550e8400-e29b-41d4-a716-446655440000"}},"required":["id"],"additionalProperties":false}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorUNAUTHORIZED"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorNOTFOUND"}}}},"409":{"description":"Serial number {serialNumber} is already in use","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorCONFLICT"}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorINTERNALSERVERERROR"}}}}},"x-access":[{"level":"full","authType":"user","description":"Users can update units"},{"level":"full","authType":"station","description":"Stations can update units"}],"x-speakeasy-name-override":"update"}},"/v2/units/{serial_number}/children":{"put":{"operationId":"unit-addChild","summary":"Add sub-unit","description":"Link a sub-unit to a parent unit to track assemblies.","tags":["Units"],"security":[{"api_key":[]}],"parameters":[{"name":"serial_number","in":"path","required":true,"schema":{"type":"string"},"description":"Serial number of the parent unit"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"child_serial_number":{"type":"string","minLength":1,"maxLength":60,"description":"Serial number of the sub-unit to add","example":"SUB-001"}},"required":["child_serial_number"]}}}},"responses":{"200":{"description":"Child unit added successfully","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","description":"ID of the child unit that was added","example":"550e8400-e29b-41d4-a716-446655440000"}},"required":["id"],"additionalProperties":false}}}},"400":{"description":"Bad request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBADREQUEST"}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorUNAUTHORIZED"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorNOTFOUND"}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorINTERNALSERVERERROR"}}}}},"x-access":[{"level":"full","authType":"user","description":"Users can update units"},{"level":"full","authType":"station","description":"Stations can update units"}],"x-speakeasy-name-override":"addChild"},"delete":{"operationId":"unit-removeChild","summary":"Remove sub-unit","description":"Unlink a sub-unit from its parent. Neither unit is deleted.","tags":["Units"],"security":[{"api_key":[]}],"parameters":[{"name":"serial_number","in":"path","required":true,"schema":{"type":"string"},"description":"Serial number of the parent unit"},{"name":"child_serial_number","in":"query","required":true,"schema":{"type":"string","minLength":1,"maxLength":60,"description":"Serial number of the sub-unit to remove","example":"SUB-001"},"description":"Serial number of the sub-unit to remove"}],"responses":{"200":{"description":"Child unit removed successfully","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","description":"ID of the child unit that was removed","example":"550e8400-e29b-41d4-a716-446655440000"}},"required":["id"],"additionalProperties":false}}}},"400":{"description":"Unit {child_serial_number} is not a child of {parent_serial_number}","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBADREQUEST"}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorUNAUTHORIZED"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorNOTFOUND"}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorINTERNALSERVERERROR"}}}}},"x-access":[{"level":"full","authType":"user","description":"Users can update units"},{"level":"full","authType":"station","description":"Stations can update units"}],"x-speakeasy-name-override":"removeChild"}},"/v2/units/{serial_number}/attachments":{"post":{"operationId":"unit-createAttachment","summary":"Attach file to unit","description":"Attach a file to a unit. Returns an upload ID and pre-signed URL; PUT the file to the URL, then call Finalize upload to commit.","tags":["Units"],"security":[{"api_key":[]}],"parameters":[{"name":"serial_number","in":"path","required":true,"schema":{"type":"string"},"description":"Serial number of the unit to attach the file to. Matched case-insensitively."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":255,"description":"File name including extension (e.g. \"calibration.pdf\"). Used to determine content type and display name.","example":"calibration_cert.pdf"}},"required":["name"]}}}},"responses":{"200":{"description":"Unit attachment created successfully","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","description":"Unique identifier of the created attachment. Use this to reference the attachment in subsequent API calls.","example":"550e8400-e29b-41d4-a716-446655440000"},"upload_url":{"type":"string","description":"Temporary pre-signed URL to upload the file directly to storage. Send a PUT request with the raw file bytes and appropriate Content-Type header. The URL expires after 60 seconds.","example":"https://storage.example.com/org/file.pdf?X-Amz-Signature=abc123"}},"required":["id","upload_url"],"additionalProperties":false}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorUNAUTHORIZED"}}}},"404":{"description":"Unit not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorNOTFOUND"}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorINTERNALSERVERERROR"}}}}},"x-access":[{"level":"full","authType":"user","description":"Users can update units"},{"level":"full","authType":"station","description":"Stations can update units"}],"x-speakeasy-name-override":"create"},"delete":{"operationId":"unit-deleteAttachment","summary":"Delete unit attachments","description":"Delete attachments from a unit by ID. Removes the files from storage and unlinks them.","tags":["Units"],"security":[{"api_key":[]}],"parameters":[{"name":"serial_number","in":"path","required":true,"schema":{"type":"string"},"description":"Serial number of the unit. Matched case-insensitively."},{"name":"ids","in":"query","required":true,"schema":{"minItems":1,"type":"array","items":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","description":"ID of the attachment to delete","example":"550e8400-e29b-41d4-a716-446655440000"},"description":"Attachment IDs to delete"},"style":"form","explode":true,"description":"Attachment IDs to delete"}],"responses":{"200":{"description":"Unit attachments deleted successfully","content":{"application/json":{"schema":{"type":"object","properties":{"ids":{"type":"array","items":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","description":"ID of a deleted attachment","example":"550e8400-e29b-41d4-a716-446655440000"},"description":"IDs of attachments that were deleted"}},"required":["ids"],"additionalProperties":false}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorUNAUTHORIZED"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorNOTFOUND"}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorINTERNALSERVERERROR"}}}}},"x-access":[{"level":"full","authType":"user","description":"Users can update units"},{"level":"full","authType":"station","description":"Stations can update units"}],"x-speakeasy-name-override":"delete"}},"/v2/parts":{"post":{"operationId":"part-create","summary":"Create part","description":"Create a part, optionally with an initial revision. Part numbers match case-insensitively (\"PART-001\" == \"part-001\").","tags":["Parts"],"security":[{"api_key":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"number":{"type":"string","minLength":1,"maxLength":60,"pattern":"^[a-zA-Z0-9_.:+-]+$","description":"Unique identifier number for the part.","example":"PCB-V2.0"},"name":{"type":"string","minLength":1,"maxLength":255,"description":"Human-readable name for the part. If not provided, a default name will be used.","example":"Main PCB Board"},"revision_number":{"type":"string","minLength":1,"maxLength":60,"pattern":"^[a-zA-Z0-9_.:+-]+$","description":"Revision identifier for the part version. If not provided, default revision identifier will be used.","example":"REV-A"}},"required":["number"]}}}},"responses":{"200":{"description":"Part created successfully","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","description":"Unique identifier of the created part.","example":"550e8400-e29b-41d4-a716-446655440000"}},"required":["id"],"additionalProperties":false}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorUNAUTHORIZED"}}}},"409":{"description":"Part with part number {partNumber} already exists","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorCONFLICT"}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorINTERNALSERVERERROR"}}}}},"x-access":[{"level":"full","authType":"user","description":"Users can create parts"},{"level":"full","authType":"station","description":"Stations can create parts"}],"x-speakeasy-name-override":"create"},"get":{"operationId":"part-list","summary":"List and filter parts","description":"List parts. Filter and search by name, number, or revision number. Cursor-paginated.","tags":["Parts"],"security":[{"api_key":[]}],"parameters":[{"name":"limit","in":"query","required":false,"schema":{"default":50,"description":"Maximum number of parts to return in a single page.","example":50,"type":"integer","minimum":1,"maximum":100},"description":"Maximum number of parts to return in a single page."},{"name":"cursor","in":"query","required":false,"schema":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Offset position for pagination. Use the next_cursor from the previous response to get the next page.","example":50}},{"name":"search_query","in":"query","required":false,"schema":{"type":"string","maxLength":100,"description":"Search text to filter parts by name, part number, or revision number.","example":"PCB"}},{"name":"procedure_ids","in":"query","required":false,"schema":{"maxItems":10,"type":"array","items":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"description":"Filter parts by procedures (parts that have runs with these procedures)."},"style":"form","explode":true},{"name":"sort_by","in":"query","required":false,"schema":{"default":"created_at","description":"Field to sort results by.","example":"created_at","type":"string","enum":["name","number","created_at"]}},{"name":"sort_order","in":"query","required":false,"schema":{"default":"desc","description":"Sort order direction.","example":"desc","type":"string","enum":["asc","desc"]}}],"responses":{"200":{"description":"Parts retrieved successfully","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","description":"Unique database identifier of the part.","example":"550e8400-e29b-41d4-a716-446655440000"},"number":{"type":"string","description":"Unique part number identifier.","example":"PCB-V2.0"},"name":{"type":"string","description":"Human-readable name of the part.","example":"Main PCB Board"},"created_at":{"type":"string","format":"date-time","pattern":"^(?:(?:\\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))$","description":"Time at which the part was created."},"revisions":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","description":"Unique identifier of the revision.","example":"550e8400-e29b-41d4-a716-446655440001"},"number":{"type":"string","description":"Revision number.","example":"REV-A"}},"required":["id","number"],"additionalProperties":false},"description":"List of revisions for this part."}},"required":["id","number","name","created_at","revisions"],"additionalProperties":false},"description":"List of parts matching the search criteria."},"meta":{"type":"object","properties":{"has_more":{"type":"boolean","description":"Whether there are more results available for pagination.","example":true},"next_cursor":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}],"description":"Cursor value to fetch the next page of results. Use this value as the cursor parameter in the next request. Null if no more results available.","example":50}},"required":["has_more","next_cursor"],"additionalProperties":false,"description":"Pagination metadata."}},"required":["data","meta"],"additionalProperties":false}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorUNAUTHORIZED"}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorINTERNALSERVERERROR"}}}}},"x-access":[{"level":"full","authType":"user","description":"Users can read parts"},{"level":"full","authType":"station","description":"Stations can read parts"}],"x-speakeasy-name-override":"list"}},"/v2/parts/{number}":{"get":{"operationId":"part-get","summary":"Get part","description":"Get a part by number, with its revisions, metadata, and linked units. Numbers match case-insensitively.","tags":["Parts"],"security":[{"api_key":[]}],"parameters":[{"name":"number","in":"path","required":true,"schema":{"type":"string"},"description":"Part number of the part to retrieve."}],"responses":{"200":{"description":"Part retrieved successfully","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","description":"Unique identifier for the part.","example":"550e8400-e29b-41d4-a716-446655440000"},"number":{"type":"string","description":"Part number.","example":"PCB-MAIN-001"},"name":{"type":"string","description":"Part name.","example":"Main Control Board"},"created_at":{"type":"string","format":"date-time","pattern":"^(?:(?:\\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))$","description":"ISO 8601 timestamp when the part was created.","example":"2024-01-15T10:30:00Z"},"created_by_user":{"description":"User who created this part.","anyOf":[{"type":"object","properties":{"id":{"type":"string","description":"User ID.","example":"550e8400-e29b-41d4-a716-446655440001"},"name":{"anyOf":[{"type":"string","description":"User display name.","example":"John Doe"},{"type":"null"}]}},"required":["id","name"],"additionalProperties":false},{"type":"null"}]},"created_by_station":{"description":"Station that created this part.","anyOf":[{"type":"object","properties":{"id":{"type":"string","description":"Station ID.","example":"550e8400-e29b-41d4-a716-446655440002"},"name":{"type":"string","description":"Station name.","example":"Assembly Station 01"}},"required":["id","name"],"additionalProperties":false},{"type":"null"}]},"revisions":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","description":"Revision ID.","example":"550e8400-e29b-41d4-a716-446655440003"},"number":{"type":"string","description":"Revision number.","example":"REV-A"},"created_at":{"type":"string","format":"date-time","pattern":"^(?:(?:\\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))$","description":"ISO 8601 timestamp when the revision was created.","example":"2024-01-15T10:30:00Z"}},"required":["id","number","created_at"],"additionalProperties":false},"description":"List of revisions for this part."}},"required":["id","number","name","created_at","revisions"],"additionalProperties":false}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorUNAUTHORIZED"}}}},"404":{"description":"Part not found: {number}","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorNOTFOUND"}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorINTERNALSERVERERROR"}}}}},"x-access":[{"level":"full","authType":"user","description":"Users can read parts"},{"level":"full","authType":"station","description":"Stations can read parts"}],"x-speakeasy-name-override":"get"},"patch":{"operationId":"part-update","summary":"Update part","description":"Update a part's number or name. Numbers match case-insensitively.","tags":["Parts"],"security":[{"api_key":[]}],"parameters":[{"name":"number","in":"path","required":true,"schema":{"type":"string"},"description":"Part number of the part to update."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"new_number":{"type":"string","minLength":1,"maxLength":60,"pattern":"^[a-zA-Z0-9_.:+-]+$","description":"New unique identifier number for the part.","example":"PCB-V3.0"},"name":{"type":"string","minLength":1,"maxLength":255,"description":"New human-readable name for the part.","example":"Updated PCB Board"}}}}}},"responses":{"200":{"description":"Part updated successfully","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","description":"Unique database identifier of the updated part.","example":"550e8400-e29b-41d4-a716-446655440000"},"number":{"type":"string","description":"Unique part number identifier.","example":"PCB-V3.0"},"name":{"type":"string","description":"Human-readable name of the part.","example":"Updated PCB Board"},"updated_at":{"type":"string","format":"date-time","pattern":"^(?:(?:\\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))$","description":"ISO 8601 timestamp when the part was updated.","example":"2024-01-15T10:30:00.000Z"}},"required":["id","number","name","updated_at"],"additionalProperties":false}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorUNAUTHORIZED"}}}},"404":{"description":"Part with ID {partId} not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorNOTFOUND"}}}},"409":{"description":"Part with part number {partNumber} already exists","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorCONFLICT"}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorINTERNALSERVERERROR"}}}}},"x-access":[{"level":"full","authType":"user","description":"Users can update parts"},{"level":"unauthorized","authType":"station","description":"Stations cannot update parts"}],"x-speakeasy-name-override":"update"},"delete":{"operationId":"part-delete","summary":"Delete part","description":"Delete a part and all its revisions. Irreversible.","tags":["Parts"],"security":[{"api_key":[]}],"parameters":[{"name":"number","in":"path","required":true,"schema":{"type":"string"},"description":"Part number to delete."}],"responses":{"200":{"description":"Part deleted successfully","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","description":"Unique identifier of the deleted part.","example":"550e8400-e29b-41d4-a716-446655440000"},"deletedRevisionIds":{"type":"array","items":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"description":"IDs of all revisions that were deleted with the part.","example":["550e8400-e29b-41d4-a716-446655440001","550e8400-e29b-41d4-a716-446655440002"]}},"required":["id","deletedRevisionIds"],"additionalProperties":false}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorUNAUTHORIZED"}}}},"404":{"description":"Part with number {number} not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorNOTFOUND"}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorINTERNALSERVERERROR"}}}}},"x-access":[{"level":"full","authType":"user","description":"Users can delete parts"},{"level":"unauthorized","authType":"station","description":"Stations cannot delete parts"}],"x-speakeasy-name-override":"delete"}},"/v2/parts/{part_number}/revisions/{revision_number}":{"get":{"operationId":"part-getRevision","summary":"Get part revision","description":"Get a part revision by part number and revision number, with its metadata, configuration, and linked units.","tags":["Parts","Revisions"],"security":[{"api_key":[]}],"parameters":[{"name":"part_number","in":"path","required":true,"schema":{"type":"string"},"description":"Part number that the revision belongs to."},{"name":"revision_number","in":"path","required":true,"schema":{"type":"string"},"description":"Revision number to retrieve."}],"responses":{"200":{"description":"Revision retrieved successfully","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","description":"Unique identifier of the revision.","example":"550e8400-e29b-41d4-a716-446655440000"},"number":{"type":"string","description":"Revision number.","example":"REV-A"},"created_at":{"anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\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))$"},{"type":"null"}],"description":"ISO 8601 timestamp when the revision was created.","example":"2024-01-15T10:30:00Z"},"created_by_user":{"anyOf":[{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","description":"Unique identifier of the user.","example":"550e8400-e29b-41d4-a716-446655440003"},"name":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Name of the user who created the revision.","example":"John Doe"}},"required":["id","name"],"additionalProperties":false},{"type":"null"}],"description":"User who created the revision."},"created_by_station":{"anyOf":[{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","description":"Unique identifier of the station.","example":"550e8400-e29b-41d4-a716-446655440004"},"name":{"type":"string","description":"Name of the station.","example":"Assembly Station 1"}},"required":["id","name"],"additionalProperties":false},{"type":"null"}],"description":"Station that created the revision."},"part":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","description":"Unique identifier of the part.","example":"550e8400-e29b-41d4-a716-446655440001"},"number":{"type":"string","description":"Part number.","example":"PCB-001"},"name":{"type":"string","description":"Name of the part.","example":"Main PCB Board"}},"required":["id","number","name"],"additionalProperties":false,"description":"Part associated with this revision."},"units":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","description":"Unique identifier of the unit.","example":"550e8400-e29b-41d4-a716-446655440002"},"serial_number":{"type":"string","description":"Serial number of the unit.","example":"UNIT-001"}},"required":["id","serial_number"],"additionalProperties":false},"description":"List of units created with this revision."}},"required":["id","number","created_at","created_by_user","created_by_station","part","units"],"additionalProperties":false}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorUNAUTHORIZED"}}}},"404":{"description":"Revision not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorNOTFOUND"}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorINTERNALSERVERERROR"}}}}},"x-access":[{"level":"full","authType":"user","description":"Users can read revisions"},{"level":"full","authType":"station","description":"Stations can read revisions"}],"x-speakeasy-group":"parts.revisions","x-speakeasy-name-override":"get"},"patch":{"operationId":"part-updateRevision","summary":"Update part revision","description":"Update a revision's number or image.","tags":["Parts","Revisions"],"security":[{"api_key":[]}],"parameters":[{"name":"part_number","in":"path","required":true,"schema":{"type":"string"},"description":"Part number that the revision belongs to."},{"name":"revision_number","in":"path","required":true,"schema":{"type":"string"},"description":"Current revision number to update."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"number":{"type":"string","minLength":1,"maxLength":60,"pattern":"^[a-zA-Z0-9_.:+-]+$","description":"New revision number to set.","example":"REV-B"},"image_id":{"anyOf":[{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},{"type":"string","const":""}],"description":"Upload ID for the revision image, or empty string to remove image","example":"550e8400-e29b-41d4-a716-446655440001"}}}}}},"responses":{"200":{"description":"Revision updated successfully","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","description":"Unique identifier of the updated revision.","example":"550e8400-e29b-41d4-a716-446655440000"}},"required":["id"],"additionalProperties":false}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorUNAUTHORIZED"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorNOTFOUND"}}}},"409":{"description":"Another revision with number {number} already exists for this part","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorCONFLICT"}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorINTERNALSERVERERROR"}}}}},"x-access":[{"level":"full","authType":"user","description":"Users can update revisions"},{"level":"unauthorized","authType":"station","description":"Stations cannot update revisions"}],"x-speakeasy-group":"parts.revisions","x-speakeasy-name-override":"update"},"delete":{"operationId":"part-deleteRevision","summary":"Delete part revision","description":"Delete a part revision. Irreversible.","tags":["Parts","Revisions"],"security":[{"api_key":[]}],"parameters":[{"name":"part_number","in":"path","required":true,"schema":{"type":"string"},"description":"Part number that the revision belongs to."},{"name":"revision_number","in":"path","required":true,"schema":{"type":"string"},"description":"Revision number to delete."}],"responses":{"200":{"description":"Revision deleted successfully","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","description":"Unique identifier of the deleted revision.","example":"550e8400-e29b-41d4-a716-446655440000"}},"required":["id"],"additionalProperties":false}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorUNAUTHORIZED"}}}},"404":{"description":"Revision {revision_number} not found for part {part_number}","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorNOTFOUND"}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorINTERNALSERVERERROR"}}}}},"x-access":[{"level":"full","authType":"user","description":"Users can delete revisions"},{"level":"unauthorized","authType":"station","description":"Stations cannot delete revisions"}],"x-speakeasy-group":"parts.revisions","x-speakeasy-name-override":"delete"}},"/v2/parts/{part_number}/revisions":{"post":{"operationId":"part-createRevision","summary":"Create part revision","description":"Create a revision of a part. Revision numbers match case-insensitively (\"REV-A\" == \"rev-a\").","tags":["Parts","Revisions"],"security":[{"api_key":[]}],"parameters":[{"name":"part_number","in":"path","required":true,"schema":{"type":"string"},"description":"Part number to create a revision for."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"number":{"type":"string","minLength":1,"maxLength":60,"pattern":"^[a-zA-Z0-9_.:+-]+$","description":"Revision number (e.g., version number or code).","example":"REV-A"}},"required":["number"]}}}},"responses":{"200":{"description":"Revision created successfully","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","description":"Unique identifier of the created revision.","example":"550e8400-e29b-41d4-a716-446655440001"}},"required":["id"],"additionalProperties":false}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorUNAUTHORIZED"}}}},"404":{"description":"Part with ID {part_number} not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorNOTFOUND"}}}},"409":{"description":"Revision with number {number} already exists for this part","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorCONFLICT"}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorINTERNALSERVERERROR"}}}}},"x-access":[{"level":"full","authType":"user","description":"Users can create revisions"},{"level":"full","authType":"station","description":"Stations can create revisions"}],"x-speakeasy-group":"parts.revisions","x-speakeasy-name-override":"create"}},"/v2/batches/{number}":{"get":{"operationId":"batch-get","summary":"Get batch","description":"Get a batch by number, with its units, serial numbers, and part revisions.","tags":["Batches"],"security":[{"api_key":[]}],"parameters":[{"name":"number","in":"path","required":true,"schema":{"type":"string"},"description":"Number of the batch to retrieve."}],"responses":{"200":{"description":"Batch retrieved successfully","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","description":"Unique identifier for the batch.","example":"550e8400-e29b-41d4-a716-446655440000"},"number":{"type":"string","description":"Batch number.","example":"BATCH-2024-001"},"created_at":{"type":"string","format":"date-time","pattern":"^(?:(?:\\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))$","description":"ISO 8601 timestamp when the batch was created.","example":"2024-01-15T10:30:00Z"},"created_by_user":{"description":"User who created this batch.","anyOf":[{"type":"object","properties":{"id":{"type":"string","description":"User ID.","example":"550e8400-e29b-41d4-a716-446655440001"},"name":{"anyOf":[{"type":"string","description":"User display name.","example":"John Doe"},{"type":"null"}]}},"required":["id","name"],"additionalProperties":false},{"type":"null"}]},"created_by_station":{"description":"Station that created this batch.","anyOf":[{"type":"object","properties":{"id":{"type":"string","description":"Station ID.","example":"550e8400-e29b-41d4-a716-446655440002"},"name":{"type":"string","description":"Station name.","example":"Assembly Station 01"}},"required":["id","name"],"additionalProperties":false},{"type":"null"}]},"units":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","description":"Unit ID.","example":"550e8400-e29b-41d4-a716-446655440000"},"serial_number":{"type":"string","description":"Unit serial number.","example":"SN-2024-001234"},"created_at":{"type":"string","format":"date-time","pattern":"^(?:(?:\\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))$","description":"ISO 8601 timestamp when the unit was created.","example":"2024-01-15T10:30:00Z"},"part":{"type":"object","properties":{"id":{"type":"string","description":"Part ID.","example":"550e8400-e29b-41d4-a716-446655440007"},"number":{"type":"string","description":"Part number.","example":"PCB-MAIN-001"},"name":{"type":"string","description":"Part name.","example":"Main Control Board"},"revision":{"type":"object","properties":{"id":{"type":"string","description":"Revision ID.","example":"550e8400-e29b-41d4-a716-446655440006"},"number":{"type":"string","description":"Revision number.","example":"REV-A"}},"required":["id","number"],"additionalProperties":false,"description":"Revision information for this unit."}},"required":["id","number","name","revision"],"additionalProperties":false,"description":"Part information with revision details for this unit."}},"required":["id","serial_number","created_at","part"],"additionalProperties":false},"description":"Array of units in this batch. Empty array if no units."}},"required":["id","number","created_at","units"],"additionalProperties":false}}}},"400":{"description":"{message}","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBADREQUEST"}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorUNAUTHORIZED"}}}},"404":{"description":"Batch not found: {number}","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorNOTFOUND"}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorINTERNALSERVERERROR"}}}}},"x-access":[{"level":"full","authType":"user","description":"Users can read batchs"},{"level":"full","authType":"station","description":"Stations can read batchs"}],"x-speakeasy-name-override":"get"},"delete":{"operationId":"batch-delete","summary":"Delete batch","description":"Delete a batch by number. Linked units are unlinked, not deleted.","tags":["Batches"],"security":[{"api_key":[]}],"parameters":[{"name":"number","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Batches deleted successfully","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"array","items":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"description":"IDs of successfully deleted batches","example":["550e8400-e29b-41d4-a716-446655440000"]}},"required":["id"],"additionalProperties":false,"description":"Response for successful batch deletion"}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorUNAUTHORIZED"}}}},"404":{"description":"No batches found with numbers: {batchNumbers}","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorNOTFOUND"}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorINTERNALSERVERERROR"}}}}},"x-access":[{"level":"full","authType":"user","description":"Users can delete batchs"},{"level":"unauthorized","authType":"station","description":"Stations cannot delete batchs"}],"x-speakeasy-name-override":"delete"},"patch":{"operationId":"batch-update","summary":"Update batch","description":"Rename a batch. The current number matches case-insensitively.","tags":["Batches"],"security":[{"api_key":[]}],"parameters":[{"name":"number","in":"path","required":true,"schema":{"type":"string"},"description":"Current batch number to update."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"new_number":{"type":"string","minLength":1,"maxLength":60,"pattern":"^[a-zA-Z0-9_.:+-]+$","description":"New batch number.","example":"BATCH-2024-002"}},"required":["new_number"]}}}},"responses":{"200":{"description":"Batch updated successfully","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","description":"Unique identifier of the updated batch.","example":"550e8400-e29b-41d4-a716-446655440000"}},"required":["id"],"additionalProperties":false}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorUNAUTHORIZED"}}}},"404":{"description":"Batch with number {batchNumber} not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorNOTFOUND"}}}},"409":{"description":"A batch with number {newNumber} already exists","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorCONFLICT"}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorINTERNALSERVERERROR"}}}}},"x-access":[{"level":"full","authType":"user","description":"Users can update batchs"},{"level":"unauthorized","authType":"station","description":"Stations cannot update batchs"}],"x-speakeasy-name-override":"update"}},"/v2/batches":{"get":{"operationId":"batch-list","summary":"List and filter batches","description":"List batches with their units, serial numbers, and part revisions. Cursor-paginated.","tags":["Batches"],"security":[{"api_key":[]}],"parameters":[{"name":"ids","in":"query","required":false,"schema":{"description":"Filter by specific batch IDs.","example":["550e8400-e29b-41d4-a716-446655440000"],"type":"array","items":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"}}},{"name":"numbers","in":"query","required":false,"schema":{"description":"Filter by batch numbers.","example":["BATCH-2024-01","BATCH-2024-02"],"type":"array","items":{"type":"string"}}},{"name":"created_after","in":"query","required":false,"schema":{"type":"string","format":"date-time","pattern":"^(?:(?:\\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)))$","description":"Filter for batches created at or after this time.","example":"2024-01-15T10:30:00Z"}},{"name":"created_before","in":"query","required":false,"schema":{"type":"string","format":"date-time","pattern":"^(?:(?:\\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)))$","description":"Filter for batches created at or before this time.","example":"2024-01-15T11:30:00Z"}},{"name":"limit","in":"query","required":false,"schema":{"default":50,"description":"Maximum number of batches to return. Use `cursor` to fetch additional results.","example":50,"type":"integer","minimum":1,"maximum":100},"description":"Maximum number of batches to return. Use `cursor` to fetch additional results."},{"name":"cursor","in":"query","required":false,"schema":{"type":"integer","minimum":0,"maximum":9007199254740991,"description":"Cursor for pagination (offset-based). Use with `limit` to fetch results in batches.","example":0}},{"name":"search_query","in":"query","required":false,"schema":{"type":"string","maxLength":100,"description":"Search query to filter batches by batch number or unit serial number.","example":"BATCH-2024"}},{"name":"part_numbers","in":"query","required":false,"schema":{"description":"Filter batches by part number of contained units.","example":["PCB-V1.2","PCB-V1.3"],"type":"array","items":{"type":"string"}}},{"name":"revision_numbers","in":"query","required":false,"schema":{"description":"Filter batches by revision number of contained units.","example":["1.0","1.1"],"type":"array","items":{"type":"string"}}},{"name":"sort_by","in":"query","required":false,"schema":{"default":"created_at","description":"Field to sort results by.","example":"created_at","type":"string","enum":["number","created_at"]}},{"name":"sort_order","in":"query","required":false,"schema":{"default":"desc","description":"Sort order direction.","example":"desc","type":"string","enum":["asc","desc"]}}],"responses":{"200":{"description":"Batches retrieved successfully","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","description":"Unique identifier for the batch.","example":"550e8400-e29b-41d4-a716-446655440000"},"number":{"type":"string","description":"Batch number.","example":"BATCH-2024-001"},"created_at":{"type":"string","format":"date-time","pattern":"^(?:(?:\\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))$","description":"ISO timestamp when the batch was created.","example":"2024-01-15T10:30:00Z"},"created_by_user":{"description":"User who created this batch.","anyOf":[{"type":"object","properties":{"id":{"type":"string","description":"User ID.","example":"550e8400-e29b-41d4-a716-446655440001"},"name":{"anyOf":[{"type":"string","description":"User display name.","example":"John Doe"},{"type":"null"}]}},"required":["id","name"],"additionalProperties":false},{"type":"null"}]},"created_by_station":{"description":"Station that created this batch.","anyOf":[{"type":"object","properties":{"id":{"type":"string","description":"Station ID.","example":"550e8400-e29b-41d4-a716-446655440002"},"name":{"type":"string","description":"Station name.","example":"Assembly Station 01"}},"required":["id","name"],"additionalProperties":false},{"type":"null"}]},"unit_count":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Total number of units in this batch.","example":150}},"required":["id","number","created_at","unit_count"],"additionalProperties":false},"description":"Array of batches matching the query."},"meta":{"type":"object","properties":{"has_more":{"type":"boolean","description":"Whether there are more results available.","example":true},"next_cursor":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}],"description":"Cursor for fetching the next page of results.","example":50}},"required":["has_more","next_cursor"],"additionalProperties":false,"description":"Pagination metadata."}},"required":["data","meta"],"additionalProperties":false}}}},"400":{"description":"{message}","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBADREQUEST"}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorUNAUTHORIZED"}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorINTERNALSERVERERROR"}}}}},"x-access":[{"level":"full","authType":"user","description":"Users can read batchs"},{"level":"full","authType":"station","description":"Stations can read batchs"}],"x-speakeasy-name-override":"list"},"post":{"operationId":"batch-create","summary":"Create batch","description":"Create an empty batch. Batch numbers match case-insensitively (\"BATCH-001\" == \"batch-001\").","tags":["Batches"],"security":[{"api_key":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"number":{"type":"string","minLength":1,"maxLength":60,"pattern":"^[a-zA-Z0-9_.:+-]+$","description":"The batch number identifier"}},"required":["number"]}}}},"responses":{"200":{"description":"Batch created successfully","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","description":"Unique identifier for the created batch"}},"required":["id"],"additionalProperties":false}}}},"400":{"description":"Batch number can only contain letters, numbers, underscores, dashes, plus signs, dots and colons","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBADREQUEST"}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorUNAUTHORIZED"}}}},"409":{"description":"A batch with this number already exists in the organization","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorCONFLICT"}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorINTERNALSERVERERROR"}}}}},"x-access":[{"level":"full","authType":"user","description":"Users can create batchs"},{"level":"full","authType":"station","description":"Stations can create batchs"}],"x-speakeasy-name-override":"create"}},"/v2/stations":{"post":{"operationId":"station-create","summary":"Create station","description":"Create a station to register production equipment and link it to procedures.","tags":["Stations"],"security":[{"api_key":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":60,"description":"Name of the station","example":"Assembly Station 1"},"procedure_id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","description":"Optional procedure ID to link the station to","example":"550e8400-e29b-41d4-a716-446655440000"}},"required":["name"]}}}},"responses":{"200":{"description":"Station created successfully","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","description":"Unique identifier of the created station","example":"550e8400-e29b-41d4-a716-446655440000"}},"required":["id"],"additionalProperties":false}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorUNAUTHORIZED"}}}},"403":{"description":"You can't add a station without upgrading your plan.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorFORBIDDEN"}}}},"409":{"description":"A station with this name already exists.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorCONFLICT"}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorINTERNALSERVERERROR"}}}}},"x-access":[{"level":"full","authType":"user","description":"Users can create stations"},{"level":"unauthorized","authType":"station","description":"Stations cannot create stations"}],"x-speakeasy-name-override":"create"},"get":{"operationId":"station-list","summary":"List and filter stations","description":"List stations. Search by name and filter by status. Cursor-paginated.","tags":["Stations"],"security":[{"api_key":[]}],"parameters":[{"name":"limit","in":"query","required":false,"schema":{"default":50,"description":"Number of stations to return per page","example":50,"type":"integer","minimum":1,"maximum":100},"description":"Number of stations to return per page"},{"name":"cursor","in":"query","required":false,"schema":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Cursor for pagination. Use the nextCursor from previous response","example":1}},{"name":"search_query","in":"query","required":false,"schema":{"type":"string","description":"Search query to filter stations by name","example":"assembly"}},{"name":"procedure_ids","in":"query","required":false,"schema":{"type":"array","items":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"description":"Filter stations by linked procedure IDs","example":["550e8400-e29b-41d4-a716-446655440000"]},"style":"form","explode":true}],"responses":{"200":{"description":"Stations retrieved successfully","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","description":"Unique identifier of the station","example":"550e8400-e29b-41d4-a716-446655440000"},"name":{"type":"string","description":"Name of the station","example":"Assembly Station 1"},"procedures":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","description":"Procedure ID","example":"550e8400-e29b-41d4-a716-446655440001"},"name":{"type":"string","description":"Procedure name","example":"Assembly Test"}},"required":["id","name"],"additionalProperties":false},"description":"Procedures linked to this station"},"procedures_count":{"type":"number","description":"Total number of procedures linked to this station","example":5},"team":{"anyOf":[{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","description":"Team ID","example":"550e8400-e29b-41d4-a716-446655440002"},"name":{"type":"string","description":"Team name","example":"Assembly Team"}},"required":["id","name"],"additionalProperties":false},{"type":"null"}],"description":"Team this station belongs to"}},"required":["id","name","procedures","procedures_count","team"],"additionalProperties":false},"description":"List of stations matching the search criteria"},"meta":{"type":"object","properties":{"has_more":{"type":"boolean","description":"Whether there are more results available for pagination","example":true},"next_cursor":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}],"description":"Cursor value to fetch the next page of results. Use this value as the cursor parameter in the next request. Null if no more results available","example":2}},"required":["has_more","next_cursor"],"additionalProperties":false,"description":"Pagination metadata"}},"required":["data","meta"],"additionalProperties":false}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorUNAUTHORIZED"}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorINTERNALSERVERERROR"}}}}},"x-access":[{"level":"full","authType":"user","description":"Users can read stations"},{"level":"unauthorized","authType":"station","description":"Stations cannot read stations"}],"x-speakeasy-name-override":"list"}},"/v2/stations/current":{"get":{"operationId":"station-getCurrent","summary":"Get current station","description":"Get the station the request is authenticated as, with its linked procedures and connection status.","tags":["Stations"],"security":[{"api_key":[]}],"responses":{"200":{"description":"Current station retrieved successfully","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","description":"Unique identifier of the station","example":"550e8400-e29b-41d4-a716-446655440000"},"name":{"type":"string","description":"Name of the station","example":"Assembly Station 1"},"api_key":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"API key prefix for the station (full key only shown on creation)","example":"550e8400..."},"procedures":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","description":"Procedure ID","example":"550e8400-e29b-41d4-a716-446655440002"},"name":{"type":"string","description":"Procedure name","example":"Assembly Test"},"runs_count":{"type":"number","description":"Number of runs created by this station in the last 7 days","example":42},"deployment":{"description":"Deployment information for this procedure on this station","anyOf":[{"type":"object","properties":{"deployed_at":{"type":"string","description":"When the procedure was deployed","example":"2026-01-22T10:00:00Z"},"commit":{"anyOf":[{"type":"object","properties":{"sha":{"type":"string","description":"Git commit SHA","example":"a1b2c3d4e5f6"},"message":{"type":"string","description":"Git commit message","example":"Update procedure"},"branch":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Git branch name","example":"main"}},"required":["sha","message","branch"],"additionalProperties":false},{"type":"null"}]},"repository":{"anyOf":[{"type":"object","properties":{"owner":{"type":"string","description":"Repository owner","example":"tofupilot"},"name":{"type":"string","description":"Repository name","example":"procedures"},"provider":{"type":"string","enum":["github","gitlab"],"description":"Git provider","example":"github"},"gitlab_project_id":{"anyOf":[{"type":"number"},{"type":"null"}],"description":"GitLab project ID (only for GitLab repos)","example":12345}},"required":["owner","name","provider","gitlab_project_id"],"additionalProperties":false},{"type":"null"}]}},"required":["deployed_at","commit","repository"],"additionalProperties":false},{"type":"null"}]}},"required":["id","name","runs_count"],"additionalProperties":false},"description":"Procedures linked to this station with recent run counts"},"organization_slug":{"type":"string","description":"Slug of the organization this station belongs to","example":"my-org"},"team":{"anyOf":[{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"name":{"type":"string"}},"required":["id","name"],"additionalProperties":false},{"type":"null"}],"description":"Team this station is assigned to"}},"required":["id","name","api_key","procedures","organization_slug","team"],"additionalProperties":false}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorUNAUTHORIZED"}}}},"403":{"description":"Must be authenticated as a station to use this endpoint","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorFORBIDDEN"}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorINTERNALSERVERERROR"}}}}},"x-access":[{"level":"unauthorized","authType":"user","description":"Users cannot read stations"},{"level":"full","authType":"station","description":"Stations can read stations"}],"x-speakeasy-name-override":"getCurrent"}},"/v2/stations/{id}":{"get":{"operationId":"station-get","summary":"Get station","description":"Get a station by ID, with its linked procedures, connection status, and recent activity.","tags":["Stations"],"security":[{"api_key":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"Unique identifier of the station to retrieve"}],"responses":{"200":{"description":"Station retrieved successfully","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","description":"Unique identifier of the station","example":"550e8400-e29b-41d4-a716-446655440000"},"name":{"type":"string","description":"Name of the station","example":"Assembly Station 1"},"api_key":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"API key prefix for the station (full key only shown on creation)","example":"550e8400..."},"procedures":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","description":"Procedure ID","example":"550e8400-e29b-41d4-a716-446655440002"},"name":{"type":"string","description":"Procedure name","example":"Assembly Test"},"runs_count":{"type":"number","description":"Number of runs created by this station in the last 7 days","example":42},"deployment":{"description":"Deployment information for this procedure on this station","anyOf":[{"type":"object","properties":{"deployed_at":{"type":"string","description":"When the procedure was deployed","example":"2026-01-22T10:00:00Z"},"commit":{"anyOf":[{"type":"object","properties":{"sha":{"type":"string","description":"Git commit SHA","example":"a1b2c3d4e5f6"},"message":{"type":"string","description":"Git commit message","example":"Update procedure"},"branch":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Git branch name","example":"main"}},"required":["sha","message","branch"],"additionalProperties":false},{"type":"null"}]},"repository":{"anyOf":[{"type":"object","properties":{"owner":{"type":"string","description":"Repository owner","example":"tofupilot"},"name":{"type":"string","description":"Repository name","example":"procedures"},"provider":{"type":"string","enum":["github","gitlab"],"description":"Git provider","example":"github"},"gitlab_project_id":{"anyOf":[{"type":"number"},{"type":"null"}],"description":"GitLab project ID (only for GitLab repos)","example":12345}},"required":["owner","name","provider","gitlab_project_id"],"additionalProperties":false},{"type":"null"}]}},"required":["deployed_at","commit","repository"],"additionalProperties":false},{"type":"null"}]}},"required":["id","name","runs_count"],"additionalProperties":false},"description":"Procedures linked to this station with recent run counts"},"organization_slug":{"type":"string","description":"Slug of the organization this station belongs to","example":"my-org"},"team":{"anyOf":[{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"name":{"type":"string"}},"required":["id","name"],"additionalProperties":false},{"type":"null"}],"description":"Team this station is assigned to"}},"required":["id","name","api_key","procedures","organization_slug","team"],"additionalProperties":false}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorUNAUTHORIZED"}}}},"404":{"description":"Station not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorNOTFOUND"}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorINTERNALSERVERERROR"}}}}},"x-access":[{"level":"full","authType":"user","description":"Users can read stations"},{"level":"limited","authType":"station","description":"Stations cannot read stations"}],"x-speakeasy-name-override":"get"},"patch":{"operationId":"station-update","summary":"Update station","description":"Update a station name and/or image. Pass an empty string for image_id to remove the image.","tags":["Stations"],"security":[{"api_key":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"Unique identifier of the station to update"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":60,"description":"New name for the station","example":"Assembly Station 2"},"image_id":{"anyOf":[{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},{"type":"string","const":""}],"description":"Upload ID for the station image, or empty string to remove image","example":"550e8400-e29b-41d4-a716-446655440001"},"team_id":{"anyOf":[{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},{"type":"null"}],"description":"Team ID to assign this station to, or null to unassign","example":"550e8400-e29b-41d4-a716-446655440002"}}}}}},"responses":{"200":{"description":"Station updated successfully","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","description":"Unique identifier of the updated station","example":"550e8400-e29b-41d4-a716-446655440000"},"name":{"type":"string","description":"Name of the station","example":"Assembly Station 2"}},"required":["id","name"],"additionalProperties":false}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorUNAUTHORIZED"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorNOTFOUND"}}}},"409":{"description":"Another station with this name already exists","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorCONFLICT"}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorINTERNALSERVERERROR"}}}}},"x-access":[{"level":"full","authType":"user","description":"Users can update stations"},{"level":"unauthorized","authType":"station","description":"Stations cannot update stations"}],"x-speakeasy-name-override":"update"},"delete":{"operationId":"station-remove","summary":"Remove station","description":"Remove a station. Deleted if unused; archived (history preserved) if runs reference it.","tags":["Stations"],"security":[{"api_key":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"Unique identifier of the station to remove"}],"responses":{"200":{"description":"Station removed successfully","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","description":"Unique identifier of the removed station","example":"550e8400-e29b-41d4-a716-446655440000"}},"required":["id"],"additionalProperties":false}}}},"400":{"description":"Station is already archived","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBADREQUEST"}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorUNAUTHORIZED"}}}},"404":{"description":"Station not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorNOTFOUND"}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorINTERNALSERVERERROR"}}}}},"x-access":[{"level":"full","authType":"user","description":"Users can delete stations"},{"level":"unauthorized","authType":"station","description":"Stations cannot delete stations"}],"x-speakeasy-name-override":"remove"}},"/v2/users":{"get":{"operationId":"user-list","summary":"List users","description":"List users in your organization. Set `current=true` to return only the authenticated user.","tags":["Users"],"security":[{"api_key":[]}],"parameters":[{"name":"current","in":"query","required":false,"schema":{"description":"If true, returns only the current authenticated user","example":true,"type":"boolean"},"description":"If true, returns only the current authenticated user"}],"responses":{"200":{"description":"Users retrieved successfully","content":{"application/json":{"schema":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","description":"Unique identifier for the user.","example":"550e8400-e29b-41d4-a716-446655440000"},"email":{"type":"string","format":"email","pattern":"^(?!\\.)(?!.*\\.\\.)([A-Za-z0-9_'+\\-\\.]*)[A-Za-z0-9_+-]@([A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$","description":"Email address of the user.","example":"john.doe@example.com"},"name":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Display name of the user.","example":"John Doe"},"image":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Profile image URL for the user.","example":"https://example.com/user-avatar.jpg"},"banned":{"type":"boolean","description":"Whether the user is banned.","example":false}},"required":["id","email","name","image","banned"],"additionalProperties":false}}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorUNAUTHORIZED"}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorINTERNALSERVERERROR"}}}}},"x-access":[{"level":"full","authType":"user","description":"Users can read users"},{"level":"full","authType":"station","description":"Stations can read users"}],"x-speakeasy-name-override":"list"}},"/v2/imports/structured":{"post":{"operationId":"import-structured","summary":"Import runs from structured files","description":"Import one or more previously uploaded structured files (OpenHTF, WATS WSJF/WSXF, ATML, NI TestStand, STDF, or ATDF) in a single call. Each file is parsed independently and its result returned per-item, so one bad file does not fail the others. A file that contains several units (a multi-part STDF/ATDF datalog or a multi-report WSXF/TestStand document) creates one run per unit; all run ids are returned in the item’s `ids`.","tags":["Imports"],"security":[{"api_key":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"items":{"minItems":1,"maxItems":100,"type":"array","items":{"type":"object","properties":{"upload_id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","description":"ID of a previously uploaded file (via Initialize and Finalize upload).","example":"550e8400-e29b-41d4-a716-446655440000"},"importer":{"type":"string","enum":["OPENHTF","WATS","WSXF","ATML","TESTSTAND","STDF","ATDF"],"description":"Source format of the uploaded file. OPENHTF for OpenHTF JSON logs; WATS for Virinco WATS WSJF (JSON); WSXF for WATS WSXF (XML); ATML for IEEE 1671 ATML Test Results (XML); TESTSTAND for NI TestStand native XML reports; STDF for binary STDF V4 datalogs; ATDF for ATDF (the ASCII text form of STDF). For CSV/tabular files use the dedicated tabular import endpoint.","example":"OPENHTF"}},"required":["upload_id","importer"]},"description":"Files to import (1–100). Pass a single-item list to import one file. Each item is parsed independently; one failure does not abort the others."}},"required":["items"]}}}},"responses":{"200":{"description":"Run imported successfully","content":{"application/json":{"schema":{"type":"object","properties":{"results":{"type":"array","items":{"type":"object","properties":{"upload_id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","description":"Upload ID this result corresponds to."},"success":{"type":"boolean","description":"Whether the file was imported successfully."},"id":{"description":"ID of the created run (present when success is true). For a multi-run file this is the first run; see `ids`.","type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"ids":{"description":"All run ids created from the file. Present when the file produced more than one run.","type":"array","items":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"}},"error":{"description":"Error message (present when success is false).","type":"string"}},"required":["upload_id","success"],"additionalProperties":false}}},"required":["results"],"additionalProperties":false}}}},"400":{"description":"Bad request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBADREQUEST"}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorUNAUTHORIZED"}}}},"404":{"description":"Could not find upload with ID: {uploadId}","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorNOTFOUND"}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorINTERNALSERVERERROR"}}}}},"x-access":[{"level":"full","authType":"user","description":"Users can create runs"},{"level":"limited","authType":"station","description":"Stations cannot create runs"}],"x-speakeasy-name-override":"structured"}},"/v2/imports/tabular":{"post":{"operationId":"import-tabular","summary":"Import a run from a tabular file","description":"Import a previously uploaded tabular file (CSV or Excel) by mapping its columns to TofuPilot fields. Provide exactly one of `mapping` (an inline column mapping) or `template_id` (a mapping template saved in the dashboard). The `procedure_id` is required and overrides any procedure referenced in the file.","tags":["Imports"],"security":[{"api_key":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"upload_id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","description":"ID of a previously uploaded tabular file.","example":"550e8400-e29b-41d4-a716-446655440000"},"procedure_id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","description":"Procedure to attach the imported run to. Always overrides any procedure referenced in the file. Create the procedure in the app first, then find the auto-generated ID on the procedure page.","example":"550e8400-e29b-41d4-a716-446655440000"},"mapping":{"description":"Inline column mapping describing how source columns feed TofuPilot fields. Provide this OR template_id, not both.","type":"object","properties":{"fields":{"type":"object","properties":{"serial_number":{"anyOf":[{"type":"object","properties":{"column":{"type":"string","minLength":1}},"required":["column"]},{"type":"object","properties":{"value":{"type":"string","minLength":1}},"required":["value"]}]},"part_number":{"anyOf":[{"type":"object","properties":{"column":{"type":"string","minLength":1}},"required":["column"]},{"type":"object","properties":{"value":{"type":"string","minLength":1}},"required":["value"]}]},"outcome":{"anyOf":[{"type":"object","properties":{"column":{"type":"string","minLength":1},"valueMap":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{"type":"string","enum":["PASS","FAIL","ERROR","TIMEOUT","ABORTED"]}}},"required":["column"]},{"type":"object","properties":{"value":{"type":"string","enum":["PASS","FAIL","ERROR","TIMEOUT","ABORTED"]}},"required":["value"]}]},"started_at":{"anyOf":[{"type":"object","properties":{"column":{"type":"string","minLength":1}},"required":["column"]},{"type":"object","properties":{"value":{"type":"string","minLength":1}},"required":["value"]}]},"ended_at":{"anyOf":[{"type":"object","properties":{"column":{"type":"string","minLength":1}},"required":["column"]},{"type":"object","properties":{"value":{"type":"string","minLength":1}},"required":["value"]}]},"revision_number":{"anyOf":[{"type":"object","properties":{"column":{"type":"string","minLength":1}},"required":["column"]},{"type":"object","properties":{"value":{"type":"string","minLength":1}},"required":["value"]}]},"batch_number":{"anyOf":[{"type":"object","properties":{"column":{"type":"string","minLength":1}},"required":["column"]},{"type":"object","properties":{"value":{"type":"string","minLength":1}},"required":["value"]}]},"operated_by":{"anyOf":[{"type":"object","properties":{"column":{"type":"string","minLength":1}},"required":["column"]},{"type":"object","properties":{"value":{"type":"string","minLength":1}},"required":["value"]}]},"docstring":{"anyOf":[{"type":"object","properties":{"column":{"type":"string","minLength":1}},"required":["column"]},{"type":"object","properties":{"value":{"type":"string","minLength":1}},"required":["value"]}]}},"required":["serial_number","outcome","started_at","ended_at"]},"measurements":{"oneOf":[{"type":"object","properties":{"layout":{"type":"string","const":"long"},"nameColumn":{"type":"string","minLength":1},"valueColumn":{"type":"string","minLength":1},"unitsColumn":{"type":"string","minLength":1},"lowerColumn":{"type":"string","minLength":1},"upperColumn":{"type":"string","minLength":1},"outcomeColumn":{"type":"string","minLength":1},"phaseColumn":{"type":"string","minLength":1}},"required":["layout","nameColumn","valueColumn"]},{"type":"object","properties":{"layout":{"type":"string","const":"wide"},"columns":{"minItems":1,"maxItems":1000,"type":"array","items":{"type":"object","properties":{"column":{"type":"string","minLength":1},"name":{"type":"string","minLength":1},"units":{"type":"string","minLength":1},"lowerLimit":{"type":"number"},"upperLimit":{"type":"number"},"phase":{"type":"string","minLength":1}},"required":["column"]}}},"required":["layout","columns"]},{"type":"object","properties":{"layout":{"type":"string","const":"none"}},"required":["layout"]}],"type":"object"},"phases":{"type":"object","properties":{"nameColumn":{"type":"string","minLength":1},"outcomeColumn":{"type":"string","minLength":1},"startedColumn":{"type":"string","minLength":1},"endedColumn":{"type":"string","minLength":1},"valueMap":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{"type":"string","enum":["PASS","FAIL","SKIP","ERROR"]}}},"required":["nameColumn"]},"metadata":{"maxItems":50,"type":"array","items":{"type":"object","properties":{"column":{"type":"string","minLength":1},"value":{"type":"string","minLength":1},"key":{"type":"string","minLength":1}},"required":["key"]}},"unitMetadata":{"maxItems":50,"type":"array","items":{"type":"object","properties":{"column":{"type":"string","minLength":1},"value":{"type":"string","minLength":1},"key":{"type":"string","minLength":1}},"required":["key"]}}},"required":["fields","measurements"]},"template_id":{"description":"ID of a saved mapping template to apply. Provide this OR mapping, not both.","example":"550e8400-e29b-41d4-a716-446655440000","type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"}},"required":["upload_id","procedure_id"]}}}},"responses":{"200":{"description":"Run imported successfully","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","description":"ID of the created run."},"file_import_id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","description":"ID of the file import record that links this run to the uploaded file."}},"required":["id","file_import_id"],"additionalProperties":false}}}},"400":{"description":"Bad request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBADREQUEST"}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorUNAUTHORIZED"}}}},"404":{"description":"Could not find upload with ID: {uploadId}","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorNOTFOUND"}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorINTERNALSERVERERROR"}}}}},"x-access":[{"level":"full","authType":"user","description":"Users can create runs"},{"level":"limited","authType":"station","description":"Stations cannot create runs"}],"x-speakeasy-name-override":"tabular"}},"/v2/logs":{"get":{"operationId":"log-list","summary":"List and filter logs","description":"List logs with filtering by run, procedure, level, date range, unit, and source. Cursor-paginated.","tags":["Logs"],"security":[{"api_key":[]}],"parameters":[{"name":"procedure_ids","in":"query","required":false,"schema":{"description":"Filter logs by procedure ID(s).","example":["550e8400-e29b-41d4-a716-446655440000"],"type":"array","items":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"}}},{"name":"search_query","in":"query","required":false,"schema":{"type":"string","description":"Search query to filter logs by message content.","example":"error"}},{"name":"levels","in":"query","required":false,"schema":{"description":"Filter logs by level.","example":["INFO","WARNING","ERROR"],"type":"array","items":{"type":"string","enum":["DEBUG","INFO","WARNING","ERROR","CRITICAL"]}}},{"name":"timestamp_after","in":"query","required":false,"schema":{"description":"Filter logs with timestamp after this date (inclusive).","example":"2024-01-01T00:00:00Z","type":"string","format":"date-time","pattern":"^(?:(?:\\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))$"},"description":"Filter logs with timestamp after this date (inclusive)."},{"name":"timestamp_before","in":"query","required":false,"schema":{"description":"Filter logs with timestamp before this date (inclusive).","example":"2024-12-31T23:59:59Z","type":"string","format":"date-time","pattern":"^(?:(?:\\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))$"},"description":"Filter logs with timestamp before this date (inclusive)."},{"name":"source_files","in":"query","required":false,"schema":{"description":"Filter logs by source file path.","example":["test_procedure.py","main.py"],"type":"array","items":{"type":"string"}}},{"name":"run_ids","in":"query","required":false,"schema":{"description":"Filter logs by run ID.","example":["550e8400-e29b-41d4-a716-446655440001"],"type":"array","items":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"}}},{"name":"run_outcomes","in":"query","required":false,"schema":{"description":"Filter logs by run outcome.","example":["PASS","FAIL"],"type":"array","items":{"type":"string","enum":["PASS","FAIL","ERROR","TIMEOUT","ABORTED"]}}},{"name":"procedure_versions","in":"query","required":false,"schema":{"description":"Filter logs by the procedure version tag of their run.","example":["v1.0.0","v2.0.0"],"type":"array","items":{"type":"string"}}},{"name":"deployment_ids","in":"query","required":false,"schema":{"description":"Filter logs by the deployment ID their run executed from.","example":["550e8400-e29b-41d4-a716-446655440000"],"type":"array","items":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"}}},{"name":"environments","in":"query","required":false,"schema":{"description":"Filter logs by the deployment environment of their run (production, preview, development).","example":["production"],"type":"array","items":{"type":"string","enum":["production","preview","development"]}}},{"name":"serial_numbers","in":"query","required":false,"schema":{"description":"Filter logs by unit serial number.","example":["SN-2024-001234"],"type":"array","items":{"type":"string"}}},{"name":"part_numbers","in":"query","required":false,"schema":{"description":"Filter logs by unit part number.","example":["PCBA-MAIN"],"type":"array","items":{"type":"string"}}},{"name":"revision_numbers","in":"query","required":false,"schema":{"description":"Filter logs by unit revision number.","example":["REV-A"],"type":"array","items":{"type":"string"}}},{"name":"batch_numbers","in":"query","required":false,"schema":{"description":"Filter logs by unit batch number.","example":["BATCH-1"],"type":"array","items":{"type":"string"}}},{"name":"samples","in":"query","required":false,"schema":{"description":"Filter logs by unit sample class.","example":["golden"],"type":"array","items":{"type":"string","enum":["golden","failing","ignored"]}}},{"name":"created_by_station_ids","in":"query","required":false,"schema":{"description":"Filter logs by station ID.","example":["550e8400-e29b-41d4-a716-446655440005"],"type":"array","items":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"}}},{"name":"created_by_user_ids","in":"query","required":false,"schema":{"description":"Filter logs by user ID.","example":["550e8400-e29b-41d4-a716-446655440006"],"type":"array","items":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"}}},{"name":"sort_by","in":"query","required":false,"schema":{"default":"created_at","description":"Field to sort results by.","example":"created_at","enum":["created_at","level","run_id","outcome"],"type":"string"}},{"name":"sort_order","in":"query","required":false,"schema":{"default":"desc","description":"Sort order direction.","example":"desc","enum":["asc","desc"],"type":"string"}},{"name":"limit","in":"query","required":false,"schema":{"default":50,"description":"Maximum number of logs to return.","example":50,"type":"integer","minimum":1,"maximum":100},"description":"Maximum number of logs to return."},{"name":"cursor","in":"query","required":false,"schema":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Cursor for pagination. Use next_cursor from previous response to fetch next page.","example":50}}],"responses":{"200":{"description":"Logs retrieved successfully","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","description":"Unique identifier for the log entry.","example":"550e8400-e29b-41d4-a716-446655440000"},"level":{"type":"string","enum":["DEBUG","INFO","WARNING","ERROR","CRITICAL"],"description":"Log level indicating the severity.","example":"INFO"},"message":{"type":"string","description":"The log message content.","example":"Test execution started"},"created_at":{"type":"string","format":"date-time","pattern":"^(?:(?:\\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))$","description":"ISO 8601 timestamp when the log was created.","example":"2024-01-15T10:30:00Z"},"source_file":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Source file where the log originated.","example":"test_procedure.py"},"line_number":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}],"description":"Line number in the source file.","example":42},"run":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","description":"ID of the run this log belongs to.","example":"550e8400-e29b-41d4-a716-446655440001"},"outcome":{"type":"string","enum":["PASS","FAIL","ERROR","TIMEOUT","ABORTED"],"description":"Outcome of the run.","example":"PASS"},"started_at":{"type":"string","format":"date-time","pattern":"^(?:(?:\\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))$","description":"When the run started.","example":"2024-01-15T10:25:00Z"}},"required":["id","outcome","started_at"],"additionalProperties":false,"description":"Run information for this log entry."},"unit":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","description":"ID of the unit tested.","example":"550e8400-e29b-41d4-a716-446655440002"},"serial_number":{"type":"string","description":"Serial number of the unit.","example":"SN-2024-001234"}},"required":["id","serial_number"],"additionalProperties":false,"description":"Unit information for this log entry."},"procedure":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","description":"ID of the procedure.","example":"550e8400-e29b-41d4-a716-446655440005"},"name":{"type":"string","description":"Name of the procedure.","example":"Functional Test"}},"required":["id","name"],"additionalProperties":false,"description":"Procedure information for this log entry."},"created_by_user":{"description":"User who created this log. Null if created by a station or system.","anyOf":[{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","description":"Unique identifier for the user.","example":"550e8400-e29b-41d4-a716-446655440003"},"name":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Display name of the user who created this log.","example":"John Doe"},"email":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Email of the user.","example":"john@example.com"}},"required":["id","name","email"],"additionalProperties":false},{"type":"null"}]},"created_by_station":{"description":"Station that created this log. Null if created by a user.","anyOf":[{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","description":"Unique identifier for the station.","example":"550e8400-e29b-41d4-a716-446655440004"},"name":{"type":"string","description":"Name of the station that created this log.","example":"Assembly Station 01"}},"required":["id","name"],"additionalProperties":false},{"type":"null"}]}},"required":["id","level","message","created_at","source_file","line_number","run","unit","procedure"],"additionalProperties":false}},"meta":{"type":"object","properties":{"has_more":{"type":"boolean","description":"Whether there are more results available for pagination.","example":true},"next_cursor":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}],"description":"Cursor value to fetch the next page of results. Use this value as the cursor parameter in the next request. Null if no more results available.","example":100}},"required":["has_more","next_cursor"],"additionalProperties":false}},"required":["data","meta"],"additionalProperties":false}}}},"400":{"description":"{message}","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBADREQUEST"}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorUNAUTHORIZED"}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorINTERNALSERVERERROR"}}}}},"x-access":[{"level":"full","authType":"user","description":"Users can read runs"},{"level":"limited","authType":"station","description":"Stations cannot read runs"}],"x-speakeasy-name-override":"list"}},"/v2/logs/{id}":{"get":{"operationId":"log-get","summary":"Get log","description":"Get a single log entry by ID, with its run and unit context.","tags":["Logs"],"security":[{"api_key":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"Unique identifier for the log entry."}],"responses":{"200":{"description":"Log retrieved successfully","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"level":{"type":"string","enum":["DEBUG","INFO","WARNING","ERROR","CRITICAL"]},"message":{"type":"string"},"created_at":{"type":"string","format":"date-time","pattern":"^(?:(?:\\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))$"},"source_file":{"anyOf":[{"type":"string"},{"type":"null"}]},"line_number":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}]},"run":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"outcome":{"type":"string","enum":["PASS","FAIL","ERROR","TIMEOUT","ABORTED"]},"started_at":{"type":"string","format":"date-time","pattern":"^(?:(?:\\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))$"}},"required":["id","outcome","started_at"],"additionalProperties":false},"unit":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"serial_number":{"type":"string"}},"required":["id","serial_number"],"additionalProperties":false},"procedure":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"name":{"type":"string"}},"required":["id","name"],"additionalProperties":false},"created_by_user":{"anyOf":[{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"name":{"anyOf":[{"type":"string"},{"type":"null"}]},"email":{"anyOf":[{"type":"string"},{"type":"null"}]}},"required":["id","name","email"],"additionalProperties":false},{"type":"null"}]},"created_by_station":{"anyOf":[{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"name":{"type":"string"}},"required":["id","name"],"additionalProperties":false},{"type":"null"}]}},"required":["id","level","message","created_at","source_file","line_number","run","unit","procedure","created_by_user","created_by_station"],"additionalProperties":false}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorUNAUTHORIZED"}}}},"404":{"description":"Log with ID {id} not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorNOTFOUND"}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorINTERNALSERVERERROR"}}}}},"x-access":[{"level":"full","authType":"user","description":"Users can read runs"},{"level":"limited","authType":"station","description":"Stations cannot read runs"}],"x-speakeasy-name-override":"get"}},"/v2/phases":{"get":{"operationId":"phase-list","summary":"List and filter phases","description":"List phases for a procedure with filtering by outcome, date range, unit, and run details. Cursor-paginated.","tags":["Phases"],"security":[{"api_key":[]}],"parameters":[{"name":"procedure_id","in":"query","required":true,"schema":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","description":"Procedure to list phases for. Required: phases are scoped to a single procedure.","example":"550e8400-e29b-41d4-a716-446655440000"},"description":"Procedure to list phases for. Required: phases are scoped to a single procedure."},{"name":"names","in":"query","required":false,"schema":{"description":"Filter by phase name.","example":["Power","Report"],"type":"array","items":{"type":"string"}}},{"name":"outcomes","in":"query","required":false,"schema":{"description":"Filter by phase outcome (PASS/FAIL/SKIP/ERROR).","example":["PASS","FAIL"],"type":"array","items":{"type":"string","enum":["PASS","FAIL","SKIP","ERROR"]}}},{"name":"started_after","in":"query","required":false,"schema":{"type":"string","format":"date-time","pattern":"^(?:(?:\\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))$","description":"Filter phases that started after this date (inclusive).","example":"2024-01-01T00:00:00Z"}},{"name":"started_before","in":"query","required":false,"schema":{"type":"string","format":"date-time","pattern":"^(?:(?:\\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))$","description":"Filter phases that started before this date (inclusive).","example":"2024-12-31T23:59:59Z"}},{"name":"exclude_retries","in":"query","required":false,"schema":{"default":true,"description":"Exclude retried phase attempts, keeping only the final attempt.","example":true,"type":"boolean"}},{"name":"run_outcomes","in":"query","required":false,"schema":{"description":"Filter phases by the outcome of their run.","example":["PASS","FAIL"],"type":"array","items":{"type":"string","enum":["PASS","FAIL","ERROR","TIMEOUT","ABORTED"]}}},{"name":"ids","in":"query","required":false,"schema":{"description":"Filter phases by run ID.","example":["550e8400-e29b-41d4-a716-446655440001"],"type":"array","items":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"}}},{"name":"duration_min","in":"query","required":false,"schema":{"type":"string","format":"duration","pattern":"^P(?:(\\d+W)|(?!.*W)(?=\\d|T\\d)(\\d+Y)?(\\d+M)?(\\d+D)?(T(?=\\d)(\\d+H)?(\\d+M)?(\\d+([.,]\\d+)?S)?)?)$","description":"Filter phases whose run lasted at least this ISO 8601 duration.","example":"PT30S"}},{"name":"duration_max","in":"query","required":false,"schema":{"type":"string","format":"duration","pattern":"^P(?:(\\d+W)|(?!.*W)(?=\\d|T\\d)(\\d+Y)?(\\d+M)?(\\d+D)?(T(?=\\d)(\\d+H)?(\\d+M)?(\\d+([.,]\\d+)?S)?)?)$","description":"Filter phases whose run lasted at most this ISO 8601 duration.","example":"PT5M"}},{"name":"deployment_ids","in":"query","required":false,"schema":{"description":"Filter phases by the deployment ID their run executed from.","example":["550e8400-e29b-41d4-a716-446655440000"],"type":"array","items":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"}}},{"name":"procedure_versions","in":"query","required":false,"schema":{"description":"Filter phases by the procedure version tag of their run.","example":["v1.0.0","v2.0.0"],"type":"array","items":{"type":"string"}}},{"name":"environments","in":"query","required":false,"schema":{"description":"Filter phases by the deployment environment of their run (production, preview, development).","example":["production"],"type":"array","items":{"type":"string","enum":["production","preview","development"]}}},{"name":"operated_by_ids","in":"query","required":false,"schema":{"description":"Filter phases by the operator user ID of their run.","example":["550e8400-e29b-41d4-a716-446655440006"],"type":"array","items":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"}}},{"name":"created_by_station_ids","in":"query","required":false,"schema":{"description":"Filter phases by the station ID that created their run.","example":["550e8400-e29b-41d4-a716-446655440005"],"type":"array","items":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"}}},{"name":"created_by_user_ids","in":"query","required":false,"schema":{"description":"Filter phases by the user ID that created their run.","example":["550e8400-e29b-41d4-a716-446655440006"],"type":"array","items":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"}}},{"name":"serial_numbers","in":"query","required":false,"schema":{"description":"Filter phases by unit serial number.","example":["SN-2024-001234"],"type":"array","items":{"type":"string"}}},{"name":"part_numbers","in":"query","required":false,"schema":{"description":"Filter phases by unit part number.","example":["PCBA-MAIN"],"type":"array","items":{"type":"string"}}},{"name":"revision_numbers","in":"query","required":false,"schema":{"description":"Filter phases by unit revision number.","example":["REV-A"],"type":"array","items":{"type":"string"}}},{"name":"batch_numbers","in":"query","required":false,"schema":{"description":"Filter phases by unit batch number.","example":["BATCH-1"],"type":"array","items":{"type":"string"}}},{"name":"samples","in":"query","required":false,"schema":{"description":"Filter by unit sample class (production / golden / failing). Omit for all.","example":["golden"],"type":"array","items":{"type":"string","enum":["production","golden","failing","ignored"]}}},{"name":"sort_by","in":"query","required":false,"schema":{"default":"started_at","description":"Field to sort results by.","example":"started_at","enum":["started_at","duration","outcome","serial_number","phase_name"],"type":"string"}},{"name":"sort_order","in":"query","required":false,"schema":{"default":"desc","description":"Sort order direction.","example":"desc","enum":["asc","desc"],"type":"string"}},{"name":"limit","in":"query","required":false,"schema":{"default":50,"description":"Maximum number of phases to return.","example":50,"type":"integer","minimum":1,"maximum":100},"description":"Maximum number of phases to return."},{"name":"cursor","in":"query","required":false,"schema":{"description":"Cursor for pagination. Use next_cursor from the previous response to fetch the next page.","example":50,"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"description":"Cursor for pagination. Use next_cursor from the previous response to fetch the next page."}],"responses":{"200":{"description":"Phases retrieved successfully","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","description":"Unique identifier for the phase.","example":"550e8400-e29b-41d4-a716-446655440000"},"name":{"type":"string","description":"Name of the phase.","example":"Power"},"outcome":{"type":"string","enum":["PASS","FAIL","SKIP","ERROR"],"description":"Outcome of the phase.","example":"PASS"},"started_at":{"anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\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))$"},{"type":"null"}],"description":"ISO 8601 timestamp when the phase started.","example":"2024-01-15T10:30:00Z"},"ended_at":{"anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\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))$"},{"type":"null"}],"description":"ISO 8601 timestamp when the phase ended.","example":"2024-01-15T10:35:00Z"},"duration_ms":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}],"description":"Phase duration in milliseconds. Null when start or end is missing.","example":300000},"retry_count":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Retry attempt number of the phase (0 for the first attempt).","example":0},"is_final_attempt":{"type":"boolean","description":"True when this is the final attempt of the phase.","example":true},"run_id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","description":"ID of the run this phase belongs to.","example":"550e8400-e29b-41d4-a716-446655440001"},"run_outcome":{"type":"string","enum":["PASS","FAIL","ERROR","TIMEOUT","ABORTED"],"description":"Outcome of the run this phase belongs to.","example":"PASS"},"serial_number":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Serial number of the unit tested.","example":"SN-2024-001234"},"sample":{"anyOf":[{"type":"string","enum":["golden","failing","ignored"]},{"type":"null"}],"description":"Sample class of the unit (golden or failing). Null for regular units.","example":null}},"required":["id","name","outcome","started_at","ended_at","duration_ms","retry_count","is_final_attempt","run_id","run_outcome","serial_number","sample"],"additionalProperties":false},"description":"The list of phases matching the request."},"meta":{"type":"object","properties":{"has_more":{"type":"boolean","description":"Whether more phases are available beyond this page.","example":true},"next_cursor":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}],"description":"Cursor to fetch the next page. Null when there are no more results.","example":50}},"required":["has_more","next_cursor"],"additionalProperties":false,"description":"Pagination metadata."}},"required":["data","meta"],"additionalProperties":false}}}},"400":{"description":"{message}","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBADREQUEST"}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorUNAUTHORIZED"}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorINTERNALSERVERERROR"}}}}},"x-access":[{"level":"full","authType":"user","description":"Users can read runs"},{"level":"limited","authType":"station","description":"Stations cannot read runs"}],"x-speakeasy-name-override":"list"}},"/v2/phases/{id}":{"get":{"operationId":"phase-get","summary":"Get phase","description":"Get a single phase by ID, with its measurements and run context.","tags":["Phases"],"security":[{"api_key":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"ID of the phase to retrieve."}],"responses":{"200":{"description":"Phase retrieved successfully","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"name":{"type":"string"},"outcome":{"type":"string","enum":["PASS","FAIL","SKIP","ERROR"]},"started_at":{"type":"string","format":"date-time","pattern":"^(?:(?:\\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))$"},"ended_at":{"type":"string","format":"date-time","pattern":"^(?:(?:\\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))$"},"duration":{"type":"string"},"retry_count":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"docstring":{"anyOf":[{"type":"string"},{"type":"null"}]},"measurements":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"name":{"type":"string"},"outcome":{"type":"string","enum":["PASS","FAIL","UNSET"]},"units":{"anyOf":[{"type":"string"},{"type":"null"}]},"validators":{"anyOf":[{"type":"array","items":{"type":"object","properties":{"outcome":{"type":"string","enum":["PASS","FAIL","UNSET"],"description":"Validation result: PASS, FAIL, or UNSET.","example":"PASS"},"operator":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Comparison operator used for validation.","example":">="},"expected_value":{"anyOf":[{"anyOf":[{"type":"null"},{"type":"boolean"},{"type":"number"},{"type":"string"},{"type":"array","items":{"type":"number"}},{"type":"array","items":{"type":"string"}}]},{"type":"null"}],"description":"Expected value for comparison. Type depends on measurement type.","example":3},"expression":{"type":"string","description":"Human-readable expression string for display.","example":"x >= 3.0"},"is_decisive":{"anyOf":[{"type":"boolean"},{"type":"null"}],"description":"Whether this validator is decisive (if it fails, measurement fails). False for marginal/warning validators."},"is_expression_only":{"type":"boolean","description":"True if validator only has expression (no structured operator/expected_value)."},"analytics_expression":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Synthetic expression from operator+expected_value for analytics tooltip. Null if expression-only."},"has_custom_expression":{"type":"boolean","description":"True if user provided a custom expression (shown in italic with analytics tooltip)."}},"required":["outcome","operator","expected_value","expression","is_decisive","is_expression_only","analytics_expression","has_custom_expression"],"additionalProperties":false,"description":"Validator result with outcome and comparison details."}},{"type":"null"}]},"aggregations":{"anyOf":[{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","description":"Unique identifier for the aggregation."},"type":{"type":"string","description":"Aggregation type (e.g., MIN, MAX, MEAN, RANGE, STD_DEV).","example":"MEAN"},"outcome":{"anyOf":[{"type":"string","enum":["PASS","FAIL","UNSET"]},{"type":"null"}],"description":"Aggregation validation result: PASS, FAIL, UNSET, or null if no validators.","example":"PASS"},"value":{"anyOf":[{"anyOf":[{"type":"number"},{"type":"string"},{"type":"boolean"}]},{"type":"null"}],"description":"Computed aggregation value. Type depends on aggregation type.","example":42.5},"unit":{"description":"Unit of measurement for the aggregated value.","example":"V","anyOf":[{"type":"string"},{"type":"null"}]},"validators":{"description":"Validators applied to the aggregated value.","anyOf":[{"type":"array","items":{"type":"object","properties":{"outcome":{"type":"string","enum":["PASS","FAIL","UNSET"],"description":"Validation result: PASS, FAIL, or UNSET.","example":"PASS"},"operator":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Comparison operator used for validation.","example":">="},"expected_value":{"anyOf":[{"anyOf":[{"type":"null"},{"type":"boolean"},{"type":"number"},{"type":"string"},{"type":"array","items":{"type":"number"}},{"type":"array","items":{"type":"string"}}]},{"type":"null"}],"description":"Expected value for comparison. Type depends on measurement type.","example":3},"expression":{"type":"string","description":"Human-readable expression string for display.","example":"x >= 3.0"},"is_decisive":{"anyOf":[{"type":"boolean"},{"type":"null"}],"description":"Whether this validator is decisive (if it fails, measurement fails). False for marginal/warning validators."},"is_expression_only":{"type":"boolean","description":"True if validator only has expression (no structured operator/expected_value)."},"analytics_expression":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Synthetic expression from operator+expected_value for analytics tooltip. Null if expression-only."},"has_custom_expression":{"type":"boolean","description":"True if user provided a custom expression (shown in italic with analytics tooltip)."}},"required":["outcome","operator","expected_value","expression","is_decisive","is_expression_only","analytics_expression","has_custom_expression"],"additionalProperties":false,"description":"Validator result with outcome and comparison details."}},{"type":"null"}]}},"required":["id","type","outcome","value"],"additionalProperties":false,"description":"Aggregation result with computed value and optional validators."}},{"type":"null"}]},"measured_value":{"anyOf":[{"type":"number"},{"type":"string"},{"type":"boolean"},{"type":"array","items":{"type":"array","items":{"type":"number"}}},{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{}},{"type":"array","items":{}}]},"data_series":{"type":"array","items":{"type":"object","properties":{"data":{"type":"array","items":{"type":"number"}},"units":{"anyOf":[{"type":"string"},{"type":"null"}]},"name":{"anyOf":[{"type":"string"},{"type":"null"}]},"description":{"anyOf":[{"type":"string"},{"type":"null"}]},"validators":{"anyOf":[{"type":"array","items":{"type":"object","properties":{"outcome":{"type":"string","enum":["PASS","FAIL","UNSET"],"description":"Validation result: PASS, FAIL, or UNSET.","example":"PASS"},"operator":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Comparison operator used for validation.","example":">="},"expected_value":{"anyOf":[{"anyOf":[{"type":"null"},{"type":"boolean"},{"type":"number"},{"type":"string"},{"type":"array","items":{"type":"number"}},{"type":"array","items":{"type":"string"}}]},{"type":"null"}],"description":"Expected value for comparison. Type depends on measurement type.","example":3},"expression":{"type":"string","description":"Human-readable expression string for display.","example":"x >= 3.0"},"is_decisive":{"anyOf":[{"type":"boolean"},{"type":"null"}],"description":"Whether this validator is decisive (if it fails, measurement fails). False for marginal/warning validators."},"is_expression_only":{"type":"boolean","description":"True if validator only has expression (no structured operator/expected_value)."},"analytics_expression":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Synthetic expression from operator+expected_value for analytics tooltip. Null if expression-only."},"has_custom_expression":{"type":"boolean","description":"True if user provided a custom expression (shown in italic with analytics tooltip)."}},"required":["outcome","operator","expected_value","expression","is_decisive","is_expression_only","analytics_expression","has_custom_expression"],"additionalProperties":false,"description":"Validator result with outcome and comparison details."}},{"type":"null"}]},"aggregations":{"anyOf":[{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","description":"Unique identifier for the aggregation."},"type":{"type":"string","description":"Aggregation type (e.g., MIN, MAX, MEAN, RANGE, STD_DEV).","example":"MEAN"},"outcome":{"anyOf":[{"type":"string","enum":["PASS","FAIL","UNSET"]},{"type":"null"}],"description":"Aggregation validation result: PASS, FAIL, UNSET, or null if no validators.","example":"PASS"},"value":{"anyOf":[{"anyOf":[{"type":"number"},{"type":"string"},{"type":"boolean"}]},{"type":"null"}],"description":"Computed aggregation value. Type depends on aggregation type.","example":42.5},"unit":{"description":"Unit of measurement for the aggregated value.","example":"V","anyOf":[{"type":"string"},{"type":"null"}]},"validators":{"description":"Validators applied to the aggregated value.","anyOf":[{"type":"array","items":{"type":"object","properties":{"outcome":{"type":"string","enum":["PASS","FAIL","UNSET"],"description":"Validation result: PASS, FAIL, or UNSET.","example":"PASS"},"operator":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Comparison operator used for validation.","example":">="},"expected_value":{"anyOf":[{"anyOf":[{"type":"null"},{"type":"boolean"},{"type":"number"},{"type":"string"},{"type":"array","items":{"type":"number"}},{"type":"array","items":{"type":"string"}}]},{"type":"null"}],"description":"Expected value for comparison. Type depends on measurement type.","example":3},"expression":{"type":"string","description":"Human-readable expression string for display.","example":"x >= 3.0"},"is_decisive":{"anyOf":[{"type":"boolean"},{"type":"null"}],"description":"Whether this validator is decisive (if it fails, measurement fails). False for marginal/warning validators."},"is_expression_only":{"type":"boolean","description":"True if validator only has expression (no structured operator/expected_value)."},"analytics_expression":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Synthetic expression from operator+expected_value for analytics tooltip. Null if expression-only."},"has_custom_expression":{"type":"boolean","description":"True if user provided a custom expression (shown in italic with analytics tooltip)."}},"required":["outcome","operator","expected_value","expression","is_decisive","is_expression_only","analytics_expression","has_custom_expression"],"additionalProperties":false,"description":"Validator result with outcome and comparison details."}},{"type":"null"}]}},"required":["id","type","outcome","value"],"additionalProperties":false,"description":"Aggregation result with computed value and optional validators."}},{"type":"null"}]}},"required":["data","units"],"additionalProperties":false}},"docstring":{"anyOf":[{"type":"string"},{"type":"null"}]}},"required":["id","name","outcome","validators"],"additionalProperties":false}},"run":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"serial_number":{"anyOf":[{"type":"string"},{"type":"null"}]}},"required":["id"],"additionalProperties":false},"procedure":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"name":{"type":"string"}},"required":["id","name"],"additionalProperties":false}},"required":["id","name","outcome","started_at","ended_at","duration","retry_count","measurements","run","procedure"],"additionalProperties":false}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorUNAUTHORIZED"}}}},"404":{"description":"Phase with ID {id} not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorNOTFOUND"}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorINTERNALSERVERERROR"}}}}},"x-access":[{"level":"full","authType":"user","description":"Users can read runs"},{"level":"limited","authType":"station","description":"Stations cannot read runs"}],"x-speakeasy-name-override":"get"}},"/v2/measurements":{"get":{"operationId":"measurement-list","summary":"List and filter measurements","description":"List measurements for a procedure with filtering by phase, measurement, value, outcome, date range, unit, and run details. Cursor-paginated.","tags":["Measurements"],"security":[{"api_key":[]}],"parameters":[{"name":"procedure_id","in":"query","required":true,"schema":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","description":"Procedure to list measurements for. Required: measurements are scoped to a single procedure.","example":"550e8400-e29b-41d4-a716-446655440000"},"description":"Procedure to list measurements for. Required: measurements are scoped to a single procedure."},{"name":"phase_name","in":"query","required":false,"schema":{"type":"string","description":"Pin results to a single phase by name (used with measurement_name).","example":"Power"}},{"name":"measurement_name","in":"query","required":false,"schema":{"type":"string","description":"Pin results to a single measurement by name (used with phase_name).","example":"Voltage"}},{"name":"phase_names","in":"query","required":false,"schema":{"description":"Restrict results to these phase names.","example":["Power","Report"],"type":"array","items":{"type":"string"}}},{"name":"outcomes","in":"query","required":false,"schema":{"description":"Filter measurements by the outcome of their run.","example":["PASS","FAIL"],"type":"array","items":{"type":"string","enum":["PASS","FAIL","ERROR","TIMEOUT","ABORTED"]}}},{"name":"ids","in":"query","required":false,"schema":{"description":"Filter measurements by run ID.","example":["550e8400-e29b-41d4-a716-446655440001"],"type":"array","items":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"}}},{"name":"duration_min","in":"query","required":false,"schema":{"type":"string","format":"duration","pattern":"^P(?:(\\d+W)|(?!.*W)(?=\\d|T\\d)(\\d+Y)?(\\d+M)?(\\d+D)?(T(?=\\d)(\\d+H)?(\\d+M)?(\\d+([.,]\\d+)?S)?)?)$","description":"Filter measurements whose run lasted at least this ISO 8601 duration.","example":"PT30S"}},{"name":"duration_max","in":"query","required":false,"schema":{"type":"string","format":"duration","pattern":"^P(?:(\\d+W)|(?!.*W)(?=\\d|T\\d)(\\d+Y)?(\\d+M)?(\\d+D)?(T(?=\\d)(\\d+H)?(\\d+M)?(\\d+([.,]\\d+)?S)?)?)$","description":"Filter measurements whose run lasted at most this ISO 8601 duration.","example":"PT5M"}},{"name":"deployment_ids","in":"query","required":false,"schema":{"description":"Filter measurements by the deployment ID their run executed from.","example":["550e8400-e29b-41d4-a716-446655440000"],"type":"array","items":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"}}},{"name":"procedure_versions","in":"query","required":false,"schema":{"description":"Filter measurements by the procedure version tag of their run.","example":["v1.0.0","v2.0.0"],"type":"array","items":{"type":"string"}}},{"name":"environments","in":"query","required":false,"schema":{"description":"Filter measurements by the deployment environment of their run (production, preview, development).","example":["production"],"type":"array","items":{"type":"string","enum":["production","preview","development"]}}},{"name":"serial_numbers","in":"query","required":false,"schema":{"description":"Filter measurements by unit serial number.","example":["SN-2024-001234"],"type":"array","items":{"type":"string"}}},{"name":"part_numbers","in":"query","required":false,"schema":{"description":"Filter measurements by unit part number.","example":["PCBA-MAIN"],"type":"array","items":{"type":"string"}}},{"name":"revision_numbers","in":"query","required":false,"schema":{"description":"Filter measurements by unit revision number.","example":["REV-A"],"type":"array","items":{"type":"string"}}},{"name":"batch_numbers","in":"query","required":false,"schema":{"description":"Filter measurements by unit batch number.","example":["BATCH-1"],"type":"array","items":{"type":"string"}}},{"name":"operated_by_ids","in":"query","required":false,"schema":{"description":"Filter measurements by the operator user ID of their run.","example":["550e8400-e29b-41d4-a716-446655440006"],"type":"array","items":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"}}},{"name":"created_by_station_ids","in":"query","required":false,"schema":{"description":"Filter measurements by the station ID that created their run.","example":["550e8400-e29b-41d4-a716-446655440005"],"type":"array","items":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"}}},{"name":"created_by_user_ids","in":"query","required":false,"schema":{"description":"Filter measurements by the user ID that created their run.","example":["550e8400-e29b-41d4-a716-446655440006"],"type":"array","items":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"}}},{"name":"started_after","in":"query","required":false,"schema":{"type":"string","format":"date-time","pattern":"^(?:(?:\\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))$","description":"Filter measurements whose run started after this date (inclusive).","example":"2024-01-01T00:00:00Z"}},{"name":"started_before","in":"query","required":false,"schema":{"type":"string","format":"date-time","pattern":"^(?:(?:\\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))$","description":"Filter measurements whose run started before this date (inclusive).","example":"2024-12-31T23:59:59Z"}},{"name":"exclude_retries","in":"query","required":false,"schema":{"default":true,"description":"Exclude retried phase attempts, keeping only the final attempt.","example":true,"type":"boolean"},"description":"Exclude retried phase attempts, keeping only the final attempt."},{"name":"value_min","in":"query","required":false,"schema":{"type":"number","description":"Filter numeric measurements with a value at or above this number.","example":3}},{"name":"value_max","in":"query","required":false,"schema":{"type":"number","description":"Filter numeric measurements with a value at or below this number.","example":3.6}},{"name":"value_bool","in":"query","required":false,"schema":{"type":"boolean","description":"Filter boolean measurements by value.","example":true}},{"name":"value_strings","in":"query","required":false,"schema":{"description":"Filter string measurements by value.","example":["OK","READY"],"type":"array","items":{"type":"string"}}},{"name":"measurement_outcomes","in":"query","required":false,"schema":{"description":"Filter by measurement outcome.","example":["PASS","FAIL"],"type":"array","items":{"type":"string","enum":["PASS","FAIL","UNSET"]}}},{"name":"measurement_types","in":"query","required":false,"schema":{"description":"Filter by measurement value type (numeric, boolean, string, multidimensional, empty, json).","example":["numeric"],"type":"array","items":{"type":"string","enum":["numeric","boolean","string","multidimensional","empty","json"]}}},{"name":"sort_by","in":"query","required":false,"schema":{"default":"started_at","description":"Field to sort results by.","example":"started_at","enum":["started_at","value","outcome","serial_number","phase_name","measurement_name"],"type":"string"}},{"name":"sort_order","in":"query","required":false,"schema":{"default":"desc","description":"Sort order direction.","example":"desc","enum":["asc","desc"],"type":"string"}},{"name":"limit","in":"query","required":false,"schema":{"default":50,"description":"Maximum number of measurements to return.","example":50,"type":"integer","minimum":1,"maximum":100},"description":"Maximum number of measurements to return."},{"name":"cursor","in":"query","required":false,"schema":{"description":"Cursor for pagination. Use next_cursor from the previous response to fetch the next page.","example":50,"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"description":"Cursor for pagination. Use next_cursor from the previous response to fetch the next page."}],"responses":{"200":{"description":"Measurements retrieved successfully","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","description":"Unique identifier for the measurement.","example":"550e8400-e29b-41d4-a716-446655440000"},"phase_name":{"type":"string","description":"Name of the phase this measurement belongs to.","example":"Power"},"measurement_name":{"type":"string","description":"Name of the measurement.","example":"Voltage"},"started_at":{"anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\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))$"},{"type":"null"}],"description":"ISO 8601 timestamp when the measurement's phase started.","example":"2024-01-15T10:30:00Z"},"value":{"anyOf":[{"type":"number"},{"type":"null"}],"description":"Numeric value, when the measurement is numeric. Null otherwise.","example":3.3},"bool_value":{"anyOf":[{"type":"boolean"},{"type":"null"}],"description":"Boolean value, when the measurement is boolean. Null otherwise.","example":true},"string_value":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"String value, when the measurement is a string. Null otherwise.","example":"OK"},"units":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Measurement units, when applicable.","example":"V"},"measurement_outcome":{"type":"string","enum":["PASS","FAIL","UNSET"],"description":"Outcome of the measurement.","example":"PASS"},"run_id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","description":"ID of the run this measurement belongs to.","example":"550e8400-e29b-41d4-a716-446655440001"},"serial_number":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Serial number of the unit tested.","example":"SN-2024-001234"},"sample":{"anyOf":[{"type":"string","enum":["golden","failing","ignored"]},{"type":"null"}],"description":"Sample class of the unit (golden or failing). Null for regular units.","example":null},"measurement_type":{"type":"string","enum":["numeric","boolean","string","multidimensional","empty","json"],"description":"Value type of the measurement.","example":"numeric"},"retry_count":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Retry attempt number of the phase this measurement belongs to (0 for the first attempt).","example":0},"is_final_attempt":{"type":"boolean","description":"True when this measurement comes from the final attempt of its phase.","example":true},"validators":{"anyOf":[{"type":"array","items":{"type":"object","properties":{"outcome":{"type":"string","enum":["PASS","FAIL","UNSET"],"description":"Outcome of this validator against the measured value.","example":"PASS"},"operator":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Comparison operator (e.g. \">\", \"<=\", \"==\"). Null for expression-only validators.","example":"<="},"expected_value":{"anyOf":[{"type":"null"},{"type":"boolean"},{"type":"number"},{"type":"string"},{"type":"array","items":{"type":"number"}},{"type":"array","items":{"type":"string"}}],"description":"Expected value the operator compares against.","example":3.6},"expression":{"type":"string","description":"Human-readable validator expression.","example":"x <= 3.6"},"is_decisive":{"anyOf":[{"type":"boolean"},{"type":"null"}],"description":"Whether this validator drove the measurement outcome. Null if unknown.","example":true},"is_expression_only":{"type":"boolean","description":"True when the validator is defined purely by a custom expression.","example":false},"analytics_expression":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Synthetic operator+value expression for analytics. Null if expression-only.","example":"<= 3.6"},"has_custom_expression":{"type":"boolean","description":"True when the user supplied a custom validator expression.","example":false}},"required":["outcome","operator","expected_value","expression","is_decisive","is_expression_only","analytics_expression","has_custom_expression"],"additionalProperties":false}},{"type":"null"}],"description":"Validators applied to this measurement. Null when none."}},"required":["id","phase_name","measurement_name","started_at","value","bool_value","string_value","units","measurement_outcome","run_id","serial_number","sample","measurement_type","retry_count","is_final_attempt","validators"],"additionalProperties":false},"description":"The list of measurements matching the request."},"meta":{"type":"object","properties":{"has_more":{"type":"boolean","description":"Whether more measurements are available beyond this page.","example":true},"next_cursor":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}],"description":"Cursor to fetch the next page. Null when there are no more results.","example":50}},"required":["has_more","next_cursor"],"additionalProperties":false,"description":"Pagination metadata."}},"required":["data","meta"],"additionalProperties":false}}}},"400":{"description":"{message}","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBADREQUEST"}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorUNAUTHORIZED"}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorINTERNALSERVERERROR"}}}}},"x-access":[{"level":"full","authType":"user","description":"Users can read runs"},{"level":"limited","authType":"station","description":"Stations cannot read runs"}],"x-speakeasy-name-override":"list"}},"/v2/measurements/{id}":{"get":{"operationId":"measurement-get","summary":"Get measurement","description":"Get a single measurement by ID, with its value, validators, and run context.","tags":["Measurements"],"security":[{"api_key":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"ID of the measurement to retrieve."}],"responses":{"200":{"description":"Measurement retrieved successfully","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"name":{"type":"string"},"outcome":{"type":"string","enum":["PASS","FAIL","UNSET"]},"units":{"anyOf":[{"type":"string"},{"type":"null"}]},"validators":{"anyOf":[{"type":"array","items":{"type":"object","properties":{"outcome":{"type":"string","enum":["PASS","FAIL","UNSET"],"description":"Validation result: PASS, FAIL, or UNSET.","example":"PASS"},"operator":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Comparison operator used for validation.","example":">="},"expected_value":{"anyOf":[{"anyOf":[{"type":"null"},{"type":"boolean"},{"type":"number"},{"type":"string"},{"type":"array","items":{"type":"number"}},{"type":"array","items":{"type":"string"}}]},{"type":"null"}],"description":"Expected value for comparison. Type depends on measurement type.","example":3},"expression":{"type":"string","description":"Human-readable expression string for display.","example":"x >= 3.0"},"is_decisive":{"anyOf":[{"type":"boolean"},{"type":"null"}],"description":"Whether this validator is decisive (if it fails, measurement fails). False for marginal/warning validators."},"is_expression_only":{"type":"boolean","description":"True if validator only has expression (no structured operator/expected_value)."},"analytics_expression":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Synthetic expression from operator+expected_value for analytics tooltip. Null if expression-only."},"has_custom_expression":{"type":"boolean","description":"True if user provided a custom expression (shown in italic with analytics tooltip)."}},"required":["outcome","operator","expected_value","expression","is_decisive","is_expression_only","analytics_expression","has_custom_expression"],"additionalProperties":false,"description":"Validator result with outcome and comparison details."}},{"type":"null"}]},"aggregations":{"anyOf":[{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","description":"Unique identifier for the aggregation."},"type":{"type":"string","description":"Aggregation type (e.g., MIN, MAX, MEAN, RANGE, STD_DEV).","example":"MEAN"},"outcome":{"anyOf":[{"type":"string","enum":["PASS","FAIL","UNSET"]},{"type":"null"}],"description":"Aggregation validation result: PASS, FAIL, UNSET, or null if no validators.","example":"PASS"},"value":{"anyOf":[{"anyOf":[{"type":"number"},{"type":"string"},{"type":"boolean"}]},{"type":"null"}],"description":"Computed aggregation value. Type depends on aggregation type.","example":42.5},"unit":{"description":"Unit of measurement for the aggregated value.","example":"V","anyOf":[{"type":"string"},{"type":"null"}]},"validators":{"description":"Validators applied to the aggregated value.","anyOf":[{"type":"array","items":{"type":"object","properties":{"outcome":{"type":"string","enum":["PASS","FAIL","UNSET"],"description":"Validation result: PASS, FAIL, or UNSET.","example":"PASS"},"operator":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Comparison operator used for validation.","example":">="},"expected_value":{"anyOf":[{"anyOf":[{"type":"null"},{"type":"boolean"},{"type":"number"},{"type":"string"},{"type":"array","items":{"type":"number"}},{"type":"array","items":{"type":"string"}}]},{"type":"null"}],"description":"Expected value for comparison. Type depends on measurement type.","example":3},"expression":{"type":"string","description":"Human-readable expression string for display.","example":"x >= 3.0"},"is_decisive":{"anyOf":[{"type":"boolean"},{"type":"null"}],"description":"Whether this validator is decisive (if it fails, measurement fails). False for marginal/warning validators."},"is_expression_only":{"type":"boolean","description":"True if validator only has expression (no structured operator/expected_value)."},"analytics_expression":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Synthetic expression from operator+expected_value for analytics tooltip. Null if expression-only."},"has_custom_expression":{"type":"boolean","description":"True if user provided a custom expression (shown in italic with analytics tooltip)."}},"required":["outcome","operator","expected_value","expression","is_decisive","is_expression_only","analytics_expression","has_custom_expression"],"additionalProperties":false,"description":"Validator result with outcome and comparison details."}},{"type":"null"}]}},"required":["id","type","outcome","value"],"additionalProperties":false,"description":"Aggregation result with computed value and optional validators."}},{"type":"null"}]},"measured_value":{"anyOf":[{"type":"number"},{"type":"string"},{"type":"boolean"},{"type":"array","items":{"type":"array","items":{"type":"number"}}},{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{}},{"type":"array","items":{}}]},"data_series":{"type":"array","items":{"type":"object","properties":{"data":{"type":"array","items":{"type":"number"}},"units":{"anyOf":[{"type":"string"},{"type":"null"}]},"name":{"anyOf":[{"type":"string"},{"type":"null"}]},"description":{"anyOf":[{"type":"string"},{"type":"null"}]},"validators":{"anyOf":[{"type":"array","items":{"type":"object","properties":{"outcome":{"type":"string","enum":["PASS","FAIL","UNSET"],"description":"Validation result: PASS, FAIL, or UNSET.","example":"PASS"},"operator":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Comparison operator used for validation.","example":">="},"expected_value":{"anyOf":[{"anyOf":[{"type":"null"},{"type":"boolean"},{"type":"number"},{"type":"string"},{"type":"array","items":{"type":"number"}},{"type":"array","items":{"type":"string"}}]},{"type":"null"}],"description":"Expected value for comparison. Type depends on measurement type.","example":3},"expression":{"type":"string","description":"Human-readable expression string for display.","example":"x >= 3.0"},"is_decisive":{"anyOf":[{"type":"boolean"},{"type":"null"}],"description":"Whether this validator is decisive (if it fails, measurement fails). False for marginal/warning validators."},"is_expression_only":{"type":"boolean","description":"True if validator only has expression (no structured operator/expected_value)."},"analytics_expression":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Synthetic expression from operator+expected_value for analytics tooltip. Null if expression-only."},"has_custom_expression":{"type":"boolean","description":"True if user provided a custom expression (shown in italic with analytics tooltip)."}},"required":["outcome","operator","expected_value","expression","is_decisive","is_expression_only","analytics_expression","has_custom_expression"],"additionalProperties":false,"description":"Validator result with outcome and comparison details."}},{"type":"null"}]},"aggregations":{"anyOf":[{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","description":"Unique identifier for the aggregation."},"type":{"type":"string","description":"Aggregation type (e.g., MIN, MAX, MEAN, RANGE, STD_DEV).","example":"MEAN"},"outcome":{"anyOf":[{"type":"string","enum":["PASS","FAIL","UNSET"]},{"type":"null"}],"description":"Aggregation validation result: PASS, FAIL, UNSET, or null if no validators.","example":"PASS"},"value":{"anyOf":[{"anyOf":[{"type":"number"},{"type":"string"},{"type":"boolean"}]},{"type":"null"}],"description":"Computed aggregation value. Type depends on aggregation type.","example":42.5},"unit":{"description":"Unit of measurement for the aggregated value.","example":"V","anyOf":[{"type":"string"},{"type":"null"}]},"validators":{"description":"Validators applied to the aggregated value.","anyOf":[{"type":"array","items":{"type":"object","properties":{"outcome":{"type":"string","enum":["PASS","FAIL","UNSET"],"description":"Validation result: PASS, FAIL, or UNSET.","example":"PASS"},"operator":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Comparison operator used for validation.","example":">="},"expected_value":{"anyOf":[{"anyOf":[{"type":"null"},{"type":"boolean"},{"type":"number"},{"type":"string"},{"type":"array","items":{"type":"number"}},{"type":"array","items":{"type":"string"}}]},{"type":"null"}],"description":"Expected value for comparison. Type depends on measurement type.","example":3},"expression":{"type":"string","description":"Human-readable expression string for display.","example":"x >= 3.0"},"is_decisive":{"anyOf":[{"type":"boolean"},{"type":"null"}],"description":"Whether this validator is decisive (if it fails, measurement fails). False for marginal/warning validators."},"is_expression_only":{"type":"boolean","description":"True if validator only has expression (no structured operator/expected_value)."},"analytics_expression":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Synthetic expression from operator+expected_value for analytics tooltip. Null if expression-only."},"has_custom_expression":{"type":"boolean","description":"True if user provided a custom expression (shown in italic with analytics tooltip)."}},"required":["outcome","operator","expected_value","expression","is_decisive","is_expression_only","analytics_expression","has_custom_expression"],"additionalProperties":false,"description":"Validator result with outcome and comparison details."}},{"type":"null"}]}},"required":["id","type","outcome","value"],"additionalProperties":false,"description":"Aggregation result with computed value and optional validators."}},{"type":"null"}]}},"required":["data","units"],"additionalProperties":false}},"docstring":{"anyOf":[{"type":"string"},{"type":"null"}]},"phase":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"name":{"type":"string"}},"required":["id","name"],"additionalProperties":false},"run":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"outcome":{"anyOf":[{"type":"string"},{"type":"null"}]},"serial_number":{"anyOf":[{"type":"string"},{"type":"null"}]}},"required":["id"],"additionalProperties":false},"procedure":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"name":{"type":"string"}},"required":["id","name"],"additionalProperties":false}},"required":["id","name","outcome","validators","phase","run","procedure"],"additionalProperties":false}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorUNAUTHORIZED"}}}},"404":{"description":"Measurement with ID {id} not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorNOTFOUND"}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorINTERNALSERVERERROR"}}}}},"x-access":[{"level":"full","authType":"user","description":"Users can read runs"},{"level":"limited","authType":"station","description":"Stations cannot read runs"}],"x-speakeasy-name-override":"get"}},"/v2/deployments":{"get":{"operationId":"deployment-list","summary":"List and filter deployments","description":"List deployments with filtering by procedure, environment, build status, branch, author, and date range. Cursor-paginated.","tags":["Deployments"],"security":[{"api_key":[]}],"parameters":[{"name":"procedure_ids","in":"query","required":false,"schema":{"description":"Filter deployments by procedure ID(s). Omit to list across all procedures.","example":["123e4567-e89b-12d3-a456-426614174000"],"type":"array","items":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"}}},{"name":"environments","in":"query","required":false,"schema":{"description":"Filter by deployment environment.","example":["production"],"type":"array","items":{"type":"string","enum":["production","preview","development"]}}},{"name":"build_statuses","in":"query","required":false,"schema":{"description":"Filter by build status.","example":["ready"],"type":"array","items":{"type":"string","enum":["pending","building","ready","failed"]}}},{"name":"pushed","in":"query","required":false,"schema":{"type":"boolean","description":"True = only deployments pushed to at least one station. False = only deployments not yet pushed.","example":true}},{"name":"branch_names","in":"query","required":false,"schema":{"description":"Filter by the git branch name of the deployment's commit.","example":["main"],"type":"array","items":{"type":"string"}}},{"name":"author_usernames","in":"query","required":false,"schema":{"description":"Filter by the commit author username.","example":["octocat"],"type":"array","items":{"type":"string"}}},{"name":"deployed_after","in":"query","required":false,"schema":{"type":"string","format":"date-time","pattern":"^(?:(?:\\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)))$","description":"Filter deployments created after this date (inclusive).","example":"2024-01-01T00:00:00Z"}},{"name":"deployed_before","in":"query","required":false,"schema":{"type":"string","format":"date-time","pattern":"^(?:(?:\\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)))$","description":"Filter deployments created before this date (inclusive).","example":"2024-12-31T23:59:59Z"}},{"name":"search_query","in":"query","required":false,"schema":{"type":"string","maxLength":256,"description":"Search deployments by commit message or SHA.","example":"fix build"}},{"name":"limit","in":"query","required":false,"schema":{"default":50,"description":"Maximum number of deployments to return.","example":50,"type":"integer","minimum":1,"maximum":100},"description":"Maximum number of deployments to return."},{"name":"cursor","in":"query","required":false,"schema":{"description":"Cursor for pagination. Use next_cursor from the previous response to fetch the next page.","example":50,"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"description":"Cursor for pagination. Use next_cursor from the previous response to fetch the next page."}],"responses":{"200":{"description":"Deployments retrieved successfully","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","description":"Unique identifier for the deployment.","example":"550e8400-e29b-41d4-a716-446655440000"},"environment":{"type":"string","enum":["production","preview","development"],"description":"Deployment environment.","example":"production"},"trigger":{"type":"string","enum":["auto","manual","cli"],"description":"How the deployment was triggered.","example":"auto"},"status":{"type":"string","enum":["pending","building","ready","failed"],"description":"Build status of the deployment.","example":"ready"},"skipped":{"type":"boolean","description":"True when an auto-push deployment was recorded for audit but never enqueued to build.","example":false},"started_at":{"anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\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))$"},{"type":"null"}],"description":"ISO 8601 timestamp when the build started. Null if not started.","example":"2024-01-15T10:30:00Z"},"ended_at":{"anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\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))$"},{"type":"null"}],"description":"ISO 8601 timestamp when the build ended. Null if not ended.","example":"2024-01-15T10:35:00Z"},"deployed_at":{"type":"string","format":"date-time","pattern":"^(?:(?:\\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))$","description":"ISO 8601 timestamp when the deployment was created.","example":"2024-01-15T10:25:00Z"},"procedure":{"anyOf":[{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"name":{"type":"string"}},"required":["id","name"],"additionalProperties":false},{"type":"null"}],"description":"Procedure this deployment targets."},"commit":{"anyOf":[{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"sha":{"type":"string"},"message":{"type":"string"},"author_username":{"type":"string"},"author_avatar_url":{"anyOf":[{"type":"string"},{"type":"null"}]},"committed_at":{"anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\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))$"},{"type":"null"}]},"branch":{"anyOf":[{"type":"string"},{"type":"null"}]}},"required":["id","sha","message","author_username","author_avatar_url","committed_at","branch"],"additionalProperties":false},{"type":"null"}],"description":"Git commit the deployment was built from. Null for non-git deployments."},"repository":{"anyOf":[{"type":"object","properties":{"provider":{"type":"string","enum":["github","gitlab"]}},"required":["provider"],"additionalProperties":false},{"type":"null"}],"description":"Source repository provider. Null for non-git deployments."},"stations":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"name":{"type":"string"}},"required":["id","name"],"additionalProperties":false},"description":"Stations this deployment has been pushed to."}},"required":["id","environment","trigger","status","skipped","started_at","ended_at","deployed_at","procedure","commit","repository","stations"],"additionalProperties":false},"description":"The list of deployments matching the request."},"meta":{"type":"object","properties":{"has_more":{"type":"boolean","description":"Whether more deployments are available beyond this page.","example":true},"next_cursor":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}],"description":"Cursor to fetch the next page. Null when there are no more results.","example":50}},"required":["has_more","next_cursor"],"additionalProperties":false,"description":"Pagination metadata."}},"required":["data","meta"],"additionalProperties":false}}}},"400":{"description":"{message}","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBADREQUEST"}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorUNAUTHORIZED"}}}},"404":{"description":"Procedure not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorNOTFOUND"}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorINTERNALSERVERERROR"}}}}},"x-access":[{"level":"full","authType":"user","description":"Users can read proceduredeployments"},{"level":"limited","authType":"station","description":"Stations cannot read proceduredeployments"}],"x-speakeasy-name-override":"list"}},"/v2/deployments/{id}":{"get":{"operationId":"deployment-get","summary":"Get deployment","description":"Get a deployment by ID, with its artifact metadata, commit, creator, and per-station push state.","tags":["Deployments"],"security":[{"api_key":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"The deployment ID to retrieve."}],"responses":{"200":{"description":"Deployment retrieved successfully","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","description":"Unique identifier for the deployment.","example":"550e8400-e29b-41d4-a716-446655440000"},"environment":{"type":"string","enum":["production","preview","development"],"description":"Deployment environment.","example":"production"},"trigger":{"type":"string","enum":["auto","manual","cli"],"description":"How the deployment was triggered.","example":"auto"},"status":{"type":"string","enum":["pending","building","ready","failed"],"description":"Build status of the deployment.","example":"ready"},"deployed_at":{"type":"string","format":"date-time","pattern":"^(?:(?:\\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))$","description":"ISO 8601 timestamp when the deployment was created.","example":"2024-01-15T10:25:00Z"},"started_at":{"anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\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))$"},{"type":"null"}],"description":"ISO 8601 timestamp when the build started. Null if not started.","example":"2024-01-15T10:30:00Z"},"ended_at":{"anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\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))$"},{"type":"null"}],"description":"ISO 8601 timestamp when the build ended. Null if not ended.","example":"2024-01-15T10:35:00Z"},"artifact_url":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"URL of the built artifact. Null if not built.","example":null},"artifact_sha256":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"SHA-256 checksum of the artifact. Null if not built.","example":null},"artifact_size_bytes":{"anyOf":[{"type":"number"},{"type":"null"}],"description":"Size of the artifact in bytes. Null if not built.","example":null},"deployment_mode":{"type":"string","enum":["sync","standalone"],"description":"Deployment mode.","example":"sync"},"platform":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Target platform. Null if unspecified.","example":"linux"},"language":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Procedure language. Null if unspecified.","example":"python"},"runtime_version":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Runtime version. Null if unspecified.","example":"3.12"},"procedure":{"anyOf":[{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"name":{"type":"string"}},"required":["id","name"],"additionalProperties":false},{"type":"null"}],"description":"Procedure this deployment targets."},"created_by_user":{"anyOf":[{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"name":{"type":"string"},"image":{"anyOf":[{"type":"string"},{"type":"null"}]}},"required":["id","name","image"],"additionalProperties":false},{"type":"null"}],"description":"User who created the deployment. Null for system-created deployments."},"commit":{"anyOf":[{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"sha":{"type":"string"},"message":{"type":"string"},"author_username":{"type":"string"},"author_avatar_url":{"anyOf":[{"type":"string"},{"type":"null"}]},"committed_at":{"anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\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))$"},{"type":"null"}]},"branch":{"anyOf":[{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"name":{"type":"string"}},"required":["id","name"],"additionalProperties":false},{"type":"null"}]},"repository":{"anyOf":[{"type":"object","properties":{"full_name":{"type":"string"},"provider":{"type":"string","enum":["github","gitlab"]}},"required":["full_name","provider"],"additionalProperties":false},{"type":"null"}]}},"required":["id","sha","message","author_username","author_avatar_url","committed_at","branch","repository"],"additionalProperties":false},{"type":"null"}],"description":"Git commit the deployment was built from. Null for non-git deployments."},"stations":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"name":{"type":"string"},"image_url":{"anyOf":[{"type":"string"},{"type":"null"}]},"pushed_at":{"anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\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))$"},{"type":"null"}]}},"required":["id","name","image_url","pushed_at"],"additionalProperties":false},"description":"Stations linked to the procedure, with per-station push state. pushed_at is null when this deployment has not been pushed to that station."},"build_logs":{"type":"array","items":{"type":"object","properties":{"seq":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Sequence number ordering the log line within the build.","example":0},"level":{"type":"string","enum":["DEBUG","INFO","WARNING","ERROR","CRITICAL"],"description":"Severity of the build log line.","example":"INFO"},"message":{"type":"string","description":"Build log line content.","example":"Installing dependencies..."},"created_at":{"type":"string","format":"date-time","pattern":"^(?:(?:\\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))$","description":"ISO 8601 timestamp when the log line was emitted.","example":"2024-01-15T10:30:00Z"}},"required":["seq","level","message","created_at"],"additionalProperties":false},"description":"Build log lines for this deployment, ordered by sequence. Empty if the build has not produced logs."}},"required":["id","environment","trigger","status","deployed_at","started_at","ended_at","artifact_url","artifact_sha256","artifact_size_bytes","deployment_mode","platform","language","runtime_version","procedure","created_by_user","commit","stations","build_logs"],"additionalProperties":false}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorUNAUTHORIZED"}}}},"404":{"description":"Deployment with ID {id} not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorNOTFOUND"}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorINTERNALSERVERERROR"}}}}},"x-access":[{"level":"full","authType":"user","description":"Users can read proceduredeployments"},{"level":"limited","authType":"station","description":"Stations cannot read proceduredeployments"}],"x-speakeasy-name-override":"get"}}},"components":{"securitySchemes":{"api_key":{"type":"http","scheme":"bearer","bearerFormat":"UUID","description":"API key for authentication. Use format: Bearer YOUR_API_KEY"}},"schemas":{"ErrorBADREQUEST":{"type":"object","properties":{"message":{"type":"string","description":"The error message","example":"Bad request"},"code":{"type":"string","description":"The error code","example":"BAD_REQUEST"},"issues":{"description":"An array of issues that were responsible for the error","example":[],"type":"array","items":{"type":"object","properties":{"message":{"type":"string"}},"required":["message"],"additionalProperties":false}}},"required":["message","code"],"additionalProperties":false,"description":"Bad request error"},"ErrorUNAUTHORIZED":{"type":"object","properties":{"message":{"type":"string","description":"The error message","example":"Unauthorized"},"code":{"type":"string","description":"The error code","example":"UNAUTHORIZED"},"issues":{"description":"An array of issues that were responsible for the error","example":[],"type":"array","items":{"type":"object","properties":{"message":{"type":"string"}},"required":["message"],"additionalProperties":false}}},"required":["message","code"],"additionalProperties":false,"description":"Unauthorized error"},"ErrorFORBIDDEN":{"type":"object","properties":{"message":{"type":"string","description":"The error message","example":"Forbidden"},"code":{"type":"string","description":"The error code","example":"FORBIDDEN"},"issues":{"description":"An array of issues that were responsible for the error","example":[],"type":"array","items":{"type":"object","properties":{"message":{"type":"string"}},"required":["message"],"additionalProperties":false}}},"required":["message","code"],"additionalProperties":false,"description":"Forbidden error"},"ErrorNOTFOUND":{"type":"object","properties":{"message":{"type":"string","description":"The error message","example":"Not found"},"code":{"type":"string","description":"The error code","example":"NOT_FOUND"},"issues":{"description":"An array of issues that were responsible for the error","example":[],"type":"array","items":{"type":"object","properties":{"message":{"type":"string"}},"required":["message"],"additionalProperties":false}}},"required":["message","code"],"additionalProperties":false,"description":"Not found error"},"ErrorCONFLICT":{"type":"object","properties":{"message":{"type":"string","description":"The error message","example":"Conflict"},"code":{"type":"string","description":"The error code","example":"CONFLICT"},"issues":{"description":"An array of issues that were responsible for the error","example":[],"type":"array","items":{"type":"object","properties":{"message":{"type":"string"}},"required":["message"],"additionalProperties":false}}},"required":["message","code"],"additionalProperties":false,"description":"Conflict error"},"ErrorUNPROCESSABLECONTENT":{"type":"object","properties":{"message":{"type":"string","description":"The error message","example":"Unprocessable content"},"code":{"type":"string","description":"The error code","example":"UNPROCESSABLE_CONTENT"},"issues":{"description":"An array of issues that were responsible for the error","example":[],"type":"array","items":{"type":"object","properties":{"message":{"type":"string"}},"required":["message"],"additionalProperties":false}}},"required":["message","code"],"additionalProperties":false,"description":"Unprocessable content error"},"ErrorINTERNALSERVERERROR":{"type":"object","properties":{"message":{"type":"string","description":"The error message","example":"Internal server error"},"code":{"type":"string","description":"The error code","example":"INTERNAL_SERVER_ERROR"},"issues":{"description":"An array of issues that were responsible for the error","example":[],"type":"array","items":{"type":"object","properties":{"message":{"type":"string"}},"required":["message"],"additionalProperties":false}}},"required":["message","code"],"additionalProperties":false,"description":"Internal server error error"},"ErrorBADGATEWAY":{"type":"object","properties":{"message":{"type":"string","description":"The error message","example":"Bad gateway"},"code":{"type":"string","description":"The error code","example":"BAD_GATEWAY"},"issues":{"description":"An array of issues that were responsible for the error","example":[],"type":"array","items":{"type":"object","properties":{"message":{"type":"string"}},"required":["message"],"additionalProperties":false}}},"required":["message","code"],"additionalProperties":false,"description":"Bad gateway error"}}}}