{
  "openapi": "3.1.0",
  "info": {
    "title": "PCBA Quote Lab API",
    "version": "0.1.2",
    "description": "Reference-board quote comparison. Public historical sample; authenticated live pilot. No ordering, payment, engineering approval or Google AI Mode integration.",
    "contact": {
      "name": "Random Walk",
      "email": "biz@random-walk.co.jp"
    }
  },
  "servers": [
    {
      "url": "https://pcba-quote-lab.pages.dev"
    }
  ],
  "paths": {
    "/api/health": {
      "get": {
        "operationId": "getQuoteServiceHealth",
        "summary": "Check service and live configuration",
        "responses": {
          "200": {
            "description": "Configuration status; not product validation",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "const": "ok"
                    },
                    "version": {
                      "type": "string"
                    },
                    "liveConfigured": {
                      "type": "boolean"
                    },
                    "productValidated": {
                      "const": false
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/providers": {
      "get": {
        "operationId": "listQuoteProviders",
        "summary": "List provider availability and supported designs",
        "responses": {
          "200": {
            "description": "Only configured providers can quote; planned providers have no quote capability",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "providers": {
                      "type": "array",
                      "items": {
                        "type": "object"
                      }
                    },
                    "coverage": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/quotes": {
      "post": {
        "operationId": "comparePcbaQuotes",
        "summary": "Compare cost and manufacturing time per quantity",
        "description": "Sample is anonymous and supports observed quantity 5 only. Live requires PilotBearer and is bounded to four quantities. Never automatically retry unknown or timed-out requests. Always preserve warnings, source and observation time. No live-to-sample fallback.",
        "security": [
          {},
          {
            "PilotBearer": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/QuoteRequest"
              },
              "example": {
                "providerId": "macrofab",
                "designId": "macro-watch",
                "mode": "sample",
                "quantities": [
                  5
                ],
                "maxBudgetMinor": 150000,
                "maxBusinessDays": 20
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Quotes and limitations. errors can contain no_sample for unobserved quantities.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Comparison"
                }
              }
            }
          },
          "400": {
            "description": "Request could not be completed",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid pilot access code",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "403": {
            "description": "Request could not be completed",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "405": {
            "description": "Request could not be completed",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "413": {
            "description": "Request could not be completed",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "415": {
            "description": "Request could not be completed",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "422": {
            "description": "Unsupported provider/design or sample tier selection",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "429": {
            "description": "Provider rate limit",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "500": {
            "description": "Request could not be completed",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "502": {
            "description": "Upstream failure, incomplete response or expired provider authentication",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "503": {
            "description": "Live service is not configured",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "PilotBearer": {
        "type": "http",
        "scheme": "bearer",
        "description": "Our privately issued pilot access code. Required only for mode=live. Never use a MacroFab API key."
      }
    },
    "schemas": {
      "QuoteRequest": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "providerId",
          "designId",
          "mode",
          "quantities"
        ],
        "properties": {
          "providerId": {
            "const": "macrofab"
          },
          "designId": {
            "const": "macro-watch"
          },
          "mode": {
            "type": "string",
            "enum": [
              "sample",
              "live"
            ]
          },
          "quantities": {
            "type": "array",
            "minItems": 1,
            "maxItems": 4,
            "uniqueItems": true,
            "items": {
              "type": "integer",
              "minimum": 1,
              "maximum": 1000
            }
          },
          "tiers": {
            "type": "array",
            "minItems": 1,
            "maxItems": 4,
            "uniqueItems": true,
            "items": {
              "type": "string",
              "enum": [
                "budget",
                "standard",
                "fast",
                "extreme"
              ]
            },
            "description": "Live only. Defaults to all tiers. Omit in sample mode."
          },
          "maxBudgetMinor": {
            "type": [
              "integer",
              "null"
            ],
            "minimum": 0,
            "maximum": 100000000,
            "description": "Maximum batch price in USD cents, per quantity; null means no budget limit."
          },
          "maxBusinessDays": {
            "type": [
              "integer",
              "null"
            ],
            "minimum": 1,
            "maximum": 365,
            "description": "Maximum manufacturing business days; null means no limit."
          }
        },
        "allOf": [
          {
            "if": {
              "properties": {
                "mode": {
                  "const": "sample"
                }
              }
            },
            "then": {
              "not": {
                "required": [
                  "tiers"
                ]
              }
            }
          }
        ]
      },
      "NormalizedQuoteRequest": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "providerId",
          "designId",
          "mode",
          "quantities",
          "tiers",
          "maxBudgetMinor",
          "maxBusinessDays"
        ],
        "properties": {
          "providerId": {
            "const": "macrofab"
          },
          "designId": {
            "const": "macro-watch"
          },
          "mode": {
            "type": "string",
            "enum": [
              "sample",
              "live"
            ]
          },
          "quantities": {
            "type": "array",
            "minItems": 1,
            "maxItems": 4,
            "uniqueItems": true,
            "items": {
              "type": "integer",
              "minimum": 1,
              "maximum": 1000
            }
          },
          "tiers": {
            "type": "array",
            "minItems": 1,
            "maxItems": 4,
            "uniqueItems": true,
            "items": {
              "type": "string",
              "enum": [
                "budget",
                "standard",
                "fast",
                "extreme"
              ]
            },
            "description": "Normalized tiers; defaults are recorded even for sample mode, where historical tier mapping remains unknown."
          },
          "maxBudgetMinor": {
            "type": [
              "integer",
              "null"
            ],
            "minimum": 0,
            "maximum": 100000000,
            "description": "Maximum batch price in USD cents, per quantity; null means no budget limit."
          },
          "maxBusinessDays": {
            "type": [
              "integer",
              "null"
            ],
            "minimum": 1,
            "maximum": 365,
            "description": "Maximum manufacturing business days; null means no limit."
          }
        }
      },
      "Quote": {
        "type": "object",
        "required": [
          "id",
          "providerId",
          "designId",
          "quantity",
          "totalMinor",
          "unitMinor",
          "currency",
          "manufacturingBusinessDays",
          "valid",
          "warnings",
          "engineeringApproved",
          "landedCostFinal"
        ],
        "properties": {
          "id": {
            "type": "string"
          },
          "providerId": {
            "const": "macrofab"
          },
          "designId": {
            "const": "macro-watch"
          },
          "quantity": {
            "type": "integer"
          },
          "tier": {
            "type": [
              "string",
              "null"
            ]
          },
          "label": {
            "type": "string"
          },
          "totalMinor": {
            "type": [
              "integer",
              "null"
            ],
            "description": "Batch price in USD cents; null if quote is incomplete."
          },
          "unitMinor": {
            "type": [
              "integer",
              "null"
            ],
            "description": "Display-rounded USD cents per board. Do not multiply to reconstruct the batch price."
          },
          "currency": {
            "const": "USD"
          },
          "manufacturingBusinessDays": {
            "type": [
              "integer",
              "null"
            ],
            "description": "Manufacturing only; delivery is excluded."
          },
          "estimatedShipDate": {
            "type": [
              "string",
              "null"
            ]
          },
          "valid": {
            "type": "boolean"
          },
          "autoQuoteAllowed": {
            "type": [
              "boolean",
              "null"
            ]
          },
          "status": {
            "type": "string"
          },
          "warnings": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "breakdown": {
            "type": "array",
            "items": {
              "type": "object"
            }
          },
          "shippingIncluded": {
            "type": [
              "boolean",
              "null"
            ],
            "description": "null means the provider has not confirmed whether shipping is included."
          },
          "engineeringApproved": {
            "const": false
          },
          "landedCostFinal": {
            "const": false
          },
          "providerWarnings": {
            "type": [
              "object",
              "null"
            ],
            "description": "Original provider warning fields, without flattening or truncation. Null for historical observations lacking structured evidence.",
            "properties": {
              "quoteWarnings": {},
              "invalidReasons": {},
              "readinessObservations": {
                "type": "array",
                "items": {
                  "type": "object",
                  "additionalProperties": true
                }
              }
            }
          },
          "availableActions": {
            "type": [
              "array",
              "null"
            ],
            "items": {
              "type": "string"
            },
            "description": "Provider-reported readiness actions; always read blockedActions as well."
          },
          "blockedActions": {
            "type": [
              "array",
              "null"
            ],
            "items": {
              "type": "string"
            },
            "description": "Union of explicit observation prevents_actions. These restrictions override contradictory availability."
          }
        }
      },
      "Comparison": {
        "type": "object",
        "required": [
          "schemaVersion",
          "requestId",
          "mode",
          "source",
          "freshness",
          "observedAt",
          "quotes",
          "comparison",
          "errors",
          "warnings",
          "engineeringApproved",
          "landedCostFinal"
        ],
        "properties": {
          "schemaVersion": {
            "const": 1
          },
          "requestId": {
            "type": "string",
            "format": "uuid"
          },
          "mode": {
            "enum": [
              "sample",
              "live"
            ]
          },
          "source": {
            "enum": [
              "browser_receipt",
              "official_api"
            ]
          },
          "freshness": {
            "enum": [
              "historical",
              "live"
            ]
          },
          "observedAt": {
            "type": "string",
            "format": "date-time"
          },
          "currency": {
            "const": "USD"
          },
          "design": {
            "type": "object"
          },
          "request": {
            "$ref": "#/components/schemas/NormalizedQuoteRequest"
          },
          "quotes": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Quote"
            }
          },
          "comparison": {
            "type": "object",
            "properties": {
              "bestByQuantity": {
                "type": "object",
                "additionalProperties": {
                  "type": [
                    "string",
                    "null"
                  ]
                }
              },
              "feasibleIds": {
                "type": "array",
                "items": {
                  "type": "string"
                }
              },
              "basis": {
                "type": "string"
              },
              "engineeringApproved": {
                "const": false
              }
            }
          },
          "errors": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "quantity": {
                  "type": "integer"
                },
                "code": {
                  "type": "string"
                },
                "message": {
                  "type": "string"
                }
              }
            }
          },
          "warnings": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "receipts": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "quantity": {
                  "type": "integer"
                },
                "sourceSha256": {
                  "type": "string",
                  "pattern": "^[a-f0-9]{64}$"
                },
                "observedAt": {
                  "type": "string",
                  "format": "date-time"
                }
              }
            }
          },
          "costScope": {
            "type": "object"
          },
          "engineeringApproved": {
            "const": false
          },
          "landedCostFinal": {
            "const": false
          }
        }
      },
      "Problem": {
        "type": "object",
        "required": [
          "error",
          "requestId"
        ],
        "properties": {
          "requestId": {
            "type": "string"
          },
          "error": {
            "type": "object",
            "required": [
              "code",
              "message"
            ],
            "properties": {
              "code": {
                "type": "string"
              },
              "message": {
                "type": "string"
              }
            }
          }
        }
      }
    }
  }
}
