Public API
Public API for custom wire harnesses
Look up stocked connectors, validate a harness spec, and get a signed price. This API does not place orders.
Last updated 2026-08-21
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 stocked connectors, 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 }
}Authentication
Write routes are not live yet. When they are, they require authentication. They are not bot-gated as a substitute for auth. OpenAPI names the write-route schemes CustomerOAuth and CustomerApiKey; neither is applied to live routes.
| Scheme | Status | Access |
|---|---|---|
| Anonymous | Live | Rate-limited reads plus POST /api/v1/validations and POST /api/v1/price-snapshots. Cannot create orders, quotes, or any other resource. |
CustomerOAuth | Specified, not live | 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 | Specified, issued on request | 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
Call GET /api/v1/capabilities first. It lists the stocked connector families, wire families with gauges and colours, lead-time tiers (tier plus a business-day range), and spec limits this API accepts. Five read routes are live. None of them create an order.
| Method | Path | Purpose |
|---|---|---|
| GET | /api/v1/capabilities | Call this first. Lists stocked connector families, wire families with gauges and colours, lead-time tiers (tier plus a business-day range), and spec limits. Copy leadTimes[].tier when selecting a timeline. |
| GET | /api/v1/connectors | List stocked connectors. Query parameters: mpn, family, pinCount, q, limit. |
| GET | /api/v1/connectors/{id} | Fetch one stocked connector by component id. |
| POST | /api/v1/validations | Validate a harness spec without returning a price. |
| POST | /api/v1/price-snapshots | Validate a harness spec and return a signed price snapshot. |
| 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, and limit (integer 1–100, default 25). 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.sideis"left"or"right".wires[]— minimum 1, maximum 500.sourceConnectorandtargetConnectorare 0-based indices intoconnectors[].sourcePinandtargetPinare 1-based pin numbers. Each wire also hasgauge,color,wireFamily, andlengthMm.wireFamilyandcolormust be copied fromGET /api/v1/capabilities. The canonicalgaugeform is"18 AWG".quantity— order quantity used for the price. Defaults to 1.projectNameanddesignNotes— optional strings.
Copy wireFamily, gauge, and color from GET /api/v1/capabilities → 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 stocked 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 stocked 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/capabilities→leadTimes[].tier. Bounds are business-day counts, ornullwhen unknown.
A token is required later to open a draft quote. 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. |
| NOT_FOUND | 404 | The requested resource does not exist. |
| UNKNOWN_CONNECTOR | 404 | No stocked connector matched the MPN or componentId. |
| AMBIGUOUS_MPN | 409 | The MPN matched more than one stocked 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.
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 stocked catalog. See
GET /api/v1/capabilities. - Harnesses are 2 to 16 connectors and up to 500 wires per spec.
- No minimum order quantity. Engineer review still gates unusual work.
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. |