> ## Documentation Index
> Fetch the complete documentation index at: https://lava.so/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Duro PLM v1

> GraphQL API for Duro PLM v1, the legacy Duro platform at mfg.duro.app.

GraphQL API for Duro PLM v1, the legacy Duro platform at mfg.duro.app. Use when a customer's Duro lives at mfg.duro.app (component links look like mfg.duro.app/component/view/{id}); customers on the new platform, durohub.com, connect the separate "Duro Design" provider (`duro`) instead. Query and manage the v1 data model: components, products, component trees/revisions, categories, change orders, libraries, and webhooks, with create/update/delete mutations. Every request is a POST to [https://mfg.duro.app/graphql](https://mfg.duro.app/graphql) with the operation in the body; see the routing hint for the v1 query shapes, which differ from Duro Design's.

7 example endpoints available through Lava's AI Gateway. See the [Duro PLM v1 API docs](https://mfg-core-api.duro.app/docs/) for full documentation.

<Warning>This provider requires your own credentials — connect your API key or OAuth account before use.</Warning>

<Info>This is a **catch-all provider** — any valid URL under `https://mfg.duro.app/graphql` is supported. Duro PLM v1 (legacy) GraphQL API. Single endpoint: POST [https://mfg.duro.app/graphql](https://mfg.duro.app/graphql) with a JSON body containing a "query" string and optional "variables". Auth is supplied automatically (apiToken header). The v1 schema differs from Duro Design: list queries are top-level and wrap results in connection envelopes, e.g. components(libraryType: GENERAL) \{ connection(first: N, after: cursor) \{ totalCount pageInfo \{ hasNextPage endCursor } edges \{ cursor node \{ id name } } } }. Lookups by id use plural ByIds queries: componentsByIds(ids: \[...]), productsByIds, changeOrdersByIds, categoriesByIds, componentRevisionsByIds, productRevisionsByIds. Other queries: componentTreeById / componentTreeByIds (assembly trees), products, changeOrders, categories, libraries, tokenActiveLibrary (which library the token operates in; the "hello world" auth check), userById, webhooksByIds, apiToken (mints a fresh 90-day token from the current one). Mutations: createComponent, updateComponent, deleteComponent, createProduct, updateProduct, deleteProduct, createChangeOrder, updateChangeOrder, deleteChangeOrder, createDocuments, deleteDocuments, createWebhook, deleteWebhookById, updateCategories, and change-order approval template CRUD. IDs are 24-char hex strings (mfg.duro.app/component/view/\{id} in the web app). Full reference: [https://mfg-core-api.duro.app/docs/](https://mfg-core-api.duro.app/docs/). ITAR-hosted customers (app.govduro.us) are not routed by this provider. The endpoints below are curated examples.</Info>

## Endpoints

### Show which library the connected token operates in. Use as the auth/connectivity check (the "hello world" query).

**POST** `https://mfg.duro.app/graphql` — Free

<Tabs>
  <Tab title="SDK">
    ```typescript theme={null}
    const data = await lava.gateway('https://mfg.duro.app/graphql', {
      body: {
    "query": "query { tokenActiveLibrary { id name description } }"
    },
    });
    ```
  </Tab>

  <Tab title="cURL">
    ```bash theme={null}
    curl -X POST "https://api.lava.so/v1/forward?u=https%3A%2F%2Fmfg.duro.app%2Fgraphql" \
      -H "Authorization: Bearer $LAVA_SECRET_KEY" \
      -H "Content-Type: application/json" \
      -d '{"query":"query { tokenActiveLibrary { id name description } }"}'
    ```
  </Tab>
</Tabs>

### List components in the company (GENERAL) library with relay pagination. Sortable by name, date, mass, revision, category.

**POST** `https://mfg.duro.app/graphql` — Free

<Tabs>
  <Tab title="SDK">
    ```typescript theme={null}
    const data = await lava.gateway('https://mfg.duro.app/graphql', {
      body: {
    "query": "query ListComponents { components(libraryType: GENERAL) { connection(first: 50) { totalCount pageInfo { hasNextPage endCursor } edges { node { id name created lastModified } } } } }"
    },
    });
    ```
  </Tab>

  <Tab title="cURL">
    ```bash theme={null}
    curl -X POST "https://api.lava.so/v1/forward?u=https%3A%2F%2Fmfg.duro.app%2Fgraphql" \
      -H "Authorization: Bearer $LAVA_SECRET_KEY" \
      -H "Content-Type: application/json" \
      -d '{"query":"query ListComponents { components(libraryType: GENERAL) { connection(first: 50) { totalCount pageInfo { hasNextPage endCursor } edges { node { id name created lastModified } } } } }"}'
    ```
  </Tab>
</Tabs>

### Fetch components by their 24-char hex ids, including CPN, children (BOM), and revision history.

**POST** `https://mfg.duro.app/graphql` — Free

<Tabs>
  <Tab title="SDK">
    ```typescript theme={null}
    const data = await lava.gateway('https://mfg.duro.app/graphql', {
      body: {
    "query": "query ComponentsByIds($ids: [ID!]) { componentsByIds(ids: $ids) { id alias name cpn { displayValue } children { itemNumber quantity } revisionHistory { id name } } }",
    "variables": {
      "ids": [
        "6a3941c43241d10008131111"
      ]
    }
    },
    });
    ```
  </Tab>

  <Tab title="cURL">
    ```bash theme={null}
    curl -X POST "https://api.lava.so/v1/forward?u=https%3A%2F%2Fmfg.duro.app%2Fgraphql" \
      -H "Authorization: Bearer $LAVA_SECRET_KEY" \
      -H "Content-Type: application/json" \
      -d '{"query":"query ComponentsByIds($ids: [ID!]) { componentsByIds(ids: $ids) { id alias name cpn { displayValue } children { itemNumber quantity } revisionHistory { id name } } }","variables":{"ids":["6a3941c43241d10008131111"]}}'
    ```
  </Tab>
</Tabs>

### Fetch the full assembly tree (BOM hierarchy) for a component by id.

**POST** `https://mfg.duro.app/graphql` — Free

<Tabs>
  <Tab title="SDK">
    ```typescript theme={null}
    const data = await lava.gateway('https://mfg.duro.app/graphql', {
      body: {
    "query": "query Tree($id: ID!) { componentTreeById(id: $id) { id name children { id name children { id name } } } }",
    "variables": {
      "id": "6a3941c43241d10008131111"
    }
    },
    });
    ```
  </Tab>

  <Tab title="cURL">
    ```bash theme={null}
    curl -X POST "https://api.lava.so/v1/forward?u=https%3A%2F%2Fmfg.duro.app%2Fgraphql" \
      -H "Authorization: Bearer $LAVA_SECRET_KEY" \
      -H "Content-Type: application/json" \
      -d '{"query":"query Tree($id: ID!) { componentTreeById(id: $id) { id name children { id name children { id name } } } }","variables":{"id":"6a3941c43241d10008131111"}}'
    ```
  </Tab>
</Tabs>

### List products (top-level sellable assemblies) with relay pagination.

**POST** `https://mfg.duro.app/graphql` — Free

<Tabs>
  <Tab title="SDK">
    ```typescript theme={null}
    const data = await lava.gateway('https://mfg.duro.app/graphql', {
      body: {
    "query": "query ListProducts { products { connection(first: 50) { totalCount edges { node { id name created lastModified } } } } }"
    },
    });
    ```
  </Tab>

  <Tab title="cURL">
    ```bash theme={null}
    curl -X POST "https://api.lava.so/v1/forward?u=https%3A%2F%2Fmfg.duro.app%2Fgraphql" \
      -H "Authorization: Bearer $LAVA_SECRET_KEY" \
      -H "Content-Type: application/json" \
      -d '{"query":"query ListProducts { products { connection(first: 50) { totalCount edges { node { id name created lastModified } } } } }"}'
    ```
  </Tab>
</Tabs>

### List change orders (ECOs) with relay pagination.

**POST** `https://mfg.duro.app/graphql` — Free

<Tabs>
  <Tab title="SDK">
    ```typescript theme={null}
    const data = await lava.gateway('https://mfg.duro.app/graphql', {
      body: {
    "query": "query ListChangeOrders { changeOrders { connection(first: 50) { totalCount edges { node { id name status created } } } } }"
    },
    });
    ```
  </Tab>

  <Tab title="cURL">
    ```bash theme={null}
    curl -X POST "https://api.lava.so/v1/forward?u=https%3A%2F%2Fmfg.duro.app%2Fgraphql" \
      -H "Authorization: Bearer $LAVA_SECRET_KEY" \
      -H "Content-Type: application/json" \
      -d '{"query":"query ListChangeOrders { changeOrders { connection(first: 50) { totalCount edges { node { id name status created } } } } }"}'
    ```
  </Tab>
</Tabs>

### Mint a fresh 90-day API token using the currently connected token. Reconnect with the returned value before the old one expires.

**POST** `https://mfg.duro.app/graphql` — Free

<Tabs>
  <Tab title="SDK">
    ```typescript theme={null}
    const data = await lava.gateway('https://mfg.duro.app/graphql', { body: {"query":"query { apiToken { token } }"} });
    ```
  </Tab>

  <Tab title="cURL">
    ```bash theme={null}
    curl -X POST "https://api.lava.so/v1/forward?u=https%3A%2F%2Fmfg.duro.app%2Fgraphql" \
      -H "Authorization: Bearer $LAVA_SECRET_KEY" \
      -H "Content-Type: application/json" \
      -d '{"query":"query { apiToken { token } }"}'
    ```
  </Tab>
</Tabs>

## Next Steps

<CardGroup cols={2}>
  <Card title="All Providers" icon="grid" href="/gateway/supported-providers">
    Browse all supported AI providers
  </Card>

  <Card title="Forward Proxy" icon="route" href="/gateway/forward-proxy">
    Learn how to construct proxy URLs and authenticate requests
  </Card>
</CardGroup>
