For the complete documentation index, see llms.txt. This page is also available as Markdown.

Sourcing

Sourcing describes how a component gets built: the manufacturer parts (MPNs) that source it, the distributor quotes (DPNs) that price each part, and which of those sources is currently primary. A component can carry multiple parts, and each part multiple quotes — that is what lets you multi-source a component instead of committing to a single vendor.

This page covers the sourcing operations with practical examples. For the exact field-by-field shape of every type, introspect the schema in Apollo Explorer — the schema descriptions there are the source of truth.

Overview

The Sourcing Model

Component
  └─ Part            an MPN from a manufacturer
       ├─ Quote       a distributor's DPN offer — pricing, MOQ, lead time
       │    └─ Document (via QuoteDocument)
       └─ Document (via PartDocument)

Component
  └─ PrimarySource   the ranked list of quotes — rank 1 is the current primary
Entity
Identity
Description

Part

MPN + manufacturer

A manufacturer part that can source the component

Quote

DPN + distributor

A distributor's offer for a part

Vendor

Shared catalog entry; types says whether it acts as MANUFACTURER, DISTRIBUTOR, or both

LibraryVendor

A library's curated entry for a vendor, with an approvalStatus

PrimarySource

One entry in a component's ranked source list

The vendorSourcing Namespace

All sourcing operations are namespaced: queries live under Query.vendorSourcing and mutations under Mutation.vendorSourcing. There are no root-level sourcing fields.

Required Headers

All sourcing operations require the same headers as the rest of the API:

Sourcing operations never take a libraryId argument — the library comes from the x-library header.


Querying Sourcing Data

Parts on a Component

part(id) fetches a single part; partHistory(partId) returns its full version history. Parts carry mpnUrl — a link to the manufacturer's page for the MPN — accepted on the create and update inputs as well.

Quotes

quotes(partId) lists a single part's quotes. To compare offers across every part on a component in one call, use quotesByComponent:

Quote fields that drive sourcing decisions:

Field
Type
Description

unitPrice

Float

Price per unit. Nullable — a quote can be recorded before its price is known

minQuantity

Int

The distributor's minimum order quantity

maxQuantity

Int

The distributor's cap, if any

packageQuantity

Int

Units per reel, tube, or tray

leadTimeDays

Int

Distributor lead time (the part's manufacturerLeadTimeDays is separate)

dpnUrl

String

Link to the distributor's page for this DPN

description

String

Free-text notes about the quote

Vendors

The org-wide catalog is vendors / vendor(id); manufacturers narrows to vendors visible in the current library that can act as manufacturers. A library's own approved list is libraryVendorList, each entry carrying an approvalStatus.

Before creating a vendor, check for near-duplicates:

Primary Sources and Rollup State

rollupPriorityState reports whether a component's sourcing is prioritized within its assembly rollup and whether it is currently the primary source in that context.


Adding Sourcing

Creating Parts

createParts takes an array — batch multiple manufacturers in one call:

Creating Quotes

createQuotes is also batch. On CreateQuoteInput, every field except partId is optional:

updatePart / updateQuote edit a single row; archivePart / archiveQuote remove a row as an active source while partHistory / quoteHistory retain its record.

updatePart and updateQuote are unconditional writes — no version check, no conflict error. If two callers edit the same row concurrently, the later write silently wins. When overwrite detection matters, use applySourcingChangeset with expectedVersion instead.


Ranking Primary Sources

createParts, createQuotes, and setPrimarySource are independent calls with no cross-call atomicity — if a later step fails (for example MAX_PRIMARY_SOURCES_REACHED), earlier steps are not rolled back. When the group needs to succeed or fail together, use applySourcingChangeset.

setPrimarySource places a quote in the component's ranked source list; rank 1 is the primary:

  • The ranked list has a per-library maximum (3 by default). At the cap, setPrimarySource returns MAX_PRIMARY_SOURCES_REACHED — un-rank an existing source first.

  • removePrimarySource(id) takes the PrimarySource entry's own id (from primarySources), not the quote id.

  • reorderPrimarySources re-ranks the existing list; setRollupAsPrimarySource promotes the assembly rollup itself.


Applying a Sourcing Changeset

applySourcingChangeset stages a whole set of part/quote adds, edits, deletes, and re-ranks as a single atomic operation — the same mechanism the Duro app uses for its sourcing edit sessions. It returns Boolean!true on success — and a changeset that fails validation leaves the component's sourcing unchanged.

Two patterns to know:

  • tempId / Ref — reference a row created in the same call before it has a real id: newQuotes[0].partRef points at newParts[0].tempId, and prioritizedOrder can reference new quotes' tempIds. primary.kind is QUOTE or PART — a manufacturer part itself can be the primary when no distributor offer is ranked.

  • expectedVersion — when editing an existing part or quote, pass the version you last read. If it no longer matches at flush time, the whole changeset is rejected (PART_VERSION_CONFLICT / QUOTE_VERSION_CONFLICT) instead of silently overwriting a concurrent change.


Documents on Sourcing

Documents attach at either level: to a part (e.g. a manufacturer datasheet) via linkDocumentToPart, or to a quote (e.g. a distributor-specific document) via linkDocumentToQuote.

documentsByComponent(componentId) returns every sourcing document on a component regardless of level — each result carries linkType (PART or QUOTE).


Error Codes

Sourcing errors are GraphQLErrors with a stable code in extensions (see Error Handling):

Code
Meaning

DUPLICATE_PART

A part already exists for that manufacturer + MPN

DUPLICATE_QUOTE

A quote already exists for that part + distributor + DPN + minQuantity

PART_VERSION_CONFLICT / QUOTE_VERSION_CONFLICT

expectedVersion mismatch — re-read and retry

MAX_PRIMARY_SOURCES_REACHED

The ranked-source list is at its per-library cap

INVALID_QUANTITY_RANGE

A quote's minQuantity exceeds its maxQuantity

Next Steps

  • Evaluate sourcing changes as part of a formal review with Change Orders

  • Attach datasheets and certifications with Documents

Last updated

Was this helpful?