{
  "openapi": "3.1.0",
  "info": {
    "title": "pcb.express API",
    "version": "1.1.0",
    "description": "Instant PCB quoting in USD. Every tier returns a door-to-door delivery_by date; US and EU shipments are DDP. No API key required. Orders are not open yet: save a quote with the leads endpoint to be notified at launch.",
    "contact": {
      "email": "hello@pcb.express"
    }
  },
  "servers": [
    {
      "url": "https://pcb.express"
    }
  ],
  "paths": {
    "/api/quote": {
      "get": {
        "operationId": "getPcbQuote",
        "summary": "Parametric PCB quote: USD prices and delivery dates per tier",
        "parameters": [
          {
            "name": "layers",
            "in": "query",
            "schema": {
              "type": "integer",
              "enum": [
                2,
                4,
                6
              ],
              "default": 2
            }
          },
          {
            "name": "width_mm",
            "in": "query",
            "schema": {
              "type": "number",
              "minimum": 10,
              "maximum": 400,
              "default": 100
            }
          },
          {
            "name": "height_mm",
            "in": "query",
            "schema": {
              "type": "number",
              "minimum": 10,
              "maximum": 500,
              "default": 100
            }
          },
          {
            "name": "qty",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 1000,
              "default": 5
            }
          },
          {
            "name": "thickness_mm",
            "in": "query",
            "schema": {
              "type": "number",
              "enum": [
                0.6,
                0.8,
                1,
                1.2,
                1.6,
                2
              ]
            }
          },
          {
            "name": "finish",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "hasl_lf",
                "hasl",
                "enig"
              ]
            }
          },
          {
            "name": "mask",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "green",
                "blue",
                "red",
                "black",
                "white",
                "yellow",
                "purple"
              ]
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Tiered quote",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": {
                      "type": "boolean"
                    },
                    "currency": {
                      "type": "string",
                      "const": "USD"
                    },
                    "tiers": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "type": "string",
                            "enum": [
                              "economy",
                              "standard",
                              "express"
                            ]
                          },
                          "label": {
                            "type": "string"
                          },
                          "usd": {
                            "type": "number",
                            "description": "final USD price for the batch"
                          },
                          "per_piece_usd": {
                            "type": "number"
                          },
                          "delivery_by": {
                            "type": "string",
                            "format": "date",
                            "description": "door-to-door date"
                          },
                          "transit_days": {
                            "type": "string",
                            "description": "door-to-door day range, e.g. 5-9"
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Invalid parameter"
          }
        }
      }
    },
    "/api/analyze": {
      "post": {
        "operationId": "precheckGerber",
        "summary": "Analyze a Gerber .zip: layers, board size, holes, DFM findings",
        "requestBody": {
          "required": true,
          "content": {
            "multipart/form-data": {
              "schema": {
                "type": "object",
                "properties": {
                  "file": {
                    "type": "string",
                    "format": "binary",
                    "description": "One .zip with Gerber RS-274X and Excellon files, up to 25 MB"
                  }
                },
                "required": [
                  "file"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Analysis with detected layers, size, holes, findings and a reusable id"
          },
          "400": {
            "description": "Unreadable or unsupported file"
          }
        }
      }
    },
    "/api/analyze/{id}": {
      "get": {
        "operationId": "getAnalysis",
        "summary": "Re-read a cached analysis by id (kept 24 hours after last use)",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[0-9a-f]{16}$"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The cached analysis"
          },
          "404": {
            "description": "Unknown or expired id"
          }
        }
      }
    },
    "/api/leads": {
      "post": {
        "operationId": "saveQuote",
        "summary": "Save a quote with an e-mail; notified at launch with a 10% first-order discount",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "kind": {
                    "type": "string",
                    "enum": [
                      "quote"
                    ]
                  },
                  "spec": {
                    "type": "object",
                    "properties": {
                      "layers": {
                        "type": "integer",
                        "enum": [
                          2,
                          4,
                          6
                        ]
                      },
                      "qty": {
                        "type": "integer"
                      },
                      "widthMm": {
                        "type": "number"
                      },
                      "heightMm": {
                        "type": "number"
                      }
                    },
                    "required": [
                      "layers",
                      "qty",
                      "widthMm",
                      "heightMm"
                    ]
                  },
                  "tier": {
                    "type": "string",
                    "enum": [
                      "economy",
                      "standard",
                      "express"
                    ]
                  },
                  "email": {
                    "type": "string",
                    "format": "email"
                  }
                },
                "required": [
                  "kind",
                  "spec",
                  "tier",
                  "email"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Saved; returns { ok, id }. The price is computed server-side."
          },
          "400": {
            "description": "Validation error"
          }
        }
      }
    }
  }
}