{
  "openapi": "3.1.0",
  "info": {
    "title": "Balance Engine Agent API",
    "version": "0.1.4",
    "description": "Energy-rhythm engine for AI agents (adjust ≠ infuse; preview ≠ prediction). Wellness questions in; rhythm / energy / potential out. Free JSON: today-rhythm / body-rhythm / energy-adjust / activity-window / month-brief / sky-window (no key). ICS feed also free. personal-day / personal-month need Authorization: Bearer be_… from join.html. Prefer MCP package balance-engine-mcp for Claude / Cursor."
  },
  "servers": [
    {
      "url": "https://balance-engine.vercel.app"
    }
  ],
  "paths": {
    "/api/calendar/feed": {
      "get": {
        "operationId": "calendarFeed",
        "summary": "Public daily-rhythm ICS feed",
        "description": "Subscribeable calendar. No API key.",
        "parameters": [
          {
            "name": "locale",
            "in": "query",
            "schema": { "type": "string", "enum": ["zh", "en"], "default": "zh" }
          },
          {
            "name": "days",
            "in": "query",
            "schema": { "type": "integer", "minimum": 14, "maximum": 120, "default": 60 }
          }
        ],
        "responses": {
          "200": {
            "description": "text/calendar ICS"
          }
        }
      }
    },
    "/api/calendar/today-rhythm": {
      "get": {
        "operationId": "todayRhythm",
        "summary": "Today rhythm JSON (free)",
        "description": "Day pillar + one action line. Same facts as MCP today_rhythm. No API key.",
        "parameters": [
          {
            "name": "date",
            "in": "query",
            "schema": { "type": "string", "pattern": "^\\d{4}-\\d{2}-\\d{2}$" }
          },
          {
            "name": "locale",
            "in": "query",
            "schema": { "type": "string", "enum": ["zh", "en"], "default": "zh" }
          }
        ],
        "responses": {
          "200": { "description": "JSON brief" },
          "400": { "description": "invalid_date" }
        }
      }
    },
    "/api/calendar/month-brief": {
      "get": {
        "operationId": "monthBrief",
        "summary": "Flow-month brief JSON (free)",
        "description": "Baseline tone, dated sky, do/drop. Same facts as MCP month_brief. No API key.",
        "parameters": [
          {
            "name": "month",
            "in": "query",
            "schema": { "type": "string", "pattern": "^\\d{4}-\\d{2}$" }
          },
          {
            "name": "locale",
            "in": "query",
            "schema": { "type": "string", "enum": ["zh", "en"], "default": "zh" }
          }
        ],
        "responses": {
          "200": { "description": "JSON brief" },
          "404": { "description": "month_unavailable" }
        }
      }
    },
    "/api/calendar/body-rhythm": {
      "get": {
        "operationId": "bodyRhythm",
        "summary": "Body rhythm JSON (free)",
        "description": "Sleep / load / this hour. Same facts as MCP body_rhythm. Not a diagnosis. No API key.",
        "parameters": [
          {
            "name": "date",
            "in": "query",
            "schema": { "type": "string", "pattern": "^\\d{4}-\\d{2}-\\d{2}$" }
          },
          {
            "name": "locale",
            "in": "query",
            "schema": { "type": "string", "enum": ["zh", "en"], "default": "zh" }
          }
        ],
        "responses": {
          "200": { "description": "JSON brief" },
          "400": { "description": "invalid_date" }
        }
      }
    },
    "/api/calendar/activity-window": {
      "get": {
        "operationId": "activityWindow",
        "summary": "Activity window JSON (free)",
        "description": "2–3 clock windows for deep_work / train / meet / ship / rest. Same facts as MCP activity_window. Not meds, not glucose. No API key.",
        "parameters": [
          {
            "name": "date",
            "in": "query",
            "schema": { "type": "string", "pattern": "^\\d{4}-\\d{2}-\\d{2}$" }
          },
          {
            "name": "task",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": ["deep_work", "train", "meet", "ship", "rest"],
              "default": "deep_work"
            }
          },
          {
            "name": "locale",
            "in": "query",
            "schema": { "type": "string", "enum": ["zh", "en"], "default": "zh" }
          }
        ],
        "responses": {
          "200": { "description": "JSON brief" },
          "400": { "description": "invalid_date or invalid_task" }
        }
      }
    },
    "/api/calendar/energy-adjust": {
      "get": {
        "operationId": "energyAdjust",
        "summary": "Energy adjust JSON (free)",
        "description": "Personal seat (sleep/load) or org seat (push vs hold). Same facts as MCP energy_adjust. No API key.",
        "parameters": [
          {
            "name": "seat",
            "in": "query",
            "schema": { "type": "string", "enum": ["personal", "org"], "default": "personal" }
          },
          {
            "name": "date",
            "in": "query",
            "schema": { "type": "string", "pattern": "^\\d{4}-\\d{2}-\\d{2}$" }
          },
          {
            "name": "month",
            "in": "query",
            "schema": { "type": "string", "pattern": "^\\d{4}-\\d{2}$" }
          },
          {
            "name": "locale",
            "in": "query",
            "schema": { "type": "string", "enum": ["zh", "en"], "default": "zh" }
          }
        ],
        "responses": {
          "200": { "description": "JSON brief" },
          "400": { "description": "invalid_date" }
        }
      }
    },
    "/api/calendar/sky-window": {
      "get": {
        "operationId": "skyWindow",
        "summary": "Sky window JSON (free)",
        "description": "Dated L1 sky marks. Same facts as MCP sky_window. No API key. Max span 45 days.",
        "parameters": [
          {
            "name": "from",
            "in": "query",
            "schema": { "type": "string", "pattern": "^\\d{4}-\\d{2}-\\d{2}$" }
          },
          {
            "name": "to",
            "in": "query",
            "schema": { "type": "string", "pattern": "^\\d{4}-\\d{2}-\\d{2}$" }
          },
          {
            "name": "locale",
            "in": "query",
            "schema": { "type": "string", "enum": ["zh", "en"], "default": "zh" }
          }
        ],
        "responses": {
          "200": { "description": "JSON brief" }
        }
      }
    },
    "/api/report/personal-day": {
      "post": {
        "operationId": "personalDay",
        "summary": "Personal day brief (paid)",
        "description": "Day-master vs today's stem (ten-god). Optional hour (HH:MM or 子–亥) adds hour-pillar ten-god. Birth defaults to the account cloud profile.",
        "security": [{ "bearerAuth": [] }],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": { "$ref": "#/components/schemas/PersonalDayRequest" }
            }
          }
        },
        "responses": {
          "200": { "description": "Brief JSON" },
          "401": { "description": "invalid_api_key" },
          "400": { "description": "birth_required | invalid_birth" },
          "429": { "description": "rate_limited" }
        }
      }
    },
    "/api/report/personal-month": {
      "post": {
        "operationId": "personalMonth",
        "summary": "Personal flow-month brief (paid)",
        "description": "Day-master vs month stem, dated sky marks, sandbox assumptions, fold-memory prompts.",
        "security": [{ "bearerAuth": [] }],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": { "$ref": "#/components/schemas/PersonalMonthRequest" }
            }
          }
        },
        "responses": {
          "200": { "description": "Brief JSON" },
          "401": { "description": "invalid_api_key" },
          "400": { "description": "birth_required | invalid_birth" },
          "429": { "description": "rate_limited" }
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "bearerAuth": {
        "type": "http",
        "scheme": "bearer",
        "bearerFormat": "be_"
      }
    },
    "schemas": {
      "Birth": {
        "type": "object",
        "required": ["date", "time", "gender"],
        "properties": {
          "date": { "type": "string", "pattern": "^\\d{4}-\\d{2}-\\d{2}$" },
          "time": { "type": "string", "description": "HH:MM" },
          "city": { "type": "string" },
          "longitude": { "type": "number" },
          "latitude": { "type": "number" },
          "gender": { "type": "string", "enum": ["male", "female"] }
        }
      },
      "PersonalDayRequest": {
        "type": "object",
        "properties": {
          "date": { "type": "string", "pattern": "^\\d{4}-\\d{2}-\\d{2}$" },
          "hour": { "type": "string", "description": "HH:MM or earthly branch 子–亥" },
          "locale": { "type": "string", "enum": ["zh", "en"] },
          "birth": { "$ref": "#/components/schemas/Birth" }
        }
      },
      "PersonalMonthRequest": {
        "type": "object",
        "properties": {
          "month": { "type": "string", "pattern": "^\\d{4}-\\d{2}$" },
          "date": { "type": "string", "pattern": "^\\d{4}-\\d{2}-\\d{2}$" },
          "locale": { "type": "string", "enum": ["zh", "en"] },
          "birth": { "$ref": "#/components/schemas/Birth" }
        }
      }
    }
  }
}
