{
  "openapi": "3.1.0",
  "info": {
    "title": "Founder Dinner Matching API",
    "version": "1.0.0",
    "description": "REST surface for seating founders at dinner tables of 8-10 so each table mirrors the room. The same matching is exposed over MCP at /mcp (see /mcp-skill.md and the server card at /.well-known/mcp/server-card.json). Output carries only Table, Name, and Company; all other founder attributes are treated as PII and never leave the server. Endpoints are authless and rate-limited at 60 requests / 60s per IP."
  },
  "servers": [
    {
      "url": "https://dinner.youcanjustdothings.io"
    }
  ],
  "paths": {
    "/api/health": {
      "get": {
        "operationId": "getHealth",
        "summary": "Liveness probe backed by a D1 round-trip.",
        "responses": {
          "200": {
            "description": "Service is up.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Health"
                }
              }
            }
          }
        }
      }
    },
    "/api/founders": {
      "get": {
        "operationId": "listFounders",
        "summary": "The founders stored in D1 (internal shape; unstable, for inspection only).",
        "responses": {
          "200": {
            "description": "The stored founders.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/FoundersList"
                }
              }
            }
          }
        }
      }
    },
    "/api/match": {
      "post": {
        "operationId": "matchStoredFounders",
        "summary": "Seat the stored founders with the supplied weights, max seats, and sizing mode.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/MatchRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The output document.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MatchOutput"
                }
              }
            }
          },
          "429": {
            "description": "Rate limited.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/match-list": {
      "post": {
        "operationId": "matchFounderList",
        "summary": "Seat a caller-supplied founder list. Provide founders exactly one way: an inline `founders` array, a `foundersUrl` (https, fetched and validated server-side, 5 MB / 10s caps), or a multipart JSON `file`. Lists are capped at 2,000 founders and fail fast on invalid input.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/MatchListRequest"
              }
            },
            "multipart/form-data": {
              "schema": {
                "type": "object",
                "required": [
                  "file"
                ],
                "properties": {
                  "file": {
                    "type": "string",
                    "format": "binary",
                    "description": "A JSON array of source founders."
                  },
                  "params": {
                    "type": "string",
                    "description": "JSON-encoded { weights, maxSeats, mode }; defaults applied when omitted."
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The output document.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MatchOutput"
                }
              }
            }
          },
          "400": {
            "description": "Invalid founder input or parameters (fail-fast).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limited.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/schema/input.json": {
      "get": {
        "operationId": "getInputSchema",
        "summary": "The JSON Schema (2020-12) for the canonical match input document.",
        "responses": {
          "200": {
            "description": "A JSON Schema document.",
            "content": {
              "application/schema+json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        }
      }
    },
    "/api/schema/output.json": {
      "get": {
        "operationId": "getOutputSchema",
        "summary": "The JSON Schema (2020-12) for the match output document.",
        "responses": {
          "200": {
            "description": "A JSON Schema document.",
            "content": {
              "application/schema+json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        }
      }
    },
    "/openapi.json": {
      "get": {
        "operationId": "getOpenApi",
        "summary": "This OpenAPI 3.1 description.",
        "responses": {
          "200": {
            "description": "The OpenAPI document.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        }
      }
    },
    "/api/logs": {
      "post": {
        "operationId": "postLog",
        "summary": "Fire-and-forget client log sink; the body is accepted and acknowledged.",
        "responses": {
          "200": {
            "description": "Acknowledged.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Ack"
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "SourceFounder": {
        "type": "object",
        "properties": {
          "Id": {
            "type": "string"
          },
          "Name": {
            "type": "string",
            "minLength": 1
          },
          "Group": {
            "type": "string",
            "minLength": 1
          },
          "Group Section": {
            "type": "string",
            "minLength": 1
          },
          "Company vertical": {
            "type": "string",
            "minLength": 1
          },
          "Company": {
            "type": "string",
            "minLength": 1
          },
          "Age": {
            "type": "integer"
          },
          "Education": {
            "type": "string",
            "minLength": 1
          },
          "Role": {
            "type": "string",
            "minLength": 1
          }
        },
        "required": [
          "Id",
          "Name",
          "Group",
          "Group Section",
          "Company vertical",
          "Company",
          "Age",
          "Education",
          "Role"
        ],
        "additionalProperties": false
      },
      "MatchWeights": {
        "type": "object",
        "properties": {
          "balance": {
            "type": "object",
            "properties": {
              "age": {
                "type": "number",
                "minimum": 0,
                "maximum": 5
              },
              "role": {
                "type": "number",
                "minimum": 0,
                "maximum": 5
              },
              "education": {
                "type": "number",
                "minimum": 0,
                "maximum": 5
              },
              "vertical": {
                "type": "number",
                "minimum": 0,
                "maximum": 5
              }
            },
            "required": [
              "age",
              "role",
              "education",
              "vertical"
            ],
            "additionalProperties": false
          },
          "separation": {
            "type": "object",
            "properties": {
              "group": {
                "type": "number",
                "minimum": 0,
                "maximum": 5
              },
              "section": {
                "type": "number",
                "minimum": 0,
                "maximum": 5
              }
            },
            "required": [
              "group",
              "section"
            ],
            "additionalProperties": false
          }
        },
        "required": [
          "balance",
          "separation"
        ],
        "additionalProperties": false
      },
      "MatchRequest": {
        "type": "object",
        "properties": {
          "weights": {
            "type": "object",
            "properties": {
              "balance": {
                "type": "object",
                "properties": {
                  "age": {
                    "type": "number",
                    "minimum": 0,
                    "maximum": 5
                  },
                  "role": {
                    "type": "number",
                    "minimum": 0,
                    "maximum": 5
                  },
                  "education": {
                    "type": "number",
                    "minimum": 0,
                    "maximum": 5
                  },
                  "vertical": {
                    "type": "number",
                    "minimum": 0,
                    "maximum": 5
                  }
                },
                "required": [
                  "age",
                  "role",
                  "education",
                  "vertical"
                ],
                "additionalProperties": false
              },
              "separation": {
                "type": "object",
                "properties": {
                  "group": {
                    "type": "number",
                    "minimum": 0,
                    "maximum": 5
                  },
                  "section": {
                    "type": "number",
                    "minimum": 0,
                    "maximum": 5
                  }
                },
                "required": [
                  "group",
                  "section"
                ],
                "additionalProperties": false
              }
            },
            "required": [
              "balance",
              "separation"
            ],
            "additionalProperties": false
          },
          "maxSeats": {
            "type": "integer",
            "minimum": 8,
            "maximum": 10
          },
          "mode": {
            "type": "string",
            "enum": [
              "fill",
              "mix"
            ]
          }
        },
        "required": [
          "weights",
          "maxSeats",
          "mode"
        ],
        "additionalProperties": false
      },
      "MatchListRequest": {
        "type": "object",
        "properties": {
          "weights": {
            "type": "object",
            "properties": {
              "balance": {
                "type": "object",
                "properties": {
                  "age": {
                    "type": "number",
                    "minimum": 0,
                    "maximum": 5
                  },
                  "role": {
                    "type": "number",
                    "minimum": 0,
                    "maximum": 5
                  },
                  "education": {
                    "type": "number",
                    "minimum": 0,
                    "maximum": 5
                  },
                  "vertical": {
                    "type": "number",
                    "minimum": 0,
                    "maximum": 5
                  }
                },
                "required": [
                  "age",
                  "role",
                  "education",
                  "vertical"
                ],
                "additionalProperties": false
              },
              "separation": {
                "type": "object",
                "properties": {
                  "group": {
                    "type": "number",
                    "minimum": 0,
                    "maximum": 5
                  },
                  "section": {
                    "type": "number",
                    "minimum": 0,
                    "maximum": 5
                  }
                },
                "required": [
                  "group",
                  "section"
                ],
                "additionalProperties": false
              }
            },
            "required": [
              "balance",
              "separation"
            ],
            "additionalProperties": false
          },
          "maxSeats": {
            "type": "integer",
            "minimum": 8,
            "maximum": 10
          },
          "mode": {
            "type": "string",
            "enum": [
              "fill",
              "mix"
            ]
          },
          "founders": {
            "minItems": 1,
            "maxItems": 2000,
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "Id": {
                  "type": "string"
                },
                "Name": {
                  "type": "string",
                  "minLength": 1
                },
                "Group": {
                  "type": "string",
                  "minLength": 1
                },
                "Group Section": {
                  "type": "string",
                  "minLength": 1
                },
                "Company vertical": {
                  "type": "string",
                  "minLength": 1
                },
                "Company": {
                  "type": "string",
                  "minLength": 1
                },
                "Age": {
                  "type": "integer"
                },
                "Education": {
                  "type": "string",
                  "minLength": 1
                },
                "Role": {
                  "type": "string",
                  "minLength": 1
                }
              },
              "required": [
                "Id",
                "Name",
                "Group",
                "Group Section",
                "Company vertical",
                "Company",
                "Age",
                "Education",
                "Role"
              ],
              "additionalProperties": false
            }
          },
          "foundersUrl": {
            "type": "string"
          }
        },
        "required": [
          "weights",
          "maxSeats",
          "mode"
        ],
        "additionalProperties": false
      },
      "MatchOutput": {
        "type": "object",
        "properties": {
          "Version": {
            "type": "number",
            "const": 1
          },
          "Generated At": {
            "type": "string",
            "format": "date-time",
            "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"
          },
          "Table Count": {
            "type": "integer",
            "exclusiveMinimum": 0
          },
          "Founder Count": {
            "type": "integer",
            "exclusiveMinimum": 0
          },
          "Summary": {
            "type": "object",
            "properties": {
              "Average Balance": {
                "type": "number",
                "minimum": 0,
                "maximum": 1
              },
              "Group Clashes": {
                "type": "integer",
                "minimum": 0
              },
              "Section Clashes": {
                "type": "integer",
                "minimum": 0
              },
              "Company Clashes": {
                "type": "integer",
                "minimum": 0
              }
            },
            "required": [
              "Average Balance",
              "Group Clashes",
              "Section Clashes",
              "Company Clashes"
            ],
            "additionalProperties": false
          },
          "Assignments": {
            "minItems": 1,
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "Table": {
                  "type": "integer",
                  "exclusiveMinimum": 0
                },
                "Name": {
                  "type": "string",
                  "minLength": 1
                },
                "Company": {
                  "type": "string",
                  "minLength": 1
                }
              },
              "required": [
                "Table",
                "Name",
                "Company"
              ],
              "additionalProperties": false
            }
          }
        },
        "required": [
          "Version",
          "Generated At",
          "Table Count",
          "Founder Count",
          "Summary",
          "Assignments"
        ],
        "additionalProperties": false
      },
      "Health": {
        "type": "object",
        "required": [
          "status",
          "now"
        ],
        "properties": {
          "status": {
            "type": "string"
          },
          "now": {
            "type": [
              "string",
              "null"
            ]
          }
        }
      },
      "FoundersList": {
        "type": "object",
        "required": [
          "count",
          "founders"
        ],
        "properties": {
          "count": {
            "type": "integer"
          },
          "founders": {
            "type": "array",
            "items": {
              "type": "object",
              "additionalProperties": true
            }
          }
        }
      },
      "Ack": {
        "type": "object",
        "required": [
          "ok"
        ],
        "properties": {
          "ok": {
            "type": "boolean"
          }
        }
      },
      "Error": {
        "type": "object",
        "required": [
          "error",
          "message"
        ],
        "properties": {
          "error": {
            "type": "string"
          },
          "message": {
            "type": "string"
          }
        }
      }
    }
  }
}