Quoting
Get manufacturing offers for one PCB revision and quantity.
A quote prices one project revision at one quantity. Its offers show the available manufacturing services and ship dates. Manufacturing prices exclude shipping and tax; requesting a quote does not place an order or take payment.
Request a quote
POST /v1/quotes
Supply revisionId and quantity. The revision identifies the project and owning workspace; there is no projectId input or workspace query parameter on this endpoint. The caller must have access to that revision.
The request waits for a quote, or returns a valid cached quote for the same revision and quantity. There is no separate polling resource. A request can take up to five minutes. Use expiresAt rather than assuming a full hour: normal quotes expire after one hour or earlier at the daily order cutoff.
circuithub quote request --revision 99001 --quantity 10 --workspace acme-electronicsOutput:
Quote: 50001
Revision: 99001 (3)
Quantity: 10
Currency: USD
Orderable: yes
Expires: 2026-11-03T11:00:00Z
OFFER SERVICE SHIP DATE MANUFACTURING TOTAL PER BOARD
880002 priority 2026-11-06 $774.45 $77.45
Manufacturing total excludes shipping and tax.curl -X POST -H "Authorization: Bearer $CIRCUITHUB_API_KEY" \
-H "Content-Type: application/json" \
-d '{"revisionId": 99001, "quantity": 10}' \
https://api.circuithub.com/v1/quotesResponse: 200 OK
{
"id": 50001,
"projectId": 12345,
"revisionId": 99001,
"revisionNumber": 3,
"quantity": 10,
"currency": "USD",
"createdAt": "2026-11-03T10:00:00Z",
"expiresAt": "2026-11-03T11:00:00Z",
"locked": false,
"status": "ready",
"type": "assembled",
"orderable": true,
"blockers": [],
"offers": [
{
"id": 880002,
"service": "priority",
"shipDate": {
"earliest": "2026-11-06",
"latest": "2026-11-06"
},
"fabricationCountry": "US",
"assemblyLine": "us_grid",
"price": {
"lineItems": [
{
"type": "boards",
"label": "Boards",
"amount": "504.00"
},
{
"type": "parts",
"label": "Parts",
"amount": "279.45"
},
{
"type": "assembly",
"label": "Assembly",
"amount": "396.55"
}
],
"manufacturingSubtotal": "1180.00",
"discounts": [
{
"type": "grid_proto",
"code": null,
"label": "Grid Proto",
"amount": "319.50"
},
{
"type": "account",
"code": null,
"label": "Your pricing",
"amount": "86.05"
}
],
"manufacturingTotal": "774.45",
"manufacturingUnitPrice": "77.45",
"excludes": [
"shipping",
"tax"
]
},
"checkoutUrl": "https://app.circuithub.com/projects/acme-electronics/power-supply-board/revisions/99001/order?quantity=10&offer=880002"
}
],
"designFeedback": []
}Request body
| Field | Type | Description |
|---|---|---|
revisionId | integer | Required. The specific revision to quote |
quantity | integer | Required. Positive number of boards to manufacture |
Response fields
| Field | Type | Description |
|---|---|---|
id | integer | Stable quote ID |
projectId | integer | Project containing the quoted revision |
revisionId | integer | Revision used for pricing |
revisionNumber | integer | Human-readable revision number |
quantity | integer | Requested board quantity; applies to every offer |
currency | string | Currency for all amounts; USD in this version |
createdAt | string | ISO 8601 quote creation time |
expiresAt | string | ISO 8601 expiry time |
locked | boolean | Whether the quote is locked. Read-only: the API cannot lock or unlock quotes |
status | string | ready or manual_quote_required; ready alone does not mean orderable |
type | string or null | assembled, board_only, or null when a manufacturing type is not available |
orderable | boolean | Whether the quote can currently be used to order; not a reservation of stock |
blockers | array | Reasons ordering is blocked, with affected BOM line IDs |
offers | array | Available manufacturing offers for the requested quantity; empty when manual review is required |
designFeedback | array | Changes to the design that would make the order cheaper, described below; empty when there are none |
Offer fields
| Field | Type | Description |
|---|---|---|
id | integer | Stable offer ID; select this with the quote ID when ordering |
service | string | priority, standard, flexible, manual_quote, or board_only |
shipDate | object | earliest and latest calendar dates in YYYY-MM-DD format; equal for a single ship date |
fabricationCountry | string or null | Board fabrication country code, when known |
assemblyLine | string or null | Assembly line identifier, when applicable |
price | object | Manufacturing price, detailed below |
checkoutUrl | string | Portal link to this revision's order page. The Portal does not yet preselect the quantity and offer from the link, so choose them again there |
Ship dates describe dispatch from CircuitHub, not delivery. Grid Proto is a discount on a Priority offer, not a separate service. Available offers depend on the design; not every service is returned for every quote.
Price fields
All money amounts are decimal strings in the quote's currency. Use exact decimal arithmetic rather than binary floating-point arithmetic.
| Field | Type | Description |
|---|---|---|
lineItems | array or null | Undiscounted manufacturing service amounts; null if not recorded |
manufacturingSubtotal | string or null | Sum of undiscounted line amounts; null if not recorded |
discounts | array or null | Discounts in application order; null if not recorded, [] if known to have none |
manufacturingTotal | string | Manufacturing amount after discounts, excluding shipping and tax |
manufacturingUnitPrice | string | Rounded manufacturing total divided by board quantity; for display only |
excludes | string[] | shipping and tax |
Each line item has type, label and amount. Board-only offers have a boards line. Assembled offers have boards, parts and assembly lines; a fully consigned build can have a zero parts amount. Consignment handling appears when applicable. Firmware is included in assembly. Accept new line types and display their supplied labels.
Each discount has type, code, label and amount. Types are grid_proto, account and promo_code; code is null when no code applies. Account discounts use the customer-facing label “Your pricing”. Discounts are positive amounts subtracted from the subtotal. Grid Proto is applied before an account discount; promo codes are not combined with Grid Proto. This endpoint reports applicable discounts and does not redeem codes.
manufacturingSubtotal = sum(lineItems.amount)
manufacturingTotal = manufacturingSubtotal - sum(discounts.amount)Discounts apply to the manufacturing total, not individual public line items. Do not subtract a discount again from already discounted amounts. Do not reconstruct the total by multiplying the rounded unit price by quantity.
Older offers retain their known total and unit price, but lineItems, manufacturingSubtotal and discounts are null if their breakdown was not recorded. Do not infer missing lines or treat null discounts as zero.
Blockers
Each blocker identifies its code and affected bomLineIds.
| Code | Meaning | What to do |
|---|---|---|
part_not_chosen | A BOM line has no approved part | Choose a suitable part |
no_supplier | No usable supplier for a selected part | Review the part and its sourcing |
insufficient_stock | Available stock cannot cover the build | Choose an alternative or change the quantity |
parts_require_review | An offer cannot be ordered for a reason no BOM line explains; bomLineIds is empty | Contact CircuitHub to review the parts |
For example, a blocked quote contains orderable: false and a blocker such as:
{"code": "insufficient_stock", "bomLineIds": [1003]}Use the BOM guide and part search to resolve affected lines, then request a new quote. A quote needing manual review has status: "manual_quote_required", type: null, orderable: false and no offers. Contact CircuitHub for that review rather than repeatedly requesting the same quote.
Design feedback
Each entry in designFeedback describes one way to make the order cheaper by changing the design. The design in the example above already qualifies for Grid Proto, so its feedback is empty. A design that would qualify with changes has an entry like this:
{
"type": "grid_proto",
"summary": "This design doesn't qualify for Grid Proto, which discounts board fabrication and assembly on small Priority builds. Fix the reasons below, then request a quote to see the Grid Proto price.",
"reasons": [
"Board thickness must be 1.6mm; this board is 0.8mm thick. Change it on this revision: read the board with GET /v1/revisions/99001/board, then send PATCH /v1/revisions/99001/board with \"boardThickness\": 1.6 and the board's boardId and version as expectedBoardId and expectedVersion (https://api.circuithub.com/docs/guides/board#update-board-configuration).",
"Minimum trace gap cannot be less than 0.127mm; this board's minimum trace gap is 0.115mm. Board settings can't change this. Fix it in your design files, then upload them as a new revision of project 12345 with POST /v1/projects/12345/revisions (https://api.circuithub.com/docs/guides/projects#upload-a-new-revision) and request a quote for the new revision."
],
"potential": null,
"docsUrl": "https://api.circuithub.com/docs/guides/design-feedback#grid-proto"
}| Field | Type | Description |
|---|---|---|
type | string | The kind of feedback; grid_proto in this version. Ignore entries whose type you do not know |
summary | string | One sentence on what changing the design would gain |
reasons | string[] | Each thing to change, in plain English, with the current value, the limit and the API call or design change that fixes it |
potential | object or null | The changed design's totalPrice, shipDate, leadTimeBusinessDays and savings against the offer it would replace (null when that offer was not priced), with any parts the reasons list left unfitted. Null when the quote could not price the changed design, as when the trace gap or another design-file rule other than the parts fails, or the board has CAM comments |
docsUrl | string | Where the feedback is explained |
More kinds of feedback may be added. Every entry has a summary and docsUrl to fall back on. A grid_proto entry appears only when changing the design would make the order cheaper: not when the design already qualifies, whose discount is in the Priority offer's discounts, not when only factory capacity stands in the way, and not when the changed design would cost no less. Fix the reasons, then request a new quote; see design feedback for the rules to design to from the start.
Get a quote
GET /v1/quotes/:quoteId
Retrieve a quote by its ID. This returns the same representation as the request endpoint; it does not generate a new quote or extend its expiry.
circuithub quote show 50001 --workspace acme-electronicsOutput:
Quote: 50001
Revision: 99001 (3)
Quantity: 10
Currency: USD
Orderable: yes
Expires: 2026-11-03T11:00:00Z
OFFER SERVICE SHIP DATE MANUFACTURING TOTAL PER BOARD
880002 priority 2026-11-06 $774.45 $77.45
Manufacturing total excludes shipping and tax.curl -H "Authorization: Bearer $CIRCUITHUB_API_KEY" \
https://api.circuithub.com/v1/quotes/50001Response: 200 OK
{
"id": 50001,
"projectId": 12345,
"revisionId": 99001,
"revisionNumber": 3,
"quantity": 10,
"currency": "USD",
"createdAt": "2026-11-03T10:00:00Z",
"expiresAt": "2026-11-03T11:00:00Z",
"locked": false,
"status": "ready",
"type": "assembled",
"orderable": true,
"blockers": [],
"offers": [
{
"id": 880002,
"service": "priority",
"shipDate": {
"earliest": "2026-11-06",
"latest": "2026-11-06"
},
"fabricationCountry": "US",
"assemblyLine": "us_grid",
"price": {
"lineItems": [
{
"type": "boards",
"label": "Boards",
"amount": "504.00"
},
{
"type": "parts",
"label": "Parts",
"amount": "279.45"
},
{
"type": "assembly",
"label": "Assembly",
"amount": "396.55"
}
],
"manufacturingSubtotal": "1180.00",
"discounts": [
{
"type": "grid_proto",
"code": null,
"label": "Grid Proto",
"amount": "319.50"
},
{
"type": "account",
"code": null,
"label": "Your pricing",
"amount": "86.05"
}
],
"manufacturingTotal": "774.45",
"manufacturingUnitPrice": "77.45",
"excludes": [
"shipping",
"tax"
]
},
"checkoutUrl": "https://app.circuithub.com/projects/acme-electronics/power-supply-board/revisions/99001/order?quantity=10&offer=880002"
}
],
"designFeedback": []
}Path parameters
| Field | Type | Description |
|---|---|---|
quoteId | integer | Required. Quote ID returned by the request endpoint |
Errors and expiry
These are the quote-specific errors, using the API error envelope.
| HTTP status | Code | Meaning |
|---|---|---|
| 400 | VALIDATION_ERROR | Missing or invalid revision or quantity |
| 409 | REVISION_NOT_READY | The revision has not finished importing |
| 409 | QUOTE_LOCKED | A different quantity is currently locked |
| 410 | QUOTE_EXPIRED | The requested quote has expired |
| 429 | RATE_LIMITED | Request limit reached; follow Retry-After |
| 503 | QUOTING_UNAVAILABLE | Quoting is temporarily paused |
Request a fresh quote after changing the design, parts or quantity. A quote lock does not fix shipping charges or tax. The API does not manage quote locks or give per-part cost breakdowns.
From a quote to an order
Choose an orderable offer using its quote ID and offer ID. Review shipping, tax and the complete order price separately before ordering. manufacturingTotal is not the final order total or the amount due now.
Use the offer's checkoutUrl to continue in the Portal, or follow the API ordering walkthrough. API ordering uses a calculated preview followed by order submission; it does not require a saved checkout resource or a separate quote-lock call.