Zudo Works

Manufacturing OS endpoints

Conventions as in §31. All paths are under /api/v1.

Comments and people

Method & pathBody / queryPermission
GET /comments?table_key=&row_id=&include_resolved=1threads of a table (or one row)the table's read permission
POST /commentstable_key, row_id, column_key?, row_label?, body (mentions @Display Name notify)the table's read permission
PATCH /comments/:idbody? and / or resolved?author or settings.manage
DELETE /comments/:id—author or settings.manage
GET /directory/usersactive people: id, display_name (for @mentions and owners)any signed-in user

Fields

Method & pathBody / queryPermission
GET /forms/:id/records?keys=api · GET /forms/:id/records/:rid?keys=apirecord data keyed by API nameforms.read
POST /forms/:id/records?keys=api · PUT …/:rid?keys=apidata keyed by API name (or by field id without the query)forms.write
PATCH /ui-configfields: { items: { standard_cost: { label?, order?, help?, hidden? } } }settings.manage

Schedules

Method & pathBody / queryPermission
GET /schedules · GET /:id—workflows.manage
GET /schedules/targetsthe modules and forms an update may target, with their writable fieldsworkflows.manage
POST /schedulesname, description?, is_active?, cadence { kind: once\|interval\|daily\|weekly\|monthly, … }, action { kind: update_fields\|run_function\|import_csv, … }workflows.manage
PATCH /schedules/:idany of the aboveworkflows.manage
POST /schedules/:id/runruns now → the runworkflows.manage
GET /schedules/:id/runsthe run log (newest first)workflows.manage
DELETE /schedules/:id—workflows.manage

Cadences: { kind: "once", at } · { kind: "interval", every_minutes, from?, to? } · { kind: "daily", time, from?, to? } · { kind: "weekly", days: [1,3], time, from?, to? } · { kind: "monthly", day, time, from?, to? }. Actions: { kind: "update_fields", target: { kind: "module", module } | { kind: "form", form_id }, condition: { match, conditions[] }, set: [{ field, value }] } · { kind: "run_function", function_id, args } · { kind: "import_csv", import_id, batch_size }.

Imports

Method & pathBody / queryPermission
GET /imports/targetstargets (built-in sections and custom forms) with their fieldssigned in
GET /imports · GET /:idimports of the workspace / one import with its countsthe target's write permission
POST /importsJSON { target: { kind: "module", module } \| { kind: "form", form_id }, file_name, content, delimiter? } or multipart file + targetthe target's write permission
PUT /imports/:id/mapping{ columns: { "<csv header>": "<field key>" }, options: { update_existing, key_field } } → validates every rowthe target's write permission
GET /imports/:id/rows?status=invalidrows with their messagesthe target's write permission
POST /imports/:id/start≤ 200 valid rows: imports now; more: creates the schedule and returns itthe target's write permission
POST /imports/:id/cancel—the target's write permission
GET /imports/:id/errors.csvthe failed rows as CSVthe target's write permission
DELETE /imports/:id—the target's write permission

CRM

Method & pathBody / queryPermission
GET /leads?status=&search= · GET /:id—sales.read
POST /leads · PATCH /:id · DELETE /:idname, company?, email?, phone?, source?, status?, estimated_value?, owner_user_id?, notes?sales.write
POST /leads/:id/convertcustomer_id? (attach to an existing customer), opportunity? { name, amount?, expected_close? } → { lead, opportunity }sales.write
GET /opportunities?stage=&customer_id=&search= · GET /:id—sales.read
GET /opportunities/pipelineper stage: count, amount, weightedsales.read
POST /opportunities · PATCH /:id · DELETE /:idcustomer_id, name, stage?, amount?, probability?, expected_close?, owner_user_id?, lead_id?, notes?sales.write
POST /sales-orders… plus opportunity_id? — confirming the order marks the deal wonsales.write

Shipments, invoices, payments, vendor bills

Method & pathBody / queryPermission
GET /shipments?status=&sales_order_id= · GET /:id—sales.read
GET /shipments/outstanding/:orderIdper line: line_id, item_id, outstandingsales.read
POST /shipmentssales_order_id, warehouse_id, ship_date, carrier?, tracking_no?, notes?, lines?[{ sales_order_line_id, quantity }] (omit lines = everything outstanding) → DN-…sales.write
POST /shipments/:id/ship{ idempotency_key } → { shipment, movement, order_status } (posts ISS-…)stock.post
POST /shipments/:id/cancel—sales.write
GET /invoices?status=&customer_id=&sales_order_id= · GET /:id—sales.read
GET /invoices/summaryopen, overdue, paid_month, count_opensales.read
GET /invoices/:id/pdfthe PDFsales.read
POST /invoices · PUT /:id (draft)customer_id, sales_order_id?, shipment_id?, invoice_date, due_date?, tax_rate?, customer_reference?, notes?, lines[{ item_id?, description, quantity, unit_price }] → INV-…sales.write
POST /invoices/:id/issue · /void—sales.write
POST /invoices/:id/paymentsamount, paid_on, method?, reference?, notes? → PAY-…; status follows the balancesales.write
DELETE /invoices/:id/payments/:paymentId—sales.write
GET /vendor-bills?status=&vendor_id=&purchase_order_id= · GET /:id—purchasing.read
POST /vendor-bills · PUT /:id (draft)vendor_id, purchase_order_id?, bill_date, due_date?, vendor_invoice_no?, tax_rate?, notes?, lines[…] → BILL-…purchasing.write
POST /vendor-bills/:id/approve · /void—purchasing.write
POST /vendor-bills/:id/payments · DELETE …/:paymentIdamount, paid_on, method?, reference?, notes? → VPAY-…purchasing.write

Quality

Method & pathBody / queryPermission
GET /inspections?result=&item_id= · GET /:id—jobs.read
POST /inspections · PUT /:id · DELETE /:idsource_type?, source_ref?, item_id, quantity_inspected, quantity_passed?, quantity_failed?, result, inspected_on, inspector?, checklist?[{ point, ok, note? }], notes? → INS-…jobs.write
GET /ncrs?status=&severity= · GET /:id—jobs.read
POST /ncrs · PATCH /:id · DELETE /:idtitle, description?, item_id?, inspection_id?, source_ref?, severity?, quantity?, root_cause?, containment?, disposition?, owner_user_id?, due_date? → NCR-…jobs.write
POST /ncrs/:id/status{ status } along the state machinejobs.write
GET /capas?status=&ncr_id= · GET /:id—jobs.read
POST /capas · PATCH /:id · DELETE /:idtitle, type?, ncr_id?, description?, actions?, owner_user_id?, due_date?, effectiveness_check? → CAPA-…jobs.write
POST /capas/:id/status{ status } along the state machinejobs.write

Errors follow §42: a wrong step is invalid_transition (409), delivering more than is outstanding or paying more than the balance is validation_failed (400), and a missing document is not_found (404).

Last updated