Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.firstresonance.io/llms.txt

Use this file to discover all available pages before exploring further.

Overview

When you integrate against ION, eight or nine entities cover ~95% of what you’ll touch. This page walks through them top-down — what they represent, how they connect, and what they’re called in the systems you’re probably bridging from (ERP, MES, PLM, QMS). The full schema lives in schema.graphql and the API Playground — this page is the orientation, not the reference.

Entity map

                    ┌───────────────────┐
                    │   PartSubtype     │  ← categorization (M2M)
                    └────────┬──────────┘
                             │ tags
                    ┌────────▼──────────┐
                    │      Part         │  ← catalog item (design intent)
                    └────────┬──────────┘
                             │ instances of
                    ┌────────▼──────────┐
                    │  PartInventory    │  ← stockable / serialized unit
                    └─────┬────────┬────┘
                          │        │
              ┌───────────▼─┐   ┌──▼────────────┐
              │  Procedure  │   │  PurchaseOrder │
              │   (template)│   │   LineItems    │
              └───────┬─────┘   └────────────────┘
                      │ template for

              ┌───────▼─────┐    ┌──────────────────┐
              │     Run     │◀───│   RunBatch       │
              │ (execution) │    │ (batched runs)   │
              └───────┬─────┘    └──────────────────┘

              ┌───────▼─────┐    ┌──────────────────┐
              │   RunStep   │───▶│ BuildRequirement │
              │             │    │  (aBOM line item) │
              └───────┬─────┘    └──────────────────┘

              ┌───────▼─────┐
              │    Issue    │  ← quality event
              └─────────────┘
Solid arrows are 1→many; the diagram leaves out a lot of edges (file attachments, comments, approvals) for clarity.

Parts

A Part is the catalog entry — a part number, description, revision, and the design intent. Parts are not the physical thing on the shelf; that’s PartInventory.
FieldNotes
id, partNumberOrg-unique within revision; partNumber is your SKU
descriptionFree text
revisionEngineering revision letter or string
partTypepart or tool
trackingTypeserial, lot, or unset (untracked)
statusreleased or archived
sourcingStrategymake, buy, or dual_source
purchaseTypereceivable_inventory, receivable_non_inventory, or non_receivable_non_inventory
partSubtypesMany-to-many with PartSubtype — categorization tags
cost, leadTimeOptional planning fields
revisedFromIdLinks this revision to its predecessor
query GetPart {
  part(id: 42) {
    id
    partNumber
    description
    revision
    partType
    trackingType
    status
    partSubtypes { id name }
  }
}
Maps to: “SKU” or “Item Master” in ERP, “PartNumber” in PLM.

PartSubtype

A PartSubtype is the categorization tag attached to a Part. Subtypes are how you group parts that share routing, inspection, or planning behavior — e.g. “Mounting hardware”, “Critical-to-quality fasteners”, “Long-lead-time stock”. A part can have multiple subtypes.
query Subtypes {
  partSubtypes(filters: {}, limit: 50) {
    id
    name
    description
  }
}
Maps to: “Item Family”, “Commodity Code”, or “Product Line” in ERP. Don’t confuse with revision lineage — that’s revisedFromId on Part.

PartInventory

A PartInventory is a physical instance of a Part — a serialized unit, a lot, or a quantity at a location. This is the entity that gets installed onto assemblies, consumed in runs, or shipped.
FieldNotes
serialNumberIf the part is serialized
lotNumberIf the part is lot-tracked
quantityFor non-serialized inventory (count)
stateAvailable / consumed / shipped / scrapped / etc.
partReference to its Part
locationWhere it physically lives
parentPartInventoryIf installed onto an assembly, points up the build tree
entityPolymorphic id used for file attachments, etc.
query Inventory {
  partInventory(id: 9876) {
    id
    serialNumber
    lotNumber
    quantity
    state
    part { id partNumber description }
    location { id name }
    parentPartInventory { id serialNumber }
  }
}
Maps to: “Serial” or “Lot” in MES, “Inventory unit” / “Stockable item” in WMS, “Asset” in PLM.

Assemblies (as-built BOM)

An as-built BOM is the parent/child tree of PartInventory units that compose a finished assembly. ION represents this via the parentPartInventory reference on each PartInventory plus BuildRequirement records that say “to complete this assembly, install one of these parts here.” To traverse the tree downward:
query AbomTree {
  partInventory(id: 9876) {
    id
    serialNumber
    part { partNumber }
    buildRequirements {
      id
      part { partNumber }
      quantity
      installations {
        id
        installedPartInventory {
          id
          serialNumber
          part { partNumber }
        }
      }
    }
  }
}
To walk up the tree, follow parentPartInventory recursively. Maps to: “Bill of Materials” in ERP, “Assembly tree” in PLM, “Bill of Build” in MES.
mBOM vs aBOM: mBOM (manufacturing BOM) is the planned structure; aBOM (as-built) is what was actually installed at run time. Both have GraphQL types in ION; the aBOM is the post-execution truth.

Procedures and Steps

A Procedure is the manufacturing routing template — what should happen on the floor. It’s composed of Steps.
query Proc {
  procedure(id: 12) {
    id
    title
    revision
    steps {
      id
      title
      stepNumber
      stepType
      fields {
        id
        label
        fieldType
      }
    }
  }
}
Maps to: “Routing” in ERP, “Recipe” or “Standard Operating Procedure” in MES, “Work Instruction” in QMS.

Runs and RunSteps

A Run is one execution of a Procedure against a specific PartInventory. RunSteps are the per-execution instances of the procedure’s Steps — the place where operators record measurements, sign off, and report quality issues.
FieldNotes
id, title
statusPending / In progress / Complete / etc.
procedureTemplate
partInventoryWhat’s being built
runStepsOrdered execution instances
runBatchIf the run participates in a batch (see Run Batches)
query GetRun {
  run(id: 1234) {
    id
    title
    status
    procedure { id title revision }
    partInventory { id serialNumber part { partNumber } }
    runSteps {
      id
      stepNumber
      status
      completedAt
      runStepFields { id label value }
    }
  }
}
Maps to: “Work Order” in ERP, “Production Order” in MES, “Build” or “Job” colloquially.

Build Requirements

A BuildRequirement is a line item on an aBOM that says “to complete this assembly, install N of this part.” Operators install against build requirements during a run; each install is a row of Installations linking the PartInventory consumed to the build requirement satisfied. See Editing Build Requirements for the user-facing flow.

Issues

An Issue is a quality event — nonconformance, deviation, supplier problem, observation. Issues attach to runs, run steps, or part inventories and follow a defined lifecycle (Pending → In Progress → In Review → Resolved). Disposition types determine what happens to the affected material.
query OpenIssues {
  issues(filters: { status: "in_progress" }) {
    id
    title
    status
    issueDispositionType { id title }
    assignedTo { id name }
    runStep { id }
  }
}
See Issue States, Dispositions, and Resolutions. Maps to: “Nonconformance Report” (NCR) in QMS, “CAPA” precursor in QMS, “Defect” in PLM, “Incident” in ServiceNow-style systems.

Purchase Orders

For supply chain integrations:
query OpenPOs {
  purchaseOrders(filters: { status: "open" }) {
    id
    poNumber
    status
    vendor { id name }
    lineItems {
      id
      part { partNumber }
      quantity
      receivedQuantity
    }
  }
}
Maps to: “PO” in ERP. Receiving against a PO updates PartInventory records.

File Attachments

Files attach to entities polymorphically via the entity ID. See File Upload for the upload flow and the entity { id } lookup pattern.

The entity polymorphic ID

ION uses an entities table to give every attachable object a uniform ID. Most major entities expose an entity { id } field — used as the target for:
  • File attachments
  • Subscriptions (notifications)
  • Comments
  • Cross-entity links (e.g. issue-to-run-step)
Don’t confuse this with the entity’s own id. When you see an integration calling for an entityId, fetch the parent’s entity.id first.

Field-mapping cheat sheet

When you’re bridging from another system, here’s the rough translation:
Your system says…ION calls it…
SKU / Item Master / Part NumberPart.partNumber
Item Family / Commodity / GroupPartSubtype.name (a part can belong to multiple subtypes)
Lot / Batch numberPartInventory.lotNumber
Serial / Asset TagPartInventory.serialNumber
On-hand quantityPartInventory.quantity
BOM line itemBuildRequirement
Work Order / Production OrderRun
Routing / Recipe / ProcessProcedure
Operation / Step / OpStep (template) / RunStep (execution)
NCR / NonconformanceIssue
Disposition (Use As Is, Rework, Scrap)IssueDispositionType
POPurchaseOrder
PO linePurchaseOrderLineItem
Vendor / SupplierPurchaseOrder.vendor (an Organization)
Workcenter / CellLocation (typed WORKCENTER)
Tote / Bin / RackLocation (other types)
User group / RoleRole
UserUser
Tenant / OrgOrganization

Etag-based concurrency

Every mutable entity returns an _etag on read. Pass it back on update/delete mutations; ION rejects writes whose etag doesn’t match the current row state with a 409 (see Error Codes → 409). This is how ION prevents lost-update races. When integrating: always read-then-write inside a short window, and propagate the etag through your service.

Discovering the rest of the schema

Three ways to find anything not on this page:
  1. API Playground — interactive schema explorer at /api-reference/playground
  2. schema.graphql — committed to this repository, kept in sync with diplo
  3. __schema introspection — programmatic access; see GraphQL Field Selection → Discovering available fields