{"openapi":"3.0.3","info":{"title":"OpenSpec Query API","version":"1.0.0","description":"Real manufacturer part specifications with provenance. Free trial: 20 data queries per IP without a key; counts, /manufacturers, and /categories are free and unlimited. An API key lifts the limits (email customersupport@openspecindex.com). Over-limit requests degrade to free match counts instead of blocking; see the `limited` flag. Plain-text agent instructions: /llms.txt","contact":{"email":"customersupport@openspecindex.com"}},"servers":[{"url":"https://api.openspecindex.com"}],"components":{"securitySchemes":{"ApiKeyHeader":{"type":"apiKey","in":"header","name":"X-Api-Key"},"ApiKeyQuery":{"type":"apiKey","in":"query","name":"key"}},"parameters":{"manufacturer":{"name":"manufacturer","in":"query","schema":{"type":"string"},"description":"Exact manufacturer slug (see /api/v1/manufacturers)"},"category":{"name":"category","in":"query","schema":{"type":"string"},"description":"Substring match on the raw category label (free-text; prefer family= for combed categories)"},"family":{"name":"family","in":"query","schema":{"type":"string"},"description":"Combed category slug from /api/v1/categories; enables structured search (type=, attr.<name>=)"},"type":{"name":"type","in":"query","schema":{"type":"string"},"description":"Part-type slug from /api/v1/categories (hierarchical: selecting nut/lock includes nut/lock/nylon). Requires family="},"q":{"name":"q","in":"query","schema":{"type":"string"},"description":"Substring match across MPN, description, category"},"mpn":{"name":"mpn","in":"query","schema":{"type":"string"},"description":"Exact manufacturer part number"}},"schemas":{"Part":{"type":"object","properties":{"mpn":{"type":"string"},"manufacturer":{"type":"object","properties":{"slug":{"type":"string"},"name":{"type":"string"}}},"category":{"type":"string","nullable":true},"subcategory":{"type":"string","nullable":true},"partType":{"type":"string","nullable":true,"description":"Common-layer type slug; present on family= searches"},"description":{"type":"string","nullable":true},"specs":{"type":"object","additionalProperties":true,"description":"Manufacturer-verbatim characteristic/value pairs"},"priceEach":{"type":"number","nullable":true,"description":"Unit price as published by the source, null when not published"},"assets":{"type":"object","properties":{"images":{"type":"array","items":{"type":"string"}},"cad":{"type":"array","items":{"type":"string"}},"datasheets":{"type":"array","items":{"type":"string"}}}},"source":{"type":"object","properties":{"url":{"type":"string"},"checkedAt":{"type":"string"}}}}},"Limited":{"type":"object","description":"Over-limit degrade: a free match count instead of rows, never a hard block","properties":{"limited":{"type":"boolean"},"reason":{"type":"string"},"manufacturers":{"type":"integer"},"components":{"type":"integer"},"message":{"type":"string"}}}}},"paths":{"/api/v1/find/{query}":{"get":{"summary":"One-call lookup: plain words in the path, matching parts and a spec sheet out","description":"THE entry point for an agent. Put what the user asked for into the path, hyphen-separated (/api/v1/find/10-32-nylock-stainless-nut). Resolved deterministically against the live category tree: no model, no guessing. The response echoes what was understood (family, type, filters applied) and, crucially, ignored_words: words that matched nothing and were NOT applied as filters. Words that match no category we carry return 404 with the list of categories we do carry. Costs one query. The URL is a pure path with no query string, because some agent fetch tools strip query strings, rewrite constructed URLs, or cache by path.","parameters":[{"name":"query","in":"path","required":true,"schema":{"type":"string"},"example":"10-32-nylock-stainless-nut","description":"What you are looking for, in plain words, separated by hyphens."}],"responses":{"200":{"description":"Matching parts (max 15), what was understood, and spec sheet links","content":{"application/json":{"schema":{"type":"object","properties":{"query":{"type":"string"},"understood":{"type":"object","properties":{"family":{"type":"string"},"type":{"type":"string"},"filters":{"type":"object","additionalProperties":{"type":"string"}},"ignored_words":{"type":"array","items":{"type":"string"},"description":"Words that matched nothing and were NOT applied. Do not claim they were."}}},"total":{"type":"integer"},"count":{"type":"integer"},"free_remaining":{"type":"integer"},"specsheet":{"type":"object","properties":{"receipt":{"type":"string"},"pdf":{"type":"string"},"docx":{"type":"string"}},"description":"pdf/docx are binary downloads. Hand them to the user; do not fetch them."},"parts":{"type":"array","items":{"type":"object"}}}}}}},"404":{"description":"No category we carry matched those words; the response lists the ones we do carry"}}}},"/api/v1/categories":{"get":{"summary":"Combed-category tree: families, part types, gates, and common attribute values (free, no key)","description":"The discovery endpoint for structured search. Each category lists its part types (hierarchical slugs), the GATES per type (identity attributes; an inner array is a one-of group where any member satisfies the gate), and the most common values per attribute. Use these slugs/names/values verbatim as family=, type=, and attr.<name>= filters on /api/v1/parts and /api/v1/count. Computed live from the database: newly combed categories appear automatically.","responses":{"200":{"description":"The category tree","content":{"application/json":{"schema":{"type":"object","properties":{"note":{"type":"string"},"categories":{"type":"array","items":{"type":"object","properties":{"slug":{"type":"string"},"name":{"type":"string"},"parts":{"type":"integer"},"attributes":{"type":"array","items":{"type":"object","properties":{"attr":{"type":"string"},"label":{"type":"string"},"kind":{"type":"string","description":"text | num | conn | atLeast | atMost"},"gate":{"type":"boolean","description":"true = identity attribute (drives equivalence pooling)"}}}},"partTypes":{"type":"array","items":{"type":"object","properties":{"type":{"type":"string"},"parts":{"type":"integer"},"gates":{"type":"array","items":{"oneOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}]},"description":"Identity gates for this type; an inner array is a one-of group"},"values":{"type":"object","additionalProperties":{"type":"array","items":{"type":"object","properties":{"value":{"type":"string"},"parts":{"type":"integer"}}}},"description":"Top values per attribute, most common first: the valid attr.<name>= filter values"}}}}}}}}}}}}}}},"/api/v1/count":{"get":{"summary":"Count matching parts (free, no key, unlimited)","parameters":[{"$ref":"#/components/parameters/manufacturer"},{"$ref":"#/components/parameters/category"},{"$ref":"#/components/parameters/family"},{"$ref":"#/components/parameters/type"},{"$ref":"#/components/parameters/q"},{"$ref":"#/components/parameters/mpn"}],"responses":{"200":{"description":"Match counts","content":{"application/json":{"schema":{"type":"object","properties":{"manufacturers":{"type":"integer"},"components":{"type":"integer"}}}}}}}}},"/api/v1/manufacturers":{"get":{"summary":"List queryable manufacturer catalogs (free, no key)","parameters":[{"name":"q","in":"query","schema":{"type":"string"},"description":"Substring filter on manufacturer name and slug"}],"responses":{"200":{"description":"Catalog list","content":{"application/json":{"schema":{"type":"object","properties":{"manufacturers":{"type":"array","items":{"type":"object","properties":{"slug":{"type":"string"},"name":{"type":"string"},"homepageUrl":{"type":"string","nullable":true},"parts":{"type":"integer"}}}}}}}}}}}},"/api/v1/parts":{"get":{"summary":"Search parts (no key needed on the free trial: 20 queries/IP; a key lifts limits; max 15 rows per call)","description":"Structured category search: pass family= (plus optional type=) and any number of attr.<name>=<value> parameters, using names and values from /api/v1/categories. attr.* parameters are dynamic and therefore not enumerated here; an unknown family or attribute returns a 400 listing the valid options. Anonymous callers get 10 lifetime queries per IP; over the limit the response degrades to a Limited match count, never a hard block.","security":[{},{"ApiKeyHeader":[]},{"ApiKeyQuery":[]}],"parameters":[{"$ref":"#/components/parameters/manufacturer"},{"$ref":"#/components/parameters/category"},{"$ref":"#/components/parameters/family"},{"$ref":"#/components/parameters/type"},{"$ref":"#/components/parameters/q"},{"$ref":"#/components/parameters/mpn"},{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":15,"default":15}},{"name":"offset","in":"query","schema":{"type":"integer","minimum":0,"default":0}}],"responses":{"200":{"description":"Matching rows, or a Limited count when over the rate limit","content":{"application/json":{"schema":{"oneOf":[{"type":"object","properties":{"total":{"type":"integer"},"limit":{"type":"integer"},"offset":{"type":"integer"},"count":{"type":"integer"},"parts":{"type":"array","items":{"$ref":"#/components/schemas/Part"}}}},{"$ref":"#/components/schemas/Limited"}]}}}}}}},"/api/v1/xref/{partNumber}":{"get":{"summary":"Cross-reference lookup: spec facts for a known catalog part number (free trial or API key)","security":[{},{"ApiKeyHeader":[]},{"ApiKeyQuery":[]}],"parameters":[{"name":"partNumber","in":"path","required":true,"schema":{"type":"string"},"description":"Catalog part number, e.g. 8574K123"}],"responses":{"200":{"description":"Spec facts for equivalent-part hunting","content":{"application/json":{"schema":{"type":"object","properties":{"partNumber":{"type":"string"},"specs":{"type":"object","additionalProperties":true}}}}}},"404":{"description":"Part number not on file"}}}},"/api/v1/equivalents/{partNumber}":{"get":{"summary":"Verified equivalence search for a catalog part number (free trial or API key)","description":"Classifies the part into its common category, pools candidates that agree on every stated mandatory attribute (the gates), scores the remaining specs, and returns the top 15 with matchPercent plus explicit agreements/disagreements arrays. supported: false means that family has no verified template yet; fall back to /api/v1/parts?q= word search.","security":[{},{"ApiKeyHeader":[]},{"ApiKeyQuery":[]}],"parameters":[{"name":"partNumber","in":"path","required":true,"schema":{"type":"string"},"description":"Catalog part number, e.g. 47885K74"}],"responses":{"200":{"description":"Verified equivalents ranked by matchPercent, or a Limited notice over the rate limit"},"404":{"description":"Part number not on file"}}}},"/api/v1/parts/{manufacturer}/{mpn}":{"get":{"summary":"One part, full detail (free trial or API key)","security":[{},{"ApiKeyHeader":[]},{"ApiKeyQuery":[]}],"parameters":[{"name":"manufacturer","in":"path","required":true,"schema":{"type":"string"},"description":"Manufacturer slug"},{"name":"mpn","in":"path","required":true,"schema":{"type":"string"},"description":"Exact manufacturer part number"}],"responses":{"200":{"description":"The part, or a Limited notice when over the rate limit","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/Part"},{"$ref":"#/components/schemas/Limited"}]}}}},"404":{"description":"Part not found"}}}}}}