EightyOnedocseightyone.app

EightyOne capabilities

Every operation EightyOne exposes to code and agents. Each is one capability: the REST API (/api/v1, OpenAPI at /api/v1/openapi.json) and the MCP server (/mcp) are generated from these definitions, so they cannot disagree.

Account

me.get: Who am I

The caller: the user this credential acts as, the company it is bound to, how it is calling (REST or MCP; human, agent or service account) and the permissions it actually has here (the union of the user's roles' groups ∩ the credential's permissions). Call it first to know what you can do.

REST: GET /api/v1/me · Permission: any member of the company · Effect: read · MCP: tool me_get

Output

Field Type Required Description
user object yes
company object yes
actorType human | agent | service yes
channel string yes
permissions string[] yes

Guides

guide.get: Read a guide

EightyOne concepts and how to read the data: the glossary, downtime, maintenance, production, inventory, quality, commissioning, what deserves attention, and this company's own guidance (topic "company"). Without a topic, lists the topics. Read the glossary before working on an unfamiliar area.

REST: GET /api/v1/guides · Permission: any member of the company · Effect: read · MCP: tool guide_get

Input

Field Type Required Description
topic glossary | downtime | maintenance | production | inventory | quality | commissioning | signals | company "company": what this company's administrators tell agents, including notes on specific machines

Output

Field Type Required Description
topic string | null yes
title string yes
body string yes Markdown
topics object[] yes

guidance.list: List company guidance for agents

What the company's administrators tell every AI agent: company-wide guidance and notes on specific machines, work centers, products and task types, with any thresholds they set.

REST: GET /api/v1/guidance · Permission: any member of the company · Effect: read · MCP: via capabilities_call

Output: { data, pagination }, each item:

Field Type Required Description
subject company | ssu | work_center | product | task_type yes
ref string | null yes The SSU / product / task type external id, or the work center name
name string | null yes What it's about, by name
body string yes
thresholds object yes
version integer yes
reviewedAt string (date-time) | null yes
updatedAt string (date-time) yes

guidance.set: Set company guidance for agents

Write the guidance agents get for the company, or for one machine, work center, product or task type. Replaces that subject's text; the previous version is kept in the audit log. Every agent connected to the company follows it.

REST: PUT /api/v1/guidance · Permission: ai_guidance:manage · Effect: write · Idempotency-Key: accepted · Dry run: supported · MCP: no

Input

Field Type Required Description
subject company | ssu | work_center | product | task_type yes
ref string Which one (not for company): SSU external id, work center name, product external id or SKU, task type external id
body string yes Plain text or Markdown. Company: up to 4000 characters; one subject: 1000
thresholds object
reviewed boolean | true | false Mark it as reviewed now (agents see how fresh it is)

Output

Field Type Required Description
subject company | ssu | work_center | product | task_type yes
ref string | null yes The SSU / product / task type external id, or the work center name
name string | null yes What it's about, by name
body string yes
thresholds object yes
version integer yes
reviewedAt string (date-time) | null yes
updatedAt string (date-time) yes

guidance.delete: Remove company guidance for agents

Remove the guidance for the company or one subject. The audit log keeps what it said.

REST: DELETE /api/v1/guidance · Permission: ai_guidance:manage · Effect: destructive · Idempotency-Key: accepted · Dry run: supported · MCP: no

Input

Field Type Required Description
subject company | ssu | work_center | product | task_type yes
ref string

Tasks

tasks.list: List tasks

Tasks, newest first. Everything in EightyOne is a task (work-order operations, maintenance, inspections, NCRs, approvals…). Open tasks only unless a status is given or includeCompleted=true. Without the 'See all tasks' permission you see only tasks assigned to you, plus your teams' tasks with 'See tasks for my team'.

REST: GET /api/v1/tasks · Permission: any member of the company · Effect: read · MCP: tool tasks_list

Input

Field Type Required Description
limit integer Page size (1–100, default 50)
offset integer Rows to skip
status open | preparation | ready | dispatched | submitted | incomplete | done | declined
typeId string Task type external id
ssuId string SSU external id
includeCompleted boolean | true | false Include done and declined tasks

Output: { data, pagination }, each item:

Field Type Required Description
id string yes Task external id
title string yes
details string | null yes
status string yes
startDate string (date-time) | null yes
endDate string (date-time) | null yes
dueDate string (date-time) | null yes
priorityId integer yes
typeId string | null yes Task type external id
team object | null yes The team whose members see and take this task: its task type's team (change it on the type)
ssuId string | null yes SSU external id
externalSystemId string | null yes Your id for the task
incompleteReason string | null yes
declinedReason string | null yes
isPartialCompletion boolean yes Completed in part; a follow-up task carries the rest
handoffRole proxy | mirror | null yes proxy: you sent it to a partner; mirror: a partner sent it to you
problemCodeId integer | null yes Failure coding: what was wrong
causeCodeId integer | null yes Failure coding: why
remedyCodeId integer | null yes Failure coding: what fixed it
createdAt string (date-time) yes
updatedAt string (date-time) yes

tasks.get: Get a task

One task by its id.

REST: GET /api/v1/tasks/:id · Permission: any member of the company · Effect: read · MCP: tool tasks_get

Input

Field Type Required Description
id string yes

Output

Field Type Required Description
id string yes Task external id
title string yes
details string | null yes
status string yes
startDate string (date-time) | null yes
endDate string (date-time) | null yes
dueDate string (date-time) | null yes
priorityId integer yes
typeId string | null yes Task type external id
team object | null yes The team whose members see and take this task: its task type's team (change it on the type)
ssuId string | null yes SSU external id
externalSystemId string | null yes Your id for the task
incompleteReason string | null yes
declinedReason string | null yes
isPartialCompletion boolean yes Completed in part; a follow-up task carries the rest
handoffRole proxy | mirror | null yes proxy: you sent it to a partner; mirror: a partner sent it to you
problemCodeId integer | null yes Failure coding: what was wrong
causeCodeId integer | null yes Failure coding: why
remedyCodeId integer | null yes Failure coding: what fixed it
createdAt string (date-time) yes
updatedAt string (date-time) yes

tasks.create: Create a task

Create a task of a task type, exactly as the dashboard does: the type's defaults apply (SLA due date, default assignee, transit, created-as-ready), and the task.created webhook fires. Needs 'Create tasks' unless the type is user-generated.

REST: POST /api/v1/tasks · Permission: any member of the company · Effect: write · Idempotency-Key: accepted · Dry run: preview (checks the change and lists its effects, without making it) · MCP: tool tasks_create

Input

Field Type Required Description
typeId string yes Task type external id
title string yes
details string
status open | preparation | ready | dispatched | submitted | incomplete | done
startDate string (date-time) | string (date)
endDate string (date-time) | string (date)
dueDate string (date-time) | string (date) Defaults to the type's SLA for the priority
priorityId integer
ssuId string SSU external id
externalSystemId string
fromStorageUnitId integer
toStorageUnitId integer
fromVendorId integer
toVendorId integer
assigneeIds integer[] Personnel ids
incompleteReason string Required when status is 'incomplete'
after object Link the new task to an existing one: dependency (it waits for that task) or follow

Output

Field Type Required Description
id string yes Task external id
title string yes
details string | null yes
status string yes
startDate string (date-time) | null yes
endDate string (date-time) | null yes
dueDate string (date-time) | null yes
priorityId integer yes
typeId string | null yes Task type external id
team object | null yes The team whose members see and take this task: its task type's team (change it on the type)
ssuId string | null yes SSU external id
externalSystemId string | null yes Your id for the task
incompleteReason string | null yes
declinedReason string | null yes
isPartialCompletion boolean yes Completed in part; a follow-up task carries the rest
handoffRole proxy | mirror | null yes proxy: you sent it to a partner; mirror: a partner sent it to you
problemCodeId integer | null yes Failure coding: what was wrong
causeCodeId integer | null yes Failure coding: why
remedyCodeId integer | null yes Failure coding: what fixed it
createdAt string (date-time) yes
updatedAt string (date-time) yes

tasks.update: Update a task

Change a task, with the dashboard's rules: status changes need 'Change task status from mobile' (assignees may still complete their own work), reassigning needs 'Reassign tasks', blocked tasks can't progress, producing tasks complete with goodQuantity / scrapQuantity (counts during the run: tasks_record_counts), maintenance types may need failure codes (problemCodeId, causeCodeId, remedyCodeId) to complete, 'incomplete' needs a reason and can create a follow-up (createFollowUp), 'declined' needs a reason. Tasks sent to a partner only accept details, dueDate and priorityId.

REST: PATCH /api/v1/tasks/:id · Permission: any member of the company · Effect: write · Idempotency-Key: accepted · Dry run: preview (checks the change and lists its effects, without making it) · MCP: tool tasks_update

Input

Field Type Required Description
id string yes
title string
details string
status open | preparation | ready | dispatched | submitted | incomplete | done | declined
startDate string (date-time) | string (date) | null
endDate string (date-time) | string (date) | null
dueDate string (date-time) | string (date) | null
priorityId integer
ssuId string | null SSU external id, or null to clear
externalSystemId string
assigneeIds integer[] Personnel ids: replaces the assignees
incompleteReason string
declinedReason string
createFollowUp boolean With status 'incomplete': create a follow-up task for the rest
goodQuantity number
scrapQuantity number
scrapReasonCodeId integer
problemCodeId integer Failure coding (reason_codes_list kind failure_problem); types that require it can't complete without all three
causeCodeId integer Failure coding: kind failure_cause
remedyCodeId integer Failure coding: kind failure_remedy

Output

Field Type Required Description
id string yes Task external id
title string yes
details string | null yes
status string yes
startDate string (date-time) | null yes
endDate string (date-time) | null yes
dueDate string (date-time) | null yes
priorityId integer yes
typeId string | null yes Task type external id
team object | null yes The team whose members see and take this task: its task type's team (change it on the type)
ssuId string | null yes SSU external id
externalSystemId string | null yes Your id for the task
incompleteReason string | null yes
declinedReason string | null yes
isPartialCompletion boolean yes Completed in part; a follow-up task carries the rest
handoffRole proxy | mirror | null yes proxy: you sent it to a partner; mirror: a partner sent it to you
problemCodeId integer | null yes Failure coding: what was wrong
causeCodeId integer | null yes Failure coding: why
remedyCodeId integer | null yes Failure coding: what fixed it
createdAt string (date-time) yes
updatedAt string (date-time) yes
_meta object yes

tasks.record_counts: Record production counts

Add good and scrap quantities to a running work-order operation or producing task, as operators do from the app. Counts add up and feed OEE; the output posts to stock once, when the task completes. To count at completion instead, pass goodQuantity / scrapQuantity to tasks.update with the status.

REST: POST /api/v1/tasks/:id/counts · Permission: any member of the company · Effect: write · Idempotency-Key: accepted · Dry run: supported · MCP: tool tasks_record_counts

Input

Field Type Required Description
id string yes Task external id
goodQuantity number
scrapQuantity number
scrapReasonCodeId integer A scrap reason (reason_codes_list, kind scrap)

Output

Field Type Required Description
id string yes
goodQuantity number yes
scrapQuantity number yes
scrapReasonCodeId integer | null yes

tasks.connect: Connect two tasks

Link two tasks. 'dependency': the second waits for the first. It can't progress until the first is done, and goes back to open if it was already ready or dispatched (it becomes ready if the first is already done). 'follow': only records that the second follows the first. Connections are removed in the dashboard.

REST: POST /api/v1/tasks/:from/connections · Permission: any member of the company · Effect: write · Idempotency-Key: accepted · Dry run: supported · MCP: tool tasks_connect

Input

Field Type Required Description
from string yes The first task's external id
to string yes The external id of the task that waits for or follows it
type dependency | follow yes
description string

Output

Field Type Required Description
from string yes
to string yes
type string yes
description string | null yes
toStatus string yes The second task's status after connecting

tasks.delete: Delete a task

Delete a task, as the dashboard does: a task you sent to a partner withdraws the handoff; a task a partner sent you can't be deleted (decline it instead).

REST: DELETE /api/v1/tasks/:id · Permission: tasks:delete · Effect: destructive · Idempotency-Key: accepted · Dry run: not supported · MCP: no

Input

Field Type Required Description
id string yes

tasks.get_form: A task's form

The fields a task's form records, in order: type, whether it's required, the choices of a select, the limits of a measurement, whether a condition hides it, and the current answer. Answer them with tasks_submit_form.

REST: GET /api/v1/tasks/:id/form · Permission: any member of the company · Effect: read · MCP: tool tasks_get_form

Input

Field Type Required Description
id string yes Task external id

Output

Field Type Required Description
id string yes
fields object[] yes

tasks.submit_form: Fill in a task's form

Answer a task's form fields by title (tasks_get_form lists them), and optionally complete the task (status done or submitted) or mark it incomplete, as the app does. Completing needs every required field; measurements outside their limits open an NCR; machine-status fields set the machine's status. Counts and failure codes go with the completion, as in tasks_update. Preview it first.

REST: POST /api/v1/tasks/:id/form · Permission: any member of the company · Effect: write · Idempotency-Key: accepted · Dry run: preview (checks the change and lists its effects, without making it) · MCP: tool tasks_submit_form

Input

Field Type Required Description
id string yes Task external id
answers object[] yes Answers by field title; fields left out keep their answer
status done | submitted | incomplete Complete it (done, or submitted for review) or mark it incomplete; leave out to only save the answers
incompleteReason string
createFollowUp boolean
goodQuantity number
scrapQuantity number
scrapReasonCodeId integer
problemCodeId integer
causeCodeId integer
remedyCodeId integer

Output

Field Type Required Description
id string yes Task external id
title string yes
details string | null yes
status string yes
startDate string (date-time) | null yes
endDate string (date-time) | null yes
dueDate string (date-time) | null yes
priorityId integer yes
typeId string | null yes Task type external id
team object | null yes The team whose members see and take this task: its task type's team (change it on the type)
ssuId string | null yes SSU external id
externalSystemId string | null yes Your id for the task
incompleteReason string | null yes
declinedReason string | null yes
isPartialCompletion boolean yes Completed in part; a follow-up task carries the rest
handoffRole proxy | mirror | null yes proxy: you sent it to a partner; mirror: a partner sent it to you
problemCodeId integer | null yes Failure coding: what was wrong
causeCodeId integer | null yes Failure coding: why
remedyCodeId integer | null yes Failure coding: what fixed it
createdAt string (date-time) yes
updatedAt string (date-time) yes
failedChecks string[] yes
ncrId string | null yes

Task types

task_types.list: List task types

The company's task types: the templates every task is created from (work orders' operations, maintenance, NCRs, inspections, approvals…), alphabetically. Use a type's id as typeId when creating a task.

REST: GET /api/v1/task-types · Permission: any member of the company · Effect: read · MCP: tool task_types_list

Input

Field Type Required Description
limit integer Page size (1–100, default 50)
offset integer Rows to skip

Output: { data, pagination }, each item:

Field Type Required Description
id string yes Task type external id
typeName string yes
color string | null yes
isQuote boolean yes
isUserGenerated boolean yes Field users may create tasks of this type themselves
isDataRequest boolean yes Tasks of this type ask a partner company for traceability data
isRemote boolean yes
isInventory boolean yes
defaultUseTransit boolean yes Inventory tasks stage stock through the transit bin by default
isBulk boolean yes
workCenterId integer | null yes
team object | null yes The team whose members see and take this type's tasks. Changing it moves every task of the type
parentProductId integer | null yes The product a production operation of this type makes
createdAt string (date-time) yes
updatedAt string (date-time) yes

task_types.get: Get a task type

One task type by its id.

REST: GET /api/v1/task-types/:id · Permission: any member of the company · Effect: read · MCP: tool task_types_get

Input

Field Type Required Description
id string yes Task type external id

Output

Field Type Required Description
id string yes Task type external id
typeName string yes
color string | null yes
isQuote boolean yes
isUserGenerated boolean yes Field users may create tasks of this type themselves
isDataRequest boolean yes Tasks of this type ask a partner company for traceability data
isRemote boolean yes
isInventory boolean yes
defaultUseTransit boolean yes Inventory tasks stage stock through the transit bin by default
isBulk boolean yes
workCenterId integer | null yes
team object | null yes The team whose members see and take this type's tasks. Changing it moves every task of the type
parentProductId integer | null yes The product a production operation of this type makes
createdAt string (date-time) yes
updatedAt string (date-time) yes

Teams

teams.list: List teams

The company's teams, alphabetically, with their members' personnel ids. A task belongs to its task type's team: team members with 'See tasks for my team' see those tasks and can take them in the field.

REST: GET /api/v1/teams · Permission: any member of the company · Effect: read · MCP: via capabilities_call

Output: { data, pagination }, each item:

Field Type Required Description
id string yes Team id
name string yes
color string yes
memberIds integer[] yes Personnel ids of the members
createdAt string (date-time) yes
updatedAt string (date-time) yes

teams.create: Create a team

Create a team, optionally with its members. Point task types at it to give it work.

REST: POST /api/v1/teams · Permission: settings:manage · Effect: write · Idempotency-Key: accepted · Dry run: supported · MCP: no

Input

Field Type Required Description
name string yes
color string Hex color, e.g. #026485
memberIds integer[] Personnel ids: replaces the members

Output

Field Type Required Description
id string yes Team id
name string yes
color string yes
memberIds integer[] yes Personnel ids of the members
createdAt string (date-time) yes
updatedAt string (date-time) yes

teams.update: Update a team

Rename or recolor a team, or replace its members (memberIds). Only the fields sent change. Members see the team's tasks at once.

REST: PATCH /api/v1/teams/:id · Permission: settings:manage · Effect: write · Idempotency-Key: accepted · Dry run: supported · MCP: no

Input

Field Type Required Description
id string yes
name string
color string Hex color, e.g. #026485
memberIds integer[] Personnel ids: replaces the members

Output

Field Type Required Description
id string yes Team id
name string yes
color string yes
memberIds integer[] yes Personnel ids of the members
createdAt string (date-time) yes
updatedAt string (date-time) yes

teams.delete: Delete a team

Delete a team and its memberships. Refused while a task type still belongs to it: move those types to another team (or none) first.

REST: DELETE /api/v1/teams/:id · Permission: settings:manage · Effect: destructive · Idempotency-Key: accepted · Dry run: supported · MCP: no

Input

Field Type Required Description
id string yes

Clients

clients.list: List clients

The company's clients (the customers whose sites and SSUs work happens at), newest first. Filter by name or active flag.

REST: GET /api/v1/clients · Permission: any member of the company · Effect: read · MCP: tool clients_list

Input

Field Type Required Description
limit integer Page size (1–100, default 50)
offset integer Rows to skip
search string Case-insensitive name contains
isActive boolean | true | false

Output: { data, pagination }, each item:

Field Type Required Description
id string | null yes Your id for the client (its external system id). null for clients created in EightyOne without one: they are listed, but can't be fetched or changed by id over the API
name string yes
isActive boolean yes
contactPersonName string | null yes
contactPersonEmail string | null yes
contactPersonPhone string | null yes
freeText string | null yes
color string | null yes
isDefault boolean yes
createdAt string (date-time) yes
updatedAt string (date-time) yes

clients.get: Get a client

One client by your id for it.

REST: GET /api/v1/clients/:id · Permission: any member of the company · Effect: read · MCP: tool clients_get

Input

Field Type Required Description
id string yes

Output

Field Type Required Description
id string | null yes Your id for the client (its external system id). null for clients created in EightyOne without one: they are listed, but can't be fetched or changed by id over the API
name string yes
isActive boolean yes
contactPersonName string | null yes
contactPersonEmail string | null yes
contactPersonPhone string | null yes
freeText string | null yes
color string | null yes
isDefault boolean yes
createdAt string (date-time) yes
updatedAt string (date-time) yes

clients.create: Create a client

Create a client with your own id for it (used to address it afterwards). Fires the client.created webhook.

REST: POST /api/v1/clients · Permission: clients:manage · Effect: write · Idempotency-Key: accepted · Dry run: supported · MCP: no

Input

Field Type Required Description
id string yes Your id for the client; must be unique in the company
name string yes
contactPersonName string | null
contactPersonEmail string (email) | null
contactPersonPhone string | null
freeText string | null
color string
isDefault boolean Make this the company's default client (unsets the previous default)

Output

Field Type Required Description
id string | null yes Your id for the client (its external system id). null for clients created in EightyOne without one: they are listed, but can't be fetched or changed by id over the API
name string yes
isActive boolean yes
contactPersonName string | null yes
contactPersonEmail string | null yes
contactPersonPhone string | null yes
freeText string | null yes
color string | null yes
isDefault boolean yes
createdAt string (date-time) yes
updatedAt string (date-time) yes

clients.update: Update a client

Change any of a client's fields; only the fields sent change.

REST: PATCH /api/v1/clients/:id · Permission: clients:manage · Effect: write · Idempotency-Key: accepted · Dry run: supported · MCP: no

Input

Field Type Required Description
id string yes
name string
isActive boolean
contactPersonName string | null
contactPersonEmail string (email) | null
contactPersonPhone string | null
freeText string | null
color string
isDefault boolean Make this the company's default client (unsets the previous default)

Output

Field Type Required Description
id string | null yes Your id for the client (its external system id). null for clients created in EightyOne without one: they are listed, but can't be fetched or changed by id over the API
name string yes
isActive boolean yes
contactPersonName string | null yes
contactPersonEmail string | null yes
contactPersonPhone string | null yes
freeText string | null yes
color string | null yes
isDefault boolean yes
createdAt string (date-time) yes
updatedAt string (date-time) yes

clients.delete: Delete a client

Delete (archive) a client. Its history is kept.

REST: DELETE /api/v1/clients/:id · Permission: clients:manage · Effect: destructive · Idempotency-Key: accepted · Dry run: supported · MCP: no

Input

Field Type Required Description
id string yes

SSUs

ssus.list: List SSUs

The company's SSUs (sub-site units: machines, assets, locations within a site), newest first.

REST: GET /api/v1/ssus · Permission: any member of the company · Effect: read · MCP: tool ssus_list

Input

Field Type Required Description
limit integer Page size (1–100, default 50)
offset integer Rows to skip

Output: { data, pagination }, each item:

Field Type Required Description
id string yes SSU external id (also its QR identity)
name string yes
imageUrl string | null yes
isActive boolean yes
isDefault boolean yes
location any | null yes GeoJSON point (PostGIS geometry), or null
make string | null yes Machine make, from the global machine catalog (factories)
model string | null yes Machine model, from the global machine catalog
sku string | null yes Model-level SKU / part number (not a serial number)
createdAt string (date-time) yes
updatedAt string (date-time) yes

ssus.get: Get an SSU

One SSU by its external id, with the company's guidance note on it for agents (if any): read it before drawing conclusions about this machine.

REST: GET /api/v1/ssus/:id · Permission: any member of the company · Effect: read · MCP: tool ssus_get

Input

Field Type Required Description
id string yes

Output

Field Type Required Description
id string yes SSU external id (also its QR identity)
name string yes
imageUrl string | null yes
isActive boolean yes
isDefault boolean yes
location any | null yes GeoJSON point (PostGIS geometry), or null
make string | null yes Machine make, from the global machine catalog (factories)
model string | null yes Machine model, from the global machine catalog
sku string | null yes Model-level SKU / part number (not a serial number)
createdAt string (date-time) yes
updatedAt string (date-time) yes
guidance object | null yes What the company's administrators tell agents about this SSU

ssus.update: Update an SSU

Change an SSU's name, image, active flag, default flag or location. Making it the default unsets the default on the other SSUs of its sites.

REST: PUT /api/v1/ssus/:id · Permission: clients:manage · Effect: write · Idempotency-Key: accepted · Dry run: supported · MCP: no

Input

Field Type Required Description
id string yes
name string
imageUrl string
isActive boolean
isDefault boolean
location object

Output

Field Type Required Description
id string yes SSU external id (also its QR identity)
name string yes
imageUrl string | null yes
isActive boolean yes
isDefault boolean yes
location any | null yes GeoJSON point (PostGIS geometry), or null
make string | null yes Machine make, from the global machine catalog (factories)
model string | null yes Machine model, from the global machine catalog
sku string | null yes Model-level SKU / part number (not a serial number)
createdAt string (date-time) yes
updatedAt string (date-time) yes

Inventory

line_items.find_ssu_by_barcode: Find the SSU holding a scanned unit

Resolve a scanned line-item barcode to the SSU (machine / location) whose storage unit holds it. 404 when the unit, its storage unit or that storage unit's SSU is unknown.

REST: GET /api/v1/line-items/ssu · Permission: any member of the company · Effect: read · MCP: tool line_items_find_ssu_by_barcode

Input

Field Type Required Description
barcode string yes Line item barcode (code)

Output

Field Type Required Description
id string yes
name string yes
imageUrl string | null yes
isActive boolean yes
location any | null yes GeoJSON point (PostGIS geometry), or null

stock_transactions.list: Export stock movements

The stock movement ledger (consumption, receipts, transfers, shipments), newest first, for pull-based ERP sync. Quantities only.

REST: GET /api/v1/stock-transactions · Permission: inventory:view · Effect: read · MCP: tool stock_transactions_list

Input

Field Type Required Description
from string (date-time) Movements at or after this time
to string (date-time) Movements before this time
limit integer

Output: { data, pagination }, each item:

Field Type Required Description
id integer yes
time string (date-time) yes
quantity number yes
bin string | null yes goods, bads, installed, transit, quarantine
itemId integer | null yes Line item (unit) id
fromStorageUnitId integer | null yes
toStorageUnitId integer | null yes
fromVendorId integer | null yes
toVendorId integer | null yes
toClientId integer | null yes
toCustomerId integer | null yes
taskId integer | null yes
lotId integer | null yes
serialId integer | null yes
reasonCodeId integer | null yes
stockTransactionGroupId integer | null yes

inventory.stock_levels: Stock on hand

Goods on hand per product and storage site (up to 2000 rows), by the same rule reordering uses: good stock only (not the bads bin), not counting stock held by a partner. Filter by product id, SKU or storage site.

REST: GET /api/v1/inventory/stock-levels · Permission: inventory:view · Effect: read · MCP: tool inventory_stock_levels

Input

Field Type Required Description
productId string Product external id
sku string Product SKU (case-insensitive)
storageSiteId string Storage site external id

Output: { data, pagination }, each item:

Field Type Required Description
productId string yes
sku string | null yes
name string yes
uom string | null yes
itemClass string yes raw, wip, finished, operations or spare_part
storageSiteId string | null yes
storageSiteName string | null yes
onHand number yes

inventory.reorder_suggestions: Reorder suggestions

Products below their minimum or at their dynamic reorder point (lead time × measured consumption), with the suggested quantity and vendor. Quantities and days only.

REST: GET /api/v1/inventory/reorder-suggestions · Permission: products:view · Effect: read · MCP: tool inventory_reorder_suggestions

Output: { data, pagination }, each item:

Field Type Required Description
productName string yes
sku string | null yes
onHand number yes
minQty number yes
suggestedQty number yes
suggestedVendorName string | null yes
vendorLeadTime number | null yes Days
dailyConsumption number | null yes
reorderPoint number | null yes
triggerReason below_min | below_reorder_point yes

storage_units.list: List storage units

Where stock sits: each storage unit (shelf, rack, bay, dock…) with its storage site and whose it is: warehouse or site (the company's own), client, personnel (a technician's van), customer_consigned, partner.

REST: GET /api/v1/storage-units · Permission: inventory:view · Effect: read · MCP: tool storage_units_list

Input

Field Type Required Description
storageSiteId string Storage site external id

Output: { data, pagination }, each item:

Field Type Required Description
id string yes Storage unit external id
name string yes
site object | null yes

storage_units.get: What's in a storage unit

A storage unit and everything in it: per product, bin (goods / bads / quarantine), lot and serial.

REST: GET /api/v1/storage-units/:id · Permission: inventory:view · Effect: read · MCP: tool storage_units_get

Input

Field Type Required Description
id string yes Storage unit external id

Output

Field Type Required Description
id string yes Storage unit external id
name string yes
site object | null yes
contents object[] yes

stock.transfer: Move stock

Move stock between storage units, or between bins in one unit, as the dashboard's transfers do: name the product by SKU, and the lot or serial when it's tracked. It can't move more than is there. Needs 'Manage inventory'.

REST: POST /api/v1/stock/transfers · Permission: inventory:manage · Effect: write · Idempotency-Key: accepted · Dry run: preview (checks the change and lists its effects, without making it) · MCP: tool stock_transfer

Input

Field Type Required Description
sku string yes
quantity number yes
from string yes Storage unit external id it leaves
to string yes Storage unit external id it goes to
bin goods | bads | quarantine The bin it's taken from
toBin goods | bads | quarantine The bin it lands in (default: the same)
lotCode string Which lot, for lot-tracked products
serialCode string Which unit, for serialized products

Output

Field Type Required Description
sku string yes
quantity number yes
from object yes
to object yes
bin string yes
toBin string yes
lotCode string | null yes

purchase_orders.list: List purchase orders

Purchase orders (purchase requests): vendor, status, and each line's product, quantity ordered and received. Quantities only: EightyOne holds no prices.

REST: GET /api/v1/purchase-orders · Permission: any member of the company · Effect: read · MCP: tool purchase_orders_list

Input

Field Type Required Description
status string e.g. open, partially_received, received

Output: { data, pagination }, each item:

Field Type Required Description
id integer yes
name string | null yes
status string yes
vendor string | null yes
externalSystemId string | null yes
lines object[] yes

purchase_orders.receive: Receive against a purchase order

Book what arrived: per PO line, the quantity and the storage unit it goes to (with the lot for lot-tracked products). An inspection plan for the product or vendor puts it in quarantine and opens an inspection task. Can't receive more than ordered. Needs 'Receive inventory'. Preview it first.

REST: POST /api/v1/purchase-orders/:id/receive · Permission: inventory:receive · Effect: write · Idempotency-Key: accepted · Dry run: preview (checks the change and lists its effects, without making it) · MCP: tool purchase_orders_receive

Input

Field Type Required Description
id integer yes Purchase order id
lines object[] yes

Output

Field Type Required Description
id integer yes
name string | null yes
status string yes
vendor string | null yes
externalSystemId string | null yes
lines object[] yes

customers.list: List customers

A factory's customers, who shipments go to: name, reference and ship-to address.

REST: GET /api/v1/customers · Permission: inventory:view · Effect: read · MCP: tool customers_list

Output: { data, pagination }, each item:

Field Type Required Description
id string yes
name string yes
externalRef string | null yes
shipToAddress string | null yes
isEightyOneCompany boolean yes Shipments arrive in their EightyOne stock

shipments.list: List shipments

Shipments to customers, newest first: draft (being prepared), shipped or cancelled.

REST: GET /api/v1/shipments · Permission: inventory:view · Effect: read · MCP: tool shipments_list

Input

Field Type Required Description
status draft | shipped | cancelled

Output: { data, pagination }, each item:

Field Type Required Description
id string yes
code string yes
status string yes draft / shipped / cancelled
customer object | null yes
shipToAddress string | null yes
trackingReference string | null yes
notes string | null yes
shippedAt string (date-time) | null yes
partnerDeliveryState string | null yes For a customer that is an EightyOne company
lines object[] yes

shipments.get: Get a shipment

A shipment with its lines.

REST: GET /api/v1/shipments/:id · Permission: inventory:view · Effect: read · MCP: tool shipments_get

Input

Field Type Required Description
id string yes Shipment external id

Output

Field Type Required Description
id string yes
code string yes
status string yes draft / shipped / cancelled
customer object | null yes
shipToAddress string | null yes
trackingReference string | null yes
notes string | null yes
shippedAt string (date-time) | null yes
partnerDeliveryState string | null yes For a customer that is an EightyOne company
lines object[] yes

shipments.create: Prepare a shipment

Draft a shipment to a customer: per line the SKU, quantity and the storage unit it ships from (and the lot for lot-tracked products). Nothing leaves stock until shipments_ship. Factories only. Needs 'Manage inventory'.

REST: POST /api/v1/shipments · Permission: inventory:manage · Effect: write · Idempotency-Key: accepted · Dry run: supported · MCP: tool shipments_create

Input

Field Type Required Description
customerId string yes Customer external id (customers_list)
lines object[] yes
shipToAddress string Defaults to the customer's
code string
trackingReference string
notes string

Output

Field Type Required Description
id string yes
code string yes
status string yes draft / shipped / cancelled
customer object | null yes
shipToAddress string | null yes
trackingReference string | null yes
notes string | null yes
shippedAt string (date-time) | null yes
partnerDeliveryState string | null yes For a customer that is an EightyOne company
lines object[] yes

shipments.ship: Ship it

Confirm a draft shipment left: each line's goods come out of stock, written to the customer. For a customer that is an EightyOne company, the goods arrive in their transit. Refused if any line lacks the stock, names a lot that isn't available, or takes another customer's consigned stock. Needs 'Manage inventory'. Preview it first.

REST: POST /api/v1/shipments/:id/ship · Permission: inventory:manage · Effect: write · Idempotency-Key: accepted · Dry run: preview (checks the change and lists its effects, without making it) · MCP: tool shipments_ship

Input

Field Type Required Description
id string yes Shipment external id

Output

Field Type Required Description
id string yes
code string yes
status string yes draft / shipped / cancelled
customer object | null yes
shipToAddress string | null yes
trackingReference string | null yes
notes string | null yes
shippedAt string (date-time) | null yes
partnerDeliveryState string | null yes For a customer that is an EightyOne company
lines object[] yes

shipments.cancel: Cancel a draft shipment

Cancel a shipment that hasn't shipped. Nothing moves: a draft holds no stock. Needs 'Manage inventory'.

REST: POST /api/v1/shipments/:id/cancel · Permission: inventory:manage · Effect: write · Idempotency-Key: accepted · Dry run: supported · MCP: tool shipments_cancel

Input

Field Type Required Description
id string yes Shipment external id

Output

Field Type Required Description
id string yes
code string yes
status string yes draft / shipped / cancelled
customer object | null yes
shipToAddress string | null yes
trackingReference string | null yes
notes string | null yes
shippedAt string (date-time) | null yes
partnerDeliveryState string | null yes For a customer that is an EightyOne company
lines object[] yes

inventory_counts.list: List cycle counts

Cycle counts, newest first: which storage unit, status (draft, in_progress, completed = finalized and waiting to be reconciled, reconciled) and totals. inventory_counts_get shows the lines and discrepancies.

REST: GET /api/v1/inventory-counts · Permission: inventory:view · Effect: read · MCP: tool inventory_counts_list

Input

Field Type Required Description
status draft | in_progress | completed | reconciled

Output: { data, pagination }, each item:

Field Type Required Description
id integer yes
storageUnit object | null yes
status string yes draft / in_progress / completed (finalized, awaiting reconciliation) / reconciled
countType string | null yes
totalExpected number | null yes
totalCounted number | null yes
taskId string | null yes The count task operators fill in, if any
dueDate string (date-time) | null yes
completedAt string (date-time) | null yes
reconciledAt string (date-time) | null yes
createdAt string (date-time) yes

inventory_counts.get: Get a cycle count

A cycle count with its lines: expected (on hand by the system), counted, the discrepancy once finalized, and whether stock moved while it was open (a reason to recount rather than adjust).

REST: GET /api/v1/inventory-counts/:id · Permission: inventory:view · Effect: read · MCP: tool inventory_counts_get

Input

Field Type Required Description
id integer yes

Output

Field Type Required Description
id integer yes
storageUnit object | null yes
status string yes draft / in_progress / completed (finalized, awaiting reconciliation) / reconciled
countType string | null yes
totalExpected number | null yes
totalCounted number | null yes
taskId string | null yes The count task operators fill in, if any
dueDate string (date-time) | null yes
completedAt string (date-time) | null yes
reconciledAt string (date-time) | null yes
createdAt string (date-time) yes
lines object[] yes

inventory_counts.create: Start a cycle count

Open a count of one storage unit. It snapshots what the system expects there, and when the company has an inventory task type it also creates the count task operators fill in from the app. Needs 'Manage inventory'.

REST: POST /api/v1/inventory-counts · Permission: inventory:manage · Effect: write · Idempotency-Key: accepted · Dry run: supported · MCP: tool inventory_counts_create

Input

Field Type Required Description
storageUnitId string yes Storage unit external id (storage_units_list)
title string The count task's title
dueDate string (date-time) | string (date)

Output

Field Type Required Description
id integer yes
storageUnit object | null yes
status string yes draft / in_progress / completed (finalized, awaiting reconciliation) / reconciled
countType string | null yes
totalExpected number | null yes
totalCounted number | null yes
taskId string | null yes The count task operators fill in, if any
dueDate string (date-time) | null yes
completedAt string (date-time) | null yes
reconciledAt string (date-time) | null yes
createdAt string (date-time) yes
lines object[] yes

inventory_counts.record_lines: Record counted quantities

Add what someone counted to an open count, by SKU (and bin, lot or serial where it matters). Quantities add to what was already counted for that line, as in the dashboard. Then finalize it. Needs 'Manage inventory'.

REST: POST /api/v1/inventory-counts/:id/lines · Permission: inventory:manage · Effect: write · Idempotency-Key: accepted · Dry run: supported · MCP: tool inventory_counts_record_lines

Input

Field Type Required Description
id integer yes Count id
lines object[] yes

Output

Field Type Required Description
id integer yes
storageUnit object | null yes
status string yes draft / in_progress / completed (finalized, awaiting reconciliation) / reconciled
countType string | null yes
totalExpected number | null yes
totalCounted number | null yes
taskId string | null yes The count task operators fill in, if any
dueDate string (date-time) | null yes
completedAt string (date-time) | null yes
reconciledAt string (date-time) | null yes
createdAt string (date-time) yes
lines object[] yes

inventory_counts.finalize: Finish a cycle count

Close counting: each line's expected quantity becomes what's on hand now, discrepancies are computed, and anything on hand the count never saw becomes a line counted 0. Nothing is posted to stock until it's reconciled. Needs 'Manage inventory'.

REST: POST /api/v1/inventory-counts/:id/finalize · Permission: inventory:manage · Effect: write · Idempotency-Key: accepted · Dry run: supported · MCP: tool inventory_counts_finalize

Input

Field Type Required Description
id integer yes

Output

Field Type Required Description
id integer yes
storageUnit object | null yes
status string yes draft / in_progress / completed (finalized, awaiting reconciliation) / reconciled
countType string | null yes
totalExpected number | null yes
totalCounted number | null yes
taskId string | null yes The count task operators fill in, if any
dueDate string (date-time) | null yes
completedAt string (date-time) | null yes
reconciledAt string (date-time) | null yes
createdAt string (date-time) yes
lines object[] yes

inventory_counts.reconcile: Post a cycle count to stock

Decide each line of a finalized count and post it. accepted: stock becomes the counted quantity; adjusted: becomes adjustedQuantity; ignored (and any line not listed): stock stays as the system has it. Every write-off needs an adjustment reasonCodeId (reason_codes_list kind adjustment). Needs 'Manage inventory' and 'Adjust inventory'. Preview it first: it lists each addition, write-off and bin move.

REST: POST /api/v1/inventory-counts/:id/reconcile · Permission: inventory:manage + inventory:adjust · Effect: write · Idempotency-Key: accepted · Dry run: preview (checks the change and lists its effects, without making it) · MCP: tool inventory_counts_reconcile

Input

Field Type Required Description
id integer yes
decisions object[] yes

Output

Field Type Required Description
id integer yes
storageUnit object | null yes
status string yes draft / in_progress / completed (finalized, awaiting reconciliation) / reconciled
countType string | null yes
totalExpected number | null yes
totalCounted number | null yes
taskId string | null yes The count task operators fill in, if any
dueDate string (date-time) | null yes
completedAt string (date-time) | null yes
reconciledAt string (date-time) | null yes
createdAt string (date-time) yes
lines object[] yes

Production

work_orders.list: List work orders

The company's work orders, newest first, optionally by status. Use for ERP pull-sync or to see what production is working on.

REST: GET /api/v1/work-orders · Permission: production:view · Effect: read · MCP: tool work_orders_list

Input

Field Type Required Description
status draft | released | in_progress | completed | closed | cancelled

Output: { data, pagination }, each item:

Field Type Required Description
id string yes Work order external id
code string yes Human code, e.g. WO-1009
externalSystemId string | null yes Your (ERP) id for the order
source string yes dashboard or erp
status draft | released | in_progress | completed | closed | cancelled yes
product object | null yes
quantity number yes
uom string | null yes
dueDate string (date-time) | null yes
routing object | null yes
releasedAt string (date-time) | null yes
completedAt string (date-time) | null yes
createdAt string (date-time) yes
updatedAt string (date-time) yes

work_orders.get: Get a work order

One work order with its operations (the traveler's tasks) and their status.

REST: GET /api/v1/work-orders/:externalId · Permission: production:view · Effect: read · MCP: tool work_orders_get

Input

Field Type Required Description
externalId string yes Work order external id

Output

Field Type Required Description
id string yes Work order external id
code string yes Human code, e.g. WO-1009
externalSystemId string | null yes Your (ERP) id for the order
source string yes dashboard or erp
status draft | released | in_progress | completed | closed | cancelled yes
product object | null yes
quantity number yes
uom string | null yes
dueDate string (date-time) | null yes
routing object | null yes
releasedAt string (date-time) | null yes
completedAt string (date-time) | null yes
createdAt string (date-time) yes
updatedAt string (date-time) yes
operations object[] yes

work_orders.release: Release a work order

Release a draft work order to the floor: one operation task per routing step, each on the only machine of its work center when there is just one, with the type's parameters pinned and later steps waiting for gates. Needs 'Release work orders'. Preview it with dryRun first: it lists the operations it creates.

REST: POST /api/v1/work-orders/:externalId/release · Permission: work_orders:release · Effect: write · Idempotency-Key: accepted · Dry run: preview (checks the change and lists its effects, without making it) · MCP: tool work_orders_release

Input

Field Type Required Description
externalId string yes Work order external id

Output

Field Type Required Description
id string yes Work order external id
code string yes Human code, e.g. WO-1009
externalSystemId string | null yes Your (ERP) id for the order
source string yes dashboard or erp
status draft | released | in_progress | completed | closed | cancelled yes
product object | null yes
quantity number yes
uom string | null yes
dueDate string (date-time) | null yes
routing object | null yes
releasedAt string (date-time) | null yes
completedAt string (date-time) | null yes
createdAt string (date-time) yes
updatedAt string (date-time) yes

work_orders.upsert: Create or update a work order (ERP orders in)

Idempotent on externalSystemId: a new id creates a draft order; re-sending updates it while it is still a draft and is a no-op afterwards. Lands on the product's released routing when there is exactly one. Release it with work_orders.release.

REST: POST /api/v1/work-orders · Permission: production:manage · Effect: write · Idempotency-Key: accepted · Dry run: supported · MCP: no

Input

Field Type Required Description
externalSystemId string yes Your (ERP) id for the order: the upsert key
productId integer EightyOne product id (or give productSku)
productSku string Product SKU (case-insensitive)
quantity number
uom string
dueDate string (date-time) | string (date)
code string Human code; defaults to the next WO-n

Output

Field Type Required Description
workOrder object yes
created boolean yes

work_orders.batch_upsert: Create or update many work orders

Upsert up to 500 orders; each succeeds or fails on its own (results in input order).

REST: POST /api/v1/work-orders/batch · Permission: production:manage · Effect: write · Idempotency-Key: accepted · Dry run: supported · MCP: no

Input

Field Type Required Description
orders any[] yes Each item is a work_orders.upsert input; an invalid item fails on its own

Output

Field Type Required Description
results object[] yes

Webhooks

webhooks.list: List webhooks

The company's webhook subscriptions.

REST: GET /api/v1/webhooks · Permission: api_keys:view · Effect: read · MCP: via capabilities_call

Input

Field Type Required Description
limit integer Page size (1–100, default 50)
offset integer Rows to skip
isActive boolean | true | false

Output: { data, pagination }, each item:

Field Type Required Description
id string yes
name string yes
targetUrl string yes
eventTypes string[] yes
isActive boolean yes
failureCount integer yes
disabledAt string (date-time) | null yes Set when repeated failures switched the webhook off
headers object | null yes
createdAt string (date-time) yes
updatedAt string (date-time) yes

webhooks.event_types: List webhook event types

Every event a webhook can subscribe to, with what triggers it.

REST: GET /api/v1/webhooks/events · Permission: api_keys:view · Effect: read · MCP: via capabilities_call

Output

Field Type Required Description
eventTypes object[] yes

webhooks.create: Create a webhook

Subscribe a URL to events. Deliveries are Standard Webhooks messages signed with EightyOne's Ed25519 key: verify them with the public keys at /api/v1/webhook-signing-keys. There is no secret to store.

REST: POST /api/v1/webhooks · Permission: webhooks:manage · Effect: write · Idempotency-Key: accepted · Dry run: not supported · MCP: no

Input

Field Type Required Description
name string yes
targetUrl string (uri) yes HTTPS endpoint; private and internal addresses are refused
eventTypes task.status_changed | task.created | client.created | work_order.released | work_order.completed | downtime.started | downtime.ended | lot.created | stock.reorder_triggered | handoff.received | handoff.status_changed | handoff.declined | handoff.deleted | partner_delivery.incoming | partner_delivery.received | partner_delivery.shortfall | data_package.received[] yes
headers object Extra headers sent with each delivery

Output

Field Type Required Description
id string yes
name string yes
targetUrl string yes
eventTypes string[] yes
isActive boolean yes
failureCount integer yes
disabledAt string (date-time) | null yes Set when repeated failures switched the webhook off
headers object | null yes
createdAt string (date-time) yes
updatedAt string (date-time) yes
verification object yes Verify each delivery's signature with EightyOne's public key

webhooks.get: Get a webhook

One webhook subscription.

REST: GET /api/v1/webhooks/:id · Permission: api_keys:view · Effect: read · MCP: via capabilities_call

Input

Field Type Required Description
id string yes

Output

Field Type Required Description
id string yes
name string yes
targetUrl string yes
eventTypes string[] yes
isActive boolean yes
failureCount integer yes
disabledAt string (date-time) | null yes Set when repeated failures switched the webhook off
headers object | null yes
createdAt string (date-time) yes
updatedAt string (date-time) yes

webhooks.update: Update a webhook

Change a webhook's name, URL, events, headers or active flag.

REST: PATCH /api/v1/webhooks/:id · Permission: webhooks:manage · Effect: write · Idempotency-Key: accepted · Dry run: not supported · MCP: no

Input

Field Type Required Description
id string yes
name string
targetUrl string (uri)
eventTypes task.status_changed | task.created | client.created | work_order.released | work_order.completed | downtime.started | downtime.ended | lot.created | stock.reorder_triggered | handoff.received | handoff.status_changed | handoff.declined | handoff.deleted | partner_delivery.incoming | partner_delivery.received | partner_delivery.shortfall | data_package.received[]
isActive boolean
headers object

Output

Field Type Required Description
id string yes
name string yes
targetUrl string yes
eventTypes string[] yes
isActive boolean yes
failureCount integer yes
disabledAt string (date-time) | null yes Set when repeated failures switched the webhook off
headers object | null yes
createdAt string (date-time) yes
updatedAt string (date-time) yes

webhooks.delete: Delete a webhook

Remove a webhook subscription.

REST: DELETE /api/v1/webhooks/:id · Permission: webhooks:manage · Effect: destructive · Idempotency-Key: accepted · Dry run: not supported · MCP: no

Input

Field Type Required Description
id string yes

webhooks.delivery_logs: Webhook delivery log

Recent deliveries of one webhook with their status, response and timing.

REST: GET /api/v1/webhooks/:id/logs · Permission: api_keys:view · Effect: read · MCP: via capabilities_call

Input

Field Type Required Description
id string yes
limit integer Page size (1–100, default 50)
offset integer Rows to skip
status pending | success | failed | retrying
eventType task.status_changed | task.created | client.created | work_order.released | work_order.completed | downtime.started | downtime.ended | lot.created | stock.reorder_triggered | handoff.received | handoff.status_changed | handoff.declined | handoff.deleted | partner_delivery.incoming | partner_delivery.received | partner_delivery.shortfall | data_package.received

Output: { data, pagination }, each item:

Field Type Required Description
id integer yes
eventType string yes
eventId string yes
payload any yes
status string yes
attemptCount integer yes
responseStatusCode integer | null yes
responseBody string | null yes
responseTimeMs integer | null yes
errorMessage string | null yes
nextRetryAt string (date-time) | null yes
deliveredAt string (date-time) | null yes
createdAt string (date-time) yes

webhooks.test: Send a test event

Queue a test delivery to THIS webhook only: a signed message of type webhook.test, to check your endpoint and its signature verification.

REST: POST /api/v1/webhooks/:id/test · Permission: webhooks:manage · Effect: write · Idempotency-Key: not accepted · Dry run: not supported · MCP: no

Input

Field Type Required Description
id string yes

Output

Field Type Required Description
message string yes
webhookId string yes

webhooks.retry_delivery: Retry a delivery

Re-send one logged delivery of this webhook.

REST: POST /api/v1/webhooks/:id/logs/:logId/retry · Permission: webhooks:manage · Effect: write · Idempotency-Key: not accepted · Dry run: not supported · MCP: no

Input

Field Type Required Description
id string yes
logId integer yes

Output

Field Type Required Description
message string yes
deliveryLogId integer yes

Partner network

handoffs.send: Send a task to a partner company

Hand one of your tasks to another EightyOne company (by its short name, or a partner subcontractor). The partner gets its own copy; your people come off the task. Goods can travel with it (items), and a data-request task carries the scopes it asks for.

REST: POST /api/v1/handoffs · Permission: handoffs:send · Effect: write · Idempotency-Key: accepted · Dry run: supported · MCP: tool handoffs_send

Input

Field Type Required Description
taskId string yes Your task's id
recipientShortName string
subContractorId integer A subcontractor that is an EightyOne company
items object[]
dataRequest object

Output

Field Type Required Description
id string yes
direction incoming | outgoing yes
state string yes
partner object yes
taskId string yes This company's own task (never the partner's)
status string yes
declinedReason string | null yes
requestedItems object[] yes
dataRequest object | null yes
deliveries object[] yes
linkActive boolean yes
createdAt string (date-time) yes

handoffs.list: List handoffs

Tasks you sent to, or received from, partner companies (newest first, up to 500).

REST: GET /api/v1/handoffs · Permission: handoffs:send · Effect: read · MCP: via capabilities_call

Input

Field Type Required Description
direction incoming | outgoing | all
state active | withdrawn | deleted

Output: an array of

Field Type Required Description
id string yes
direction incoming | outgoing yes
state string yes
partner object yes
taskId string yes This company's own task (never the partner's)
status string yes
declinedReason string | null yes
requestedItems object[] yes
dataRequest object | null yes
deliveries object[] yes
linkActive boolean yes
createdAt string (date-time) yes

handoffs.get: Get a handoff

One handoff from your side.

REST: GET /api/v1/handoffs/:id · Permission: handoffs:send · Effect: read · MCP: via capabilities_call

Input

Field Type Required Description
id string yes

Output

Field Type Required Description
id string yes
direction incoming | outgoing yes
state string yes
partner object yes
taskId string yes This company's own task (never the partner's)
status string yes
declinedReason string | null yes
requestedItems object[] yes
dataRequest object | null yes
deliveries object[] yes
linkActive boolean yes
createdAt string (date-time) yes

handoffs.timeline: Handoff timeline

What happened on a handoff, in order; your own people are named, the partner's are not.

REST: GET /api/v1/handoffs/:id/timeline · Permission: handoffs:send · Effect: read · MCP: via capabilities_call

Input

Field Type Required Description
id string yes

Output: an array of

Field Type Required Description
type string yes
at string (date-time) yes
by you | partner yes
actorName string | null yes Only your own people are named
payload any yes

handoffs.decline: Decline a received handoff

Decline a task a partner sent you, with a reason they will see.

REST: POST /api/v1/handoffs/:id/decline · Permission: handoffs:send · Effect: write · Idempotency-Key: accepted · Dry run: supported · MCP: tool handoffs_decline

Input

Field Type Required Description
id string yes
reason string yes

Output

Field Type Required Description
id string yes
direction incoming | outgoing yes
state string yes
partner object yes
taskId string yes This company's own task (never the partner's)
status string yes
declinedReason string | null yes
requestedItems object[] yes
dataRequest object | null yes
deliveries object[] yes
linkActive boolean yes
createdAt string (date-time) yes

handoffs.withdraw: Withdraw a sent handoff

Take back an active handoff you sent; the partner's copy is removed.

REST: DELETE /api/v1/handoffs/:id · Permission: handoffs:send · Effect: destructive · Idempotency-Key: accepted · Dry run: not supported · MCP: no

Input

Field Type Required Description
id string yes

partner_deliveries.list: List partner deliveries

Goods sent to or received from partner companies, from your side.

REST: GET /api/v1/partner-deliveries · Permission: handoffs:send · Effect: read · MCP: via capabilities_call

Input

Field Type Required Description
direction incoming | outgoing | all
state in_transit | partially_received | shortfall | received | reversed | refused | unmapped | held | settled

Output: an array of

Field Type Required Description
id string yes
kind string yes
direction incoming | outgoing yes
state string yes
partner object yes
taskId string | null yes
handoffId string | null yes
shipmentCode string | null yes
returnOf string | null yes
receivingStorageUnit object | null yes
linkActive boolean yes
createdAt string (date-time) yes
lines object[] yes

partner_deliveries.get: Get a partner delivery

One delivery from your side.

REST: GET /api/v1/partner-deliveries/:id · Permission: handoffs:send · Effect: read · MCP: via capabilities_call

Input

Field Type Required Description
id string yes

Output

Field Type Required Description
id string yes
kind string yes
direction incoming | outgoing yes
state string yes
partner object yes
taskId string | null yes
handoffId string | null yes
shipmentCode string | null yes
returnOf string | null yes
receivingStorageUnit object | null yes
linkActive boolean yes
createdAt string (date-time) yes
lines object[] yes

partner_deliveries.receive: Receive a partner delivery

Book goods a partner sent you into stock, line by line (damaged quantities go to the bads bin), optionally reporting the rest missing.

REST: POST /api/v1/partner-deliveries/:id/receive · Permission: handoffs:send + inventory:receive · Effect: write · Idempotency-Key: accepted · Dry run: supported · MCP: tool partner_deliveries_receive

Input

Field Type Required Description
id string yes
lines object[]
reportRestMissing boolean

Output

Field Type Required Description
id string yes
kind string yes
direction incoming | outgoing yes
state string yes
partner object yes
taskId string | null yes
handoffId string | null yes
shipmentCode string | null yes
returnOf string | null yes
receivingStorageUnit object | null yes
linkActive boolean yes
createdAt string (date-time) yes
lines object[] yes

data_packages.list: List data packages

Traceability data packages you released to, or received from, partners.

REST: GET /api/v1/data-packages · Permission: handoffs:send · Effect: read · MCP: via capabilities_call

Input

Field Type Required Description
role released | received

Output: an array of

Field Type Required Description
id string yes
role string yes
createdAt string (date-time) yes
from any yes
object any yes

data_packages.get: Get a data package

A data package's content, with short-lived links to its photos.

REST: GET /api/v1/data-packages/:id · Permission: handoffs:send · Effect: read · MCP: via capabilities_call

Input

Field Type Required Description
id string yes

Output

Field Type Required Description
id string yes
role string yes
createdAt string (date-time) yes
content any yes
files object[] yes

Analytics

analytics.overview: Factory performance overview

Headline numbers for a window: total downtime, failures, average availability and OEE, and how many machines are monitored. unavailableMetrics names OEE factors with no source data yet. Start here, then drill into analytics.downtime / analytics.reliability.

REST: GET /api/v1/analytics/overview · Permission: insights:view · Effect: read · MCP: tool analytics_overview

Input

Field Type Required Description
from string (date-time) | string (date) Window start (ISO 8601). Default: 30 days before to
to string (date-time) | string (date) Window end, exclusive (ISO 8601). Default: now

Output

Field Type Required Description
range object yes
downtimeSeconds number yes
downtimeHours number yes
failures integer yes
avgAvailability number | null yes 0–1
avgOee number | null yes 0–1
monitoredSsus integer yes
unavailableMetrics string[] yes

analytics.downtime: Downtime by machine

Time each machine (SSU) spent DOWN or in MAINTENANCE in the window, most first, with how many times it entered that state. For the reasons, follow up with downtime_events.list (reason-coded stoppages) or storylines.ssu (the machine's story).

REST: GET /api/v1/analytics/downtime · Permission: insights:view · Effect: read · MCP: tool analytics_downtime

Input

Field Type Required Description
from string (date-time) | string (date) Window start (ISO 8601). Default: 30 days before to
to string (date-time) | string (date) Window end, exclusive (ISO 8601). Default: now

Output: { data, pagination }, each item:

Field Type Required Description
ssuId string | null yes SSU external id
ssuName string | null yes
category string yes DOWN or MAINTENANCE
seconds number yes
hours number yes
transitions integer yes Times the machine entered this state

analytics.reliability: Machine reliability (MTTR / MTBF)

Per machine: failures (entries into DOWN), mean time to repair and mean time between failures, in seconds, most failures first.

REST: GET /api/v1/analytics/reliability · Permission: insights:view · Effect: read · MCP: tool analytics_reliability

Input

Field Type Required Description
from string (date-time) | string (date) Window start (ISO 8601). Default: 30 days before to
to string (date-time) | string (date) Window end, exclusive (ISO 8601). Default: now

Output: { data, pagination }, each item:

Field Type Required Description
ssuId string | null yes SSU external id
ssuName string | null yes
failures integer yes
mttrSeconds number | null yes
mtbfSeconds number | null yes

analytics.oee: OEE by machine

Overall equipment effectiveness per machine: availability, performance and quality (0–1) with good / scrap quantities. A factor is null when its source data is missing (no routed work, no counts).

REST: GET /api/v1/analytics/oee · Permission: insights:view · Effect: read · MCP: tool analytics_oee

Input

Field Type Required Description
from string (date-time) | string (date) Window start (ISO 8601). Default: 30 days before to
to string (date-time) | string (date) Window end, exclusive (ISO 8601). Default: now

Output: { data, pagination }, each item:

Field Type Required Description
ssuId string | null yes SSU external id
ssuName string | null yes
plannedSeconds number yes
downtimeSeconds number yes
availability number | null yes
performance number | null yes Can exceed 1 when the line beats its standards
quality number | null yes
goodQuantity number yes
scrapQuantity number yes
oee number | null yes

analytics.failure_pareto: Failure modes (Pareto)

What breaks most: completed failure-coded tasks grouped by problem code, most frequent first (top 25), with the machine that suffers each mode most.

REST: GET /api/v1/analytics/failure-pareto · Permission: insights:view · Effect: read · MCP: tool analytics_failure_pareto

Input

Field Type Required Description
from string (date-time) | string (date) Window start (ISO 8601). Default: 30 days before to
to string (date-time) | string (date) Window end, exclusive (ISO 8601). Default: now

Output: { data, pagination }, each item:

Field Type Required Description
problemCodeId integer yes
code string | null yes
label string yes
count integer yes
worstSsuName string | null yes

Machines

downtime_events.list: List machine stoppages

Individual downtime events (newest first, up to 500): when each machine stopped, for how long, and the reason code someone classified it with. Use it to explain the totals from analytics.downtime. Filter by machine and window; unclassifiedOnly lists stops still waiting for a reason.

REST: GET /api/v1/downtime-events · Permission: any member of the company · Effect: read · MCP: tool downtime_events_list

Input

Field Type Required Description
ssuId string SSU external id
from string (date-time) | string (date) Stops that started at or after this time
to string (date-time) | string (date) Stops that started before this time
unclassifiedOnly boolean | true | false
openOnly boolean | true | false Only machines still stopped

Output: { data, pagination }, each item:

Field Type Required Description
id integer yes
ssuId string yes SSU external id
ssuName string | null yes
startedAt string (date-time) yes
endedAt string (date-time) | null yes null while the machine is still stopped
durationSeconds number | null yes
source auto | manual yes auto: detected from machine telemetry; manual: reported by a person
reason object | null yes The downtime reason code, once someone classified the stop
note string | null yes

downtime_events.classify: Give a stop its reason

Classify a machine stoppage with a downtime reason code (reason_codes_list, kind downtime), optionally with a note. Re-classifying replaces the reason. Find stops waiting for one with downtime_events_list and unclassifiedOnly.

REST: POST /api/v1/downtime-events/:id/classify · Permission: any member of the company · Effect: write · Idempotency-Key: accepted · Dry run: supported · MCP: tool downtime_events_classify

Input

Field Type Required Description
id integer yes Downtime event id
reasonCodeId integer yes A downtime reason code id
note string

Output

Field Type Required Description
id integer yes
ssuId string yes SSU external id
ssuName string | null yes
startedAt string (date-time) yes
endedAt string (date-time) | null yes null while the machine is still stopped
durationSeconds number | null yes
source auto | manual yes auto: detected from machine telemetry; manual: reported by a person
reason object | null yes The downtime reason code, once someone classified the stop
note string | null yes

downtime_events.open: Report a machine stopped

Record that a machine stopped now, for machines without telemetry (those report stops themselves). Close it with downtime_events_close when it runs again, and classify it with a reason. Needs 'Manage machine data'.

REST: POST /api/v1/downtime-events · Permission: machine_data:manage · Effect: write · Idempotency-Key: accepted · Dry run: preview (checks the change and lists its effects, without making it) · MCP: tool downtime_events_open

Input

Field Type Required Description
ssuId string yes SSU external id
note string

Output

Field Type Required Description
id integer yes
ssuId string yes SSU external id
ssuName string | null yes
startedAt string (date-time) yes
endedAt string (date-time) | null yes null while the machine is still stopped
durationSeconds number | null yes
source auto | manual yes auto: detected from machine telemetry; manual: reported by a person
reason object | null yes The downtime reason code, once someone classified the stop
note string | null yes

downtime_events.close: Report a machine running again

End a stoppage now. Closing one that already ended changes nothing. Needs 'Manage machine data'.

REST: POST /api/v1/downtime-events/:id/close · Permission: machine_data:manage · Effect: write · Idempotency-Key: accepted · Dry run: preview (checks the change and lists its effects, without making it) · MCP: tool downtime_events_close

Input

Field Type Required Description
id integer yes Downtime event id

Output

Field Type Required Description
id integer yes
ssuId string yes SSU external id
ssuName string | null yes
startedAt string (date-time) yes
endedAt string (date-time) | null yes null while the machine is still stopped
durationSeconds number | null yes
source auto | manual yes auto: detected from machine telemetry; manual: reported by a person
reason object | null yes The downtime reason code, once someone classified the stop
note string | null yes

downtime_events.summary: Downtime by machine and reason

Recorded stoppages per machine in a window (default: the last 30 days), most stopped time first, each broken down by reason code: the direct answer to "which machines were down most, and why?". Counts only the part of each stop inside the window; a stop still open counts up to the window end. Complements analytics.downtime, which measures time in a DOWN / MAINTENANCE status.

REST: GET /api/v1/downtime-events/summary · Permission: any member of the company · Effect: read · MCP: tool downtime_events_summary

Input

Field Type Required Description
from string (date-time) | string (date) Window start (ISO 8601). Default: 30 days before to
to string (date-time) | string (date) Window end, exclusive (ISO 8601). Default: now

Output: { data, pagination }, each item:

Field Type Required Description
ssuId string yes SSU external id
ssuName string | null yes
seconds number yes
hours number yes
stops integer yes
openStops integer yes Stops not yet ended
byReason object[] yes

reason_codes.list: List reason codes

The company's reason codes: why machines stop (downtime), failure problem / cause / remedy codes on maintenance tasks, scrap and stock-adjustment reasons.

REST: GET /api/v1/reason-codes · Permission: any member of the company · Effect: read · MCP: via capabilities_call

Input

Field Type Required Description
kind downtime | failure_problem | failure_cause | failure_remedy | scrap | adjustment

Output: { data, pagination }, each item:

Field Type Required Description
id integer yes
kind string yes
code string | null yes
label string yes
parentId integer | null yes
isActive boolean yes

meters.list: List machine meters

Usage meters on machines (run hours, strokes, cycles…) and their current readings. Usage-based maintenance rules open a task each time a meter advances by their interval. Filter by machine.

REST: GET /api/v1/meters · Permission: maintenance:view · Effect: read · MCP: tool meters_list

Input

Field Type Required Description
ssuId string SSU external id

Output: { data, pagination }, each item:

Field Type Required Description
id integer yes
ssuId string yes SSU external id
ssuName string | null yes
key string yes
name string yes
uom string | null yes
source manual | signal yes signal: counted from machine data; manual: people enter readings
currentValue number yes

meters.record_reading: Record a meter reading

Enter a meter's current total (not the change), as a technician reads it off the machine. It can open usage-based maintenance tasks: preview it with dryRun first to see which. Needs 'Manage maintenance'.

REST: POST /api/v1/meters/:id/readings · Permission: maintenance:manage · Effect: write · Idempotency-Key: accepted · Dry run: preview (checks the change and lists its effects, without making it) · MCP: tool meters_record_reading

Input

Field Type Required Description
id integer yes Meter id (meters_list)
value number yes The meter's reading: its running total

Output

Field Type Required Description
id integer yes
ssuId string yes SSU external id
ssuName string | null yes
key string yes
name string yes
uom string | null yes
source manual | signal yes signal: counted from machine data; manual: people enter readings
currentValue number yes

machine_catalog.search_makes: Search machine makes

Search the global catalog of machine manufacturers (e.g. 'Trumpf'). Use the existing spelling when it matches: everyone shares one catalog.

REST: GET /api/v1/machine-catalog/makes · Permission: any member of the company · Effect: read · MCP: tool machine_catalog_search_makes

Input

Field Type Required Description
q string Part of the make's name; empty lists common makes

Output: an array of

Field Type Required Description
id integer yes
name string yes
matchType exact | prefix | contains | similar | null yes similar = a 'did you mean' suggestion for a likely misspelling

machine_catalog.search_models: Search machine models

Search the models of one make in the global catalog.

REST: GET /api/v1/machine-catalog/models · Permission: any member of the company · Effect: read · MCP: tool machine_catalog_search_models

Input

Field Type Required Description
makeId integer yes Make id from machine_catalog.search_makes
q string

Output: an array of

Field Type Required Description
id integer yes
name string yes
matchType exact | prefix | contains | similar | null yes similar = a 'did you mean' suggestion for a likely misspelling

machine_catalog.lookup_sku: Find a machine by SKU

The make and model registered for a model-level SKU / part number (not a serial number).

REST: GET /api/v1/machine-catalog/sku-lookup · Permission: any member of the company · Effect: read · MCP: via capabilities_call

Input

Field Type Required Description
sku string

Output: an array of

Field Type Required Description
make object yes
model object yes

Quality

ncrs.open: Open an NCR

Open a nonconformance report: a task of the company's NCR task type (Settings), linked to the task it was found on and carrying its machine and work order, with the affected lot or product recorded on it. A failed in-line check opens one by itself; use this for what people find. Disposition it with ncrs_disposition.

REST: POST /api/v1/ncrs · Permission: any member of the company · Effect: write · Idempotency-Key: accepted · Dry run: preview (checks the change and lists its effects, without making it) · MCP: tool ncrs_open

Input

Field Type Required Description
title string yes What's wrong, in a line
details string What was found: measurements, quantities, how it was noticed
foundOn string External id of the task it was found on (an operation or inspection): the NCR takes its machine and work order
ssuId string SSU external id, when not taken from foundOn
workOrderId string Work order external id, when not taken from foundOn
lotCode string The affected lot
productSku string The affected product
priorityId integer
assigneeIds integer[] Personnel ids

Output

Field Type Required Description
id string yes Task external id
title string yes
details string | null yes
status string yes
startDate string (date-time) | null yes
endDate string (date-time) | null yes
dueDate string (date-time) | null yes
priorityId integer yes
typeId string | null yes Task type external id
team object | null yes The team whose members see and take this task: its task type's team (change it on the type)
ssuId string | null yes SSU external id
externalSystemId string | null yes Your id for the task
incompleteReason string | null yes
declinedReason string | null yes
isPartialCompletion boolean yes Completed in part; a follow-up task carries the rest
handoffRole proxy | mirror | null yes proxy: you sent it to a partner; mirror: a partner sent it to you
problemCodeId integer | null yes Failure coding: what was wrong
causeCodeId integer | null yes Failure coding: why
remedyCodeId integer | null yes Failure coding: what fixed it
createdAt string (date-time) yes
updatedAt string (date-time) yes
foundOn string | null yes
lotCode string | null yes
productSku string | null yes

ncrs.disposition: Disposition an NCR

Decide what happens to nonconforming material, once per NCR. use_as_is: recorded only. rework: creates a rework task (of reworkTaskTypeId, or the NCR's own type). scrap: moves quantity of the lot to the bads bin and blocks the lot. return: blocks the lot for return to the vendor. Needs 'Disposition NCRs'.

REST: POST /api/v1/ncrs/:id/disposition · Permission: ncr:disposition · Effect: write · Idempotency-Key: accepted · Dry run: supported · MCP: tool ncrs_disposition

Input

Field Type Required Description
id string yes The NCR's task external id
disposition use_as_is | rework | scrap | return yes
lotCode string The affected lot (scrap and return act on it)
quantity number For scrap: how much of the lot
reworkTaskTypeId string For rework: the task type's external id
notes string

Output

Field Type Required Description
id string yes
disposition use_as_is | rework | scrap | return yes
lot object | null yes
reworkTaskId string | null yes The rework task's external id

Storylines

storylines.ssu: A machine's story

What happened on one machine (SSU) in a window (default: the last 7 days), as a chronological narrative: orders run, stops and their reasons, maintenance done, scrap and NCRs, meter readings, plus headline numbers. The best way to explain a machine's downtime.

REST: GET /api/v1/storylines/ssus/:id · Permission: maintenance:view · Effect: read · MCP: tool storylines_ssu

Input

Field Type Required Description
id string yes SSU external id
from string (date-time) | string (date)
to string (date-time) | string (date)

Output

Field Type Required Description
subject object yes
plotPoints object yes The story's headline numbers
chapters object[] yes

storylines.work_order: A work order's story

The life of one work order as a narrative: release, each operation started and finished, what was consumed and produced, scrap, quality checks and NCRs, shipment; with lead time and yield.

REST: GET /api/v1/storylines/work-orders/:id · Permission: production:view · Effect: read · MCP: tool storylines_work_order

Input

Field Type Required Description
id string yes Work order external id

Output

Field Type Required Description
subject object yes
plotPoints object yes The story's headline numbers
chapters object[] yes

Users

invitations.revoke: Revoke an invitation

Withdraw a pending invitation: it is revoked on WorkOS (the emailed link stops working) and the invitee is removed from the company, so the same address can be invited again.

Permission: users:manage · Effect: destructive · Idempotency-Key: not accepted · Dry run: not supported · MCP: no

Input

Field Type Required Description
userId string (uuid) yes The invited user's id (from the company's invitee list)

Output

Field Type Required Description
email string yes

invitations.resend: Resend an invitation

Email the invitee a new invitation with a fresh expiry, for one that expired or got lost. The previous invitation is revoked if it is still pending; the invitee keeps their role.

Permission: users:manage · Effect: write · Idempotency-Key: not accepted · Dry run: not supported · MCP: no

Input

Field Type Required Description
userId string (uuid) yes The invited user's id (from the company's invitee list)

Output

Field Type Required Description
email string yes
expiresAt string yes

Issues

issues.list: List reportable issues

The issues a member can report (e.g. Breakdown, Safety hazard). Each one is a form that files a task of its configured type on the chosen SSU.

Permission: any member of the company · Effect: read · MCP: no

Output

Field Type Required Description
issues object[] yes

issues.get_form: Get an issue's report form

The fields of an issue's report form, in order, as configured in the form builder: the same form the issue's QR code opens.

Permission: any member of the company · Effect: read · MCP: no

Input

Field Type Required Description
issueId string yes The issue's id (from issues.list)

Output

Field Type Required Description
id string yes
name string yes
items object[] yes

issues.upload_url: Get an upload URL for an issue photo

A short-lived URL to upload one photo for an issue report, stored where the QR flow stores its photos. PUT the file to it, then submit the URL without its query string as the answer.

Permission: any member of the company · Effect: write · Idempotency-Key: not accepted · Dry run: not supported · MCP: no

Input

Field Type Required Description
issueId string yes The issue's id (from issues.list)
fileName string yes
contentType string yes

Output

Field Type Required Description
uploadUrl string yes

issues.report: Report an issue

File an issue report on an SSU, as its QR code would: creates a task of the issue's type with the answers attached, and applies any SSU status the form's machine-status fields set.

Permission: any member of the company · Effect: write · Idempotency-Key: not accepted · Dry run: supported · MCP: no

Input

Field Type Required Description
issueId string yes The issue's id (from issues.list)
ssuId string yes The SSU's id
answers object[] yes

Output

Field Type Required Description
taskId string yes

Commissioning

config.export: Export the factory setup

The company's setup as a factory spec: settings, SSU statuses, reason codes, work centers, sites with their storage units and SSU trees, warehouses, product categories, vendors, products by SKU with their vendors, recipe and stock policies, parameter sets, task types with their forms, SLAs and gates, routings, per-machine signals, meters, condition rules and spare parts, flows, issue reports, inspection plans, and people (permission groups, roles, teams, skills, existing people by email, subcontractors). Everything is referenced by name, so the spec can be applied to another company as a template. Start here before changing setup: edit the export, then config.plan and config.apply.

REST: GET /api/v1/config/export · Permission: any member of the company · Effect: read · MCP: tool config_export

Output

Field Type Required Description
version number yes
settings object
ssuStatuses object[]
reasonCodes object[]
workCenters object[]
sites object[]
warehouses object[]
productCategories object[]
vendors object[]
products object[] Products by SKU, with their vendors, recipe and stock policies. No prices or costs
parameterSets object[]
taskTypes object[] Kinds of work, each with its form, SLAs and gates. People (default assignee, skills) come later
routings object[] Step sequences that work orders follow
machineData object[] Per machine: signals, meters, condition rules and spare parts
flows object[] Automations: a task's status change creates the next task
issues object[] Issue reports people can file (from the app or a QR code)
permissionGroups object[]
roles object[] What people are; each role grants one permission group
teams object[]
skills object[]
people object[] Users already in the company, by email: their roles, teams, skills. Specs never invite
subcontractors object[]
inspectionPlans object[] Which receipts or products must be inspected, and how
guidance object[] What the company tells every AI agent: company-wide and on specific machines, work centers, products, task types

config.validate: Validate a factory spec

Checks a spec beyond its schema: duplicate names or SKUs, references to statuses, work centers, reason codes, storage, categories, vendors, SKUs, task types, parameter sets or permission groups that don't exist, ambiguous names, a product both bought and made, gates naming fields the form doesn't have. Doesn't change anything.

REST: POST /api/v1/config/validate · Permission: any member of the company · Effect: read · MCP: tool config_validate

Input

Field Type Required Description
spec object yes The factory spec (export one with config.export to see the shape)

Output

Field Type Required Description
valid boolean yes
problems object[] yes

config.plan: Preview applying a factory spec

What config.apply would do, change by change: create, update (with each field's current and new value), unchanged, and extra (in the company but not in the spec). Doesn't change anything. Show this plan to the user before applying.

REST: POST /api/v1/config/plan · Permission: any member of the company · Effect: read · MCP: tool config_plan

Input

Field Type Required Description
spec object yes The factory spec (export one with config.export to see the shape)
prune boolean | true | false Also remove what the spec leaves out of the sections it includes. Records with history (sites, SSUs, reason codes, products) are deactivated, not deleted; vendors, categories, task types and routings are removed only when nothing uses them; parameter sets are never removed. REST only

Output

Field Type Required Description
valid boolean yes
problems object[] yes
summary object yes
changes object[] yes

config.apply: Apply a factory spec

Converges the company's setup to the spec, through the same rules as the dashboard; every change is audited. Safe to re-run: unchanged items are skipped. Not one transaction: if a change fails, the ones before it stay and the result says where it stopped; fix the cause and apply again. Always run config.plan first and get the user's go-ahead.

REST: POST /api/v1/config/apply · Permission: settings:manage or task_types:manage or clients:manage or inventory:manage or products:manage or production:manage or mobile_builder:manage or machine_data:manage or maintenance:manage or flows:manage or quality:manage or permissions:manage or personnel:manage or subcontractors:manage or ai_guidance:manage · Effect: write · Idempotency-Key: accepted · Dry run: not supported · MCP: tool config_apply

Input

Field Type Required Description
spec object yes The factory spec (export one with config.export to see the shape)
prune boolean | true | false Also remove what the spec leaves out of the sections it includes. Records with history (sites, SSUs, reason codes, products) are deactivated, not deleted; vendors, categories, task types and routings are removed only when nothing uses them; parameter sets are never removed. REST only

Output

Field Type Required Description
complete boolean yes
applied object[] yes
failed object
skipped integer yes Changes not attempted after a failure