Public API
Public API for custom wire harnesses
Look up connectors, wire families, and lead times, validate a harness spec, and get a signed price. This API does not place orders.
Last updated 2026-08-23
Overview
MiniProto is a US custom wire-harness and cable-assembly manufacturer in Kingston, NY.
This API lets a program or an LLM look up real connectors, wire families, and lead times, validate a harness spec, and get a real price.
It does not place orders. There is no create_order endpoint. Checkout happens on miniproto.com, and a human confirms the order.
To choose ConfigV2 versus a drawing RFQ, see /guides/configure-vs-send-a-drawing. For the fields a harness RFQ should include, see /guides/what-to-put-in-a-harness-rfq.
Quickstart
The one call that matters is POST /api/v1/price-snapshots. Send connectors by manufacturer part number (MPN). You do not need to look up a UUID first.
A 12-pin Deutsch DTM pair has 12 circuits. This example sends two wires; the other ten are elided.
curl -sS -X POST 'https://www.miniproto.com/api/v1/price-snapshots' \
-H 'Content-Type: application/json' \
-d '{
"spec": {
"quantity": 1,
"connectors": [
{ "ref": { "mpn": "DTM06-12SA" }, "side": "left" },
{ "ref": { "mpn": "DTM04-12PA" }, "side": "right" }
],
"wires": [
{
"sourceConnector": 0,
"sourcePin": 1,
"targetConnector": 1,
"targetPin": 1,
"gauge": "18 AWG",
"color": "black",
"wireFamily": "GXL",
"lengthMm": 300
},
{
"sourceConnector": 0,
"sourcePin": 2,
"targetConnector": 1,
"targetPin": 2,
"gauge": "18 AWG",
"color": "red",
"wireFamily": "GXL",
"lengthMm": 300
}
]
}
}'The response is a signed price snapshot. Shape:
{
"priceToken": "example-not-a-real-signature",
"priceVersion": "v1-2026-08-20",
"expiresAt": "2026-08-27T00:00:00.000Z",
"currency": "USD",
"quantity": 1,
"unitPriceCents": 4850,
"setupFeeCents": 0,
"totalCents": 4850,
"priceBreaks": [
{ "quantity": 1, "unitPriceCents": 4850, "totalCents": 4850 },
{ "quantity": 10, "unitPriceCents": 4120, "totalCents": 41200 },
{ "quantity": 25, "unitPriceCents": 3790, "totalCents": 94750 }
],
"bomHash": "a3f1c8e0b4d27591e6a0c2f8d1b94735c0e8a6f2b1d4c7e9a5b0c3d6e8f1a247",
"resolvedConnectors": [
{
"index": 0,
"componentId": "8f3a1c2e-4b5d-4e6f-8a9b-0c1d2e3f4a5b",
"mpn": "DTM06-12SA",
"pinCount": 12
},
{
"index": 1,
"componentId": "9c0d1e2f-3a4b-5c6d-7e8f-901234567890",
"mpn": "DTM04-12PA",
"pinCount": 12
}
],
"leadTime": { "tier": "standard", "businessDaysMin": 20, "businessDaysMax": 40 },
"assumptions": [],
"continueUrl": "https://www.miniproto.com/configuratorV2?d=a1B2c3D4e5"
}Authentication
POST /api/v1/quotes and GET /api/v1/quotes/{id} are live and require MiniProto customer credentials. Reads plus POST /api/v1/validations and POST /api/v1/price-snapshots are anonymous. A price snapshot saves one seven-day configurator design (the continueUrl handoff) — its only side effect — and creates no quote, no order, and no reservation. Writes are not bot-gated as a substitute for auth. OpenAPI names the quote-route schemes CustomerOAuth and CustomerApiKey; both are live on the quote routes.
| Scheme | Status | Access |
|---|---|---|
| Anonymous | Live | Rate-limited reads plus POST /api/v1/validations and POST /api/v1/price-snapshots. Cannot create quotes or orders; its only side effect is the seven-day saved configurator design behind continueUrl. |
CustomerOAuth | Live on POST /api/v1/quotes | OAuth 2.1 authorization code with PKCE. The host links to an existing MiniProto customer; writes run as that customer. Email on a spec is not identity. |
CustomerApiKey | Issued on request; live on POST /api/v1/quotes | Named B2B accounts only. Issued to an existing customer after a human request. Not Hermes agent_api_keys, and not handed out by a Claude connector. |
Endpoints
Configurator flow: read GET /api/v1/connector-families, GET /api/v1/connectors, GET /api/v1/wires, and GET /api/v1/lead-times, copy family, gauge, and colour values verbatim into the spec, then POST /api/v1/validations, then POST /api/v1/price-snapshots. The anonymous snapshot response adds resolvedSpec, assumptions, and an absolute seven-day continueUrl that opens the saved design at /configuratorV2?d=<id>. That saved design is the snapshot's only side effect; it creates no quote and no order. Only when MiniProto customer credentials are available, finish with authenticated POST /api/v1/quotes sending the returned priceToken.
RFQ flow: authenticated POST /api/v1/quotes with a written description plus PDF/PNG/JPEG files up to 10MB for engineer review.
| Method | Path | Purpose |
|---|---|---|
| GET | /api/v1/company | Who MiniProto is: name, location, differentiators, industries, ordering flow, and links. |
| GET | /api/v1/services | Commercial offerings. Each service names its intake: configurator or rfq. |
| GET | /api/v1/capabilities | Physical manufacturing abilities: processes, materials, standards, testing, and what is not offered. |
| GET | /api/v1/connector-families | Digitised instant-priceable connector families with manufacturer, category, and AWG range. |
| GET | /api/v1/connectors | List connectors. Query parameters: mpn, family, pinCount, q, limit, offset. |
| GET | /api/v1/connectors/{id} | Fetch one connector by component id or MPN. |
| GET | /api/v1/wires | Wire families with gauges and colours. Copy wireFamily, gauge, and color verbatim. |
| GET | /api/v1/lead-times | Lead-time tiers (tier plus a business-day range). Copy tier when selecting a timeline. |
| POST | /api/v1/validations | Validate a harness spec without returning a price. Design failures are 422 DESIGN_INVALID. |
| POST | /api/v1/price-snapshots | Validate a harness spec and return a signed price snapshot with resolvedSpec, assumptions, and a continueUrl that opens the saved design. Saves one seven-day configurator design; creates no quote or order. |
| POST | /api/v1/quotes | Authenticated. Create a priced draft from a price snapshot or an engineer-review RFQ. Returns checkoutUrl or a human quote URL. Does not place an order. |
| GET | /api/v1/quotes/{id} | Authenticated. Read back a draft or RFQ the caller created. |
GET /api/v1/connectors accepts these query parameters: mpn, family, pinCount, q, limit (integer 1–100, default 25), and offset (integer ≥ 0, default 0). q is free-text search across MPN and description. An unknown query parameter — including search — returns 400 INVALID_INPUT rather than being ignored.
Harness Spec
POST /api/v1/validations and POST /api/v1/price-snapshots take { "spec": <harness spec> }. The machine-readable JSON Schema is at /docs/api/schema.json.
connectors[]— minimum 2, maximum 16. Each item hasrefandside.refis either{ "mpn": "..." }or{ "componentId": "..." }, never both.sidedefines wire direction: wires run from a left connector (sourceConnector/sourcePin) to a right connector (targetConnector/targetPin). Same-side or right-to-left is422 DESIGN_INVALID.wires[]— minimum 1, maximum 500. A pin-to-pin end usessourceConnector/sourcePinortargetConnector/targetPin. A splice end usessourceSpliceortargetSplice(0-based index intosplices[]). Each end is one or the other, not both. Each wire also hasgauge,color,wireFamily, andlengthMm(maximum 10000 mm / 10 m).wireFamilyandcolormust be copied fromGET /api/v1/wires. The canonicalgaugeform is"18 AWG".splices[]— optional, maximum 50. Each item may setmethodto"solder"or"crimp".quantity— order quantity used for the price. Defaults to 1. Maximum 1000. Larger runs need engineer review.projectNameanddesignNotes— optional strings.wireProfile— optional. Set it to"standard-automotive"to omitwireFamily,gauge, andcoloron wires; the API fills them with GXL, 18 AWG, and deterministic per-wire colours (Black, Red, White, Green, Blue, Yellow, Orange, Violet, brown, Gray, repeating by wire index). Explicit values always override the profile. Every value the profile supplied is reported in the response'sassumptionsentries ({ path, value, source }, wheresourceis"standard-automotive"), and the fully explicit normalized spec comes back asresolvedSpec. Without the profile,wireFamily,gauge, andcolorare required on every wire.
A spec that fails schema checks is 400 INVALID_INPUT. A spec that is schema-valid but cannot be built is 422 DESIGN_INVALID from POST /api/v1/validations and POST /api/v1/price-snapshots.
Copy wireFamily, gauge, and color from GET /api/v1/wires → wireFamilies. Colours are listed per gauge (gauges[].colors), not as a sibling of gauges and not as a family-level colors array, because a family stocks different colours at different gauges — GXL has 11 colours at 8 AWG and 27 at 20 AWG. Pick a gauge first, then a colour from that gauge's list. Combining a family-level colour with an arbitrary gauge is rejected.
{
"wireFamilies": [
{
"name": "GXL",
"description": "Automotive-grade, 8-22 AWG",
"gauges": [
{ "gauge": "18 AWG", "colors": ["Black", "Blue", "Red"] },
{ "gauge": "20 AWG", "colors": ["Black", "brown", "Red"] }
]
}
]
}A wires[] entry built from that excerpt:
{
"sourceConnector": 0,
"sourcePin": 1,
"targetConnector": 1,
"targetPin": 1,
"wireFamily": "GXL",
"gauge": "18 AWG",
"color": "Black",
"lengthMm": 500
}The canonical gauge spelling is "18 AWG". These spellings are also accepted and resolve to that form: "18", "18awg", "18 gauge", "18 ga", "#18", and "AWG18". Anything else is rejected with a DESIGN_INVALID 422 that names the accepted values.
A complete minimal valid spec:
{
"quantity": 1,
"connectors": [
{ "ref": { "mpn": "DTM06-12SA" }, "side": "left" },
{ "ref": { "mpn": "DTM04-12PA" }, "side": "right" }
],
"wires": [
{
"sourceConnector": 0,
"sourcePin": 1,
"targetConnector": 1,
"targetPin": 1,
"gauge": "18 AWG",
"color": "black",
"wireFamily": "GXL",
"lengthMm": 300
}
]
}MPN Resolution
A connector ref may be an MPN or a componentId. Exact MPN match wins because MPNs are unique in the catalog.
If exact match misses, lookup falls back to search.
- Zero matches →
404 UNKNOWN_CONNECTOR. - More than one match →
409 AMBIGUOUS_MPN. Theerrorsfield is the candidate array. Pick one and retry withcomponentId.
Ambiguous response:
{
"type": "https://www.miniproto.com/docs/api#error-ambiguous-mpn",
"title": "Ambiguous manufacturer part number",
"status": 409,
"code": "AMBIGUOUS_MPN",
"detail": "MPN DTM06 matches more than one catalog connector at connectors[0].",
"errors": [
{
"componentId": "8f3a1c2e-4b5d-4e6f-8a9b-0c1d2e3f4a5b",
"mpn": "DTM06-12SA",
"manufacturer": "TE Connectivity",
"pinCount": 12
},
{
"componentId": "1a2b3c4d-5e6f-7081-92a3-b4c5d6e7f809",
"mpn": "DTM06-12SB",
"manufacturer": "TE Connectivity",
"pinCount": 12
}
]
}Price Snapshots
A price token is a stateless signed snapshot of a price for a specific BOM, quantity, and price version. It is not an order and not a reservation of parts or capacity.
priceToken— HMAC signature over the snapshot payload.priceVersion— pricing ruleset id. Current value:v1-2026-08-20.expiresAt— 7 days after issuance.unitPriceCents— customer unit price in cents.setupFeeCents— setup fee in cents.totalCents— quantity × unit price, plus setup fee, in cents.priceBreaks[]— quantity tiers withunitPriceCentsandtotalCents.bomHash— SHA-256 hex of the canonical spec JSON.currency— alwaysUSD.quantityisspec.quantity.resolvedConnectorsrepeats catalog resolution.leadTimeis{ tier, businessDaysMin, businessDaysMax }for the selected manufacturing lead-time tier, ornullif none is resolvable.tieris a value fromGET /api/v1/lead-times→leadTimes[].tier. Bounds are business-day counts, ornullwhen unknown.resolvedSpec— the fully explicit normalized harness spec actually priced: caller-supplied values plus anythingwireProfile: "standard-automotive"filled in.assumptions[]— one{ path, value, source }entry for every value the API chose on the caller's behalf;sourceis"standard-automotive"when the wire profile supplied it, and the array is empty when nothing was defaulted.continueUrl— absolute URL that opens the saved design in the visual configurator at/configuratorV2?d=<id>; it stays valid for the token's seven-day life. That saved design is the snapshot's only side effect: it creates no quote, no order, and no reservation.
A token is required later to create a draft quote with authenticated POST /api/v1/quotes. A stale token is rejected with PRICE_EXPIRED.
Errors
Errors use RFC 9457 problem details. The Content-Type is application/problem+json. Branch on code, not on title.
type is https://www.miniproto.com/docs/api#error- plus the kebab-case code. Example: AMBIGUOUS_MPN → https://www.miniproto.com/docs/api#error-ambiguous-mpn.
| Code | HTTP status | Meaning |
|---|---|---|
| INVALID_INPUT | 400 | Request JSON failed schema or type checks. |
| UNAUTHORIZED | 401 | Missing, invalid, or non-customer credentials. |
| FORBIDDEN | 403 | The token does not include the required quotes scope. |
| NOT_FOUND | 404 | The requested resource does not exist. |
| UNKNOWN_CONNECTOR | 404 | No connector matched the MPN or componentId. |
| AMBIGUOUS_MPN | 409 | The MPN matched more than one connector. |
| DESIGN_INVALID | 422 | The spec is schema-valid but cannot be built as a harness. |
| PRICE_EXPIRED | 409 | The price token is past expiresAt. |
| PRICE_TOKEN_INVALID | 400 | The price token is missing, malformed, or the signature does not verify. |
| IDEMPOTENCY_CONFLICT | 409 | Idempotency-Key was reused with a different request body. |
| RATE_LIMITED | 429 | The IP exceeded the read or write bucket. |
| INTERNAL | 500 | An unexpected server error. |
Problem document:
{
"type": "https://www.miniproto.com/docs/api#error-invalid-input",
"title": "Invalid input",
"status": 400,
"code": "INVALID_INPUT",
"detail": "Request body failed schema validation.",
"errors": [
{
"path": ["wires", 0, "sourcePin"],
"message": "Expected number >= 1"
}
]
}Rate Limits
Limits are per IP: 120 reads/min and 20 writes/min. GET routes use the read bucket. POST /api/v1/validations and POST /api/v1/price-snapshots use the write bucket.
Successful and error responses include RateLimit-* headers. A 429 also includes Retry-After.
Browser clients are supported. /api/v1 answers OPTIONS preflight with 204 and sends Access-Control-Allow-Origin: *, Allow-Methods: GET, POST, OPTIONS, and Allow-Headers: Authorization, Content-Type, Idempotency-Key. Do not send cookies; use a Bearer token when a route requires auth.
Price scraping is an abuse case, not a feature.
Idempotency
Send Idempotency-Key on POST requests.
A replay of the same key, route, and body returns the original response with Idempotency-Replayed: true.
Reusing a key on the same route with a different body is 409 IDEMPOTENCY_CONFLICT.
What We Refuse
- No agent-placed orders. There is no
create_order. - No connector families outside the digitised catalog. See
GET /api/v1/connector-families. - Harnesses are 2 to 16 connectors and up to 500 wires per spec.
- No minimum order quantity. Maximum order quantity is 1000; larger runs need engineer review.
Machine-Readable
| Path | Format | Purpose |
|---|---|---|
| /docs/api.md | Markdown | This document as GitHub-flavoured markdown. |
| /docs/api/openapi.yaml | OpenAPI YAML | Machine-readable OpenAPI description of the live routes. |
| /docs/api/schema.json | JSON Schema | JSON Schema for the harness spec and related request/response bodies. |
| /llms.txt | text/plain | Site index of public pages for language models. |
| /documentation | HTML | Human harness-design reference. Not this API. |