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 primaryPart
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.
mutation { applySourcingChangeset(...) } fails. Wrap every sourcing operation:
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:
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
Quote.unitPrice was previously non-nullable (Float!) and is now nullable. Clients that assumed a value is always present should handle null.
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.
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,
setPrimarySourcereturnsMAX_PRIMARY_SOURCES_REACHED— un-rank an existing source first.removePrimarySource(id)takes thePrimarySourceentry's ownid(fromprimarySources), not the quote id.reorderPrimarySourcesre-ranks the existing list;setRollupAsPrimarySourcepromotes 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].partRefpoints atnewParts[0].tempId, andprioritizedOrdercan reference new quotes'tempIds.primary.kindisQUOTEorPART— a manufacturer part itself can be the primary when no distributor offer is ranked.expectedVersion— when editing an existing part or quote, pass theversionyou 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):
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?