Work Instructions API
This API is in active development and may change without notice. It is designed for programmatic creation of work instructions and does not have feature parity with the Pico Manage UI. Use with caution — it will overwrite changes made through the UI.
The Work Instructions API allows you to programmatically create and update processes, products, and stations in Pico. This is useful for:
- Migrating work instructions from other systems
- Generating instructions from external data sources (PLM, CAD, etc.)
- Automating instruction creation as part of a CI/CD pipeline
Overview
The API consists of three main mutations:
| Mutation | Description |
|---|---|
processCreate | Create or update a process with steps and actions |
productCreate | Create or update a product workflow with process dependencies |
stationCreate | Create or update a station |
All IDs must match the pattern ^[a-z0-9_]{3,50}$ (case-insensitive, 3-50 characters, alphanumeric and underscores only).
Authentication
All requests require the x-pico-api-org header with your API token:
x-pico-api-org: YOUR_API_TOKEN
See the Authentication guide for details on obtaining an API token.
Creating a Process
A process consists of steps, and each step contains actions that operators perform.
mutation CreateProcess($input: ProcessCreateInput!) {
processCreate(input: $input)
}
Basic Example
curl -X POST https://example.picomes.io/graph/v2 \
-H "Content-Type: application/json" \
-H "x-pico-api-org: YOUR_API_TOKEN" \
-d '{
"query": "mutation CreateProcess($input: ProcessCreateInput!) { processCreate(input: $input) }",
"variables": {
"input": {
"process": {
"id": "assembly_step_1",
"name": "Main Assembly",
"description": "Assemble the main components",
"steps": [
{
"id": "step_1",
"name": "Attach Component A",
"instructionText": {"text": "Secure component A to the base plate"},
"actions": [
{
"id": "action_1",
"description": {"text": "Align mounting holes"}
},
{
"id": "action_2",
"description": {"text": "Insert and tighten bolts"},
"toolUsed": {"id": "torque_wrench", "name": "Torque Wrench"},
"confirmation": {"confirmed": "Bolts torqued to spec"}
}
]
}
]
}
}
}
}'
Process Options
| Field | Type | Description |
|---|---|---|
id | String! | Unique process identifier |
name | String! | Display name |
description | String | Process description |
partNumber | String | Associated part number |
startBehavior | Enum | CONFIRM (default) or IMMEDIATE |
endBehavior | Enum | SUMMARY (default), EXIT, RESTART, or NEXT_PROCESS |
autoSignoutMinutes | Int | Auto sign-out timeout |
steps | [StepInput!] | List of steps |
image | ImageInput | Process thumbnail image |
Step Structure
Each step can contain:
| Field | Type | Description |
|---|---|---|
id | String! | Unique step identifier |
name | String | Step name |
instructionText | StyledTextInput | Main instruction text |
primaryImage | ImageInput | Step instruction image |
video | VideoInput | Step instruction video |
actions | [ActionInput!] | Actions in this step |
alerts | [AlertInput!] | Alert boxes |
notes | [InstructionNoteInput!] | Note boxes |
Action Structure
Actions represent individual operator tasks:
| Field | Type | Description |
|---|---|---|
id | String! | Unique action identifier |
description | StyledTextInput | Action description |
inputParts | [InputPartInput!] | Parts consumed |
outputPart | PartInput | Part produced/modified |
toolUsed | ToolInput | Tool required |
measurement | MeasurementInput | Measurement to record |
confirmation | ConfirmationInput | Confirmation required |
Parts and Tools
{
"inputParts": [
{
"part": {
"id": "bolt_m8",
"description": "M8 Hex Bolt",
"serial": {
"id": "bolt_serial",
"name": "Bolt Serial",
"pattern": "^BOLT-[0-9]+$"
}
},
"quantity": 4
}
],
"toolUsed": {
"id": "torque_wrench_25nm",
"name": "25Nm Torque Wrench",
"description": "Calibrated torque wrench"
}
}
Measurements and Confirmations
{
"measurement": {
"measured": "Torque value",
"units": "torque-Nm",
"min": 23.0,
"max": 27.0
},
"confirmation": {
"confirmed": "Component is flush with surface"
}
}
Creating a Product
Products define workflows by linking processes together with dependencies.
mutation CreateProduct($input: ProductCreateInput!) {
productCreate(input: $input)
}
Example
curl -X POST https://example.picomes.io/graph/v2 \
-H "Content-Type: application/json" \
-H "x-pico-api-org: YOUR_API_TOKEN" \
-d '{
"query": "mutation CreateProduct($input: ProductCreateInput!) { productCreate(input: $input) }",
"variables": {
"input": {
"product": {
"id": "widget_assembly",
"name": "Widget Assembly",
"finalProcessId": "final_inspection",
"dependencies": [
{
"processId": "final_inspection",
"upstreamProcessId": "sub_assembly_a",
"quantity": 2
},
{
"processId": "final_inspection",
"upstreamProcessId": "sub_assembly_b",
"quantity": 1
}
]
}
}
}
}'
The dependencies array defines the workflow DAG:
processId: The downstream processupstreamProcessId: The process that must complete firstquantity: How many times the upstream process must complete
Creating a Station
mutation CreateStation($input: StationCreateInput!) {
stationCreate(input: $input)
}
curl -X POST https://example.picomes.io/graph/v2 \
-H "Content-Type: application/json" \
-H "x-pico-api-org: YOUR_API_TOKEN" \
-d '{
"query": "mutation CreateStation($input: StationCreateInput!) { stationCreate(input: $input) }",
"variables": {
"input": {
"station": {
"id": "station_01",
"name": "Assembly Station 1"
}
}
}
}'
Uploading Images
See the Media Upload API guide for details on uploading step images and videos.
Complete Example
Here's a Python script that creates a complete product with processes and images:
import json
import urllib.request
GRAPHQL_ENDPOINT = "https://example.picomes.io/graph/v2"
UPLOAD_ENDPOINT = "https://example.picomes.io/uploads"
API_TOKEN = "YOUR_API_TOKEN"
def gql(query, variables=None):
payload = json.dumps({"query": query, "variables": variables or {}}).encode()
req = urllib.request.Request(
GRAPHQL_ENDPOINT,
data=payload,
headers={
"Content-Type": "application/json",
"x-pico-api-org": API_TOKEN
}
)
with urllib.request.urlopen(req) as resp:
return json.loads(resp.read().decode())
def upload_image(file_path):
# See Media Upload API guide for implementation
pass
# Create a process
gql("""
mutation CreateProcess($input: ProcessCreateInput!) {
processCreate(input: $input)
}
""", {
"input": {
"process": {
"id": "my_process",
"name": "My Process",
"steps": [
{
"id": "step_1",
"name": "First Step",
"instructionText": {"text": "Do the thing"},
"actions": [
{"id": "action_1", "description": {"text": "Action description"}}
]
}
]
}
}
})
Automatic Translations
The API performs automatic translations based on action content:
Torque Actions
Actions containing keywords like "tighten," "screw," or "wrench" in the description or tool are automatically flagged as torque actions and grouped by tool within each step.
Scans
A scan action is added for any Part with a serial field the first time that part appears in an action.
BOM (Bill of Materials)
Input parts are automatically added to the process BOM if:
- The part hasn't previously been listed as an output
- The part is not associated with an action that includes both confirmation and measurement fields
Limitations
- This API does not have feature parity with the Pico Manage UI
- Updating a process will overwrite all changes made through the UI
- No validation is performed on serial number patterns
- Image/video uploads must be done separately via the Media Upload API