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.

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.

SchemeStatusAccess
AnonymousLiveRate-limited reads plus POST /api/v1/validations and POST /api/v1/price-snapshots. Cannot create orders, quotes, or any other resource.
CustomerOAuthSpecified, not liveOAuth 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.
CustomerApiKeySpecified, issued on requestNamed 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.

MethodPathPurpose
GET/api/v1/capabilitiesCall 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/connectorsList stocked connectors. Query parameters: mpn, family, pinCount, q, limit.
GET/api/v1/connectors/{id}Fetch one stocked connector by component id.
POST/api/v1/validationsValidate a harness spec without returning a price.
POST/api/v1/price-snapshotsValidate a harness spec and return a signed price snapshot.
POST/api/v1/quotesAuthenticated. 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 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/capabilitieswireFamilies. 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/capabilitiesleadTimes[].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_MPNhttps://www.miniproto.com/docs/api#error-ambiguous-mpn.

CodeHTTP statusMeaning
INVALID_INPUT400Request JSON failed schema or type checks.
NOT_FOUND404The requested resource does not exist.
UNKNOWN_CONNECTOR404No stocked connector matched the MPN or componentId.
AMBIGUOUS_MPN409The MPN matched more than one stocked connector.
DESIGN_INVALID422The spec is schema-valid but cannot be built as a harness.
PRICE_EXPIRED409The price token is past expiresAt.
PRICE_TOKEN_INVALID400The price token is missing, malformed, or the signature does not verify.
IDEMPOTENCY_CONFLICT409Idempotency-Key was reused with a different request body.
RATE_LIMITED429The IP exceeded the read or write bucket.
INTERNAL500An 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

PathFormatPurpose
/docs/api.mdMarkdownThis document as GitHub-flavoured markdown.
/docs/api/openapi.yamlOpenAPI YAMLMachine-readable OpenAPI description of the live routes.
/docs/api/schema.jsonJSON SchemaJSON Schema for the harness spec and related request/response bodies.
/llms.txttext/plainSite index of public pages for language models.
/documentationHTMLHuman harness-design reference. Not this API.

Newsletter

Stay Wired with MiniProto.

Join our community and be the first to know about the latest in wire harness prototyping. Get exclusive insights, tips, and updates delivered straight to your inbox.

Latest Prototyping Trends
Stay ahead in the field with our articles on MiniProto updates, new technologies, design tips, and industry insights.
No Spam, Only Value
We respect your inbox. Receive only the most relevant updates and offers, without the clutter of unwanted emails.