## Main Content

This page collects the most common queries and mutations you can run on the ION API. The quickest way to run them is through the [API Playground](https://docs.firstresonance.io/api-reference/playground).

### Queries

- **Search parts**  
Find parts by part number or description substring:

```
    query SearchParts($q: String!, $first: Int) {
      parts(filters: { partNumber: { ilike: $q } }, first: $first) {
        edges {
          node {
            id
            partNumber
            description
            revision
            partType
            status
            partSubtypes { id name }
          }
        }
      }
    }
    ```
    
    ```
    { "q": "%BRKT%", "first": 25 }
    ```

- **Get a procedure with all steps**  
Fetch a procedure template plus every step and its fields:

```
    query GetProcedure($id: Int!) {
      procedure(id: $id) {
        id
        title
        steps {
          id
          title
          fields { id }
        }
      }
    }
    ```
    
    ```
    { "id": 12 }
    ```

- **Get an aBOM with full hierarchy**  
Walk an as-built BOM tree from the parent down to all installations:

```
    query AbomTree($id: Int!) {
      partInventory(id: $id) {
        id
        serialNumber
        part { partNumber }
        buildRequirements {
          id
          part { partNumber }
          quantity
        }
      }
    }
    ```
    
    ```
    { "id": 9876 }
    ```

- **Compare two aBOM versions**  
Pull two as-built BOMs and diff them client-side:

```
    query CompareAboms($idA: Int!, $idB: Int!) {
      a: partInventory(id: $idA) {
        id
        serialNumber
        buildRequirements { id part { partNumber } quantity }
      }
      b: partInventory(id: $idB) {
        id
        serialNumber
        buildRequirements { id part { partNumber } quantity }
      }
    }
    ```
    
    ```
    { "idA": 9876, "idB": 9877 }
    ```

- **List open runs with current step**  
Get every run that’s in progress, with the current step the operator is on:

```
    query OpenRuns {
      runs(filters: { status: { in: ["TODO", "IN_PROGRESS"] } }, first: 100) {
        edges {
          node {
            id
            title
            status
            procedure { id title }
            partInventory { id serialNumber part { partNumber } }
          }
        }
      }
    }
    ```

- **Run history for a part**  
Every run a specific part inventory has gone through, newest first:

```
    query RunHistory($partInventoryId: Int!) {
      runs(
        filters: { partInventoryId: { eq: $partInventoryId } }
        first: 50
      ) {
        edges {
          node {
            id
            title
            status
            _created
            procedure { id title }
          }
        }
      }
    }
    ```
    
    ```
    { "partInventoryId": 9876 }
    ```

- **Inventory for a part by location**  
List inventory units of a given part, grouped by physical location:

```
    query InventoryByLocation($partId: Int!) {
      partInventories(filters: { partId: { eq: $partId } }, first: 250) {
        edges {
          node {
            id
            serialNumber
            lotNumber
            quantity
            status
            location { id name type }
          }
        }
      }
    }
    ```
    
    ```
    { "partId": 12 }
    ```

- **Serialized units for a part**  
Get every serialized instance of a part with its current state:

```
    query SerializedUnits($partId: Int!) {
      partInventories(filters: { partId: { eq: $partId } }, first: 250) {
        edges {
          node {
            id
            serialNumber
            status
            location { id name }
          }
        }
      }
    }
    ```
    
    ```
    { "partId": 12 }
    ```

- **List open issues by disposition**  
All open issues grouped by disposition type for triage:

```
    query OpenIssuesByDisposition {
      issues(
        filters: { status: { in: ["PENDING", "IN_PROGRESS", "IN_REVIEW"] } }
        first: 250
      ) {
        edges {
          node {
            id
            title
            status
            issueDispositionType { id title }
            assignedTo { id name }
            _created
          }
        }
      }
    }
    ```

- **Get current user and org**  
Verify your token and find which org you’re in:

```
    query Me {
      me {
        id
        name
        email
        organization { id domain }
      }
    }
    ```

### Mutations

- **Create a part**  
Create a new part in the library:

```
    mutation CreatePart($input: CreatePartInput!) {
      createPart(input: $input) {
        part { id partNumber description revision partType status }
      }
    }
    ```
    
    ```
    {
      "input": {
        "partNumber": "TEST-001",
        "description": "Integration test part",
        "revision": "A",
        "partType": "part",
        "trackingType": "lot"
      }
    }
    ```

- **Create a run from a procedure**  
Start a new run by binding a procedure to a part inventory:

```
    mutation CreateRun($input: CreateRunInput!) {
      createRun(input: $input) {
        run {
          id
          title
          status
          procedure { id title }
          partInventory { id serialNumber }
        }
      }
    }
    ```
    
    ```
    {
      "input": {
        "procedureId": 12,
        "partInventoryId": 9876,
        "title": "Build #2026-04-26 Unit 1"
      }
    }
    ```

- **Submit a run step result**  
Sign off a step with measurements. Requires the step’s `_etag`:

```
    mutation SubmitStep($input: UpdateRunStepInput!) {
      updateRunStep(input: $input) {
        runStep {
          id
          status
          fields { id name value }
        }
      }
    }
    ```
    
    ```
    {
      "input": {
        "id": 4567,
        "_etag": "abc123",
        "status": "complete",
        "fieldValues": [
          { "runStepFieldId": 88, "value": "PASS" },
          { "runStepFieldId": 89, "value": "12.45" }
        ]
      }
    }
    ```

- **Start or complete a run**  
Move a run between lifecycle states:

```
    mutation UpdateRunStatus($input: UpdateRunInput!) {
      updateRun(input: $input) {
        run { id status startTime endTime }
      }
    }
    ```
    
    ```
    {
      "input": {
        "id": 1234,
        "_etag": "xyz789",
        "status": "complete"
      }
    }
    ```

- **Create a purchase order**  
Issue a new PO with line items:

```
    mutation CreatePO($input: CreatePurchaseOrderInput!) {
      createPurchaseOrder(input: $input) {
        purchaseOrder {
          id
          status
          supplier { id name }
          purchaseOrderLines { id part { partNumber } quantity }
        }
      }
    }
    ```
    
    ```
    {
      "input": {
        "vendorId": 42,
        "lineItems": [
          { "partId": 12, "quantity": 100 },
          { "partId": 13, "quantity": 50 }
        ]
      }
    }
    ```

- **Create an issue linked to a run**  
Open a quality issue tied to a specific run step:

```
    mutation CreateIssue($input: CreateIssueInput!) {
      createIssue(input: $input) {
        issue {
          id
          title
          status
          runStep { id }
        }
      }
    }
    ```
    
    ```
    {
      "input": {
        "title": "Surface scratches on RX-22 lot 4",
        "runStepId": 4567,
        "description": "Visible scratches across 4 of 12 units"
      }
    }
    ```

- **Close an issue with a resolution**  
Move an issue to resolved once reviews are signed off:

```
    mutation ResolveIssue($input: UpdateIssueInput!) {
      updateIssue(input: $input) {
        issue { id status }
      }
    }
    ```
    
    ```
    {
      "input": {
        "id": 7777,
        "_etag": "etag-value",
        "status": "resolved"
      }
    }
    ```
