# Public API 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. ```bash 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: ```json { "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": }`. The machine-readable JSON Schema is at `/docs/api/schema.json`. - `connectors[]` — minimum 2, maximum 16. Each item has `ref` and `side`. `ref` is either `{ "mpn": "..." }` or `{ "componentId": "..." }`, never both. `side` is `"left"` or `"right"`. - `wires[]` — minimum 1, maximum 500. `sourceConnector` and `targetConnector` are 0-based indices into `connectors[]`. `sourcePin` and `targetPin` are 1-based pin numbers. Each wire also has `gauge`, `color`, `wireFamily`, and `lengthMm`. `wireFamily` and `color` must be copied from `GET /api/v1/capabilities`. The canonical `gauge` form is `"18 AWG"`. - `quantity` — order quantity used for the price. Defaults to 1. - `projectName` and `designNotes` — 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. ```json { "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: ```json { "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: ```json { "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`. The `errors` field is the candidate array. Pick one and retry with `componentId`. Ambiguous response: ```json { "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 with `unitPriceCents` and `totalCents`. - `bomHash` — SHA-256 hex of the canonical spec JSON. - `currency` — always `USD`. `quantity` is `spec.quantity`. `resolvedConnectors` repeats catalog resolution. `leadTime` is `{ tier, businessDaysMin, businessDaysMax }` for the selected manufacturing lead-time tier, or `null` if none is resolvable. `tier` is a value from `GET /api/v1/capabilities` → `leadTimes[].tier`. Bounds are business-day counts, or `null` when 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: ```json { "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. |