{
 "openapi": "3.1.0",
 "info": {
  "title": "Open Factory API",
  "version": "1.0.0",
  "summary": "Research, lead-time and price data on factory and datacenter equipment procurement.",
  "description": "Open Factory publishes research, lead-time and price data, models and calculators on machinery, electrical gear, power and cooling, with a procurement focus. Free endpoints mirror what open-factory.com publishes free; Pro and Institutional endpoints need a key of that tier. Every response carries as_of, source and attribution. Data is CC BY 4.0.",
  "termsOfService": "https://open-factory.com/legal/#terms",
  "contact": {
   "name": "Open Factory",
   "email": "hello@open-factory.com",
   "url": "https://open-factory.com/developers/"
  },
  "license": {
   "name": "CC BY 4.0",
   "url": "https://creativecommons.org/licenses/by/4.0/"
  }
 },
 "externalDocs": {
  "description": "Developer documentation and the MCP server",
  "url": "https://open-factory.com/developers/"
 },
 "servers": [
  {
   "url": "https://open-factory.com/api/v1"
  }
 ],
 "security": [
  {},
  {
   "bearer": []
  }
 ],
 "paths": {
  "/index.json": {
   "get": {
    "summary": "This catalog.",
    "operationId": "get_index",
    "tags": [
     "free"
    ],
    "parameters": [],
    "responses": {
     "200": {
      "description": "OK",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Envelope"
        }
       }
      }
     },
     "404": {
      "description": "Unknown slug"
     }
    }
   }
  },
  "/openapi.json": {
   "get": {
    "summary": "OpenAPI 3.1 description of the API.",
    "operationId": "get_openapi",
    "tags": [
     "free"
    ],
    "parameters": [],
    "responses": {
     "200": {
      "description": "OK",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Envelope"
        }
       }
      }
     },
     "404": {
      "description": "Unknown slug"
     }
    }
   }
  },
  "/articles.json": {
   "get": {
    "summary": "Every published article with summary, tags, models, tools and CSV files.",
    "operationId": "get_articles",
    "tags": [
     "free"
    ],
    "parameters": [],
    "responses": {
     "200": {
      "description": "OK",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Envelope"
        }
       }
      }
     },
     "404": {
      "description": "Unknown slug"
     }
    }
   }
  },
  "/articles/{slug}.json": {
   "get": {
    "summary": "One article with its free text as markdown.",
    "operationId": "get_articles_slug",
    "tags": [
     "free"
    ],
    "parameters": [
     {
      "name": "slug",
      "in": "path",
      "required": true,
      "description": "article slug from /articles.json",
      "schema": {
       "type": "string"
      }
     }
    ],
    "responses": {
     "200": {
      "description": "OK",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Envelope"
        }
       }
      }
     },
     "404": {
      "description": "Unknown slug"
     }
    }
   }
  },
  "/models.json": {
   "get": {
    "summary": "Data models: headline, public index, coverage, cadence, tiers, methodology.",
    "operationId": "get_models",
    "tags": [
     "free"
    ],
    "parameters": [],
    "responses": {
     "200": {
      "description": "OK",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Envelope"
        }
       }
      }
     },
     "404": {
      "description": "Unknown slug"
     }
    }
   }
  },
  "/indices.json": {
   "get": {
    "summary": "One public headline reading per model, with source and date.",
    "operationId": "get_indices",
    "tags": [
     "free"
    ],
    "parameters": [],
    "responses": {
     "200": {
      "description": "OK",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Envelope"
        }
       }
      }
     },
     "404": {
      "description": "Unknown slug"
     }
    }
   }
  },
  "/lead-times.json": {
   "get": {
    "summary": "Lead-Time Monitor headline and one current published lead time per class, with OEM and date.",
    "operationId": "get_lead_times",
    "tags": [
     "free"
    ],
    "parameters": [],
    "responses": {
     "200": {
      "description": "OK",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Envelope"
        }
       }
      }
     },
     "404": {
      "description": "Unknown slug"
     }
    }
   }
  },
  "/price-bands.json": {
   "get": {
    "summary": "Bid-tab price bands by class, unit and window, with n.",
    "operationId": "get_price_bands",
    "tags": [
     "free"
    ],
    "parameters": [],
    "responses": {
     "200": {
      "description": "OK",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Envelope"
        }
       }
      }
     },
     "404": {
      "description": "Unknown slug"
     }
    }
   }
  },
  "/tariffs.json": {
   "get": {
    "summary": "Tariff schedule, 22 HTS lines by origin, with instruments and citations.",
    "operationId": "get_tariffs",
    "tags": [
     "free"
    ],
    "parameters": [],
    "responses": {
     "200": {
      "description": "OK",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Envelope"
        }
       }
      }
     },
     "404": {
      "description": "Unknown slug"
     }
    }
   }
  },
  "/large-load.json": {
   "get": {
    "summary": "Large-Load Cost Table, fifteen markets.",
    "operationId": "get_large_load",
    "tags": [
     "free"
    ],
    "parameters": [],
    "responses": {
     "200": {
      "description": "OK",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Envelope"
        }
       }
      }
     },
     "404": {
      "description": "Unknown slug"
     }
    }
   }
  },
  "/book-to-bill.json": {
   "get": {
    "summary": "Book-to-Bill League Table, latest quarter per OEM.",
    "operationId": "get_book_to_bill",
    "tags": [
     "free"
    ],
    "parameters": [],
    "responses": {
     "200": {
      "description": "OK",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Envelope"
        }
       }
      }
     },
     "404": {
      "description": "Unknown slug"
     }
    }
   }
  },
  "/scorecard.json": {
   "get": {
    "summary": "OEM Disclosure Scorecard, every cell with its evidence.",
    "operationId": "get_scorecard",
    "tags": [
     "free"
    ],
    "parameters": [],
    "responses": {
     "200": {
      "description": "OK",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Envelope"
        }
       }
      }
     },
     "404": {
      "description": "Unknown slug"
     }
    }
   }
  },
  "/record.json": {
   "get": {
    "summary": "Every dated, checkable call and its score.",
    "operationId": "get_record",
    "tags": [
     "free"
    ],
    "parameters": [],
    "responses": {
     "200": {
      "description": "OK",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Envelope"
        }
       }
      }
     },
     "404": {
      "description": "Unknown slug"
     }
    }
   }
  },
  "/datasets.json": {
   "get": {
    "summary": "Catalog of CSV files behind the charts.",
    "operationId": "get_datasets",
    "tags": [
     "free"
    ],
    "parameters": [],
    "responses": {
     "200": {
      "description": "OK",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Envelope"
        }
       }
      }
     },
     "404": {
      "description": "Unknown slug"
     }
    }
   }
  },
  "/tools.json": {
   "get": {
    "summary": "The calculators, their inputs, outputs and method.",
    "operationId": "get_tools",
    "tags": [
     "free"
    ],
    "parameters": [],
    "responses": {
     "200": {
      "description": "OK",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Envelope"
        }
       }
      }
     },
     "404": {
      "description": "Unknown slug"
     }
    }
   }
  },
  "/tool-data/{tool}.json": {
   "get": {
    "summary": "Source table behind one calculator.",
    "operationId": "get_tool_data_tool",
    "tags": [
     "free"
    ],
    "parameters": [
     {
      "name": "tool",
      "in": "path",
      "required": true,
      "description": "copper-wire-price-sheet | genset-tco | interconnection-cost | lead-time-schedule | pjm-capacity-bill | quote-check | tariff-exposure-calculator | transformer-sizing-cost",
      "schema": {
       "type": "string"
      }
     }
    ],
    "responses": {
     "200": {
      "description": "OK",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Envelope"
        }
       }
      }
     },
     "404": {
      "description": "Unknown slug"
     }
    }
   }
  },
  "/roadmaps.json": {
   "get": {
    "summary": "Forecast pages with revision logs and text.",
    "operationId": "get_roadmaps",
    "tags": [
     "free"
    ],
    "parameters": [],
    "responses": {
     "200": {
      "description": "OK",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Envelope"
        }
       }
      }
     },
     "404": {
      "description": "Unknown slug"
     }
    }
   }
  },
  "/pro/articles/{slug}.json": {
   "get": {
    "summary": "Full article text past the paywall. (pro tier, not yet live)",
    "operationId": "get_pro_articles_slug",
    "tags": [
     "pro"
    ],
    "security": [
     {
      "bearer": []
     }
    ],
    "parameters": [
     {
      "name": "slug",
      "in": "path",
      "required": true,
      "description": "slug",
      "schema": {
       "type": "string"
      }
     }
    ],
    "responses": {
     "200": {
      "description": "OK, once the dataset is live. Needs a pro key.",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Envelope"
        }
       }
      }
     },
     "401": {
      "description": "Missing or invalid key."
     },
     "402": {
      "description": "Key is below the required tier; the body names where to upgrade."
     },
     "501": {
      "description": "Key accepted, dataset not yet served; the body says so."
     }
    }
   }
  },
  "/pro/lead-times/classes.json": {
   "get": {
    "summary": "Every Monitor class and source, monthly, with edition-to-edition flags. (pro tier, not yet live)",
    "operationId": "get_pro_lead_times_classes",
    "tags": [
     "pro"
    ],
    "security": [
     {
      "bearer": []
     }
    ],
    "parameters": [],
    "responses": {
     "200": {
      "description": "OK, once the dataset is live. Needs a pro key.",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Envelope"
        }
       }
      }
     },
     "401": {
      "description": "Missing or invalid key."
     },
     "402": {
      "description": "Key is below the required tier; the body names where to upgrade."
     },
     "501": {
      "description": "Key accepted, dataset not yet served; the body says so."
     }
    }
   }
  },
  "/pro/lead-times/history.json": {
   "get": {
    "summary": "Edition history of every OEM-published lead time. (institutional tier, not yet live)",
    "operationId": "get_pro_lead_times_history",
    "tags": [
     "institutional"
    ],
    "security": [
     {
      "bearer": []
     }
    ],
    "parameters": [],
    "responses": {
     "200": {
      "description": "OK, once the dataset is live. Needs a institutional key.",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Envelope"
        }
       }
      }
     },
     "401": {
      "description": "Missing or invalid key."
     },
     "402": {
      "description": "Key is below the required tier; the body names where to upgrade."
     },
     "501": {
      "description": "Key accepted, dataset not yet served; the body says so."
     }
    }
   }
  },
  "/pro/price-bands/awards.json": {
   "get": {
    "summary": "2,712 award rows and 2,567 vendor bids with document URLs; bands recomputed to a custom spec. (institutional tier, not yet live)",
    "operationId": "get_pro_price_bands_awards",
    "tags": [
     "institutional"
    ],
    "security": [
     {
      "bearer": []
     }
    ],
    "parameters": [],
    "responses": {
     "200": {
      "description": "OK, once the dataset is live. Needs a institutional key.",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Envelope"
        }
       }
      }
     },
     "401": {
      "description": "Missing or invalid key."
     },
     "402": {
      "description": "Key is below the required tier; the body names where to upgrade."
     },
     "501": {
      "description": "Key accepted, dataset not yet served; the body says so."
     }
    }
   }
  },
  "/pro/book-to-bill/history.json": {
   "get": {
    "summary": "Quarterly history, GW reservations and conversions, contract liabilities, Vertiv deferred revenue. (institutional tier, not yet live)",
    "operationId": "get_pro_book_to_bill_history",
    "tags": [
     "institutional"
    ],
    "security": [
     {
      "bearer": []
     }
    ],
    "parameters": [],
    "responses": {
     "200": {
      "description": "OK, once the dataset is live. Needs a institutional key.",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Envelope"
        }
       }
      }
     },
     "401": {
      "description": "Missing or invalid key."
     },
     "402": {
      "description": "Key is below the required tier; the body names where to upgrade."
     },
     "501": {
      "description": "Key accepted, dataset not yet served; the body says so."
     }
    }
   }
  },
  "/pro/large-load/history.json": {
   "get": {
    "summary": "Large-Load table revision history, docket alerts, custom markets. (institutional tier, not yet live)",
    "operationId": "get_pro_large_load_history",
    "tags": [
     "institutional"
    ],
    "security": [
     {
      "bearer": []
     }
    ],
    "parameters": [],
    "responses": {
     "200": {
      "description": "OK, once the dataset is live. Needs a institutional key.",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Envelope"
        }
       }
      }
     },
     "401": {
      "description": "Missing or invalid key."
     },
     "402": {
      "description": "Key is below the required tier; the body names where to upgrade."
     },
     "501": {
      "description": "Key accepted, dataset not yet served; the body says so."
     }
    }
   }
  },
  "/pro/mep/components.json": {
   "get": {
    "summary": "MEP Cost Table component lines with lead time and carrying cost. (pro tier, not yet live)",
    "operationId": "get_pro_mep_components",
    "tags": [
     "pro"
    ],
    "security": [
     {
      "bearer": []
     }
    ],
    "parameters": [],
    "responses": {
     "200": {
      "description": "OK, once the dataset is live. Needs a pro key.",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Envelope"
        }
       }
      }
     },
     "401": {
      "description": "Missing or invalid key."
     },
     "402": {
      "description": "Key is below the required tier; the body names where to upgrade."
     },
     "501": {
      "description": "Key accepted, dataset not yet served; the body says so."
     }
    }
   }
  }
 },
 "components": {
  "securitySchemes": {
   "bearer": {
    "type": "http",
    "scheme": "bearer",
    "description": "API key from the docs page. Optional on free endpoints."
   }
  },
  "schemas": {
   "Envelope": {
    "type": "object",
    "properties": {
     "api": {
      "type": "string",
      "const": "v1"
     },
     "tier": {
      "type": "string",
      "enum": [
       "free",
       "pro",
       "institutional"
      ]
     },
     "description": {
      "type": "string"
     },
     "as_of": {
      "type": [
       "string",
       "null"
      ],
      "description": "Newest dated source or data point in the response, YYYY-MM-DD."
     },
     "generated_at": {
      "type": "string",
      "format": "date-time"
     },
     "source": {},
     "license": {
      "type": "object"
     },
     "attribution": {
      "type": "string"
     },
     "docs": {
      "type": "string",
      "format": "uri"
     }
    },
    "additionalProperties": true,
    "required": [
     "api",
     "tier",
     "description",
     "generated_at",
     "license",
     "attribution",
     "docs"
    ]
   }
  }
 },
 "x-mcp": {
  "url": "https://open-factory.com/mcp",
  "transport": "streamable-http",
  "auth": "optional bearer"
 }
}