> For the complete documentation index, see [llms.txt](https://docs.durohub.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.durohub.com/core-concepts/components.md).

# Components

Components are the fundamental building blocks in Duro. They represent parts, assemblies, documents, and other items that make up your products. This guide covers how to query, create, and update components through the API.

## Overview

Every component in Duro has:

* A unique identifier (`id`)
* A name and optional description
* A revision value (e.g., "1.A", "2.B") tracking design iterations
* A category defining its type (Part, Assembly, Document, etc.)
* A status indicating its lifecycle state
* Attributes specific to its category

## Required Headers

All component operations require these headers:

```bash
curl 'https://api.durohub.com/graphql' \
  -H 'x-api-key: YOUR_API_KEY' \
  -H 'x-organization: @your-org' \
  -H 'x-library: @your-org/your-library' \
  -H 'Content-Type: application/json' \
  -d '{"query": "..."}'
```

{% hint style="info" %}
The `x-library` header is required for all component operations since components belong to a specific library.
{% endhint %}

***

## Querying Components

### Get a Single Component

Retrieve a component by its ID:

```graphql
query GetComponent {
  component {
    findOne(id: "550e8400-e29b-41d4-a716-446655440000") {
      id
      name
      description
      revisionValue
      version
      state
      status {
        name
        color
      }
      category {
        name
        type
      }
      createdAt
      updatedAt
    }
  }
}
```

### List Components

Query multiple components with optional filtering and pagination:

```graphql
query ListComponents {
  component {
    findAll(
      filter: {
        categoryType: PART
        isArchived: false
      }
      pagination: { first: 20 }
    ) {
      edges {
        node {
          id
          name
          revisionValue
          version
          status {
            name
          }
          category {
            name
          }
        }
      }
      pageInfo {
        hasNextPage
        endCursor
      }
    }
  }
}
```

### Filter Options

The `ComponentFilterInput` supports these fields:

| Field          | Type           | Description                                        |
| -------------- | -------------- | -------------------------------------------------- |
| `ids`          | `[ID!]`        | Filter by specific component IDs                   |
| `name`         | `String`       | Filter by name (partial match)                     |
| `names`        | `[String!]`    | Filter by multiple names                           |
| `exactNames`   | `[String!]`    | Filter by exact name matches                       |
| `cpns`         | `[String!]`    | Filter by Component Part Numbers                   |
| `statusId`     | `String`       | Filter by status ID                                |
| `categoryId`   | `String`       | Filter by category ID                              |
| `categoryType` | `CategoryType` | Filter by category type (ASSEMBLY, PART, DOCUMENT) |
| `isArchived`   | `Boolean`      | Include/exclude archived components                |
| `eid`          | `String`       | Filter by external identifier                      |

### Advanced Filtering

For complex queries with AND/OR logic, use the `filter` method:

```graphql
query AdvancedFilter {
  component {
    filter(input: {
      and: [
        { status: { name: "Released" } }
        { category: { type: PART } }
        { createdAt: { gte: "2024-01-01" } }
      ]
      pagination: { first: 50 }
    }) {
      edges {
        node {
          id
          name
          revisionValue
        }
      }
    }
  }
}
```

See [Searching and Filtering](/advanced-topics/searching-and-filtering.md) for comprehensive filtering options.

### Organizing Components into Groups

Group components by category, lifecycle status, type, modified-by user, or label — server-side, in a single call:

```graphql
query GroupByCategory {
  component {
    componentGroups(groupBy: CATEGORY, pagination: { first: 10 }) {
      edges {
        node {
          key
          label
          totalCount
          components {
            edges { node { id name } }
            pageInfo { hasNextPage }
          }
        }
      }
      totalCount
    }
  }
}
```

Each group returns a preview of up to 50 components. Groups with more items signal overflow via `components.pageInfo.hasNextPage`, and the remaining items can be loaded incrementally with the `componentsInGroup` query.

Grouping works with both simple and advanced filters — pass `filter` or `advancedFilter` alongside `groupBy` to scope results before grouping.

See [Component Grouping](/advanced-topics/component-grouping.md) for the full guide, including sorting within groups, sentinel keys for uncategorized items, and the complete API reference.

***

## Creating Components

Create one or more components using the `create` mutation:

```graphql
mutation CreateComponent {
  component {
    create(inputs: [{
      name: "Motor Assembly"
      description: "Primary drive motor assembly"
      categoryId: "category-uuid"
      attributeValues: [
        { attributeId: "attr-uuid-1", value: "12V" }
        { attributeId: "attr-uuid-2", value: "50W" }
      ]
    }]) {
      id
      name
      revisionValue
      version
      createdAt
    }
  }
}
```

### CreateComponentInput Fields

| Field             | Type                     | Required | Description                                         |
| ----------------- | ------------------------ | -------- | --------------------------------------------------- |
| `name`            | `String`                 | Yes      | Component name                                      |
| `description`     | `String`                 | No       | Detailed description                                |
| `categoryId`      | `String`                 | No       | Category/type for this component                    |
| `statusId`        | `ID`                     | No       | Initial status                                      |
| `revisionValue`   | `String`                 | No       | Initial revision (defaults based on library config) |
| `eid`             | `String`                 | No       | External identifier for integrations                |
| `attributeValues` | `[AttributeValueInput!]` | No       | Category-specific attribute values                  |
| `fileId`          | `ID`                     | No       | Attached file ID                                    |
| `imageFileId`     | `ID`                     | No       | Component image file ID                             |

### Example Response

```json
{
  "data": {
    "component": {
      "create": [
        {
          "id": "123e4567-e89b-12d3-a456-426614174000",
          "name": "Motor Assembly",
          "revisionValue": "1.A",
          "version": 1,
          "createdAt": "2024-01-15T10:30:00Z"
        }
      ]
    }
  }
}
```

***

## Updating Components

Update existing components using the `update` mutation:

```graphql
mutation UpdateComponent {
  component {
    update(inputs: [{
      id: "123e4567-e89b-12d3-a456-426614174000"
      name: "Motor Assembly v2"
      description: "Updated drive motor with improved efficiency"
      expectedVersion: 1
    }]) {
      id
      name
      description
      version
      updatedAt
    }
  }
}
```

{% hint style="warning" %}
**Optimistic Concurrency**: Use `expectedVersion` to prevent overwriting concurrent changes. If the current version doesn't match, the update will fail with a conflict error.
{% endhint %}

### UpdateComponentInput Fields

| Field             | Type                     | Description                        |
| ----------------- | ------------------------ | ---------------------------------- |
| `id`              | `ID!`                    | Component ID to update (required)  |
| `name`            | `String`                 | New name                           |
| `description`     | `String`                 | New description                    |
| `statusId`        | `ID`                     | New status                         |
| `revisionValue`   | `String`                 | New revision value                 |
| `categoryId`      | `ID`                     | Change category                    |
| `attributeValues` | `[AttributeValueInput!]` | Updated attribute values           |
| `isArchived`      | `Boolean`                | Archive/unarchive the component    |
| `expectedVersion` | `Int`                    | For optimistic concurrency control |

***

## Deleting Components

Delete components by their IDs:

```graphql
mutation DeleteComponents {
  component {
    delete(ids: ["component-uuid-1", "component-uuid-2"])
  }
}
```

{% hint style="warning" %}
Deleting components is permanent. Consider archiving instead by setting `isArchived: true` in an update mutation.
{% endhint %}

***

## Component States and Revisions

### State

Components have a `state` field indicating their modification status:

| State      | Description                      |
| ---------- | -------------------------------- |
| `RELEASED` | Component is released and locked |
| `MODIFIED` | Component has unreleased changes |

### Revisions

The `revisionValue` field tracks design iterations (e.g., "1.A", "1.B", "2.A"). Revision schemes are configured per-library. See [Revision Scheme](/library-configuration/revisions.md) for configuration options.

***

## Working with Assemblies

Assemblies are components that contain other components. Query assembly structure using:

```graphql
query GetAssemblyStructure {
  component {
    findOne(id: "assembly-uuid") {
      id
      name
      category {
        type  # Will be ASSEMBLY
      }
    }
  }
}
```

{% hint style="info" %}
For detailed BOM (Bill of Materials) operations, use the `assemblies` namespace. See assembly documentation for more details.
{% endhint %}

***

## Complete cURL Example

Here's a complete example creating a component:

```bash
curl 'https://api.durohub.com/graphql' \
  -H 'x-api-key: YOUR_API_KEY' \
  -H 'x-organization: @acme-corp' \
  -H 'x-library: @acme-corp/main-library' \
  -H 'Content-Type: application/json' \
  -d '{
    "query": "mutation CreateComponent($input: [CreateComponentInput!]!) { component { create(inputs: $input) { id name revisionValue } } }",
    "variables": {
      "input": [{
        "name": "Capacitor 100uF",
        "description": "Electrolytic capacitor, 100uF 25V",
        "categoryId": "part-category-uuid"
      }]
    }
  }'
```

***

## Next Steps

* Learn about [Documents](/core-concepts/documents.md) associated with components
* Explore [Change Orders](/core-concepts/change-orders.md) for managing component modifications
* See [Searching and Filtering](/advanced-topics/searching-and-filtering.md) for advanced queries


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.durohub.com/core-concepts/components.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
