{
  "openapi": "3.1.1",
  "jsonSchemaDialect": "https://spec.openapis.org/oas/3.1/dialect/base",
  "info": {
    "title": "AstroAPI calculation API",
    "version": "2026-09-15.davison-beta",
    "description": "Machine-readable description of the nineteen unversioned calculation routes, including twelve additive beta routes. This version is a DOCUMENT REVISION, not a /v1 runtime identifier or proof of deployment. Call the public Node gateway, not the internal Python service.\n\nAPI keys are server-side credentials: never put them in browser JavaScript, URLs or logs. Authentication alternatives are Bearer or x-api-key, not both required. Dashboard session cookies are not calculation credentials. Legacy routes ignore unknown JSON properties (and may echo them); all twelve additive beta routes reject unknown keys, explicit nulls, coordinate strings and noncanonical enums, including inside birth. Do not assume undocumented controls are implemented.\n\nCharts require a known civil birth time, valid IANA timezone (UTC default), date 1900-01-01 through 2050-12-31, and valid coordinates. Exact poles/undefined Ascendant geometry and ambiguous/nonexistent local clock-change times return 400. Semantic calendar, timezone, coordinate-string range and inter-field checks are performed by the server beyond JSON Schema assertions.\n\nTropical is default; sidereal supports Lahiri, Raman and Krishnamurti. Default chart calculations retain Equal and Whole Sign. The houses and natal-svg routes also offer explicit Placidus beta, with polar rejection and no fallback. Natal SVG is a generated JSON-wrapped graphic, not an upload or hosted widget. Vargas supports Parashari D1/D3/D4/D7/D9/D10/D12 only; Vimshottari supplies nine major periods and nine subperiods each using fixed 365.25-day years. Both are sidereal-only with mean nodes; no specialist/practitioner sign-off has been completed. The legacy true node equals the mean node. Horoscope is deterministic structured beta, not prose or validated prediction. Hourly timeline sampling can miss short departure/re-entry events; returned continuity is not proof of exhaustive discovery.\n\nMonthly usage resets by UTC calendar month: free 100 normal requests, Developer (internal basic) 10,000, Pro 100,000 and 1,000 timeline units. Every attempt that reaches atomic reservation consumes one unit, including invalid input, dependency failures and timeouts. There is no automatic refund/finalization or public idempotency-key mechanism; never blindly retry a calculation.\n\nProduction caps astrology concurrency at four globally and two per API-key user. Normal engine timeout is 15 seconds, timeline 60 seconds including parsing; nginx upstream windows are 40/90 seconds. Disconnect does not cancel already admitted work. Reverse-proxy errors can be non-JSON; clients must preserve HTTP status without leaking response bodies.\n\nAdditional beta scope: instant Panchang uses the explicit USNO 50-arcminute sunrise model (not regional calendars), composites use shortest-arc midpoints with synthetic houses, secondary progressions calculate planets only under the fixed 365.2421904-day TT convention, and North/South Indian varga SVGs use D1/D3/D4/D7/D9/D10/D12 sign placements. No full astrology catalogue, practitioner approval or prediction validity is implied.\n\nThe standalone lunar-nodes beta distinguishes mean and geometric osculating models without changing legacy aliases. The returns beta searches only Sun/Moon longitude returns under fixed bounded windows, and returns a chart at the precise numerical root. Civil and full-UTC-window limits differ as stated in each request schema. Neither predicts outcomes or extends the ephemeris dataset.\n\nSolar-arcs adds symbolic true tropical solar-arc directions, not a physical chart. Vimshottari optionally admits depth 3 (729 third-level periods); omission/2 preserves its original response.\n\nMoon-phases adds separate instant geometry and bounded primary-event calendar modes; no observer location, zodiac, eclipse shadow or visibility prediction. Output precision is not an accuracy guarantee.\n\nDavison beta computes an uncorrected uniform-TT time mean and arithmetic canonical coordinates, not averaged planets or a corrected/spherical variant. See its method metadata. Publication of this document alone does not establish deployment.",
    "termsOfService": "https://astroapi.io/terms.html",
    "contact": {
      "name": "AstroAPI support",
      "email": "support@astroapi.io"
    }
  },
  "servers": [
    {
      "url": "https://api.astroapi.io",
      "description": "Public gateway; no runtime version prefix"
    }
  ],
  "security": [
    {
      "BearerApiKey": []
    },
    {
      "HeaderApiKey": []
    }
  ],
  "tags": [
    {
      "name": "Calculations"
    },
    {
      "name": "Pro timeline"
    },
    {
      "name": "Beta interpretation"
    },
    {
      "name": "Beta calculations",
      "description": "Additive experimental calculations; numerical tests are not practitioner acceptance."
    }
  ],
  "paths": {
    "/api/astro/birth-chart": {
      "post": {
        "operationId": "calculateBirthChart",
        "summary": "Calculate a full birth chart",
        "tags": [
          "Calculations"
        ],
        "description": "Current unversioned gateway response.\n\nEach admitted request reserves one monthly usage unit before route validation or engine work; failed or timed-out admitted attempts are not refunded. Do not automatically retry.",
        "x-contract-status": "current",
        "x-engine-timeout-ms": 15000,
        "x-quota-group": "api",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/BirthChartRequest"
              },
              "examples": {
                "canonical": {
                  "summary": "Synthetic example; send with your server-side API key",
                  "value": {
                    "date": "1990-01-01",
                    "time": "12:00",
                    "timezone": "America/New_York",
                    "lat": 40.7128,
                    "lon": -74.006
                  }
                },
                "sidereal": {
                  "summary": "Same calculation in Lahiri sidereal coordinates",
                  "value": {
                    "date": "1990-01-01",
                    "time": "12:00",
                    "timezone": "America/New_York",
                    "lat": 40.7128,
                    "lon": -74.006,
                    "zodiac": "sidereal",
                    "ayanamsa": "lahiri"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful calculation. Field nesting is specific to this route.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              },
              "Pragma": {
                "schema": {
                  "type": "string",
                  "const": "no-cache"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BirthChartResponse"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/InvalidInput"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "413": {
            "$ref": "#/components/responses/TooLarge"
          },
          "429": {
            "$ref": "#/components/responses/Limited"
          },
          "500": {
            "$ref": "#/components/responses/InternalFailure"
          },
          "502": {
            "$ref": "#/components/responses/EngineUnavailable"
          },
          "503": {
            "$ref": "#/components/responses/Busy"
          },
          "504": {
            "$ref": "#/components/responses/EngineTimeout"
          }
        }
      }
    },
    "/api/astro/aspects": {
      "post": {
        "operationId": "calculateAspects",
        "summary": "Calculate natal aspects inside a full chart envelope",
        "tags": [
          "Calculations"
        ],
        "description": "The outer aspects property contains a full Chart. The aspect array is response.aspects.aspects.\n\nEach admitted request reserves one monthly usage unit before route validation or engine work; failed or timed-out admitted attempts are not refunded. Do not automatically retry.",
        "x-contract-status": "current",
        "x-engine-timeout-ms": 15000,
        "x-quota-group": "api",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/AspectsRequest"
              },
              "examples": {
                "canonical": {
                  "summary": "Synthetic example; send with your server-side API key",
                  "value": {
                    "birth": {
                      "date": "1990-01-01",
                      "time": "12:00",
                      "timezone": "America/New_York",
                      "lat": 40.7128,
                      "lon": -74.006
                    }
                  }
                },
                "sidereal": {
                  "summary": "Same calculation in Lahiri sidereal coordinates",
                  "value": {
                    "birth": {
                      "date": "1990-01-01",
                      "time": "12:00",
                      "timezone": "America/New_York",
                      "lat": 40.7128,
                      "lon": -74.006
                    },
                    "zodiac": "sidereal",
                    "ayanamsa": "lahiri"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful calculation. Field nesting is specific to this route.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              },
              "Pragma": {
                "schema": {
                  "type": "string",
                  "const": "no-cache"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AspectsResponse"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/InvalidInput"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "413": {
            "$ref": "#/components/responses/TooLarge"
          },
          "429": {
            "$ref": "#/components/responses/Limited"
          },
          "500": {
            "$ref": "#/components/responses/InternalFailure"
          },
          "502": {
            "$ref": "#/components/responses/EngineUnavailable"
          },
          "503": {
            "$ref": "#/components/responses/Busy"
          },
          "504": {
            "$ref": "#/components/responses/EngineTimeout"
          }
        }
      }
    },
    "/api/astro/houses": {
      "post": {
        "operationId": "calculateHouses",
        "summary": "Calculate Equal or Whole Sign houses",
        "tags": [
          "Calculations"
        ],
        "description": "Current unversioned gateway response.\n\nEach admitted request reserves one monthly usage unit before route validation or engine work; failed or timed-out admitted attempts are not refunded. Do not automatically retry.",
        "x-contract-status": "current",
        "x-engine-timeout-ms": 15000,
        "x-quota-group": "api",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/HousesRequest"
              },
              "examples": {
                "canonical": {
                  "summary": "Synthetic example; send with your server-side API key",
                  "value": {
                    "birth": {
                      "date": "1990-01-01",
                      "time": "12:00",
                      "timezone": "America/New_York",
                      "lat": 40.7128,
                      "lon": -74.006
                    },
                    "system": "whole_sign"
                  }
                },
                "sidereal": {
                  "summary": "Same calculation in Lahiri sidereal coordinates",
                  "value": {
                    "birth": {
                      "date": "1990-01-01",
                      "time": "12:00",
                      "timezone": "America/New_York",
                      "lat": 40.7128,
                      "lon": -74.006
                    },
                    "system": "whole_sign",
                    "zodiac": "sidereal",
                    "ayanamsa": "lahiri"
                  }
                },
                "placidus": {
                  "summary": "Explicit Placidus beta, no fallback at unsupported polar geometry",
                  "value": {
                    "birth": {
                      "date": "2000-01-01",
                      "time": "12:00",
                      "timezone": "UTC",
                      "lat": 0,
                      "lon": 0
                    },
                    "system": "placidus"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful calculation. Field nesting is specific to this route.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              },
              "Pragma": {
                "schema": {
                  "type": "string",
                  "const": "no-cache"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HousesResponse"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/InvalidInput"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "413": {
            "$ref": "#/components/responses/TooLarge"
          },
          "429": {
            "$ref": "#/components/responses/Limited"
          },
          "500": {
            "$ref": "#/components/responses/InternalFailure"
          },
          "502": {
            "$ref": "#/components/responses/EngineUnavailable"
          },
          "503": {
            "$ref": "#/components/responses/Busy"
          },
          "504": {
            "$ref": "#/components/responses/EngineTimeout"
          }
        }
      }
    },
    "/api/astro/synastry": {
      "post": {
        "operationId": "calculateSynastry",
        "summary": "Calculate two charts and cross-chart aspects",
        "tags": [
          "Calculations"
        ],
        "description": "Current unversioned gateway response.\n\nEach admitted request reserves one monthly usage unit before route validation or engine work; failed or timed-out admitted attempts are not refunded. Do not automatically retry.",
        "x-contract-status": "current",
        "x-engine-timeout-ms": 15000,
        "x-quota-group": "api",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SynastryRequest"
              },
              "examples": {
                "canonical": {
                  "summary": "Synthetic example; send with your server-side API key",
                  "value": {
                    "personA": {
                      "date": "1990-01-01",
                      "time": "12:00",
                      "timezone": "America/New_York",
                      "lat": 40.7128,
                      "lon": -74.006
                    },
                    "personB": {
                      "date": "1992-06-15",
                      "time": "09:30",
                      "timezone": "Europe/London",
                      "lat": 51.5074,
                      "lon": -0.1278
                    }
                  }
                },
                "sidereal": {
                  "summary": "Same calculation in Lahiri sidereal coordinates",
                  "value": {
                    "personA": {
                      "date": "1990-01-01",
                      "time": "12:00",
                      "timezone": "America/New_York",
                      "lat": 40.7128,
                      "lon": -74.006
                    },
                    "personB": {
                      "date": "1992-06-15",
                      "time": "09:30",
                      "timezone": "Europe/London",
                      "lat": 51.5074,
                      "lon": -0.1278
                    },
                    "zodiac": "sidereal",
                    "ayanamsa": "lahiri"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful calculation. Field nesting is specific to this route.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              },
              "Pragma": {
                "schema": {
                  "type": "string",
                  "const": "no-cache"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SynastryResponse"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/InvalidInput"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "413": {
            "$ref": "#/components/responses/TooLarge"
          },
          "429": {
            "$ref": "#/components/responses/Limited"
          },
          "500": {
            "$ref": "#/components/responses/InternalFailure"
          },
          "502": {
            "$ref": "#/components/responses/EngineUnavailable"
          },
          "503": {
            "$ref": "#/components/responses/Busy"
          },
          "504": {
            "$ref": "#/components/responses/EngineTimeout"
          }
        }
      }
    },
    "/api/astro/transits": {
      "post": {
        "operationId": "calculateTransits",
        "summary": "Calculate transits at one requested instant",
        "tags": [
          "Calculations"
        ],
        "description": "Requested-instant transit-to-natal aspects. Not an event search, aspect windows, station prediction or house-transit report. Engine output remains nested under transits.\n\nEach admitted request reserves one monthly usage unit before route validation or engine work; failed or timed-out admitted attempts are not refunded. Do not automatically retry.",
        "x-contract-status": "current",
        "x-engine-timeout-ms": 15000,
        "x-quota-group": "api",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/TransitsRequest"
              },
              "examples": {
                "canonical": {
                  "summary": "Synthetic example; send with your server-side API key",
                  "value": {
                    "birth": {
                      "date": "1990-01-01",
                      "time": "12:00",
                      "timezone": "America/New_York",
                      "lat": 40.7128,
                      "lon": -74.006
                    },
                    "transitDate": "2026-01-01",
                    "transitTime": "12:00",
                    "timezone": "UTC"
                  }
                },
                "sidereal": {
                  "summary": "Same calculation in Lahiri sidereal coordinates",
                  "value": {
                    "birth": {
                      "date": "1990-01-01",
                      "time": "12:00",
                      "timezone": "America/New_York",
                      "lat": 40.7128,
                      "lon": -74.006
                    },
                    "transitDate": "2026-01-01",
                    "transitTime": "12:00",
                    "timezone": "UTC",
                    "zodiac": "sidereal",
                    "ayanamsa": "lahiri"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful calculation. Field nesting is specific to this route.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              },
              "Pragma": {
                "schema": {
                  "type": "string",
                  "const": "no-cache"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TransitsResponse"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/InvalidInput"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "413": {
            "$ref": "#/components/responses/TooLarge"
          },
          "429": {
            "$ref": "#/components/responses/Limited"
          },
          "500": {
            "$ref": "#/components/responses/InternalFailure"
          },
          "502": {
            "$ref": "#/components/responses/EngineUnavailable"
          },
          "503": {
            "$ref": "#/components/responses/Busy"
          },
          "504": {
            "$ref": "#/components/responses/EngineTimeout"
          }
        }
      }
    },
    "/api/astro/horoscope": {
      "post": {
        "operationId": "calculateHoroscope",
        "summary": "Calculate beta structured horoscope signals",
        "tags": [
          "Beta interpretation"
        ],
        "description": "Beta deterministic structured major-aspect signals. No language model, prose, compatibility score, medical/financial prediction, or house topics. The input echo currently omits transitTime/timezone; retain your request for reproducibility.\n\nEach admitted request reserves one monthly usage unit before route validation or engine work; failed or timed-out admitted attempts are not refunded. Do not automatically retry.\n\nBeta: documenting the current shape does not promote this endpoint to a stable contract.",
        "x-contract-status": "beta",
        "x-engine-timeout-ms": 15000,
        "x-quota-group": "api",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/HoroscopeRequest"
              },
              "examples": {
                "canonical": {
                  "summary": "Synthetic example; send with your server-side API key",
                  "value": {
                    "birth": {
                      "date": "1990-01-01",
                      "time": "12:00",
                      "timezone": "America/New_York",
                      "lat": 40.7128,
                      "lon": -74.006
                    },
                    "transitDate": "2026-01-01",
                    "transitTime": "12:00",
                    "timezone": "UTC"
                  }
                },
                "sidereal": {
                  "summary": "Same calculation in Lahiri sidereal coordinates",
                  "value": {
                    "birth": {
                      "date": "1990-01-01",
                      "time": "12:00",
                      "timezone": "America/New_York",
                      "lat": 40.7128,
                      "lon": -74.006
                    },
                    "transitDate": "2026-01-01",
                    "transitTime": "12:00",
                    "timezone": "UTC",
                    "zodiac": "sidereal",
                    "ayanamsa": "lahiri"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful calculation. Field nesting is specific to this route.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              },
              "Pragma": {
                "schema": {
                  "type": "string",
                  "const": "no-cache"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HoroscopeResponse"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/InvalidInput"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "413": {
            "$ref": "#/components/responses/TooLarge"
          },
          "429": {
            "$ref": "#/components/responses/Limited"
          },
          "500": {
            "$ref": "#/components/responses/InternalFailure"
          },
          "502": {
            "$ref": "#/components/responses/EngineUnavailable"
          },
          "503": {
            "$ref": "#/components/responses/Busy"
          },
          "504": {
            "$ref": "#/components/responses/EngineTimeout"
          }
        }
      }
    },
    "/api/astro/nakshatra-timeline": {
      "post": {
        "operationId": "calculateNakshatraTimeline",
        "summary": "Calculate Pro sidereal nakshatra/pada residences",
        "tags": [
          "Pro timeline"
        ],
        "description": "Gap-free returned residence coverage with numerically refined boundaries. Hourly discovery can miss an out-and-back departure/re-entry entirely between samples. Boundary solver resolution is not physical absolute-time accuracy; this is not an exhaustive station/event finder.\n\nEach admitted request reserves one monthly usage unit before route validation or engine work; failed or timed-out admitted attempts are not refunded. Do not automatically retry.",
        "x-contract-status": "current",
        "x-engine-timeout-ms": 60000,
        "x-quota-group": "nakshatra",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/TimelineRequest"
              },
              "examples": {
                "canonical": {
                  "summary": "Synthetic example; send with your server-side API key",
                  "value": {
                    "planet": "saturn",
                    "start_utc": "2026-01-01T00:00:00Z",
                    "end_utc": "2026-01-03T00:00:00Z",
                    "ayanamsa": "lahiri"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful calculation. Field nesting is specific to this route.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              },
              "Pragma": {
                "schema": {
                  "type": "string",
                  "const": "no-cache"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TimelineResponse"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/InvalidInput"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/ProRequired"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "413": {
            "$ref": "#/components/responses/TooLarge"
          },
          "429": {
            "$ref": "#/components/responses/Limited"
          },
          "500": {
            "$ref": "#/components/responses/InternalFailure"
          },
          "502": {
            "$ref": "#/components/responses/EngineUnavailable"
          },
          "503": {
            "$ref": "#/components/responses/Busy"
          },
          "504": {
            "$ref": "#/components/responses/EngineTimeout"
          }
        }
      }
    },
    "/api/astro/natal-svg": {
      "post": {
        "operationId": "calculateNatalSvg",
        "summary": "Render a natal SVG wheel (beta)",
        "tags": [
          "Calculations",
          "Beta calculations"
        ],
        "description": "Additive beta calculation. Strict request shape; unknown fields, explicit nulls, noncanonical enums and numeric coordinate strings return 400. Exact poles and ambiguous/nonexistent civil times are rejected. Numerical checks are not practitioner sign-off. Placidus is opt-in with polar rejection and no fallback; rendering crowding returns 400. \n\nEach admitted request reserves one monthly usage unit before route validation or engine work; failed or timed-out admitted attempts are not refunded. Do not automatically retry.",
        "x-contract-status": "beta",
        "x-engine-timeout-ms": 15000,
        "x-quota-group": "api",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/NatalSvgRequest"
              },
              "examples": {
                "canonical": {
                  "summary": "Synthetic beta example; requires a server-side API key",
                  "value": {
                    "birth": {
                      "date": "2000-01-01",
                      "time": "12:00",
                      "timezone": "UTC",
                      "lat": 0,
                      "lon": 0
                    },
                    "house_system": "placidus",
                    "theme": "dark",
                    "show_aspects": true,
                    "zodiac": "sidereal",
                    "ayanamsa": "lahiri"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful calculation. Field nesting is specific to this route.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              },
              "Pragma": {
                "schema": {
                  "type": "string",
                  "const": "no-cache"
                }
              },
              "X-Content-Type-Options": {
                "schema": {
                  "type": "string",
                  "const": "nosniff"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/NatalSvgResponse"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/InvalidInput"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "413": {
            "$ref": "#/components/responses/TooLarge"
          },
          "429": {
            "$ref": "#/components/responses/Limited"
          },
          "500": {
            "$ref": "#/components/responses/InternalFailure"
          },
          "502": {
            "$ref": "#/components/responses/EngineUnavailable"
          },
          "503": {
            "$ref": "#/components/responses/Busy"
          },
          "504": {
            "$ref": "#/components/responses/EngineTimeout"
          }
        }
      }
    },
    "/api/astro/vargas": {
      "post": {
        "operationId": "calculateVargas",
        "summary": "Calculate sidereal D1/D3/D4/D7/D9/D10/D12 vargas (beta)",
        "tags": [
          "Calculations",
          "Beta calculations"
        ],
        "description": "Additive beta calculation. Strict request shape; unknown fields, explicit nulls, noncanonical enums and numeric coordinate strings return 400. Exact poles and ambiguous/nonexistent civil times are rejected. Numerical checks are not practitioner sign-off. Sidereal-only with Lahiri default; retained-nutation frame and mean nodes. \n\nEach admitted request reserves one monthly usage unit before route validation or engine work; failed or timed-out admitted attempts are not refunded. Do not automatically retry.",
        "x-contract-status": "beta",
        "x-engine-timeout-ms": 15000,
        "x-quota-group": "api",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/VargasRequest"
              },
              "examples": {
                "d3": {
                  "summary": "Parashari D3 beta; fixed sign convention",
                  "value": {
                    "birth": {
                      "date": "2000-01-01",
                      "time": "12:00",
                      "timezone": "UTC",
                      "lat": 0,
                      "lon": 0
                    },
                    "division": 3,
                    "ayanamsa": "lahiri"
                  }
                },
                "d4": {
                  "summary": "Parashari D4 beta; fixed sign convention",
                  "value": {
                    "birth": {
                      "date": "2000-01-01",
                      "time": "12:00",
                      "timezone": "UTC",
                      "lat": 0,
                      "lon": 0
                    },
                    "division": 4,
                    "ayanamsa": "lahiri"
                  }
                },
                "d7": {
                  "summary": "Parashari D7 beta; fixed sign convention",
                  "value": {
                    "birth": {
                      "date": "2000-01-01",
                      "time": "12:00",
                      "timezone": "UTC",
                      "lat": 0,
                      "lon": 0
                    },
                    "division": 7,
                    "ayanamsa": "lahiri"
                  }
                },
                "d12": {
                  "summary": "Parashari D12 beta; fixed sign convention",
                  "value": {
                    "birth": {
                      "date": "2000-01-01",
                      "time": "12:00",
                      "timezone": "UTC",
                      "lat": 0,
                      "lon": 0
                    },
                    "division": 12,
                    "ayanamsa": "lahiri"
                  }
                },
                "canonical": {
                  "summary": "Synthetic beta example; requires a server-side API key",
                  "value": {
                    "birth": {
                      "date": "2000-01-01",
                      "time": "12:00",
                      "timezone": "UTC",
                      "lat": 0,
                      "lon": 0
                    },
                    "division": 9,
                    "ayanamsa": "lahiri"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful calculation. Field nesting is specific to this route.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              },
              "Pragma": {
                "schema": {
                  "type": "string",
                  "const": "no-cache"
                }
              },
              "X-Content-Type-Options": {
                "schema": {
                  "type": "string",
                  "const": "nosniff"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/VargasResponse"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/InvalidInput"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "413": {
            "$ref": "#/components/responses/TooLarge"
          },
          "429": {
            "$ref": "#/components/responses/Limited"
          },
          "500": {
            "$ref": "#/components/responses/InternalFailure"
          },
          "502": {
            "$ref": "#/components/responses/EngineUnavailable"
          },
          "503": {
            "$ref": "#/components/responses/Busy"
          },
          "504": {
            "$ref": "#/components/responses/EngineTimeout"
          }
        }
      }
    },
    "/api/astro/vimshottari": {
      "post": {
        "operationId": "calculateVimshottari",
        "summary": "Calculate a natal Vimshottari cycle (beta)",
        "tags": [
          "Calculations",
          "Beta calculations"
        ],
        "description": "Additive beta calculation. Strict request shape; unknown fields, explicit nulls, noncanonical enums and numeric coordinate strings return 400. Exact poles and ambiguous/nonexistent civil times are rejected. Numerical checks are not practitioner sign-off. Sidereal-only with Lahiri default; retained-nutation frame and mean nodes. \n\nEach admitted request reserves one monthly usage unit before route validation or engine work; failed or timed-out admitted attempts are not refunded. Do not automatically retry.\n\nSidereal-only beta with fixed Julian years of 365.25 days and a 120-year cycle anchored at the theoretical start of the birth mahadasha. Omitted depth or explicit 2 returns the unchanged two-level response: nine majors and 81 antardashas. Opt-in depth 3 adds nine pratyantardashas to each antardasha (729 leaves), exact proportional integer-microsecond durations, active third-level birth lord and depth metadata. No arbitrary depth, date query, range or year model.",
        "x-contract-status": "beta",
        "x-engine-timeout-ms": 15000,
        "x-quota-group": "api",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/VimshottariRequest"
              },
              "examples": {
                "canonical": {
                  "summary": "Synthetic beta example; requires a server-side API key",
                  "value": {
                    "birth": {
                      "date": "2000-01-01",
                      "time": "12:00",
                      "timezone": "UTC",
                      "lat": 0,
                      "lon": 0
                    },
                    "ayanamsa": "lahiri"
                  }
                },
                "depth3": {
                  "summary": "Optional bounded third level; default response is unchanged",
                  "value": {
                    "birth": {
                      "date": "2000-01-01",
                      "time": "12:00",
                      "timezone": "UTC",
                      "lat": 0,
                      "lon": 0
                    },
                    "ayanamsa": "lahiri",
                    "depth": 3
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful calculation. Field nesting is specific to this route.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              },
              "Pragma": {
                "schema": {
                  "type": "string",
                  "const": "no-cache"
                }
              },
              "X-Content-Type-Options": {
                "schema": {
                  "type": "string",
                  "const": "nosniff"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/VimshottariResponse"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/InvalidInput"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "413": {
            "$ref": "#/components/responses/TooLarge"
          },
          "429": {
            "$ref": "#/components/responses/Limited"
          },
          "500": {
            "$ref": "#/components/responses/InternalFailure"
          },
          "502": {
            "$ref": "#/components/responses/EngineUnavailable"
          },
          "503": {
            "$ref": "#/components/responses/Busy"
          },
          "504": {
            "$ref": "#/components/responses/EngineTimeout"
          }
        }
      }
    },
    "/api/astro/composite": {
      "post": {
        "operationId": "calculateComposite",
        "summary": "Calculate a shortest-arc midpoint composite (beta)",
        "tags": [
          "Calculations",
          "Beta calculations"
        ],
        "description": "Shortest-arc midpoint composite. Antipodal/near-antipodal points reject; no arbitrary flip. Houses are synthetic Equal/Whole Sign from midpoint Ascendant, not physical geographic cusps. Not a Davison chart; no Placidus, node, speed or interpretation option. All admitted attempts use one standard quota unit, including free plans. No practitioner sign-off is claimed.\n\nEach admitted request reserves one monthly usage unit before route validation or engine work; failed or timed-out admitted attempts are not refunded. Do not automatically retry.",
        "x-contract-status": "beta",
        "x-engine-timeout-ms": 15000,
        "x-quota-group": "api",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CompositeRequest"
              },
              "examples": {
                "canonical": {
                  "summary": "Synthetic beta example; server-side API key required",
                  "value": {
                    "personA": {
                      "date": "2000-01-01",
                      "time": "12:00",
                      "timezone": "UTC",
                      "lat": 0,
                      "lon": 0
                    },
                    "personB": {
                      "date": "1990-06-15",
                      "time": "08:30",
                      "timezone": "Asia/Kolkata",
                      "lat": 28.6139,
                      "lon": 77.209
                    },
                    "zodiac": "tropical",
                    "house_system": "equal"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful calculation. Field nesting is specific to this route.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              },
              "Pragma": {
                "schema": {
                  "type": "string",
                  "const": "no-cache"
                }
              },
              "X-Content-Type-Options": {
                "schema": {
                  "type": "string",
                  "const": "nosniff"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CompositeResponse"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/InvalidInput"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "413": {
            "$ref": "#/components/responses/TooLarge"
          },
          "429": {
            "$ref": "#/components/responses/Limited"
          },
          "500": {
            "$ref": "#/components/responses/InternalFailure"
          },
          "502": {
            "$ref": "#/components/responses/EngineUnavailable"
          },
          "503": {
            "$ref": "#/components/responses/Busy"
          },
          "504": {
            "$ref": "#/components/responses/EngineTimeout"
          }
        }
      }
    },
    "/api/astro/panchang": {
      "post": {
        "operationId": "calculatePanchang",
        "summary": "Calculate an instant Panchang and local solar events (beta)",
        "tags": [
          "Calculations",
          "Beta calculations"
        ],
        "description": "Strict civil snapshot at the requested instant, not automatically at sunrise. Sidereal Lahiri default. Sunrise/sunset belong to the requested local civil date at elevation zero; ambiguous/nonexistent midnight boundaries return 400. No festivals, regional calendar or arbitrary event search. Latitude is restricted to inclusive [-88,88] for the verified solar-event solver domain. Returned solar candidates must satisfy a geometric crossing check; unsupported near-tangent geometry returns 400 instead of invented events. A solar event inside a recorded leap second returns 400 because its local civil timestamp cannot represent second 60. All admitted attempts reserve one standard quota unit; failed or timed-out admitted attempts are not refunded, including unsupported geometry. No automatic retries.",
        "x-contract-status": "beta",
        "x-engine-timeout-ms": 15000,
        "x-quota-group": "api",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/PanchangRequest"
              },
              "examples": {
                "canonical": {
                  "summary": "Synthetic beta example; server-side API key required",
                  "value": {
                    "at": {
                      "date": "2000-01-01",
                      "time": "12:00",
                      "timezone": "Asia/Kolkata",
                      "lat": 28.6139,
                      "lon": 77.209
                    },
                    "ayanamsa": "lahiri"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful calculation. Field nesting is specific to this route.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              },
              "Pragma": {
                "schema": {
                  "type": "string",
                  "const": "no-cache"
                }
              },
              "X-Content-Type-Options": {
                "schema": {
                  "type": "string",
                  "const": "nosniff"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PanchangResponse"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/InvalidInput"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "413": {
            "$ref": "#/components/responses/TooLarge"
          },
          "429": {
            "$ref": "#/components/responses/Limited"
          },
          "500": {
            "$ref": "#/components/responses/InternalFailure"
          },
          "502": {
            "$ref": "#/components/responses/EngineUnavailable"
          },
          "503": {
            "$ref": "#/components/responses/Busy"
          },
          "504": {
            "$ref": "#/components/responses/EngineTimeout"
          }
        }
      }
    },
    "/api/astro/secondary-progressions": {
      "post": {
        "operationId": "calculateSecondaryProgressions",
        "summary": "Calculate secondary-progressed planets with natal context (beta)",
        "tags": [
          "Calculations",
          "Beta calculations"
        ],
        "description": "Day-for-year secondary-progressed PLANETS only. Required target>=birth instant; all civil dates 1900–2050, times known, UTC defaults and DST rejection. Fixed365.2421904-day year in TT. Returned angles/houses are explicitly natal context, never progressed. No progressed angles, houses, aspects, nodes, speed or arbitrary year model. All admitted attempts use one standard quota unit, including free plans. No practitioner sign-off is claimed.\n\nEach admitted request reserves one monthly usage unit before route validation or engine work; failed or timed-out admitted attempts are not refunded. Do not automatically retry.",
        "x-contract-status": "beta",
        "x-engine-timeout-ms": 15000,
        "x-quota-group": "api",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SecondaryProgressionsRequest"
              },
              "examples": {
                "canonical": {
                  "summary": "Synthetic beta example; server-side API key required",
                  "value": {
                    "birth": {
                      "date": "2000-01-01",
                      "time": "12:00",
                      "timezone": "UTC",
                      "lat": 0,
                      "lon": 0
                    },
                    "target": {
                      "date": "2026-09-14",
                      "time": "12:00",
                      "timezone": "UTC"
                    },
                    "zodiac": "tropical",
                    "house_system": "equal"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful calculation. Field nesting is specific to this route.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              },
              "Pragma": {
                "schema": {
                  "type": "string",
                  "const": "no-cache"
                }
              },
              "X-Content-Type-Options": {
                "schema": {
                  "type": "string",
                  "const": "nosniff"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SecondaryProgressionsResponse"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/InvalidInput"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "413": {
            "$ref": "#/components/responses/TooLarge"
          },
          "429": {
            "$ref": "#/components/responses/Limited"
          },
          "500": {
            "$ref": "#/components/responses/InternalFailure"
          },
          "502": {
            "$ref": "#/components/responses/EngineUnavailable"
          },
          "503": {
            "$ref": "#/components/responses/Busy"
          },
          "504": {
            "$ref": "#/components/responses/EngineTimeout"
          }
        }
      }
    },
    "/api/astro/varga-svg": {
      "post": {
        "operationId": "calculateVargaSvg",
        "summary": "Render an original North/South Indian varga SVG (beta)",
        "tags": [
          "Calculations",
          "Beta calculations"
        ],
        "description": "Original sidereal D1/D3/D4/D7/D9/D10/D12 sign-placement SVG. Default division1 differs from /vargas default9. North fixes houses; South fixes signs. No supplied markup/chart/URL, and no bhava-chalit, outer planets or interpretation controls. All admitted attempts use one standard quota unit, including free plans. No practitioner sign-off is claimed.\n\nEach admitted request reserves one monthly usage unit before route validation or engine work; failed or timed-out admitted attempts are not refunded. Do not automatically retry.",
        "x-contract-status": "beta",
        "x-engine-timeout-ms": 15000,
        "x-quota-group": "api",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/VargaSvgRequest"
              },
              "examples": {
                "d3": {
                  "summary": "Parashari D3 beta; fixed sign convention",
                  "value": {
                    "birth": {
                      "date": "2000-01-01",
                      "time": "12:00",
                      "timezone": "UTC",
                      "lat": 0,
                      "lon": 0
                    },
                    "division": 3,
                    "ayanamsa": "lahiri"
                  }
                },
                "d4": {
                  "summary": "Parashari D4 beta; fixed sign convention",
                  "value": {
                    "birth": {
                      "date": "2000-01-01",
                      "time": "12:00",
                      "timezone": "UTC",
                      "lat": 0,
                      "lon": 0
                    },
                    "division": 4,
                    "ayanamsa": "lahiri"
                  }
                },
                "d7": {
                  "summary": "Parashari D7 beta; fixed sign convention",
                  "value": {
                    "birth": {
                      "date": "2000-01-01",
                      "time": "12:00",
                      "timezone": "UTC",
                      "lat": 0,
                      "lon": 0
                    },
                    "division": 7,
                    "ayanamsa": "lahiri"
                  }
                },
                "d12": {
                  "summary": "Parashari D12 beta; fixed sign convention",
                  "value": {
                    "birth": {
                      "date": "2000-01-01",
                      "time": "12:00",
                      "timezone": "UTC",
                      "lat": 0,
                      "lon": 0
                    },
                    "division": 12,
                    "ayanamsa": "lahiri"
                  }
                },
                "canonical": {
                  "summary": "Synthetic beta example; server-side API key required",
                  "value": {
                    "birth": {
                      "date": "2000-01-01",
                      "time": "12:00",
                      "timezone": "UTC",
                      "lat": 0,
                      "lon": 0
                    },
                    "division": 1,
                    "layout": "north_indian",
                    "theme": "dark",
                    "ayanamsa": "lahiri"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful calculation. Field nesting is specific to this route.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              },
              "Pragma": {
                "schema": {
                  "type": "string",
                  "const": "no-cache"
                }
              },
              "X-Content-Type-Options": {
                "schema": {
                  "type": "string",
                  "const": "nosniff"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/VargaSvgResponse"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/InvalidInput"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "413": {
            "$ref": "#/components/responses/TooLarge"
          },
          "429": {
            "$ref": "#/components/responses/Limited"
          },
          "500": {
            "$ref": "#/components/responses/InternalFailure"
          },
          "502": {
            "$ref": "#/components/responses/EngineUnavailable"
          },
          "503": {
            "$ref": "#/components/responses/Busy"
          },
          "504": {
            "$ref": "#/components/responses/EngineTimeout"
          }
        }
      }
    },
    "/api/astro/lunar-nodes": {
      "post": {
        "operationId": "calculateLunarNodes",
        "summary": "Calculate distinct mean and osculating lunar nodes (beta)",
        "tags": [
          "Calculations",
          "Beta calculations"
        ],
        "description": "Beta mean and distinct geometric osculating lunar nodes at a known civil instant. No coordinates, user ephemeris, chart input or URLs. Civil dates 1900–2050; timezone conversion can cross the UTC year boundary. Tropical default; optional sidereal mean P03 ayanamsa subtraction, with true-model nutation retained. Existing chart/timeline node fields are unchanged. All admitted attempts use one standard quota unit, including free plans. No practitioner sign-off is claimed.\n\nEach admitted request reserves one monthly usage unit before route validation or engine work; failed or timed-out admitted attempts are not refunded. Do not automatically retry.",
        "x-contract-status": "beta",
        "x-engine-timeout-ms": 15000,
        "x-quota-group": "api",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/LunarNodesRequest"
              },
              "examples": {
                "canonical": {
                  "summary": "Synthetic beta example; server-side API key required",
                  "value": {
                    "at": {
                      "date": "2000-01-01",
                      "time": "12:00",
                      "timezone": "UTC"
                    },
                    "zodiac": "sidereal",
                    "ayanamsa": "lahiri"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful calculation. Field nesting is specific to this route.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              },
              "Pragma": {
                "schema": {
                  "type": "string",
                  "const": "no-cache"
                }
              },
              "X-Content-Type-Options": {
                "schema": {
                  "type": "string",
                  "const": "nosniff"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/LunarNodesResponse"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/InvalidInput"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "413": {
            "$ref": "#/components/responses/TooLarge"
          },
          "429": {
            "$ref": "#/components/responses/Limited"
          },
          "500": {
            "$ref": "#/components/responses/InternalFailure"
          },
          "502": {
            "$ref": "#/components/responses/EngineUnavailable"
          },
          "503": {
            "$ref": "#/components/responses/Busy"
          },
          "504": {
            "$ref": "#/components/responses/EngineTimeout"
          }
        }
      }
    },
    "/api/astro/returns": {
      "post": {
        "operationId": "calculateReturns",
        "summary": "Find the next solar or lunar return and its chart (beta)",
        "tags": [
          "Calculations",
          "Beta calculations"
        ],
        "description": "Beta first solar or lunar longitude return beyond after +1 millisecond, subject to the documented numerical equality allowance, followed by a physical chart at that root. after may precede birth. Both civil dates 1900–2050; birth UTC and the complete fixed search window (Sun 370 TT days, Moon 32 TT days) must stay in UTC 1900–2050; no window clipping. Tropical/Equal defaults. Sidereal uses each ephemeris date's mean P03 ayanamsa with nutation retained. Return location defaults to birth coordinates and changes houses, not the return instant. No Placidus, arbitrary bodies/targets/search tolerances, cycles or predictions. All admitted attempts use one standard quota unit, including free plans. No practitioner sign-off is claimed.\n\nEach admitted request reserves one monthly usage unit before route validation or engine work; failed or timed-out admitted attempts are not refunded. Do not automatically retry.",
        "x-contract-status": "beta",
        "x-engine-timeout-ms": 15000,
        "x-quota-group": "api",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ReturnsRequest"
              },
              "examples": {
                "canonical": {
                  "summary": "Synthetic beta example; server-side API key required",
                  "value": {
                    "birth": {
                      "date": "2000-01-01",
                      "time": "12:00",
                      "timezone": "UTC",
                      "lat": 0,
                      "lon": 0
                    },
                    "body": "sun",
                    "after": {
                      "date": "2026-09-14",
                      "time": "12:00",
                      "timezone": "UTC"
                    },
                    "zodiac": "tropical",
                    "house_system": "equal"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful calculation. Field nesting is specific to this route.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              },
              "Pragma": {
                "schema": {
                  "type": "string",
                  "const": "no-cache"
                }
              },
              "X-Content-Type-Options": {
                "schema": {
                  "type": "string",
                  "const": "nosniff"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ReturnsResponse"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/InvalidInput"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "413": {
            "$ref": "#/components/responses/TooLarge"
          },
          "429": {
            "$ref": "#/components/responses/Limited"
          },
          "500": {
            "$ref": "#/components/responses/InternalFailure"
          },
          "502": {
            "$ref": "#/components/responses/EngineUnavailable"
          },
          "503": {
            "$ref": "#/components/responses/Busy"
          },
          "504": {
            "$ref": "#/components/responses/EngineTimeout"
          }
        }
      }
    },
    "/api/astro/solar-arcs": {
      "post": {
        "operationId": "calculateSolarArcs",
        "summary": "Calculate symbolic true solar-arc directions (beta)",
        "tags": [
          "Calculations",
          "Beta calculations"
        ],
        "description": "Symbolic direct true TROPICAL solar arc applied uniformly to natal planets and Ascendant/MC, not a physical sky chart or mean/Naibod arc. Input and day-for-year timing match secondary progressions: target UTC >= birth, fixed 365.2421904-day TT year, civil dates 1900–2050, strict fields/enums/numbers and DST/polar rejection. Sidereal uses the natal-date ayanamsa only; both arc Sun reference longitudes remain tropical. Equal/Whole Sign houses are synthetic from directed Ascendant, with MC independently directed. No relocation, converse arc, aspects, nodes, speeds or arbitrary year model. Internal evaluation is bounded to 152 progressed TT days and at most 5 Sun intervals of 32 days.\n\nAll plans use one standard quota unit. Each admitted request reserves one monthly usage unit before route validation or engine work; failed or timed-out admitted attempts are not refunded. Do not automatically retry. No practitioner sign-off.",
        "x-contract-status": "beta",
        "x-engine-timeout-ms": 15000,
        "x-quota-group": "api",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SolarArcsRequest"
              },
              "examples": {
                "canonical": {
                  "summary": "Synthetic beta example; server-side API key required",
                  "value": {
                    "birth": {
                      "date": "2000-01-01",
                      "time": "12:00",
                      "timezone": "UTC",
                      "lat": 0,
                      "lon": 0
                    },
                    "target": {
                      "date": "2026-09-15",
                      "time": "12:00",
                      "timezone": "UTC"
                    },
                    "zodiac": "tropical",
                    "house_system": "equal"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful calculation. Field nesting is specific to this route.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              },
              "Pragma": {
                "schema": {
                  "type": "string",
                  "const": "no-cache"
                }
              },
              "X-Content-Type-Options": {
                "schema": {
                  "type": "string",
                  "const": "nosniff"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SolarArcsResponse"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/InvalidInput"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "413": {
            "$ref": "#/components/responses/TooLarge"
          },
          "429": {
            "$ref": "#/components/responses/Limited"
          },
          "500": {
            "$ref": "#/components/responses/InternalFailure"
          },
          "502": {
            "$ref": "#/components/responses/EngineUnavailable"
          },
          "503": {
            "$ref": "#/components/responses/Busy"
          },
          "504": {
            "$ref": "#/components/responses/EngineTimeout"
          }
        }
      }
    },
    "/api/astro/moon-phases": {
      "post": {
        "operationId": "calculateMoonPhases",
        "summary": "Calculate Moon phase geometry or a bounded primary-phase calendar (beta)",
        "tags": [
          "Calculations",
          "Beta calculations"
        ],
        "description": "Explicit instant mode returns a named display sector, Moon-minus-Sun ecliptic longitude and separately calculated spherical illuminated fraction. Calendar mode returns primary longitude crossings, not eclipse predictions or visibility. Dates 1900–2050; calendar spans at most 366 UTC days. No coordinates, zodiac, user kernels or arbitrary search tuning. Uses existing DE421 and bundled time-scale data; future UTC assumes the bundled leap-second schedule. Experimental beta: one-second output and millisecond root convergence are not accuracy guarantees. Independent 2026 USNO comparison has a 60-second tolerance; broader epoch/time-scale acceptance remains separate. Each admitted request reserves one standard monthly quota unit, including invalid inputs and timeouts. All plans; no automatic retries. Source availability does not establish deployment. Each admitted request reserves one monthly usage unit before route validation or engine work; failed or timed-out admitted attempts are not refunded. Do not automatically retry.",
        "x-contract-status": "beta",
        "x-engine-timeout-ms": 15000,
        "x-quota-group": "api",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/MoonPhaseRequest"
              },
              "examples": {
                "canonical": {
                  "summary": "Instant physical phase, displayed in New York",
                  "value": {
                    "mode": "instant",
                    "at": {
                      "date": "2026-01-18",
                      "time": "19:52",
                      "timezone": "UTC"
                    },
                    "display_timezone": "America/New_York"
                  }
                },
                "calendar": {
                  "summary": "Primary phases during January 2026",
                  "value": {
                    "mode": "calendar",
                    "start": {
                      "date": "2026-01-01",
                      "time": "00:00",
                      "timezone": "UTC"
                    },
                    "end": {
                      "date": "2026-02-01",
                      "time": "00:00",
                      "timezone": "UTC"
                    }
                  }
                },
                "icalendar": {
                  "summary": "Primary phases with opt-in .ics export",
                  "value": {
                    "mode": "calendar",
                    "start": {
                      "date": "2026-01-01",
                      "time": "00:00",
                      "timezone": "UTC"
                    },
                    "end": {
                      "date": "2026-02-01",
                      "time": "00:00",
                      "timezone": "UTC"
                    },
                    "include_ical": true
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Mode-specific beta geometry/calendar envelope.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              },
              "Pragma": {
                "schema": {
                  "type": "string",
                  "const": "no-cache"
                }
              },
              "X-Content-Type-Options": {
                "schema": {
                  "type": "string",
                  "const": "nosniff"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MoonPhaseResponse"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/InvalidInput"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "413": {
            "$ref": "#/components/responses/TooLarge"
          },
          "429": {
            "$ref": "#/components/responses/Limited"
          },
          "500": {
            "$ref": "#/components/responses/InternalFailure"
          },
          "502": {
            "$ref": "#/components/responses/EngineUnavailable"
          },
          "503": {
            "$ref": "#/components/responses/Busy"
          },
          "504": {
            "$ref": "#/components/responses/EngineTimeout"
          }
        }
      }
    },
    "/api/astro/davison": {
      "post": {
        "operationId": "calculateDavison",
        "summary": "Calculate an uncorrected TT/arithmetic Davison relationship chart (beta)",
        "tags": [
          "Calculations",
          "Beta calculations"
        ],
        "description": "Uncorrected Davison with a uniform-TT time mean and arithmetic latitude/longitude after +180 is canonicalized to -180. Not a shortest-arc/spherical midpoint or corrected-MC chart. No nodes, relocation, Placidus or interpretations. Unknown fields and ambiguous/nonexistent civil times reject. See DAVISON_CONVENTIONS.md.\n\nEvery admitted attempt reserves one standard monthly unit; failed or timed-out admitted attempts are not refunded. No automatic retries. Local implementation is not proof of deployment.",
        "x-contract-status": "beta",
        "x-engine-timeout-ms": 15000,
        "x-quota-group": "api",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/DavisonRequest"
              },
              "examples": {
                "canonical": {
                  "summary": "Physical sky at 2000-01-02 12:00 UTC, latitude 45, longitude -36",
                  "value": {
                    "personA": {
                      "date": "2000-01-01",
                      "time": "12:00",
                      "lat": 40,
                      "lon": -74
                    },
                    "personB": {
                      "date": "2000-01-03",
                      "time": "12:00",
                      "lat": 50,
                      "lon": 2
                    }
                  }
                },
                "sidereal": {
                  "summary": "Midpoint-date Raman ayanamsa with Whole Sign houses",
                  "value": {
                    "personA": {
                      "date": "2000-01-01",
                      "time": "12:00",
                      "lat": 40,
                      "lon": -74
                    },
                    "personB": {
                      "date": "2000-01-03",
                      "time": "12:00",
                      "lat": 50,
                      "lon": 2
                    },
                    "zodiac": "sidereal",
                    "ayanamsa": "raman",
                    "house_system": "whole_sign"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful calculation. Field nesting is specific to this route.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-store"
                }
              },
              "Pragma": {
                "schema": {
                  "type": "string",
                  "const": "no-cache"
                }
              },
              "X-Content-Type-Options": {
                "schema": {
                  "type": "string",
                  "const": "nosniff"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DavisonResponse"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/InvalidInput"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "413": {
            "$ref": "#/components/responses/TooLarge"
          },
          "429": {
            "$ref": "#/components/responses/Limited"
          },
          "500": {
            "$ref": "#/components/responses/InternalFailure"
          },
          "502": {
            "$ref": "#/components/responses/EngineUnavailable"
          },
          "503": {
            "$ref": "#/components/responses/Busy"
          },
          "504": {
            "$ref": "#/components/responses/EngineTimeout"
          }
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "BearerApiKey": {
        "type": "http",
        "scheme": "bearer",
        "bearerFormat": "64 hexadecimal characters",
        "description": "Opaque 256-bit AstroAPI key; not a Stripe key or dashboard JWT. Exact 'Bearer ' prefix."
      },
      "HeaderApiKey": {
        "type": "apiKey",
        "in": "header",
        "name": "x-api-key",
        "description": "Opaque 64-hex-character AstroAPI key. Use instead of Authorization; a nonempty Bearer credential takes precedence if both are sent."
      }
    },
    "schemas": {
      "Date": {
        "type": "string",
        "format": "date",
        "pattern": "^(?:19[0-9]{2}|20[0-4][0-9]|2050)-(?:0[1-9]|1[0-2])-(?:0[1-9]|[12][0-9]|3[01])$",
        "description": "Valid Gregorian YYYY-MM-DD local civil date, inclusive 1900-01-01 through 2050-12-31. Calendar validity and timezone conversion are checked by the server."
      },
      "Time": {
        "type": "string",
        "pattern": "^(?:[01][0-9]|2[0-3]):[0-5][0-9](?::[0-5][0-9])?$",
        "description": "HH:MM or HH:MM:SS; no offset in this field. Use timezone to select the civil-time zone."
      },
      "Timezone": {
        "type": [
          "string",
          "null"
        ],
        "description": "IANA timezone name (for example America/New_York). Omission, null, or empty string means UTC for a birth input. Nonexistent or ambiguous local clock-change times return 400; provide the known UTC date/time with timezone UTC instead.",
        "examples": [
          "UTC",
          "America/New_York",
          "Asia/Kolkata"
        ]
      },
      "Zodiac": {
        "type": "string",
        "enum": [
          "tropical",
          "sidereal"
        ]
      },
      "Ayanamsa": {
        "type": "string",
        "enum": [
          "lahiri",
          "raman",
          "krishnamurti"
        ]
      },
      "AyanamsaResult": {
        "anyOf": [
          {
            "$ref": "#/components/schemas/Ayanamsa"
          },
          {
            "type": "null"
          }
        ],
        "description": "null for tropical charts; selected normalized ayanamsa for sidereal charts."
      },
      "ZodiacInput": {
        "type": [
          "string",
          "null"
        ],
        "pattern": "^\\s*(?:[Tt][Rr][Oo][Pp][Ii][Cc][Aa][Ll]|[Ss][Ii][Dd][Ee][Rr][Ee][Aa][Ll])\\s*$",
        "default": "tropical",
        "description": "tropical or sidereal; server trims whitespace and ignores case. Omitted/null selects tropical.",
        "x-canonical-values": [
          "tropical",
          "sidereal"
        ]
      },
      "AyanamsaInput": {
        "type": [
          "string",
          "null"
        ],
        "pattern": "\\S",
        "default": "lahiri",
        "description": "Sidereal supports lahiri, raman, krishnamurti, with case/whitespace normalization; other names return 400 in sidereal mode. Omitted/null selects lahiri. Tropical mode ignores a nonempty string and outputs null. This schema describes that compatibility behavior rather than claiming every string is a supported sidereal model.",
        "x-canonical-values": [
          "lahiri",
          "raman",
          "krishnamurti"
        ]
      },
      "Latitude": {
        "anyOf": [
          {
            "type": "number",
            "exclusiveMinimum": -90,
            "exclusiveMaximum": 90
          },
          {
            "type": "string",
            "pattern": "^\\s*[+-]?(?:[0-9]+(?:\\.[0-9]*)?|\\.[0-9]+)(?:[eE][+-]?[0-9]+)?\\s*$"
          }
        ],
        "description": "WGS84 decimal latitude. JSON numbers are recommended; numeric strings are accepted by the current engine, then checked for finiteness/range. Exact poles and undefined Ascendant geometry return 400; supported successful latitude is strictly between -90 and 90. Boolean/null/object/array coordinates are invalid."
      },
      "Longitude": {
        "anyOf": [
          {
            "type": "number",
            "minimum": -180,
            "maximum": 180
          },
          {
            "type": "string",
            "pattern": "^\\s*[+-]?(?:[0-9]+(?:\\.[0-9]*)?|\\.[0-9]+)(?:[eE][+-]?[0-9]+)?\\s*$"
          }
        ],
        "description": "WGS84 decimal longitude, east positive, within [-180,180]. JSON numbers are recommended; numeric strings are accepted then checked for finiteness/range."
      },
      "BirthInput": {
        "type": "object",
        "properties": {
          "date": {
            "$ref": "#/components/schemas/Date"
          },
          "time": {
            "$ref": "#/components/schemas/Time"
          },
          "timezone": {
            "$ref": "#/components/schemas/Timezone"
          },
          "lat": {
            "$ref": "#/components/schemas/Latitude"
          },
          "lon": {
            "$ref": "#/components/schemas/Longitude"
          }
        },
        "required": [
          "date",
          "time",
          "lat",
          "lon"
        ],
        "additionalProperties": true
      },
      "BirthChartRequest": {
        "type": "object",
        "properties": {
          "date": {
            "$ref": "#/components/schemas/Date"
          },
          "time": {
            "$ref": "#/components/schemas/Time"
          },
          "timezone": {
            "$ref": "#/components/schemas/Timezone"
          },
          "lat": {
            "$ref": "#/components/schemas/Latitude"
          },
          "lon": {
            "$ref": "#/components/schemas/Longitude"
          },
          "zodiac": {
            "$ref": "#/components/schemas/ZodiacInput"
          },
          "ayanamsa": {
            "$ref": "#/components/schemas/AyanamsaInput"
          }
        },
        "required": [
          "date",
          "time",
          "lat",
          "lon"
        ],
        "additionalProperties": true,
        "allOf": [
          {
            "$ref": "#/components/schemas/SiderealFlagsConstraint"
          }
        ]
      },
      "AspectsRequest": {
        "type": "object",
        "properties": {
          "birth": {
            "$ref": "#/components/schemas/BirthInput"
          },
          "zodiac": {
            "$ref": "#/components/schemas/ZodiacInput"
          },
          "ayanamsa": {
            "$ref": "#/components/schemas/AyanamsaInput"
          }
        },
        "required": [
          "birth"
        ],
        "additionalProperties": true,
        "allOf": [
          {
            "$ref": "#/components/schemas/SiderealFlagsConstraint"
          }
        ]
      },
      "HouseSystemInput": {
        "type": [
          "string",
          "null"
        ],
        "pattern": "^\\s*(?:[Ee][Qq][Uu][Aa][Ll]|[Ww][Hh][Oo][Ll][Ee](?:_[Ss][Ii][Gg][Nn])?|[pP][lL][aA][cC][iI][dD][uU][sS])\\s*$",
        "default": "equal",
        "description": "equal, whole_sign, or alias whole. Server trims whitespace and ignores case; omitted/null defaults equal. Placidus is opt-in beta with polar rejection and no fallback.",
        "x-canonical-values": [
          "equal",
          "whole_sign",
          "whole",
          "placidus"
        ]
      },
      "HousesRequest": {
        "type": "object",
        "properties": {
          "birth": {
            "$ref": "#/components/schemas/BirthInput"
          },
          "system": {
            "$ref": "#/components/schemas/HouseSystemInput"
          },
          "zodiac": {
            "$ref": "#/components/schemas/ZodiacInput"
          },
          "ayanamsa": {
            "$ref": "#/components/schemas/AyanamsaInput"
          }
        },
        "required": [
          "birth"
        ],
        "additionalProperties": true,
        "allOf": [
          {
            "$ref": "#/components/schemas/SiderealFlagsConstraint"
          }
        ]
      },
      "SynastryRequest": {
        "type": "object",
        "properties": {
          "personA": {
            "$ref": "#/components/schemas/BirthInput"
          },
          "personB": {
            "$ref": "#/components/schemas/BirthInput"
          },
          "zodiac": {
            "$ref": "#/components/schemas/ZodiacInput"
          },
          "ayanamsa": {
            "$ref": "#/components/schemas/AyanamsaInput"
          }
        },
        "required": [
          "personA",
          "personB"
        ],
        "additionalProperties": true,
        "allOf": [
          {
            "$ref": "#/components/schemas/SiderealFlagsConstraint"
          }
        ]
      },
      "OptionalTransitTime": {
        "anyOf": [
          {
            "$ref": "#/components/schemas/Time"
          },
          {
            "type": "null"
          }
        ],
        "default": "12:00",
        "description": "Omitted/null means 12:00; false/empty string and malformed values are rejected."
      },
      "TransitsRequest": {
        "type": "object",
        "properties": {
          "birth": {
            "$ref": "#/components/schemas/BirthInput"
          },
          "transitDate": {
            "$ref": "#/components/schemas/Date"
          },
          "transitTime": {
            "$ref": "#/components/schemas/OptionalTransitTime"
          },
          "timezone": {
            "$ref": "#/components/schemas/Timezone",
            "description": "Transit timezone only; omitted/null falls back to birth.timezone, then UTC. Empty string selects UTC. Birth timezone is not overridden."
          },
          "zodiac": {
            "$ref": "#/components/schemas/ZodiacInput"
          },
          "ayanamsa": {
            "$ref": "#/components/schemas/AyanamsaInput"
          }
        },
        "required": [
          "birth",
          "transitDate"
        ],
        "additionalProperties": true,
        "allOf": [
          {
            "$ref": "#/components/schemas/SiderealFlagsConstraint"
          }
        ]
      },
      "HoroscopeRequest": {
        "type": "object",
        "properties": {
          "birth": {
            "$ref": "#/components/schemas/BirthInput"
          },
          "transitDate": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/Date"
              },
              {
                "type": "null"
              }
            ],
            "description": "Omitted/null selects the engine host current UTC date. Supply an explicit date for reproducible results."
          },
          "transitTime": {
            "$ref": "#/components/schemas/OptionalTransitTime"
          },
          "timezone": {
            "$ref": "#/components/schemas/Timezone",
            "description": "Transit timezone only. Omitted/null/empty string means UTC, NOT the birth timezone. Birth timezone is not overridden."
          },
          "zodiac": {
            "$ref": "#/components/schemas/ZodiacInput"
          },
          "ayanamsa": {
            "$ref": "#/components/schemas/AyanamsaInput"
          }
        },
        "required": [
          "birth"
        ],
        "additionalProperties": true,
        "allOf": [
          {
            "$ref": "#/components/schemas/SiderealFlagsConstraint"
          }
        ]
      },
      "OffsetTimestamp": {
        "type": "string",
        "format": "date-time",
        "description": "ISO 8601 timestamp with Z or an explicit numeric UTC offset. Prefer RFC 3339, e.g. 2026-01-01T00:00:00Z. Naive local timestamps are rejected. The server normalizes offsets to UTC before comparing ordering, duration and the inclusive 1900-01-01 through 2050-12-31 UTC-date bounds."
      },
      "UtcTimestamp": {
        "type": "string",
        "format": "date-time",
        "pattern": "Z$",
        "description": "Normalized UTC timestamp; fractional seconds may be present."
      },
      "TimelinePlanet": {
        "type": "string",
        "enum": [
          "sun",
          "moon",
          "mercury",
          "venus",
          "mars",
          "jupiter",
          "saturn",
          "rahu",
          "ketu"
        ]
      },
      "TimelineRequest": {
        "type": "object",
        "properties": {
          "planet": {
            "type": "string",
            "description": "One of sun, moon, mercury, venus, mars, jupiter, saturn, rahu, ketu. Case/whitespace are normalized. Rahu/Ketu are mean lunar nodes.",
            "x-canonical-values": [
              "sun",
              "moon",
              "mercury",
              "venus",
              "mars",
              "jupiter",
              "saturn",
              "rahu",
              "ketu"
            ],
            "pattern": "^\\s*(?:[Ss][Uu][Nn]|[Mm][Oo][Oo][Nn]|[Mm][Ee][Rr][Cc][Uu][Rr][Yy]|[Vv][Ee][Nn][Uu][Ss]|[Mm][Aa][Rr][Ss]|[Jj][Uu][Pp][Ii][Tt][Ee][Rr]|[Ss][Aa][Tt][Uu][Rr][Nn]|[Rr][Aa][Hh][Uu]|[Kk][Ee][Tt][Uu])\\s*$"
          },
          "start_utc": {
            "$ref": "#/components/schemas/OffsetTimestamp"
          },
          "end_utc": {
            "$ref": "#/components/schemas/OffsetTimestamp",
            "description": "Must be strictly later than start_utc and at most 180 days later. Both UTC dates must be inside the public date window."
          },
          "ayanamsa": {
            "type": "string",
            "description": "Required even though chart endpoints default it. One of lahiri, raman, krishnamurti; case/whitespace are normalized.",
            "x-canonical-values": [
              "lahiri",
              "raman",
              "krishnamurti"
            ],
            "pattern": "^\\s*(?:[Ll][Aa][Hh][Ii][Rr][Ii]|[Rr][Aa][Mm][Aa][Nn]|[Kk][Rr][Ii][Ss][Hh][Nn][Aa][Mm][Uu][Rr][Tt][Ii])\\s*$"
          }
        },
        "required": [
          "planet",
          "start_utc",
          "end_utc",
          "ayanamsa"
        ],
        "additionalProperties": true,
        "description": "Pro only. Unknown fields are ignored; step_seconds is not a public control and is not passed to the engine. Each admitted request reserves one timeline unit, independent of range."
      },
      "PlanetName": {
        "type": "string",
        "enum": [
          "Sun",
          "Moon",
          "Mercury",
          "Venus",
          "Mars",
          "Jupiter",
          "Saturn",
          "Uranus",
          "Neptune",
          "Pluto"
        ]
      },
      "Sign": {
        "type": "string",
        "enum": [
          "Aries",
          "Taurus",
          "Gemini",
          "Cancer",
          "Leo",
          "Virgo",
          "Libra",
          "Scorpio",
          "Sagittarius",
          "Capricorn",
          "Aquarius",
          "Pisces"
        ]
      },
      "RoundedLongitude": {
        "type": "number",
        "minimum": 0,
        "maximum": 360,
        "description": "Ecliptic longitude in degrees, displayed to four decimals. Rounding of a value just below 360 can produce 360.0; do not recompute sign/pada from rounded display values."
      },
      "DegreeInSign": {
        "type": "number",
        "minimum": 0,
        "maximum": 30,
        "description": "Displayed to four decimals; rounding near the next sign can produce 30.0."
      },
      "Nakshatra": {
        "type": "object",
        "properties": {
          "index": {
            "type": "integer",
            "minimum": 1,
            "maximum": 27
          },
          "name": {
            "type": "string"
          },
          "ruler": {
            "type": "string"
          },
          "pada": {
            "type": "integer",
            "minimum": 1,
            "maximum": 4
          },
          "deg_into_nakshatra": {
            "type": "number",
            "minimum": 0,
            "maximum": 13.333334
          }
        },
        "required": [
          "index",
          "name",
          "ruler",
          "pada",
          "deg_into_nakshatra"
        ],
        "additionalProperties": true
      },
      "PlanetPosition": {
        "type": "object",
        "properties": {
          "lon": {
            "$ref": "#/components/schemas/RoundedLongitude"
          },
          "sign": {
            "$ref": "#/components/schemas/Sign"
          },
          "deg_in_sign": {
            "$ref": "#/components/schemas/DegreeInSign"
          },
          "speed_deg_per_day": {
            "type": "number",
            "description": "Signed tropical longitude difference over the preceding one TT day, rounded to four decimals; not an instantaneous derivative."
          },
          "retrograde": {
            "type": "boolean"
          },
          "tropical_lon": {
            "$ref": "#/components/schemas/RoundedLongitude"
          },
          "sidereal_lon": {
            "$ref": "#/components/schemas/RoundedLongitude"
          },
          "nakshatra": {
            "$ref": "#/components/schemas/Nakshatra",
            "description": "Present only for the Moon in sidereal chart output."
          }
        },
        "required": [
          "lon",
          "sign",
          "deg_in_sign",
          "speed_deg_per_day",
          "retrograde",
          "tropical_lon"
        ],
        "additionalProperties": true,
        "description": "Apparent geocentric JPL DE421 ecliptic position. sidereal_lon is present in sidereal mode; nakshatra is present only on the sidereal Moon."
      },
      "Planets": {
        "type": "object",
        "properties": {
          "Sun": {
            "$ref": "#/components/schemas/PlanetPosition"
          },
          "Moon": {
            "$ref": "#/components/schemas/PlanetPosition"
          },
          "Mercury": {
            "$ref": "#/components/schemas/PlanetPosition"
          },
          "Venus": {
            "$ref": "#/components/schemas/PlanetPosition"
          },
          "Mars": {
            "$ref": "#/components/schemas/PlanetPosition"
          },
          "Jupiter": {
            "$ref": "#/components/schemas/PlanetPosition"
          },
          "Saturn": {
            "$ref": "#/components/schemas/PlanetPosition"
          },
          "Uranus": {
            "$ref": "#/components/schemas/PlanetPosition"
          },
          "Neptune": {
            "$ref": "#/components/schemas/PlanetPosition"
          },
          "Pluto": {
            "$ref": "#/components/schemas/PlanetPosition"
          }
        },
        "required": [
          "Sun",
          "Moon",
          "Mercury",
          "Venus",
          "Mars",
          "Jupiter",
          "Saturn",
          "Uranus",
          "Neptune",
          "Pluto"
        ],
        "additionalProperties": true
      },
      "AspectType": {
        "type": "string",
        "enum": [
          "conjunction",
          "opposition",
          "trine",
          "square",
          "sextile",
          "semisextile",
          "semisquare",
          "quintile",
          "sesquiquadrate",
          "biquintile"
        ]
      },
      "NatalAspect": {
        "type": "object",
        "properties": {
          "p1": {
            "$ref": "#/components/schemas/PlanetName"
          },
          "p2": {
            "$ref": "#/components/schemas/PlanetName"
          },
          "type": {
            "$ref": "#/components/schemas/AspectType"
          },
          "exact_angle": {
            "type": "number",
            "enum": [
              0,
              180,
              120,
              90,
              60,
              30,
              45,
              72,
              135,
              144
            ]
          },
          "distance": {
            "type": "number",
            "minimum": 0,
            "maximum": 180
          },
          "orb": {
            "type": "number",
            "minimum": 0,
            "maximum": 8
          }
        },
        "required": [
          "p1",
          "p2",
          "type",
          "exact_angle",
          "distance",
          "orb"
        ],
        "additionalProperties": true
      },
      "CrossAspect": {
        "type": "object",
        "properties": {
          "transit": {
            "$ref": "#/components/schemas/PlanetName",
            "description": "Transiting planet for /transits; person B planet for /synastry."
          },
          "natal": {
            "$ref": "#/components/schemas/PlanetName",
            "description": "Natal planet for /transits; person A planet for /synastry."
          },
          "type": {
            "$ref": "#/components/schemas/AspectType"
          },
          "exact_angle": {
            "type": "number",
            "enum": [
              0,
              180,
              120,
              90,
              60,
              30,
              45,
              72,
              135,
              144
            ]
          },
          "distance": {
            "type": "number",
            "minimum": 0,
            "maximum": 180
          },
          "orb": {
            "type": "number",
            "minimum": 0,
            "maximum": 8
          }
        },
        "required": [
          "transit",
          "natal",
          "type",
          "exact_angle",
          "distance",
          "orb"
        ],
        "additionalProperties": true
      },
      "Cusps": {
        "type": "object",
        "properties": {
          "1": {
            "type": "number",
            "minimum": 0,
            "exclusiveMaximum": 360
          },
          "2": {
            "type": "number",
            "minimum": 0,
            "exclusiveMaximum": 360
          },
          "3": {
            "type": "number",
            "minimum": 0,
            "exclusiveMaximum": 360
          },
          "4": {
            "type": "number",
            "minimum": 0,
            "exclusiveMaximum": 360
          },
          "5": {
            "type": "number",
            "minimum": 0,
            "exclusiveMaximum": 360
          },
          "6": {
            "type": "number",
            "minimum": 0,
            "exclusiveMaximum": 360
          },
          "7": {
            "type": "number",
            "minimum": 0,
            "exclusiveMaximum": 360
          },
          "8": {
            "type": "number",
            "minimum": 0,
            "exclusiveMaximum": 360
          },
          "9": {
            "type": "number",
            "minimum": 0,
            "exclusiveMaximum": 360
          },
          "10": {
            "type": "number",
            "minimum": 0,
            "exclusiveMaximum": 360
          },
          "11": {
            "type": "number",
            "minimum": 0,
            "exclusiveMaximum": 360
          },
          "12": {
            "type": "number",
            "minimum": 0,
            "exclusiveMaximum": 360
          }
        },
        "required": [
          "1",
          "2",
          "3",
          "4",
          "5",
          "6",
          "7",
          "8",
          "9",
          "10",
          "11",
          "12"
        ],
        "additionalProperties": false
      },
      "HouseSystem": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string",
            "enum": [
              "Equal",
              "Whole sign"
            ]
          },
          "houses": {
            "$ref": "#/components/schemas/Cusps"
          }
        },
        "required": [
          "name",
          "houses"
        ],
        "additionalProperties": true
      },
      "HouseSystems": {
        "type": "object",
        "properties": {
          "equal": {
            "$ref": "#/components/schemas/HouseSystem"
          },
          "whole_sign": {
            "$ref": "#/components/schemas/HouseSystem"
          }
        },
        "required": [],
        "additionalProperties": false,
        "minProperties": 1
      },
      "Houses": {
        "type": "object",
        "properties": {
          "ascendant": {
            "type": "number",
            "minimum": 0,
            "exclusiveMaximum": 360
          },
          "mc": {
            "type": "number",
            "minimum": 0,
            "exclusiveMaximum": 360
          },
          "systems": {
            "$ref": "#/components/schemas/HouseSystems"
          },
          "metadata": {
            "type": "object",
            "properties": {
              "zodiac": {
                "$ref": "#/components/schemas/Zodiac"
              },
              "ayanamsa": {
                "$ref": "#/components/schemas/AyanamsaResult"
              }
            },
            "required": [
              "zodiac",
              "ayanamsa"
            ],
            "additionalProperties": true
          }
        },
        "required": [
          "ascendant",
          "mc",
          "systems",
          "metadata"
        ],
        "additionalProperties": true,
        "description": "Legacy full-chart houses contain Equal and Whole Sign, sharing the eastern-horizon Ascendant and meridian MC. These chart routes do not opt into Placidus. The separate /houses selected-system response is described by SelectedHouses."
      },
      "NodePosition": {
        "type": "object",
        "properties": {
          "longitude": {
            "$ref": "#/components/schemas/RoundedLongitude"
          },
          "sign": {
            "$ref": "#/components/schemas/Sign"
          },
          "deg_in_sign": {
            "$ref": "#/components/schemas/DegreeInSign"
          }
        },
        "required": [
          "longitude",
          "sign",
          "deg_in_sign"
        ],
        "additionalProperties": true
      },
      "Nodes": {
        "type": "object",
        "properties": {
          "mean": {
            "$ref": "#/components/schemas/NodePosition"
          },
          "true": {
            "$ref": "#/components/schemas/NodePosition",
            "description": "Legacy label: identical to mean, NOT an independently calculated true node."
          },
          "south": {
            "$ref": "#/components/schemas/NodePosition"
          },
          "note": {
            "type": "string"
          }
        },
        "required": [
          "mean",
          "true",
          "south",
          "note"
        ],
        "additionalProperties": true
      },
      "Chart": {
        "type": "object",
        "properties": {
          "status": {
            "const": "ok"
          },
          "zodiac": {
            "$ref": "#/components/schemas/Zodiac"
          },
          "ayanamsa": {
            "$ref": "#/components/schemas/AyanamsaResult"
          },
          "planets": {
            "$ref": "#/components/schemas/Planets"
          },
          "houses": {
            "$ref": "#/components/schemas/Houses"
          },
          "aspects": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/NatalAspect"
            }
          },
          "nodes": {
            "$ref": "#/components/schemas/Nodes"
          },
          "metadata": {
            "type": "object",
            "properties": {
              "note": {
                "type": "string"
              }
            },
            "required": [
              "note"
            ],
            "additionalProperties": true
          }
        },
        "required": [
          "status",
          "zodiac",
          "ayanamsa",
          "planets",
          "houses",
          "aspects",
          "nodes",
          "metadata"
        ],
        "additionalProperties": true,
        "description": "A full calculation chart, not a rendered wheel or interpretation. Sidereal longitudes subtract the selected date-aware IAU 2006/P03 mean ayanamsa from apparent tropical longitudes; this is not a promise of identity with every ephemeris convention."
      },
      "BirthChartEcho": {
        "type": "object",
        "properties": {
          "date": {
            "$ref": "#/components/schemas/Date"
          },
          "time": {
            "$ref": "#/components/schemas/Time"
          },
          "timezone": {
            "$ref": "#/components/schemas/Timezone"
          },
          "lat": {
            "$ref": "#/components/schemas/Latitude"
          },
          "lon": {
            "$ref": "#/components/schemas/Longitude"
          },
          "zodiac": {
            "$ref": "#/components/schemas/ZodiacInput"
          },
          "ayanamsa": {
            "$ref": "#/components/schemas/AyanamsaInput"
          }
        },
        "required": [
          "date",
          "time",
          "timezone",
          "lat",
          "lon"
        ],
        "additionalProperties": true,
        "description": "Original input values with omitted/null timezone replaced by UTC. Omitted zodiac/ayanamsa remain absent; use chart fields for normalized results. Numeric coordinate strings remain strings here."
      },
      "BirthChartResponse": {
        "type": "object",
        "properties": {
          "type": {
            "const": "birth-chart"
          },
          "input": {
            "$ref": "#/components/schemas/BirthChartEcho"
          },
          "chart": {
            "$ref": "#/components/schemas/Chart"
          }
        },
        "required": [
          "type",
          "input",
          "chart"
        ],
        "additionalProperties": true
      },
      "AspectsResponse": {
        "type": "object",
        "properties": {
          "type": {
            "const": "aspects"
          },
          "input": {
            "$ref": "#/components/schemas/AspectsRequest"
          },
          "aspects": {
            "$ref": "#/components/schemas/Chart"
          }
        },
        "required": [
          "type",
          "input",
          "aspects"
        ],
        "additionalProperties": true,
        "description": "The outer aspects property contains a full Chart. The aspect array is response.aspects.aspects."
      },
      "HousesResponse": {
        "type": "object",
        "properties": {
          "type": {
            "const": "houses"
          },
          "house_system": {
            "type": "string",
            "enum": [
              "equal",
              "whole_sign",
              "placidus"
            ]
          },
          "status": {
            "const": "ok"
          },
          "zodiac": {
            "$ref": "#/components/schemas/Zodiac"
          },
          "ayanamsa": {
            "$ref": "#/components/schemas/AyanamsaResult"
          },
          "planets": {
            "$ref": "#/components/schemas/Planets"
          },
          "houses": {
            "$ref": "#/components/schemas/SelectedHouses"
          },
          "aspects": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/NatalAspect"
            }
          },
          "nodes": {
            "$ref": "#/components/schemas/Nodes"
          },
          "metadata": {
            "type": "object",
            "properties": {
              "note": {
                "type": "string"
              }
            },
            "required": [
              "note"
            ],
            "additionalProperties": true
          }
        },
        "required": [
          "type",
          "house_system",
          "status",
          "zodiac",
          "ayanamsa",
          "planets",
          "houses",
          "aspects",
          "nodes",
          "metadata"
        ],
        "additionalProperties": true
      },
      "NormalizedBirth": {
        "type": "object",
        "properties": {
          "date": {
            "$ref": "#/components/schemas/Date"
          },
          "time": {
            "$ref": "#/components/schemas/Time"
          },
          "timezone": {
            "$ref": "#/components/schemas/Timezone"
          },
          "lat": {
            "type": "number",
            "exclusiveMinimum": -90,
            "exclusiveMaximum": 90
          },
          "lon": {
            "type": "number",
            "minimum": -180,
            "maximum": 180
          },
          "zodiac": {
            "$ref": "#/components/schemas/Zodiac"
          },
          "ayanamsa": {
            "$ref": "#/components/schemas/AyanamsaResult"
          }
        },
        "required": [
          "date",
          "time",
          "timezone",
          "lat",
          "lon",
          "zodiac",
          "ayanamsa"
        ],
        "additionalProperties": true,
        "description": "Synastry normalizes numeric coordinates, zodiac and ayanamsa. Supplied timezone is echoed (including null/empty string); omitted timezone is UTC."
      },
      "SynastryResponse": {
        "type": "object",
        "properties": {
          "type": {
            "const": "synastry"
          },
          "input": {
            "type": "object",
            "properties": {
              "personA": {
                "$ref": "#/components/schemas/NormalizedBirth"
              },
              "personB": {
                "$ref": "#/components/schemas/NormalizedBirth"
              },
              "zodiac": {
                "$ref": "#/components/schemas/ZodiacInput"
              },
              "ayanamsa": {
                "$ref": "#/components/schemas/AyanamsaInput"
              }
            },
            "required": [
              "personA",
              "personB",
              "zodiac",
              "ayanamsa"
            ],
            "additionalProperties": true
          },
          "charts": {
            "type": "object",
            "properties": {
              "personA": {
                "$ref": "#/components/schemas/Chart"
              },
              "personB": {
                "$ref": "#/components/schemas/Chart"
              }
            },
            "required": [
              "personA",
              "personB"
            ],
            "additionalProperties": true
          },
          "aspects": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/CrossAspect"
            }
          }
        },
        "required": [
          "type",
          "input",
          "charts",
          "aspects"
        ],
        "additionalProperties": true
      },
      "TransitsResult": {
        "type": "object",
        "properties": {
          "status": {
            "const": "ok"
          },
          "zodiac": {
            "$ref": "#/components/schemas/Zodiac"
          },
          "ayanamsa": {
            "$ref": "#/components/schemas/AyanamsaResult"
          },
          "natal_chart": {
            "$ref": "#/components/schemas/Chart"
          },
          "transit_chart": {
            "$ref": "#/components/schemas/Chart"
          },
          "aspects": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/CrossAspect"
            }
          }
        },
        "required": [
          "status",
          "zodiac",
          "ayanamsa",
          "natal_chart",
          "transit_chart",
          "aspects"
        ],
        "additionalProperties": true
      },
      "TransitsEcho": {
        "type": "object",
        "properties": {
          "birth": {
            "$ref": "#/components/schemas/BirthInput"
          },
          "transitDate": {
            "$ref": "#/components/schemas/Date"
          },
          "transitTime": {
            "$ref": "#/components/schemas/Time"
          },
          "timezone": {
            "$ref": "#/components/schemas/Timezone",
            "description": "Transit timezone only; omitted/null falls back to birth.timezone, then UTC. Empty string selects UTC. Birth timezone is not overridden."
          },
          "zodiac": {
            "$ref": "#/components/schemas/ZodiacInput"
          },
          "ayanamsa": {
            "$ref": "#/components/schemas/AyanamsaInput"
          }
        },
        "required": [
          "birth",
          "transitDate",
          "transitTime",
          "timezone"
        ],
        "additionalProperties": true
      },
      "TransitsResponse": {
        "type": "object",
        "properties": {
          "type": {
            "const": "transits"
          },
          "input": {
            "$ref": "#/components/schemas/TransitsEcho"
          },
          "transits": {
            "$ref": "#/components/schemas/TransitsResult"
          }
        },
        "required": [
          "type",
          "input",
          "transits"
        ],
        "additionalProperties": true,
        "description": "Requested-instant transit-to-natal aspects. Not an event search, aspect windows, station prediction or house-transit report. Engine output remains nested under transits."
      },
      "InterpretationAtom": {
        "type": "object",
        "properties": {
          "planet": {
            "$ref": "#/components/schemas/PlanetName"
          },
          "planet_nature": {
            "type": "string",
            "enum": [
              "luminary",
              "neutral",
              "benefic",
              "malefic"
            ]
          },
          "planet_sect": {
            "type": "string",
            "enum": [
              "day",
              "night",
              "neutral"
            ]
          },
          "chart_sect": {
            "type": "string",
            "enum": [
              "day",
              "night"
            ],
            "description": "Natal apparent topocentric Sun center geometric altitude >0 degrees means day; WGS84 elevation zero, no atmospheric refraction."
          },
          "aspect": {
            "type": "string",
            "enum": [
              "Conjunction",
              "Opposition",
              "Square",
              "Trine",
              "Sextile"
            ]
          },
          "natal_point": {
            "$ref": "#/components/schemas/PlanetName"
          },
          "house": {
            "type": "null",
            "description": "No house assignment is implemented for this endpoint."
          },
          "house_topics": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "maxItems": 0
          },
          "tone": {
            "type": "string",
            "enum": [
              "intensifying",
              "polarizing",
              "challenging",
              "supportive",
              "opportunity"
            ]
          },
          "intensity": {
            "type": "number",
            "minimum": 0.1,
            "maximum": 1,
            "description": "Deterministic traditional-rule heuristic, not a probability or scientifically validated prediction."
          },
          "tradition": {
            "type": "array",
            "items": {
              "type": "string",
              "enum": [
                "hellenistic",
                "western"
              ]
            },
            "minItems": 2,
            "maxItems": 2
          },
          "summary_key": {
            "type": "string",
            "description": "Machine key such as saturn_square_sun, not authored/generated prose."
          }
        },
        "required": [
          "planet",
          "planet_nature",
          "planet_sect",
          "chart_sect",
          "aspect",
          "natal_point",
          "house",
          "house_topics",
          "tone",
          "intensity",
          "tradition",
          "summary_key"
        ],
        "additionalProperties": true
      },
      "Interpretation": {
        "type": "object",
        "properties": {
          "summary": {
            "type": "object",
            "properties": {
              "overall_tone": {
                "type": "string",
                "enum": [
                  "supportive",
                  "challenging",
                  "mixed"
                ]
              },
              "intensity": {
                "type": "number",
                "minimum": 0,
                "maximum": 1
              }
            },
            "required": [
              "overall_tone",
              "intensity"
            ],
            "additionalProperties": true
          },
          "transits": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/InterpretationAtom"
            }
          }
        },
        "required": [
          "summary",
          "transits"
        ],
        "additionalProperties": true
      },
      "HoroscopeResponse": {
        "type": "object",
        "properties": {
          "type": {
            "const": "horoscope"
          },
          "input": {
            "type": "object",
            "properties": {
              "birth": {
                "$ref": "#/components/schemas/BirthInput"
              },
              "transitDate": {
                "$ref": "#/components/schemas/Date"
              },
              "zodiac": {
                "$ref": "#/components/schemas/ZodiacInput"
              },
              "ayanamsa": {
                "$ref": "#/components/schemas/AyanamsaInput"
              }
            },
            "required": [
              "birth",
              "transitDate",
              "zodiac",
              "ayanamsa"
            ],
            "additionalProperties": true
          },
          "interpretation": {
            "$ref": "#/components/schemas/Interpretation"
          }
        },
        "required": [
          "type",
          "input",
          "interpretation"
        ],
        "additionalProperties": true,
        "description": "Beta deterministic structured major-aspect signals. No language model, prose, compatibility score, medical/financial prediction, or house topics. The input echo currently omits transitTime/timezone; retain your request for reproducibility."
      },
      "TimelineSegment": {
        "type": "object",
        "properties": {
          "planet": {
            "$ref": "#/components/schemas/TimelinePlanet"
          },
          "ayanamsa": {
            "$ref": "#/components/schemas/Ayanamsa"
          },
          "nakshatra_index": {
            "type": "integer",
            "minimum": 1,
            "maximum": 27
          },
          "nakshatra_name": {
            "type": "string"
          },
          "pada": {
            "type": "integer",
            "minimum": 1,
            "maximum": 4
          },
          "start_utc": {
            "$ref": "#/components/schemas/UtcTimestamp"
          },
          "end_utc": {
            "$ref": "#/components/schemas/UtcTimestamp"
          },
          "sidereal_longitude_start": {
            "type": "number",
            "minimum": 0,
            "exclusiveMaximum": 360
          },
          "sidereal_longitude_end": {
            "type": "number",
            "minimum": 0,
            "exclusiveMaximum": 360
          },
          "retrograde": {
            "type": "boolean",
            "description": "Net direction across this returned residence segment, not a guarantee of uniform motion throughout a station-spanning segment."
          }
        },
        "required": [
          "planet",
          "ayanamsa",
          "nakshatra_index",
          "nakshatra_name",
          "pada",
          "start_utc",
          "end_utc",
          "sidereal_longitude_start",
          "sidereal_longitude_end",
          "retrograde"
        ],
        "additionalProperties": true
      },
      "TimelineResponse": {
        "type": "object",
        "properties": {
          "planet": {
            "$ref": "#/components/schemas/TimelinePlanet"
          },
          "zodiac_used": {
            "const": "sidereal"
          },
          "ayanamsa_used": {
            "$ref": "#/components/schemas/Ayanamsa"
          },
          "start_utc": {
            "$ref": "#/components/schemas/UtcTimestamp"
          },
          "end_utc": {
            "$ref": "#/components/schemas/UtcTimestamp"
          },
          "step_seconds": {
            "const": 3600
          },
          "segments": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/TimelineSegment"
            },
            "minItems": 1
          }
        },
        "required": [
          "planet",
          "zodiac_used",
          "ayanamsa_used",
          "start_utc",
          "end_utc",
          "step_seconds",
          "segments"
        ],
        "additionalProperties": true,
        "description": "Gap-free returned residence coverage with numerically refined boundaries. Hourly discovery can miss an out-and-back departure/re-entry entirely between samples. Boundary solver resolution is not physical absolute-time accuracy; this is not an exhaustive station/event finder."
      },
      "Error": {
        "type": "object",
        "properties": {
          "error": {
            "type": "string"
          },
          "required": {
            "anyOf": [
              {
                "type": "array",
                "items": {
                  "type": "string"
                }
              },
              {
                "type": "object",
                "additionalProperties": {
                  "anyOf": [
                    {
                      "type": "string"
                    },
                    {
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    }
                  ]
                }
              }
            ]
          },
          "example": {
            "type": "object",
            "additionalProperties": true
          }
        },
        "required": [
          "error"
        ],
        "additionalProperties": true,
        "description": "Current gateway errors guarantee an error string, not a universal code/details envelope. Some validation errors add required/example. Reverse-proxy failures can be HTML, so clients must not assume JSON for every non-2xx."
      },
      "SiderealFlagsConstraint": {
        "description": "Only supported ayanamsa names are valid when zodiac is sidereal; tropical retains its legacy ignore behavior.",
        "if": {
          "type": "object",
          "properties": {
            "zodiac": {
              "type": "string",
              "pattern": "^\\s*(?:[Ss][Ii][Dd][Ee][Rr][Ee][Aa][Ll])\\s*$"
            }
          },
          "required": [
            "zodiac"
          ]
        },
        "then": {
          "type": "object",
          "properties": {
            "ayanamsa": {
              "type": [
                "string",
                "null"
              ],
              "pattern": "^\\s*(?:[Ll][Aa][Hh][Ii][Rr][Ii]|[Rr][Aa][Mm][Aa][Nn]|[Kk][Rr][Ii][Ss][Hh][Nn][Aa][Mm][Uu][Rr][Tt][Ii])\\s*$"
            }
          }
        }
      },
      "SelectedHouseSystem": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string",
            "enum": [
              "Equal",
              "Whole sign",
              "Placidus"
            ]
          },
          "houses": {
            "$ref": "#/components/schemas/Cusps"
          }
        },
        "required": [
          "name",
          "houses"
        ],
        "additionalProperties": false
      },
      "SelectedHouseSystems": {
        "type": "object",
        "properties": {
          "equal": {
            "$ref": "#/components/schemas/SelectedHouseSystem"
          },
          "whole_sign": {
            "$ref": "#/components/schemas/SelectedHouseSystem"
          },
          "placidus": {
            "$ref": "#/components/schemas/SelectedHouseSystem"
          }
        },
        "required": [],
        "additionalProperties": false,
        "minProperties": 1,
        "maxProperties": 1
      },
      "SelectedHouseMetadata": {
        "type": "object",
        "properties": {
          "zodiac": {
            "$ref": "#/components/schemas/Zodiac"
          },
          "ayanamsa": {
            "$ref": "#/components/schemas/AyanamsaResult"
          },
          "status": {
            "type": "string",
            "const": "beta"
          },
          "fallback": {
            "type": "null"
          },
          "convention": {
            "type": "string",
            "const": "apparent-tropical-cusps-minus-selected-mean-ayanamsa"
          },
          "polar_policy": {
            "type": "string",
            "const": "reject-without-fallback"
          }
        },
        "required": [
          "zodiac",
          "ayanamsa"
        ],
        "additionalProperties": true
      },
      "SelectedHouses": {
        "type": "object",
        "properties": {
          "ascendant": {
            "type": "number",
            "minimum": 0,
            "exclusiveMaximum": 360
          },
          "mc": {
            "type": "number",
            "minimum": 0,
            "exclusiveMaximum": 360
          },
          "systems": {
            "$ref": "#/components/schemas/SelectedHouseSystems"
          },
          "metadata": {
            "$ref": "#/components/schemas/SelectedHouseMetadata"
          }
        },
        "required": [
          "ascendant",
          "mc",
          "systems",
          "metadata"
        ],
        "additionalProperties": true,
        "description": "Exactly the selected house system. Placidus beta metadata is present only for explicit Placidus; undefined/polar geometry is rejected without another-system fallback."
      },
      "BetaBirthInput": {
        "type": "object",
        "properties": {
          "date": {
            "$ref": "#/components/schemas/Date"
          },
          "time": {
            "$ref": "#/components/schemas/Time"
          },
          "timezone": {
            "type": "string",
            "minLength": 1,
            "maxLength": 100,
            "default": "UTC",
            "description": "Valid IANA zone; UTC when omitted. Ambiguous and nonexistent civil times are rejected."
          },
          "lat": {
            "type": "number",
            "exclusiveMinimum": -90,
            "exclusiveMaximum": 90
          },
          "lon": {
            "type": "number",
            "minimum": -180,
            "maximum": 180
          }
        },
        "required": [
          "date",
          "time",
          "lat",
          "lon"
        ],
        "additionalProperties": false,
        "description": "Strict nested birth input; no unknown properties, nulls, booleans or numeric strings. Known civil time required; semantic date/DST/undefined-angle validation occurs on the server."
      },
      "NatalSvgRequest": {
        "type": "object",
        "properties": {
          "birth": {
            "$ref": "#/components/schemas/BetaBirthInput"
          },
          "zodiac": {
            "$ref": "#/components/schemas/Zodiac",
            "default": "tropical"
          },
          "ayanamsa": {
            "$ref": "#/components/schemas/Ayanamsa",
            "default": "lahiri"
          },
          "house_system": {
            "type": "string",
            "enum": [
              "equal",
              "whole_sign",
              "placidus"
            ],
            "default": "equal"
          },
          "theme": {
            "type": "string",
            "enum": [
              "light",
              "dark"
            ],
            "default": "light"
          },
          "show_aspects": {
            "type": "boolean",
            "default": true
          }
        },
        "required": [
          "birth"
        ],
        "additionalProperties": false,
        "description": "Beta server-rendered natal wheel. Inputs are calculation settings only; no SVG/chart/URL/image/font uploads. Ayanamsa applies only to sidereal; exact lowercase enum remains required if supplied. Dense labels that cannot fit safely are rejected with 400, not silently omitted."
      },
      "NatalSvgMetadata": {
        "type": "object",
        "properties": {
          "renderer": {
            "type": "string",
            "const": "astroapi-original-svg-v1"
          },
          "position_source": {
            "type": "string",
            "const": "engine-chart"
          },
          "layout": {
            "type": "string",
            "const": "1200x1100"
          },
          "aspects": {
            "type": "string",
            "enum": [
              "supplied-major-only",
              "hidden"
            ]
          },
          "house_status": {
            "type": "string",
            "enum": [
              "current",
              "beta"
            ]
          },
          "polar_policy": {
            "type": "string",
            "const": "reject-without-fallback"
          }
        },
        "required": [
          "renderer",
          "position_source",
          "layout",
          "aspects",
          "house_status",
          "polar_policy"
        ],
        "additionalProperties": false
      },
      "NatalSvgResponse": {
        "type": "object",
        "properties": {
          "type": {
            "type": "string",
            "const": "natal_svg"
          },
          "status": {
            "type": "string",
            "const": "beta"
          },
          "svg": {
            "type": "string",
            "minLength": 1,
            "maxLength": 131072,
            "description": "Original static SVG source in JSON, not a URL. UTF-8 renderer output capped at 128 KiB; do not treat arbitrary external SVG as trusted."
          },
          "house_system": {
            "type": "string",
            "enum": [
              "equal",
              "whole_sign",
              "placidus"
            ]
          },
          "theme": {
            "type": "string",
            "enum": [
              "light",
              "dark"
            ]
          },
          "zodiac": {
            "$ref": "#/components/schemas/Zodiac"
          },
          "ayanamsa": {
            "$ref": "#/components/schemas/AyanamsaResult"
          },
          "metadata": {
            "$ref": "#/components/schemas/NatalSvgMetadata"
          }
        },
        "required": [
          "type",
          "status",
          "svg",
          "house_system",
          "theme",
          "zodiac",
          "ayanamsa",
          "metadata"
        ],
        "additionalProperties": false
      },
      "VargasRequest": {
        "type": "object",
        "properties": {
          "birth": {
            "$ref": "#/components/schemas/BetaBirthInput"
          },
          "ayanamsa": {
            "$ref": "#/components/schemas/Ayanamsa",
            "default": "lahiri"
          },
          "division": {
            "type": "integer",
            "enum": [
              1,
              3,
              4,
              7,
              9,
              10,
              12
            ],
            "default": 9
          }
        },
        "required": [
          "birth"
        ],
        "additionalProperties": false,
        "description": "Sidereal-only Parashari D1/D3/D4/D7/D9/D10/D12 beta. Half-open, lower-inclusive divisions use unrounded binary64 longitudes. Traditional nine bodies and Ascendant only; no outer planets or interpretation text."
      },
      "VimshottariRequest": {
        "type": "object",
        "properties": {
          "birth": {
            "$ref": "#/components/schemas/BetaBirthInput"
          },
          "ayanamsa": {
            "$ref": "#/components/schemas/Ayanamsa",
            "default": "lahiri"
          },
          "depth": {
            "type": "integer",
            "enum": [
              2,
              3
            ],
            "default": 2,
            "description": "Only 2 or 3; no null, string or boolean. Explicit 2 is output-identical to omission."
          }
        },
        "required": [
          "birth"
        ],
        "additionalProperties": false,
        "description": "Sidereal-only beta with fixed Julian years of 365.25 days and a 120-year cycle anchored at the theoretical start of the birth mahadasha. Omitted depth or explicit 2 returns the unchanged two-level response: nine majors and 81 antardashas. Opt-in depth 3 adds nine pratyantardashas to each antardasha (729 leaves), exact proportional integer-microsecond durations, active third-level birth lord and depth metadata. No arbitrary depth, date query, range or year model."
      },
      "VargaPosition": {
        "type": "object",
        "properties": {
          "sidereal_longitude": {
            "type": "number",
            "minimum": 0,
            "exclusiveMaximum": 360
          },
          "divisional_longitude": {
            "type": "number",
            "minimum": 0,
            "exclusiveMaximum": 360
          },
          "sign_index": {
            "type": "integer",
            "minimum": 1,
            "maximum": 12
          },
          "sign": {
            "$ref": "#/components/schemas/Sign"
          },
          "degree_in_sign": {
            "type": "number",
            "minimum": 0,
            "exclusiveMaximum": 30
          },
          "division_index": {
            "type": "integer",
            "minimum": 1,
            "maximum": 12
          }
        },
        "required": [
          "sidereal_longitude",
          "divisional_longitude",
          "sign_index",
          "sign",
          "degree_in_sign",
          "division_index"
        ],
        "additionalProperties": false
      },
      "VargaBodies": {
        "type": "object",
        "properties": {
          "sun": {
            "$ref": "#/components/schemas/VargaPosition"
          },
          "moon": {
            "$ref": "#/components/schemas/VargaPosition"
          },
          "mercury": {
            "$ref": "#/components/schemas/VargaPosition"
          },
          "venus": {
            "$ref": "#/components/schemas/VargaPosition"
          },
          "mars": {
            "$ref": "#/components/schemas/VargaPosition"
          },
          "jupiter": {
            "$ref": "#/components/schemas/VargaPosition"
          },
          "saturn": {
            "$ref": "#/components/schemas/VargaPosition"
          },
          "rahu": {
            "$ref": "#/components/schemas/VargaPosition"
          },
          "ketu": {
            "$ref": "#/components/schemas/VargaPosition"
          }
        },
        "required": [
          "sun",
          "moon",
          "mercury",
          "venus",
          "mars",
          "jupiter",
          "saturn",
          "rahu",
          "ketu"
        ],
        "additionalProperties": false
      },
      "VargasMetadata": {
        "type": "object",
        "properties": {
          "calculation_status": {
            "type": "string",
            "const": "experimental_beta"
          },
          "practitioner_review": {
            "type": "string",
            "const": "not_completed"
          },
          "frame": {
            "type": "string",
            "const": "apparent_geocentric_sidereal_retained_nutation"
          },
          "node_model": {
            "type": "string",
            "const": "mean_ascending_and_opposite_descending"
          },
          "classification_precision": {
            "type": "string",
            "const": "unrounded_binary64"
          },
          "interpretations": {
            "type": "boolean",
            "const": false
          },
          "mapping": {
            "type": "string",
            "enum": [
              "parashari_d1_d9_d10",
              "parashari_d3",
              "parashari_d4",
              "parashari_d7",
              "parashari_d12"
            ]
          },
          "boundaries": {
            "type": "string",
            "const": "half_open_lower_inclusive"
          },
          "divisional_degrees": {
            "type": "string",
            "const": "linear_progress_within_assigned_sign"
          }
        },
        "required": [
          "calculation_status",
          "practitioner_review",
          "frame",
          "node_model",
          "classification_precision",
          "interpretations",
          "mapping",
          "boundaries",
          "divisional_degrees"
        ],
        "additionalProperties": false
      },
      "VargasResponse": {
        "type": "object",
        "properties": {
          "status": {
            "type": "string",
            "const": "beta"
          },
          "type": {
            "type": "string",
            "const": "vargas"
          },
          "input": {
            "type": "object",
            "properties": {
              "birth": {
                "$ref": "#/components/schemas/NormalizedBirth"
              },
              "ayanamsa": {
                "$ref": "#/components/schemas/Ayanamsa"
              },
              "division": {
                "type": "integer",
                "enum": [
                  1,
                  3,
                  4,
                  7,
                  9,
                  10,
                  12
                ]
              }
            },
            "required": [
              "birth",
              "ayanamsa",
              "division"
            ],
            "additionalProperties": false
          },
          "birth_utc": {
            "$ref": "#/components/schemas/UtcTimestamp"
          },
          "division": {
            "type": "integer",
            "enum": [
              1,
              3,
              4,
              7,
              9,
              10,
              12
            ]
          },
          "zodiac": {
            "type": "string",
            "const": "sidereal"
          },
          "ayanamsa": {
            "$ref": "#/components/schemas/Ayanamsa"
          },
          "ascendant": {
            "$ref": "#/components/schemas/VargaPosition"
          },
          "bodies": {
            "$ref": "#/components/schemas/VargaBodies"
          },
          "metadata": {
            "$ref": "#/components/schemas/VargasMetadata"
          }
        },
        "required": [
          "status",
          "type",
          "input",
          "birth_utc",
          "division",
          "zodiac",
          "ayanamsa",
          "ascendant",
          "bodies",
          "metadata"
        ],
        "additionalProperties": false
      },
      "DashaLord": {
        "type": "string",
        "enum": [
          "ketu",
          "venus",
          "sun",
          "moon",
          "mars",
          "rahu",
          "jupiter",
          "saturn",
          "mercury"
        ]
      },
      "DashaSubperiod": {
        "type": "object",
        "properties": {
          "lord": {
            "$ref": "#/components/schemas/DashaLord"
          },
          "years": {
            "type": "number",
            "exclusiveMinimum": 0
          },
          "start_utc": {
            "$ref": "#/components/schemas/UtcTimestamp"
          },
          "end_utc": {
            "$ref": "#/components/schemas/UtcTimestamp"
          },
          "active_at_birth": {
            "type": "boolean"
          }
        },
        "required": [
          "lord",
          "years",
          "start_utc",
          "end_utc",
          "active_at_birth"
        ],
        "additionalProperties": false
      },
      "DashaPeriod": {
        "type": "object",
        "properties": {
          "lord": {
            "$ref": "#/components/schemas/DashaLord"
          },
          "years": {
            "type": "integer",
            "enum": [
              7,
              20,
              6,
              10,
              18,
              16,
              19,
              17
            ]
          },
          "start_utc": {
            "$ref": "#/components/schemas/UtcTimestamp"
          },
          "end_utc": {
            "$ref": "#/components/schemas/UtcTimestamp"
          },
          "active_at_birth": {
            "type": "boolean"
          },
          "subperiods": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/DashaSubperiod"
            },
            "minItems": 9,
            "maxItems": 9
          }
        },
        "required": [
          "lord",
          "years",
          "start_utc",
          "end_utc",
          "active_at_birth",
          "subperiods"
        ],
        "additionalProperties": false
      },
      "VimshottariMetadata": {
        "type": "object",
        "properties": {
          "calculation_status": {
            "type": "string",
            "const": "experimental_beta"
          },
          "practitioner_review": {
            "type": "string",
            "const": "not_completed"
          },
          "frame": {
            "type": "string",
            "const": "apparent_geocentric_sidereal_retained_nutation"
          },
          "node_model": {
            "type": "string",
            "const": "mean_ascending_and_opposite_descending"
          },
          "classification_precision": {
            "type": "string",
            "const": "unrounded_binary64"
          },
          "interpretations": {
            "type": "boolean",
            "const": false
          },
          "year_length": {
            "type": "object",
            "properties": {
              "name": {
                "type": "string",
                "const": "julian_365_25_days"
              },
              "days": {
                "type": "number",
                "const": 365.25
              },
              "seconds": {
                "type": "number",
                "const": 31557600
              }
            },
            "required": [
              "name",
              "days",
              "seconds"
            ],
            "additionalProperties": false
          },
          "interval": {
            "type": "string",
            "const": "[start_utc,end_utc)"
          },
          "timestamp_resolution": {
            "type": "string",
            "const": "microsecond"
          },
          "birth_balance_rounding": {
            "type": "string",
            "const": "elapsed_duration_floored_to_microseconds"
          },
          "cycle_anchor": {
            "type": "string",
            "const": "start_of_birth_mahadasha"
          },
          "period_timestamps": {
            "type": "string",
            "const": "theoretical_offsets_may_extend_beyond_birth_ephemeris_window_no_ephemeris_extrapolation"
          }
        },
        "required": [
          "calculation_status",
          "practitioner_review",
          "frame",
          "node_model",
          "classification_precision",
          "interpretations",
          "year_length",
          "interval",
          "timestamp_resolution",
          "birth_balance_rounding",
          "cycle_anchor",
          "period_timestamps"
        ],
        "additionalProperties": false
      },
      "VimshottariResponse": {
        "oneOf": [
          {
            "$ref": "#/components/schemas/VimshottariResponseDepth2"
          },
          {
            "$ref": "#/components/schemas/VimshottariResponseDepth3"
          }
        ],
        "description": "Depth omitted/2 returns exactly the legacy response without any depth fields. Depth 3 requires input.depth=3, all 729 third-level periods, the third-level active birth lord and complete depth metadata; mixed or partial variants are invalid."
      },
      "CivilTimeInput": {
        "type": "object",
        "properties": {
          "date": {
            "$ref": "#/components/schemas/Date"
          },
          "time": {
            "$ref": "#/components/schemas/Time"
          },
          "timezone": {
            "type": "string",
            "minLength": 1,
            "maxLength": 100,
            "default": "UTC"
          }
        },
        "required": [
          "date",
          "time"
        ],
        "additionalProperties": false
      },
      "BetaMomentResult": {
        "type": "object",
        "properties": {
          "date": {
            "$ref": "#/components/schemas/Date"
          },
          "time": {
            "$ref": "#/components/schemas/Time"
          },
          "timezone": {
            "type": "string",
            "minLength": 1,
            "maxLength": 100,
            "default": "UTC",
            "description": "Valid IANA zone; UTC when omitted. Ambiguous and nonexistent civil times are rejected."
          },
          "lat": {
            "type": "number",
            "exclusiveMinimum": -90,
            "exclusiveMaximum": 90
          },
          "lon": {
            "type": "number",
            "minimum": -180,
            "maximum": 180
          }
        },
        "required": [
          "date",
          "time",
          "timezone",
          "lat",
          "lon"
        ],
        "additionalProperties": false
      },
      "PanchangRequest": {
        "type": "object",
        "properties": {
          "at": {
            "$ref": "#/components/schemas/PanchangMomentInput"
          },
          "ayanamsa": {
            "$ref": "#/components/schemas/Ayanamsa",
            "default": "lahiri"
          }
        },
        "required": [
          "at"
        ],
        "additionalProperties": false,
        "description": "Strict civil snapshot at the requested instant, not automatically at sunrise. Sidereal Lahiri default. Sunrise/sunset belong to the requested local civil date at elevation zero; ambiguous/nonexistent midnight boundaries return 400. No festivals, regional calendar or arbitrary event search. Latitude is restricted to inclusive [-88,88] for the verified solar-event solver domain. Returned solar candidates must satisfy a geometric crossing check; unsupported near-tangent geometry returns 400 instead of invented events. A solar event inside a recorded leap second returns 400 because its local civil timestamp cannot represent second 60."
      },
      "PanchangWeekday": {
        "type": "object",
        "properties": {
          "index": {
            "type": "integer",
            "minimum": 0,
            "maximum": 6
          },
          "name": {
            "type": "string",
            "enum": [
              "Sunday",
              "Monday",
              "Tuesday",
              "Wednesday",
              "Thursday",
              "Friday",
              "Saturday"
            ]
          }
        },
        "required": [
          "index",
          "name"
        ],
        "additionalProperties": false
      },
      "PanchangVara": {
        "anyOf": [
          {
            "type": "object",
            "properties": {
              "status": {
                "type": "string",
                "const": "available"
              },
              "index": {
                "type": "integer",
                "minimum": 0,
                "maximum": 6
              },
              "name": {
                "type": "string"
              },
              "start_utc": {
                "$ref": "#/components/schemas/UtcTimestamp"
              }
            },
            "required": [
              "status",
              "index",
              "name",
              "start_utc"
            ],
            "additionalProperties": false
          },
          {
            "type": "object",
            "properties": {
              "status": {
                "type": "string",
                "enum": [
                  "unavailable_no_sunrise",
                  "unavailable_previous_date"
                ]
              },
              "index": {
                "type": "null"
              },
              "name": {
                "type": "null"
              },
              "start_utc": {
                "type": "null"
              }
            },
            "required": [
              "status",
              "index",
              "name",
              "start_utc"
            ],
            "additionalProperties": false
          }
        ],
        "description": "Most recent sunrise on the current/previous civil date, Sunday index0. No extension through a polar season. Explicit nulls when the bounded sunrise cannot define vara."
      },
      "LocalSolarTimestamp": {
        "type": "string",
        "pattern": "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}\\.\\d{6}[+-]\\d{2}:\\d{2}(?::\\d{2})?$",
        "description": "ISO local timestamp with historical IANA offsets, which can include offset seconds (not always RFC3339). Use the adjacent utc field for interoperable instant parsing."
      },
      "SolarEvent": {
        "type": "object",
        "properties": {
          "utc": {
            "$ref": "#/components/schemas/UtcTimestamp"
          },
          "local": {
            "$ref": "#/components/schemas/LocalSolarTimestamp"
          }
        },
        "required": [
          "utc",
          "local"
        ],
        "additionalProperties": false
      },
      "PanchangSolarEvents": {
        "type": "object",
        "properties": {
          "local_date": {
            "$ref": "#/components/schemas/Date"
          },
          "timezone": {
            "type": "string",
            "minLength": 1,
            "maxLength": 100
          },
          "start_utc": {
            "$ref": "#/components/schemas/UtcTimestamp"
          },
          "end_utc": {
            "$ref": "#/components/schemas/UtcTimestamp"
          },
          "sunrise": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/SolarEvent"
            },
            "maxItems": 3
          },
          "sunset": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/SolarEvent"
            },
            "maxItems": 3
          },
          "sunrise_status": {
            "type": "string",
            "enum": [
              "occurs",
              "no_event"
            ]
          },
          "sunset_status": {
            "type": "string",
            "enum": [
              "occurs",
              "no_event"
            ]
          },
          "model": {
            "type": "string",
            "const": "usno_standard_50_arcminutes"
          },
          "horizon_degrees": {
            "type": "number",
            "const": -0.8333333333333334
          },
          "elevation_m": {
            "type": "number",
            "const": 0
          }
        },
        "required": [
          "local_date",
          "timezone",
          "start_utc",
          "end_utc",
          "sunrise",
          "sunset",
          "sunrise_status",
          "sunset_status",
          "model",
          "horizon_degrees",
          "elevation_m"
        ],
        "additionalProperties": false,
        "description": "Bounded [start_utc,end_utc) local civil day; 23/25-hour DST days supported. Standard USNO -50 arcminute horizon at elevation 0, not Hindu-geocentric sunrise. Polar no-event results remain empty arrays; no transit-as-sunrise fallback."
      },
      "PanchangMetadata": {
        "type": "object",
        "properties": {
          "calculation_status": {
            "type": "string",
            "const": "experimental_beta"
          },
          "practitioner_review": {
            "type": "string",
            "const": "not_completed"
          },
          "classification_precision": {
            "type": "string",
            "const": "unrounded_binary64"
          },
          "classification_time": {
            "type": "string",
            "const": "requested_instant"
          },
          "frame": {
            "type": "string",
            "const": "apparent_geocentric_sidereal_retained_nutation"
          },
          "intervals": {
            "type": "string",
            "const": "half_open"
          },
          "weekday_basis": {
            "type": "string",
            "const": "local_civil_midnight"
          },
          "vara_basis": {
            "type": "string",
            "const": "most_recent_sunrise_on_current_or_previous_civil_date"
          },
          "regional_calendar": {
            "type": "boolean",
            "const": false
          },
          "festivals": {
            "type": "boolean",
            "const": false
          }
        },
        "required": [
          "calculation_status",
          "practitioner_review",
          "classification_precision",
          "classification_time",
          "frame",
          "intervals",
          "weekday_basis",
          "vara_basis",
          "regional_calendar",
          "festivals"
        ],
        "additionalProperties": false
      },
      "PanchangResponse": {
        "type": "object",
        "properties": {
          "status": {
            "type": "string",
            "const": "beta"
          },
          "type": {
            "type": "string",
            "const": "panchang"
          },
          "input": {
            "type": "object",
            "properties": {
              "at": {
                "$ref": "#/components/schemas/PanchangMomentResult"
              },
              "ayanamsa": {
                "$ref": "#/components/schemas/Ayanamsa"
              }
            },
            "required": [
              "at",
              "ayanamsa"
            ],
            "additionalProperties": false
          },
          "at_utc": {
            "$ref": "#/components/schemas/UtcTimestamp"
          },
          "zodiac": {
            "type": "string",
            "const": "sidereal"
          },
          "ayanamsa": {
            "$ref": "#/components/schemas/Ayanamsa"
          },
          "longitudes": {
            "type": "object",
            "properties": {
              "sun_tropical": {
                "type": "number",
                "minimum": 0,
                "exclusiveMaximum": 360
              },
              "moon_tropical": {
                "type": "number",
                "minimum": 0,
                "exclusiveMaximum": 360
              },
              "sun_sidereal": {
                "type": "number",
                "minimum": 0,
                "exclusiveMaximum": 360
              },
              "moon_sidereal": {
                "type": "number",
                "minimum": 0,
                "exclusiveMaximum": 360
              }
            },
            "required": [
              "sun_tropical",
              "moon_tropical",
              "sun_sidereal",
              "moon_sidereal"
            ],
            "additionalProperties": false
          },
          "tithi": {
            "type": "object",
            "properties": {
              "index": {
                "type": "integer",
                "minimum": 1,
                "maximum": 30
              },
              "name": {
                "type": "string"
              },
              "paksha": {
                "type": "string",
                "enum": [
                  "shukla",
                  "krishna"
                ]
              },
              "paksha_index": {
                "type": "integer",
                "minimum": 1,
                "maximum": 15
              },
              "elongation_degrees": {
                "type": "number",
                "minimum": 0,
                "exclusiveMaximum": 360
              }
            },
            "required": [
              "index",
              "name",
              "paksha",
              "paksha_index",
              "elongation_degrees"
            ],
            "additionalProperties": false
          },
          "nakshatra": {
            "type": "object",
            "properties": {
              "index": {
                "type": "integer",
                "minimum": 1,
                "maximum": 27
              },
              "name": {
                "type": "string"
              },
              "lord": {
                "$ref": "#/components/schemas/DashaLord"
              },
              "pada": {
                "type": "integer",
                "minimum": 1,
                "maximum": 4
              },
              "sidereal_longitude": {
                "type": "number",
                "minimum": 0,
                "exclusiveMaximum": 360
              }
            },
            "required": [
              "index",
              "name",
              "lord",
              "pada",
              "sidereal_longitude"
            ],
            "additionalProperties": false
          },
          "yoga": {
            "type": "object",
            "properties": {
              "index": {
                "type": "integer",
                "minimum": 1,
                "maximum": 27
              },
              "name": {
                "type": "string"
              },
              "sum_degrees": {
                "type": "number",
                "minimum": 0,
                "exclusiveMaximum": 360
              }
            },
            "required": [
              "index",
              "name",
              "sum_degrees"
            ],
            "additionalProperties": false
          },
          "karana": {
            "type": "object",
            "properties": {
              "index": {
                "type": "integer",
                "minimum": 1,
                "maximum": 60
              },
              "name": {
                "type": "string"
              },
              "kind": {
                "type": "string",
                "enum": [
                  "fixed",
                  "repeating"
                ]
              }
            },
            "required": [
              "index",
              "name",
              "kind"
            ],
            "additionalProperties": false
          },
          "weekday": {
            "$ref": "#/components/schemas/PanchangWeekday"
          },
          "vara": {
            "$ref": "#/components/schemas/PanchangVara"
          },
          "solar_events": {
            "$ref": "#/components/schemas/PanchangSolarEvents"
          },
          "metadata": {
            "$ref": "#/components/schemas/PanchangMetadata"
          }
        },
        "required": [
          "status",
          "type",
          "input",
          "at_utc",
          "zodiac",
          "ayanamsa",
          "longitudes",
          "tithi",
          "nakshatra",
          "yoga",
          "karana",
          "weekday",
          "vara",
          "solar_events",
          "metadata"
        ],
        "additionalProperties": false
      },
      "VargaSvgRequest": {
        "type": "object",
        "properties": {
          "birth": {
            "$ref": "#/components/schemas/BetaBirthInput"
          },
          "ayanamsa": {
            "$ref": "#/components/schemas/Ayanamsa",
            "default": "lahiri"
          },
          "division": {
            "type": "integer",
            "enum": [
              1,
              3,
              4,
              7,
              9,
              10,
              12
            ],
            "default": 1
          },
          "layout": {
            "type": "string",
            "enum": [
              "north_indian",
              "south_indian"
            ],
            "default": "north_indian"
          },
          "theme": {
            "type": "string",
            "enum": [
              "light",
              "dark"
            ],
            "default": "dark"
          }
        },
        "required": [
          "birth"
        ],
        "additionalProperties": false,
        "description": "Original sidereal D1/D3/D4/D7/D9/D10/D12 sign-placement SVG. Default division1 differs from /vargas default9. North fixes houses; South fixes signs. No supplied markup/chart/URL, and no bhava-chalit, outer planets or interpretation controls."
      },
      "VargaSvgResponse": {
        "type": "object",
        "properties": {
          "status": {
            "type": "string",
            "const": "beta"
          },
          "type": {
            "type": "string",
            "const": "varga_svg"
          },
          "svg": {
            "type": "string",
            "minLength": 1,
            "maxLength": 131072,
            "description": "Original static SVG source inside JSON, capped at 128 KiB UTF-8; display as an image, not arbitrary HTML."
          },
          "layout": {
            "type": "string",
            "enum": [
              "north_indian",
              "south_indian"
            ]
          },
          "theme": {
            "type": "string",
            "enum": [
              "light",
              "dark"
            ]
          },
          "chart": {
            "$ref": "#/components/schemas/VargasResponse"
          },
          "metadata": {
            "type": "object",
            "properties": {
              "renderer": {
                "type": "string",
                "const": "astroapi-original-varga-svg-v1"
              },
              "layout_size": {
                "type": "string",
                "const": "1200x1420"
              },
              "position_source": {
                "type": "string",
                "const": "unrounded-vargas-response"
              },
              "house_convention": {
                "type": "string",
                "const": "signs_from_divisional_ascendant"
              },
              "interpretations": {
                "type": "boolean",
                "const": false
              }
            },
            "required": [
              "renderer",
              "layout_size",
              "position_source",
              "house_convention",
              "interpretations"
            ],
            "additionalProperties": false
          }
        },
        "required": [
          "status",
          "type",
          "svg",
          "layout",
          "theme",
          "chart",
          "metadata"
        ],
        "additionalProperties": false
      },
      "CompositeRequest": {
        "type": "object",
        "properties": {
          "personA": {
            "$ref": "#/components/schemas/BetaBirthInput"
          },
          "personB": {
            "$ref": "#/components/schemas/BetaBirthInput"
          },
          "zodiac": {
            "$ref": "#/components/schemas/Zodiac",
            "default": "tropical"
          },
          "ayanamsa": {
            "$ref": "#/components/schemas/Ayanamsa",
            "default": "lahiri"
          },
          "house_system": {
            "type": "string",
            "enum": [
              "equal",
              "whole_sign"
            ],
            "default": "equal"
          }
        },
        "required": [
          "personA",
          "personB"
        ],
        "additionalProperties": false,
        "description": "Shortest-arc midpoint composite. Antipodal/near-antipodal points reject; no arbitrary flip. Houses are synthetic Equal/Whole Sign from midpoint Ascendant, not physical geographic cusps. Not a Davison chart; no Placidus, node, speed or interpretation option."
      },
      "SecondaryProgressionsRequest": {
        "type": "object",
        "properties": {
          "birth": {
            "$ref": "#/components/schemas/BetaBirthInput"
          },
          "target": {
            "$ref": "#/components/schemas/CivilTimeInput"
          },
          "zodiac": {
            "$ref": "#/components/schemas/Zodiac",
            "default": "tropical"
          },
          "ayanamsa": {
            "$ref": "#/components/schemas/Ayanamsa",
            "default": "lahiri"
          },
          "house_system": {
            "type": "string",
            "enum": [
              "equal",
              "whole_sign"
            ],
            "default": "equal"
          }
        },
        "required": [
          "birth",
          "target"
        ],
        "additionalProperties": false,
        "description": "Day-for-year secondary-progressed PLANETS only. Required target>=birth instant; all civil dates 1900–2050, times known, UTC defaults and DST rejection. Fixed365.2421904-day year in TT. Returned angles/houses are explicitly natal context, never progressed. No progressed angles, houses, aspects, nodes, speed or arbitrary year model."
      },
      "WesternPoint": {
        "type": "object",
        "properties": {
          "lon": {
            "type": "number",
            "minimum": 0,
            "exclusiveMaximum": 360
          },
          "sign": {
            "$ref": "#/components/schemas/Sign"
          },
          "deg_in_sign": {
            "type": "number",
            "minimum": 0,
            "exclusiveMaximum": 30
          }
        },
        "required": [
          "lon",
          "sign",
          "deg_in_sign"
        ],
        "additionalProperties": false
      },
      "WesternPlanets": {
        "type": "object",
        "properties": {
          "Sun": {
            "$ref": "#/components/schemas/WesternPoint"
          },
          "Moon": {
            "$ref": "#/components/schemas/WesternPoint"
          },
          "Mercury": {
            "$ref": "#/components/schemas/WesternPoint"
          },
          "Venus": {
            "$ref": "#/components/schemas/WesternPoint"
          },
          "Mars": {
            "$ref": "#/components/schemas/WesternPoint"
          },
          "Jupiter": {
            "$ref": "#/components/schemas/WesternPoint"
          },
          "Saturn": {
            "$ref": "#/components/schemas/WesternPoint"
          },
          "Uranus": {
            "$ref": "#/components/schemas/WesternPoint"
          },
          "Neptune": {
            "$ref": "#/components/schemas/WesternPoint"
          },
          "Pluto": {
            "$ref": "#/components/schemas/WesternPoint"
          }
        },
        "required": [
          "Sun",
          "Moon",
          "Mercury",
          "Venus",
          "Mars",
          "Jupiter",
          "Saturn",
          "Uranus",
          "Neptune",
          "Pluto"
        ],
        "additionalProperties": false
      },
      "WesternAngles": {
        "type": "object",
        "properties": {
          "ascendant": {
            "type": "number",
            "minimum": 0,
            "exclusiveMaximum": 360
          },
          "mc": {
            "type": "number",
            "minimum": 0,
            "exclusiveMaximum": 360
          }
        },
        "required": [
          "ascendant",
          "mc"
        ],
        "additionalProperties": false
      },
      "WesternHouses": {
        "type": "object",
        "properties": {
          "system": {
            "type": "string",
            "enum": [
              "equal",
              "whole_sign"
            ]
          },
          "cusps": {
            "type": "object",
            "properties": {
              "1": {
                "type": "number",
                "minimum": 0,
                "exclusiveMaximum": 360
              },
              "2": {
                "type": "number",
                "minimum": 0,
                "exclusiveMaximum": 360
              },
              "3": {
                "type": "number",
                "minimum": 0,
                "exclusiveMaximum": 360
              },
              "4": {
                "type": "number",
                "minimum": 0,
                "exclusiveMaximum": 360
              },
              "5": {
                "type": "number",
                "minimum": 0,
                "exclusiveMaximum": 360
              },
              "6": {
                "type": "number",
                "minimum": 0,
                "exclusiveMaximum": 360
              },
              "7": {
                "type": "number",
                "minimum": 0,
                "exclusiveMaximum": 360
              },
              "8": {
                "type": "number",
                "minimum": 0,
                "exclusiveMaximum": 360
              },
              "9": {
                "type": "number",
                "minimum": 0,
                "exclusiveMaximum": 360
              },
              "10": {
                "type": "number",
                "minimum": 0,
                "exclusiveMaximum": 360
              },
              "11": {
                "type": "number",
                "minimum": 0,
                "exclusiveMaximum": 360
              },
              "12": {
                "type": "number",
                "minimum": 0,
                "exclusiveMaximum": 360
              }
            },
            "required": [
              "1",
              "2",
              "3",
              "4",
              "5",
              "6",
              "7",
              "8",
              "9",
              "10",
              "11",
              "12"
            ],
            "additionalProperties": false
          }
        },
        "required": [
          "system",
          "cusps"
        ],
        "additionalProperties": false
      },
      "CompositeMetadata": {
        "type": "object",
        "properties": {
          "physical_chart": {
            "type": "boolean",
            "const": false
          },
          "source_frame": {
            "type": "string",
            "const": "apparent-geocentric-ecliptic-of-each-birth-date"
          },
          "position_precision": {
            "type": "string",
            "const": "unrounded-binary64"
          },
          "angle_policy": {
            "type": "string",
            "const": "independent-shortest-arc-ascendant-and-mc-midpoints"
          },
          "house_policy": {
            "type": "string",
            "enum": [
              "synthetic-equal-from-midpoint-ascendant",
              "synthetic-whole-sign-from-midpoint-ascendant"
            ]
          },
          "antipodal_policy": {
            "type": "string",
            "const": "reject-within-1e-10-degrees"
          },
          "inner_planet_policy": {
            "type": "string",
            "const": "no-180-degree-flips"
          },
          "sidereal_policy": {
            "type": "string",
            "enum": [
              "per-birth-date-ayanamsa-before-midpoint",
              "not-applicable"
            ]
          },
          "aspect_policy": {
            "type": "string",
            "const": "existing-natal-longitude-orbs"
          },
          "nodes": {
            "type": "string",
            "const": "not-included"
          },
          "interpretations": {
            "type": "boolean",
            "const": false
          },
          "practitioner_review": {
            "type": "string",
            "const": "not-completed"
          }
        },
        "required": [
          "physical_chart",
          "source_frame",
          "position_precision",
          "angle_policy",
          "house_policy",
          "antipodal_policy",
          "inner_planet_policy",
          "sidereal_policy",
          "aspect_policy",
          "nodes",
          "interpretations",
          "practitioner_review"
        ],
        "additionalProperties": false
      },
      "CompositeResponse": {
        "type": "object",
        "properties": {
          "type": {
            "type": "string",
            "const": "composite"
          },
          "status": {
            "type": "string",
            "const": "beta"
          },
          "method": {
            "type": "string",
            "const": "shortest_arc_midpoint"
          },
          "input": {
            "type": "object",
            "properties": {
              "personA": {
                "$ref": "#/components/schemas/BetaMomentResult"
              },
              "personB": {
                "$ref": "#/components/schemas/BetaMomentResult"
              },
              "zodiac": {
                "$ref": "#/components/schemas/Zodiac"
              },
              "ayanamsa": {
                "$ref": "#/components/schemas/AyanamsaResult"
              },
              "house_system": {
                "type": "string",
                "enum": [
                  "equal",
                  "whole_sign"
                ]
              }
            },
            "required": [
              "personA",
              "personB",
              "zodiac",
              "ayanamsa",
              "house_system"
            ],
            "additionalProperties": false
          },
          "source_utc": {
            "type": "object",
            "properties": {
              "personA": {
                "$ref": "#/components/schemas/UtcTimestamp"
              },
              "personB": {
                "$ref": "#/components/schemas/UtcTimestamp"
              }
            },
            "required": [
              "personA",
              "personB"
            ],
            "additionalProperties": false
          },
          "zodiac": {
            "$ref": "#/components/schemas/Zodiac"
          },
          "ayanamsa": {
            "$ref": "#/components/schemas/AyanamsaResult"
          },
          "planets": {
            "$ref": "#/components/schemas/WesternPlanets"
          },
          "angles": {
            "$ref": "#/components/schemas/WesternAngles"
          },
          "houses": {
            "$ref": "#/components/schemas/WesternHouses"
          },
          "aspects": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/NatalAspect"
            }
          },
          "metadata": {
            "$ref": "#/components/schemas/CompositeMetadata"
          }
        },
        "required": [
          "type",
          "status",
          "method",
          "input",
          "source_utc",
          "zodiac",
          "ayanamsa",
          "planets",
          "angles",
          "houses",
          "aspects",
          "metadata"
        ],
        "additionalProperties": false
      },
      "ProgressedUtcTimestamp": {
        "type": "string",
        "pattern": "^\\d{4}-\\d{2}-\\d{2}T(?:[01]\\d|2[0-3]):[0-5]\\d:(?:[0-5]\\d|60)\\.\\d{6}Z$",
        "description": "Derived UTC instant with six fractional digits. Second 60 is preserved during an actual recorded leap second; JavaScript Date and Python datetime cannot directly parse that value. Use progressed_tt_jd for display/reference only; no single-JD round-trip was used in the calculation."
      },
      "SecondaryProgressionsMetadata": {
        "type": "object",
        "properties": {
          "source_frame": {
            "type": "string",
            "const": "apparent-geocentric-ecliptic-of-each-ephemeris-date"
          },
          "position_precision": {
            "type": "string",
            "const": "unrounded-binary64"
          },
          "year_convention": {
            "type": "string",
            "const": "fixed-365.2421904-days-not-calendar-birthdays"
          },
          "time_policy": {
            "type": "string",
            "const": "uniform-TT-elapsed-days-divided-by-year-days"
          },
          "timescale_data": {
            "type": "string",
            "const": "bundled-skyfield"
          },
          "utc_output": {
            "type": "string",
            "const": "leap-second-aware-ISO-8601"
          },
          "progressed_angles": {
            "type": "string",
            "const": "not-calculated"
          },
          "progressed_houses": {
            "type": "string",
            "const": "not-calculated"
          },
          "angle_policy": {
            "type": "string",
            "const": "fixed-natal-context-only"
          },
          "location_policy": {
            "type": "string",
            "const": "birth-location-for-natal-context-only"
          },
          "sidereal_policy": {
            "type": "string",
            "enum": [
              "per-ephemeris-date-ayanamsa",
              "not-applicable"
            ]
          },
          "aspects": {
            "type": "string",
            "const": "not-included"
          },
          "nodes": {
            "type": "string",
            "const": "not-included"
          },
          "interpretations": {
            "type": "boolean",
            "const": false
          },
          "practitioner_review": {
            "type": "string",
            "const": "not-completed"
          }
        },
        "required": [
          "source_frame",
          "position_precision",
          "year_convention",
          "time_policy",
          "timescale_data",
          "utc_output",
          "progressed_angles",
          "progressed_houses",
          "angle_policy",
          "location_policy",
          "sidereal_policy",
          "aspects",
          "nodes",
          "interpretations",
          "practitioner_review"
        ],
        "additionalProperties": false
      },
      "SecondaryProgressionsResponse": {
        "type": "object",
        "properties": {
          "type": {
            "type": "string",
            "const": "secondary_progressions"
          },
          "status": {
            "type": "string",
            "const": "beta"
          },
          "method": {
            "type": "string",
            "const": "day_for_year"
          },
          "input": {
            "type": "object",
            "properties": {
              "birth": {
                "$ref": "#/components/schemas/BetaMomentResult"
              },
              "target": {
                "type": "object",
                "properties": {
                  "date": {
                    "$ref": "#/components/schemas/Date"
                  },
                  "time": {
                    "$ref": "#/components/schemas/Time"
                  },
                  "timezone": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 100
                  }
                },
                "required": [
                  "date",
                  "time",
                  "timezone"
                ],
                "additionalProperties": false
              },
              "zodiac": {
                "$ref": "#/components/schemas/Zodiac"
              },
              "ayanamsa": {
                "$ref": "#/components/schemas/AyanamsaResult"
              },
              "house_system": {
                "type": "string",
                "enum": [
                  "equal",
                  "whole_sign"
                ]
              }
            },
            "required": [
              "birth",
              "target",
              "zodiac",
              "ayanamsa",
              "house_system"
            ],
            "additionalProperties": false
          },
          "birth_utc": {
            "$ref": "#/components/schemas/UtcTimestamp"
          },
          "target_utc": {
            "$ref": "#/components/schemas/UtcTimestamp"
          },
          "progressed_utc": {
            "$ref": "#/components/schemas/ProgressedUtcTimestamp"
          },
          "timing": {
            "type": "object",
            "properties": {
              "year_days": {
                "type": "number",
                "const": 365.2421904
              },
              "elapsed_years": {
                "type": "number",
                "minimum": 0
              },
              "progressed_days": {
                "type": "number",
                "minimum": 0
              },
              "time_scale": {
                "type": "string",
                "const": "TT"
              },
              "progressed_tt_jd": {
                "type": "number"
              }
            },
            "required": [
              "year_days",
              "elapsed_years",
              "progressed_days",
              "time_scale",
              "progressed_tt_jd"
            ],
            "additionalProperties": false
          },
          "zodiac": {
            "$ref": "#/components/schemas/Zodiac"
          },
          "ayanamsa": {
            "$ref": "#/components/schemas/AyanamsaResult"
          },
          "progressed_planets": {
            "$ref": "#/components/schemas/WesternPlanets"
          },
          "natal_context": {
            "type": "object",
            "properties": {
              "planets": {
                "$ref": "#/components/schemas/WesternPlanets"
              },
              "angles": {
                "$ref": "#/components/schemas/WesternAngles"
              },
              "houses": {
                "$ref": "#/components/schemas/WesternHouses"
              }
            },
            "required": [
              "planets",
              "angles",
              "houses"
            ],
            "additionalProperties": false
          },
          "metadata": {
            "$ref": "#/components/schemas/SecondaryProgressionsMetadata"
          }
        },
        "required": [
          "type",
          "status",
          "method",
          "input",
          "birth_utc",
          "target_utc",
          "progressed_utc",
          "timing",
          "zodiac",
          "ayanamsa",
          "progressed_planets",
          "natal_context",
          "metadata"
        ],
        "additionalProperties": false
      },
      "PanchangMomentInput": {
        "type": "object",
        "properties": {
          "date": {
            "$ref": "#/components/schemas/Date"
          },
          "time": {
            "$ref": "#/components/schemas/Time"
          },
          "timezone": {
            "type": "string",
            "minLength": 1,
            "maxLength": 100,
            "default": "UTC",
            "description": "Valid IANA zone; UTC when omitted. Ambiguous and nonexistent civil times are rejected."
          },
          "lat": {
            "type": "number",
            "minimum": -88,
            "maximum": 88,
            "description": "Panchang beta sunrise admission is limited to inclusive [-88,88] latitude."
          },
          "lon": {
            "type": "number",
            "minimum": -180,
            "maximum": 180
          }
        },
        "required": [
          "date",
          "time",
          "lat",
          "lon"
        ],
        "additionalProperties": false,
        "description": "Strict nested birth input; no unknown properties, nulls, booleans or numeric strings. Known civil time required; semantic date/DST/undefined-angle validation occurs on the server."
      },
      "PanchangMomentResult": {
        "type": "object",
        "properties": {
          "date": {
            "$ref": "#/components/schemas/Date"
          },
          "time": {
            "$ref": "#/components/schemas/Time"
          },
          "timezone": {
            "type": "string",
            "minLength": 1,
            "maxLength": 100,
            "default": "UTC",
            "description": "Valid IANA zone; UTC when omitted. Ambiguous and nonexistent civil times are rejected."
          },
          "lat": {
            "type": "number",
            "minimum": -88,
            "maximum": 88,
            "description": "Panchang beta sunrise admission is limited to inclusive [-88,88] latitude."
          },
          "lon": {
            "type": "number",
            "minimum": -180,
            "maximum": 180
          }
        },
        "required": [
          "date",
          "time",
          "timezone",
          "lat",
          "lon"
        ],
        "additionalProperties": false,
        "description": "Strict nested birth input; no unknown properties, nulls, booleans or numeric strings. Known civil time required; semantic date/DST/undefined-angle validation occurs on the server."
      },
      "LunarNodesRequest": {
        "type": "object",
        "properties": {
          "at": {
            "$ref": "#/components/schemas/CivilTimeInput"
          },
          "zodiac": {
            "$ref": "#/components/schemas/Zodiac",
            "default": "tropical"
          },
          "ayanamsa": {
            "$ref": "#/components/schemas/Ayanamsa",
            "default": "lahiri"
          }
        },
        "required": [
          "at"
        ],
        "additionalProperties": false,
        "description": "Beta mean and distinct geometric osculating lunar nodes at a known civil instant. No coordinates, user ephemeris, chart input or URLs. Civil dates 1900–2050; timezone conversion can cross the UTC year boundary. Tropical default; optional sidereal mean P03 ayanamsa subtraction, with true-model nutation retained. Existing chart/timeline node fields are unchanged."
      },
      "LunarNodePosition": {
        "type": "object",
        "properties": {
          "longitude": {
            "type": "number",
            "minimum": 0,
            "exclusiveMaximum": 360
          },
          "sign": {
            "$ref": "#/components/schemas/Sign"
          },
          "deg_in_sign": {
            "type": "number",
            "minimum": 0,
            "exclusiveMaximum": 30
          },
          "tropical_longitude": {
            "type": "number",
            "minimum": 0,
            "exclusiveMaximum": 360
          }
        },
        "required": [
          "longitude",
          "sign",
          "deg_in_sign",
          "tropical_longitude"
        ],
        "additionalProperties": false,
        "description": "Four-decimal degrees are serialization resolution, not claimed physical accuracy. Longitude carries normalize before sign assignment."
      },
      "MeanLunarNodePair": {
        "type": "object",
        "properties": {
          "model": {
            "type": "string",
            "const": "meeus-mean-node"
          },
          "frame": {
            "type": "string",
            "const": "mean-ecliptic-equinox-of-date"
          },
          "north": {
            "$ref": "#/components/schemas/LunarNodePosition"
          },
          "south": {
            "$ref": "#/components/schemas/LunarNodePosition"
          }
        },
        "required": [
          "model",
          "frame",
          "north",
          "south"
        ],
        "additionalProperties": false
      },
      "TrueLunarNodePair": {
        "type": "object",
        "properties": {
          "model": {
            "type": "string",
            "const": "de421-osculating-node"
          },
          "frame": {
            "type": "string",
            "const": "true-ecliptic-equinox-of-date"
          },
          "north": {
            "$ref": "#/components/schemas/LunarNodePosition"
          },
          "south": {
            "$ref": "#/components/schemas/LunarNodePosition"
          }
        },
        "required": [
          "model",
          "frame",
          "north",
          "south"
        ],
        "additionalProperties": false
      },
      "LunarNodesMetadata": {
        "type": "object",
        "properties": {
          "ephemeris": {
            "type": "string",
            "const": "JPL DE421"
          },
          "mean_source": {
            "type": "string",
            "const": "existing engine/nodes.py TT mean-node polynomial"
          },
          "true_source": {
            "type": "string",
            "const": "same-instant geometric Moon-minus-Earth position and inertial velocity"
          },
          "true_geometry": {
            "type": "string",
            "const": "ascending intersection of instantaneous orbital plane and date ecliptic"
          },
          "corrections": {
            "type": "string",
            "const": "no light time, aberration, observer location, or rotating-frame velocity term"
          },
          "frame_policy": {
            "type": "string",
            "const": "frame names identify tropical source axes before any sidereal subtraction"
          },
          "sidereal_policy": {
            "type": "string",
            "const": "existing mean IAU 2006/P03 ayanamsa subtraction; true-model nutation retained"
          },
          "legacy_compatibility": {
            "type": "string",
            "const": "existing chart true equals mean; chart nodes and timeline Rahu/Ketu are unchanged"
          },
          "limitations": {
            "type": "string",
            "const": "osculating true is an instantaneous model, not an eclipse/event prediction or universal true-node convention"
          },
          "precision": {
            "type": "string",
            "const": "four decimal degrees are output resolution, not an accuracy guarantee"
          }
        },
        "required": [
          "ephemeris",
          "mean_source",
          "true_source",
          "true_geometry",
          "corrections",
          "frame_policy",
          "sidereal_policy",
          "legacy_compatibility",
          "limitations",
          "precision"
        ],
        "additionalProperties": false
      },
      "NormalizedCivilTime": {
        "type": "object",
        "properties": {
          "date": {
            "$ref": "#/components/schemas/Date"
          },
          "time": {
            "$ref": "#/components/schemas/Time"
          },
          "timezone": {
            "type": "string",
            "minLength": 1,
            "maxLength": 100,
            "default": "UTC"
          }
        },
        "required": [
          "date",
          "time",
          "timezone"
        ],
        "additionalProperties": false
      },
      "LunarNodesResponse": {
        "type": "object",
        "properties": {
          "type": {
            "type": "string",
            "const": "lunar_nodes"
          },
          "status": {
            "type": "string",
            "const": "beta"
          },
          "at": {
            "type": "object",
            "properties": {
              "date": {
                "$ref": "#/components/schemas/Date"
              },
              "time": {
                "$ref": "#/components/schemas/Time"
              },
              "timezone": {
                "type": "string",
                "minLength": 1,
                "maxLength": 100,
                "default": "UTC"
              },
              "utc": {
                "$ref": "#/components/schemas/UtcTimestamp"
              }
            },
            "required": [
              "date",
              "time",
              "timezone",
              "utc"
            ],
            "additionalProperties": false
          },
          "zodiac": {
            "$ref": "#/components/schemas/Zodiac"
          },
          "ayanamsa": {
            "$ref": "#/components/schemas/AyanamsaResult"
          },
          "mean": {
            "$ref": "#/components/schemas/MeanLunarNodePair"
          },
          "true": {
            "$ref": "#/components/schemas/TrueLunarNodePair"
          },
          "metadata": {
            "$ref": "#/components/schemas/LunarNodesMetadata"
          }
        },
        "required": [
          "type",
          "status",
          "at",
          "zodiac",
          "ayanamsa",
          "mean",
          "true",
          "metadata"
        ],
        "additionalProperties": false
      },
      "ReturnLocation": {
        "type": "object",
        "properties": {
          "lat": {
            "type": "number",
            "exclusiveMinimum": -90,
            "exclusiveMaximum": 90
          },
          "lon": {
            "type": "number",
            "minimum": -180,
            "maximum": 180
          }
        },
        "required": [
          "lat",
          "lon"
        ],
        "additionalProperties": false
      },
      "ReturnsRequest": {
        "type": "object",
        "properties": {
          "birth": {
            "$ref": "#/components/schemas/BetaBirthInput"
          },
          "body": {
            "type": "string",
            "enum": [
              "sun",
              "moon"
            ]
          },
          "after": {
            "$ref": "#/components/schemas/CivilTimeInput"
          },
          "zodiac": {
            "$ref": "#/components/schemas/Zodiac",
            "default": "tropical"
          },
          "ayanamsa": {
            "$ref": "#/components/schemas/Ayanamsa",
            "default": "lahiri"
          },
          "house_system": {
            "type": "string",
            "enum": [
              "equal",
              "whole_sign"
            ],
            "default": "equal"
          },
          "location": {
            "$ref": "#/components/schemas/ReturnLocation"
          }
        },
        "required": [
          "birth",
          "body",
          "after"
        ],
        "additionalProperties": false,
        "description": "Beta first solar or lunar longitude return beyond after +1 millisecond, subject to the documented numerical equality allowance, followed by a physical chart at that root. after may precede birth. Both civil dates 1900–2050; birth UTC and the complete fixed search window (Sun 370 TT days, Moon 32 TT days) must stay in UTC 1900–2050; no window clipping. Tropical/Equal defaults. Sidereal uses each ephemeris date's mean P03 ayanamsa with nutation retained. Return location defaults to birth coordinates and changes houses, not the return instant. No Placidus, arbitrary bodies/targets/search tolerances, cycles or predictions."
      },
      "ReturnUtcTimestamp": {
        "type": "string",
        "pattern": "^\\d{4}-\\d{2}-\\d{2}T(?:[01]\\d|2[0-3]):[0-5]\\d:(?:[0-5]\\d|60)\\.\\d{6}Z$",
        "description": "Root or bracket UTC instant with six fractional digits; actual leap second60 is preserved. JavaScript Date/Python datetime cannot directly parse second60. Numerical subsecond tolerance is not physical event-time accuracy. The single TT JD is a display/reference field; the chart is calculated using the two-part root Time object."
      },
      "ReturnSearch": {
        "type": "object",
        "properties": {
          "time_scale": {
            "type": "string",
            "const": "TT"
          },
          "max_days": {
            "type": "integer",
            "enum": [
              370,
              32
            ]
          },
          "sample_step_days": {
            "type": "number",
            "enum": [
              2,
              0.25
            ]
          },
          "samples": {
            "type": "integer",
            "enum": [
              186,
              129
            ]
          },
          "iterations": {
            "type": "integer",
            "minimum": 1,
            "maximum": 48
          },
          "max_iterations": {
            "type": "number",
            "const": 48
          },
          "start_exclusion_seconds": {
            "type": "number",
            "const": 0.001
          },
          "root_tt_jd": {
            "type": "number"
          },
          "residual_deg": {
            "type": "number",
            "minimum": -1e-7,
            "maximum": 1e-7
          },
          "angular_tolerance_deg": {
            "type": "number",
            "const": 1e-7
          },
          "time_tolerance_seconds": {
            "type": "number",
            "const": 0.001
          },
          "bracket": {
            "type": "object",
            "properties": {
              "start_utc": {
                "$ref": "#/components/schemas/ReturnUtcTimestamp"
              },
              "end_utc": {
                "$ref": "#/components/schemas/ReturnUtcTimestamp"
              },
              "width_seconds": {
                "type": "number",
                "exclusiveMinimum": 0,
                "maximum": 0.001
              }
            },
            "required": [
              "start_utc",
              "end_utc",
              "width_seconds"
            ],
            "additionalProperties": false
          }
        },
        "required": [
          "time_scale",
          "max_days",
          "sample_step_days",
          "samples",
          "iterations",
          "max_iterations",
          "start_exclusion_seconds",
          "root_tt_jd",
          "residual_deg",
          "angular_tolerance_deg",
          "time_tolerance_seconds",
          "bracket"
        ],
        "additionalProperties": false
      },
      "ReturnChart": {
        "type": "object",
        "properties": {
          "status": {
            "const": "ok"
          },
          "zodiac": {
            "$ref": "#/components/schemas/Zodiac"
          },
          "ayanamsa": {
            "$ref": "#/components/schemas/AyanamsaResult"
          },
          "planets": {
            "$ref": "#/components/schemas/Planets"
          },
          "houses": {
            "type": "object",
            "properties": {
              "ascendant": {
                "type": "number",
                "minimum": 0,
                "exclusiveMaximum": 360
              },
              "mc": {
                "type": "number",
                "minimum": 0,
                "exclusiveMaximum": 360
              },
              "systems": {
                "type": "object",
                "properties": {
                  "equal": {
                    "$ref": "#/components/schemas/HouseSystem"
                  },
                  "whole_sign": {
                    "$ref": "#/components/schemas/HouseSystem"
                  }
                },
                "required": [],
                "additionalProperties": false,
                "minProperties": 1,
                "maxProperties": 1
              },
              "metadata": {
                "type": "object",
                "properties": {
                  "zodiac": {
                    "$ref": "#/components/schemas/Zodiac"
                  },
                  "ayanamsa": {
                    "$ref": "#/components/schemas/AyanamsaResult"
                  }
                },
                "required": [
                  "zodiac",
                  "ayanamsa"
                ],
                "additionalProperties": true
              }
            },
            "required": [
              "ascendant",
              "mc",
              "systems",
              "metadata"
            ],
            "additionalProperties": true,
            "description": "Physical return-location houses; exactly one selected Equal/Whole Sign system."
          },
          "aspects": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/NatalAspect"
            }
          },
          "nodes": {
            "$ref": "#/components/schemas/Nodes"
          },
          "metadata": {
            "type": "object",
            "properties": {
              "note": {
                "type": "string"
              }
            },
            "required": [
              "note"
            ],
            "additionalProperties": true
          }
        },
        "required": [
          "status",
          "zodiac",
          "ayanamsa",
          "planets",
          "houses",
          "aspects",
          "nodes",
          "metadata"
        ],
        "additionalProperties": true,
        "description": "Existing chart serialization evaluated at the exact root Time object and requested location. Exactly one selected Equal/Whole Sign house system. Legacy chart mean-node aliases and rounding conventions remain unchanged; use lunar-nodes separately for a distinct osculating node model."
      },
      "ReturnsMetadata": {
        "type": "object",
        "properties": {
          "ephemeris": {
            "type": "string",
            "const": "JPL-DE421"
          },
          "timescale_data": {
            "type": "string",
            "const": "bundled-skyfield"
          },
          "source_frame": {
            "type": "string",
            "const": "apparent-geocentric-ecliptic-of-each-ephemeris-date"
          },
          "target_policy": {
            "type": "string",
            "const": "unrounded-natal-longitude-in-selected-zodiac"
          },
          "sidereal_policy": {
            "type": "string",
            "enum": [
              "per-ephemeris-date-mean-P03-ayanamsa-with-nutation-retained",
              "not-applicable"
            ]
          },
          "search_policy": {
            "type": "string",
            "const": "first-forward-crossing-after-one-millisecond-start-exclusion"
          },
          "window_policy": {
            "type": "string",
            "const": "full-fixed-TT-window-required-without-clipping"
          },
          "location_policy": {
            "type": "string",
            "enum": [
              "explicit-return-location",
              "birth-location"
            ]
          },
          "chart_time_policy": {
            "type": "string",
            "const": "root-Time-object-without-civil-roundtrip"
          },
          "chart_precision": {
            "type": "string",
            "const": "existing-chart-serialization"
          },
          "utc_output": {
            "type": "string",
            "const": "leap-second-aware-ISO-8601"
          },
          "root_tt_jd_policy": {
            "type": "string",
            "const": "display-only-single-float-not-used-for-chart"
          },
          "root_precision": {
            "type": "string",
            "const": "numerical-tolerance-not-physical-event-accuracy"
          },
          "house_system": {
            "type": "string",
            "enum": [
              "equal",
              "whole_sign"
            ]
          },
          "nodes": {
            "type": "string",
            "const": "existing-mean-node-contract"
          },
          "aspects": {
            "type": "string",
            "const": "existing-natal-longitude-orbs"
          },
          "interpretations": {
            "type": "boolean",
            "const": false
          },
          "practitioner_review": {
            "type": "string",
            "const": "not-completed"
          }
        },
        "required": [
          "ephemeris",
          "timescale_data",
          "source_frame",
          "target_policy",
          "sidereal_policy",
          "search_policy",
          "window_policy",
          "location_policy",
          "chart_time_policy",
          "chart_precision",
          "utc_output",
          "root_tt_jd_policy",
          "root_precision",
          "house_system",
          "nodes",
          "aspects",
          "interpretations",
          "practitioner_review"
        ],
        "additionalProperties": false
      },
      "ReturnsResponse": {
        "type": "object",
        "properties": {
          "type": {
            "type": "string",
            "const": "returns"
          },
          "status": {
            "type": "string",
            "const": "beta"
          },
          "method": {
            "type": "string",
            "const": "next_longitude_return"
          },
          "body": {
            "type": "string",
            "enum": [
              "sun",
              "moon"
            ]
          },
          "zodiac": {
            "$ref": "#/components/schemas/Zodiac"
          },
          "ayanamsa": {
            "$ref": "#/components/schemas/AyanamsaResult"
          },
          "input": {
            "type": "object",
            "properties": {
              "birth": {
                "$ref": "#/components/schemas/BetaMomentResult"
              },
              "body": {
                "type": "string",
                "enum": [
                  "sun",
                  "moon"
                ]
              },
              "after": {
                "$ref": "#/components/schemas/NormalizedCivilTime"
              },
              "zodiac": {
                "$ref": "#/components/schemas/Zodiac"
              },
              "ayanamsa": {
                "$ref": "#/components/schemas/AyanamsaResult"
              },
              "house_system": {
                "type": "string",
                "enum": [
                  "equal",
                  "whole_sign"
                ]
              },
              "location": {
                "$ref": "#/components/schemas/ReturnLocation"
              }
            },
            "required": [
              "birth",
              "body",
              "after",
              "zodiac",
              "ayanamsa",
              "house_system",
              "location"
            ],
            "additionalProperties": false
          },
          "birth_utc": {
            "$ref": "#/components/schemas/UtcTimestamp"
          },
          "after_utc": {
            "$ref": "#/components/schemas/UtcTimestamp"
          },
          "return_utc": {
            "$ref": "#/components/schemas/ReturnUtcTimestamp"
          },
          "natal_longitude_deg": {
            "type": "number",
            "minimum": 0,
            "exclusiveMaximum": 360
          },
          "return_longitude_deg": {
            "type": "number",
            "minimum": 0,
            "exclusiveMaximum": 360
          },
          "chart": {
            "$ref": "#/components/schemas/ReturnChart"
          },
          "search": {
            "$ref": "#/components/schemas/ReturnSearch"
          },
          "metadata": {
            "$ref": "#/components/schemas/ReturnsMetadata"
          }
        },
        "required": [
          "type",
          "status",
          "method",
          "body",
          "zodiac",
          "ayanamsa",
          "input",
          "birth_utc",
          "after_utc",
          "return_utc",
          "natal_longitude_deg",
          "return_longitude_deg",
          "chart",
          "search",
          "metadata"
        ],
        "additionalProperties": false
      },
      "VimshottariResponseDepth2": {
        "type": "object",
        "properties": {
          "status": {
            "type": "string",
            "const": "beta"
          },
          "type": {
            "type": "string",
            "const": "vimshottari"
          },
          "input": {
            "type": "object",
            "properties": {
              "birth": {
                "$ref": "#/components/schemas/NormalizedBirth"
              },
              "ayanamsa": {
                "$ref": "#/components/schemas/Ayanamsa"
              }
            },
            "required": [
              "birth",
              "ayanamsa"
            ],
            "additionalProperties": false
          },
          "birth_utc": {
            "$ref": "#/components/schemas/UtcTimestamp"
          },
          "zodiac": {
            "type": "string",
            "const": "sidereal"
          },
          "ayanamsa": {
            "$ref": "#/components/schemas/Ayanamsa"
          },
          "moon": {
            "type": "object",
            "properties": {
              "sidereal_longitude": {
                "type": "number",
                "minimum": 0,
                "exclusiveMaximum": 360
              },
              "nakshatra": {
                "type": "object",
                "properties": {
                  "index": {
                    "type": "integer",
                    "minimum": 1,
                    "maximum": 27
                  },
                  "name": {
                    "type": "string"
                  },
                  "lord": {
                    "$ref": "#/components/schemas/DashaLord"
                  },
                  "pada": {
                    "type": "integer",
                    "minimum": 1,
                    "maximum": 4
                  },
                  "fraction_elapsed": {
                    "type": "number",
                    "minimum": 0,
                    "exclusiveMaximum": 1
                  }
                },
                "required": [
                  "index",
                  "name",
                  "lord",
                  "pada",
                  "fraction_elapsed"
                ],
                "additionalProperties": false
              }
            },
            "required": [
              "sidereal_longitude",
              "nakshatra"
            ],
            "additionalProperties": false
          },
          "birth_balance": {
            "type": "object",
            "properties": {
              "lord": {
                "$ref": "#/components/schemas/DashaLord"
              },
              "subperiod_lord": {
                "$ref": "#/components/schemas/DashaLord"
              },
              "elapsed_years": {
                "type": "number",
                "minimum": 0
              },
              "remaining_years": {
                "type": "number",
                "exclusiveMinimum": 0
              },
              "remaining_days": {
                "type": "number",
                "exclusiveMinimum": 0
              },
              "start_utc": {
                "$ref": "#/components/schemas/UtcTimestamp"
              },
              "end_utc": {
                "$ref": "#/components/schemas/UtcTimestamp"
              }
            },
            "required": [
              "lord",
              "subperiod_lord",
              "elapsed_years",
              "remaining_years",
              "remaining_days",
              "start_utc",
              "end_utc"
            ],
            "additionalProperties": false
          },
          "cycle": {
            "type": "object",
            "properties": {
              "years": {
                "type": "number",
                "const": 120
              },
              "start_utc": {
                "$ref": "#/components/schemas/UtcTimestamp"
              },
              "end_utc": {
                "$ref": "#/components/schemas/UtcTimestamp"
              }
            },
            "required": [
              "years",
              "start_utc",
              "end_utc"
            ],
            "additionalProperties": false
          },
          "periods": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/DashaPeriod"
            },
            "minItems": 9,
            "maxItems": 9
          },
          "metadata": {
            "$ref": "#/components/schemas/VimshottariMetadata"
          }
        },
        "required": [
          "status",
          "type",
          "input",
          "birth_utc",
          "zodiac",
          "ayanamsa",
          "moon",
          "birth_balance",
          "cycle",
          "periods",
          "metadata"
        ],
        "additionalProperties": false,
        "description": "All period timestamps are UTC with microsecond resolution and half-open intervals. Derived period offsets may extend beyond the birth ephemeris window; this does not extrapolate ephemeris positions. Unrounded Moon determines nakshatra and birth balance; elapsed duration is floored to microseconds. Experimental beta without practitioner sign-off."
      },
      "DashaAntardashaDepth3": {
        "type": "object",
        "properties": {
          "lord": {
            "$ref": "#/components/schemas/DashaLord"
          },
          "years": {
            "type": "number",
            "exclusiveMinimum": 0
          },
          "start_utc": {
            "$ref": "#/components/schemas/UtcTimestamp"
          },
          "end_utc": {
            "$ref": "#/components/schemas/UtcTimestamp"
          },
          "active_at_birth": {
            "type": "boolean"
          },
          "subperiods": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/DashaSubperiod"
            },
            "minItems": 9,
            "maxItems": 9
          }
        },
        "required": [
          "lord",
          "years",
          "start_utc",
          "end_utc",
          "active_at_birth",
          "subperiods"
        ],
        "additionalProperties": false
      },
      "DashaPeriodDepth3": {
        "type": "object",
        "properties": {
          "lord": {
            "$ref": "#/components/schemas/DashaLord"
          },
          "years": {
            "type": "integer",
            "enum": [
              7,
              20,
              6,
              10,
              18,
              16,
              19,
              17
            ]
          },
          "start_utc": {
            "$ref": "#/components/schemas/UtcTimestamp"
          },
          "end_utc": {
            "$ref": "#/components/schemas/UtcTimestamp"
          },
          "active_at_birth": {
            "type": "boolean"
          },
          "subperiods": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/DashaAntardashaDepth3"
            },
            "minItems": 9,
            "maxItems": 9
          }
        },
        "required": [
          "lord",
          "years",
          "start_utc",
          "end_utc",
          "active_at_birth",
          "subperiods"
        ],
        "additionalProperties": false
      },
      "VimshottariMetadataDepth3": {
        "type": "object",
        "properties": {
          "calculation_status": {
            "type": "string",
            "const": "experimental_beta"
          },
          "practitioner_review": {
            "type": "string",
            "const": "not_completed"
          },
          "frame": {
            "type": "string",
            "const": "apparent_geocentric_sidereal_retained_nutation"
          },
          "node_model": {
            "type": "string",
            "const": "mean_ascending_and_opposite_descending"
          },
          "classification_precision": {
            "type": "string",
            "const": "unrounded_binary64"
          },
          "interpretations": {
            "type": "boolean",
            "const": false
          },
          "year_length": {
            "type": "object",
            "properties": {
              "name": {
                "type": "string",
                "const": "julian_365_25_days"
              },
              "days": {
                "type": "number",
                "const": 365.25
              },
              "seconds": {
                "type": "number",
                "const": 31557600
              }
            },
            "required": [
              "name",
              "days",
              "seconds"
            ],
            "additionalProperties": false
          },
          "interval": {
            "type": "string",
            "const": "[start_utc,end_utc)"
          },
          "timestamp_resolution": {
            "type": "string",
            "const": "microsecond"
          },
          "birth_balance_rounding": {
            "type": "string",
            "const": "elapsed_duration_floored_to_microseconds"
          },
          "cycle_anchor": {
            "type": "string",
            "const": "start_of_birth_mahadasha"
          },
          "period_timestamps": {
            "type": "string",
            "const": "theoretical_offsets_may_extend_beyond_birth_ephemeris_window_no_ephemeris_extrapolation"
          },
          "depth": {
            "type": "integer",
            "const": 3
          },
          "levels": {
            "type": "array",
            "const": [
              "mahadasha",
              "antardasha",
              "pratyantardasha"
            ],
            "items": {
              "type": "string"
            },
            "minItems": 3,
            "maxItems": 3
          },
          "period_counts": {
            "type": "object",
            "properties": {
              "mahadasha": {
                "type": "integer",
                "const": 9
              },
              "antardasha": {
                "type": "integer",
                "const": 81
              },
              "pratyantardasha": {
                "type": "integer",
                "const": 729
              }
            },
            "required": [
              "mahadasha",
              "antardasha",
              "pratyantardasha"
            ],
            "additionalProperties": false
          },
          "duration_arithmetic": {
            "type": "string",
            "const": "exact_integer_microseconds_proportional_parent_duration"
          }
        },
        "required": [
          "calculation_status",
          "practitioner_review",
          "frame",
          "node_model",
          "classification_precision",
          "interpretations",
          "year_length",
          "interval",
          "timestamp_resolution",
          "birth_balance_rounding",
          "cycle_anchor",
          "period_timestamps",
          "depth",
          "levels",
          "period_counts",
          "duration_arithmetic"
        ],
        "additionalProperties": false
      },
      "VimshottariResponseDepth3": {
        "type": "object",
        "properties": {
          "status": {
            "type": "string",
            "const": "beta"
          },
          "type": {
            "type": "string",
            "const": "vimshottari"
          },
          "input": {
            "type": "object",
            "properties": {
              "birth": {
                "$ref": "#/components/schemas/NormalizedBirth"
              },
              "ayanamsa": {
                "$ref": "#/components/schemas/Ayanamsa"
              },
              "depth": {
                "type": "integer",
                "const": 3
              }
            },
            "required": [
              "birth",
              "ayanamsa",
              "depth"
            ],
            "additionalProperties": false
          },
          "birth_utc": {
            "$ref": "#/components/schemas/UtcTimestamp"
          },
          "zodiac": {
            "type": "string",
            "const": "sidereal"
          },
          "ayanamsa": {
            "$ref": "#/components/schemas/Ayanamsa"
          },
          "moon": {
            "type": "object",
            "properties": {
              "sidereal_longitude": {
                "type": "number",
                "minimum": 0,
                "exclusiveMaximum": 360
              },
              "nakshatra": {
                "type": "object",
                "properties": {
                  "index": {
                    "type": "integer",
                    "minimum": 1,
                    "maximum": 27
                  },
                  "name": {
                    "type": "string"
                  },
                  "lord": {
                    "$ref": "#/components/schemas/DashaLord"
                  },
                  "pada": {
                    "type": "integer",
                    "minimum": 1,
                    "maximum": 4
                  },
                  "fraction_elapsed": {
                    "type": "number",
                    "minimum": 0,
                    "exclusiveMaximum": 1
                  }
                },
                "required": [
                  "index",
                  "name",
                  "lord",
                  "pada",
                  "fraction_elapsed"
                ],
                "additionalProperties": false
              }
            },
            "required": [
              "sidereal_longitude",
              "nakshatra"
            ],
            "additionalProperties": false
          },
          "birth_balance": {
            "type": "object",
            "properties": {
              "lord": {
                "$ref": "#/components/schemas/DashaLord"
              },
              "subperiod_lord": {
                "$ref": "#/components/schemas/DashaLord"
              },
              "elapsed_years": {
                "type": "number",
                "minimum": 0
              },
              "remaining_years": {
                "type": "number",
                "exclusiveMinimum": 0
              },
              "remaining_days": {
                "type": "number",
                "exclusiveMinimum": 0
              },
              "start_utc": {
                "$ref": "#/components/schemas/UtcTimestamp"
              },
              "end_utc": {
                "$ref": "#/components/schemas/UtcTimestamp"
              },
              "pratyantardasha_lord": {
                "$ref": "#/components/schemas/DashaLord"
              }
            },
            "required": [
              "lord",
              "subperiod_lord",
              "elapsed_years",
              "remaining_years",
              "remaining_days",
              "start_utc",
              "end_utc",
              "pratyantardasha_lord"
            ],
            "additionalProperties": false
          },
          "cycle": {
            "type": "object",
            "properties": {
              "years": {
                "type": "number",
                "const": 120
              },
              "start_utc": {
                "$ref": "#/components/schemas/UtcTimestamp"
              },
              "end_utc": {
                "$ref": "#/components/schemas/UtcTimestamp"
              }
            },
            "required": [
              "years",
              "start_utc",
              "end_utc"
            ],
            "additionalProperties": false
          },
          "periods": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/DashaPeriodDepth3"
            },
            "minItems": 9,
            "maxItems": 9
          },
          "metadata": {
            "$ref": "#/components/schemas/VimshottariMetadataDepth3"
          }
        },
        "required": [
          "status",
          "type",
          "input",
          "birth_utc",
          "zodiac",
          "ayanamsa",
          "moon",
          "birth_balance",
          "cycle",
          "periods",
          "metadata"
        ],
        "additionalProperties": false,
        "description": "All period timestamps are UTC with microsecond resolution and half-open intervals. Derived period offsets may extend beyond the birth ephemeris window; this does not extrapolate ephemeris positions. Unrounded Moon determines nakshatra and birth balance; elapsed duration is floored to microseconds. Experimental beta without practitioner sign-off."
      },
      "SolarArcsRequest": {
        "type": "object",
        "properties": {
          "birth": {
            "$ref": "#/components/schemas/BetaBirthInput"
          },
          "target": {
            "$ref": "#/components/schemas/CivilTimeInput"
          },
          "zodiac": {
            "$ref": "#/components/schemas/Zodiac",
            "default": "tropical"
          },
          "ayanamsa": {
            "$ref": "#/components/schemas/Ayanamsa",
            "default": "lahiri"
          },
          "house_system": {
            "type": "string",
            "enum": [
              "equal",
              "whole_sign"
            ],
            "default": "equal"
          }
        },
        "required": [
          "birth",
          "target"
        ],
        "additionalProperties": false,
        "description": "Symbolic direct true TROPICAL solar arc applied uniformly to natal planets and Ascendant/MC, not a physical sky chart or mean/Naibod arc. Input and day-for-year timing match secondary progressions: target UTC >= birth, fixed 365.2421904-day TT year, civil dates 1900–2050, strict fields/enums/numbers and DST/polar rejection. Sidereal uses the natal-date ayanamsa only; both arc Sun reference longitudes remain tropical. Equal/Whole Sign houses are synthetic from directed Ascendant, with MC independently directed. No relocation, converse arc, aspects, nodes, speeds or arbitrary year model. Internal evaluation is bounded to 152 progressed TT days and at most 5 Sun intervals of 32 days."
      },
      "SolarArcsMetadata": {
        "type": "object",
        "properties": {
          "physical_chart": {
            "type": "boolean",
            "const": false
          },
          "source_frame": {
            "type": "string",
            "const": "apparent-geocentric-ecliptic-of-each-ephemeris-date"
          },
          "position_precision": {
            "type": "string",
            "const": "unrounded-binary64"
          },
          "year_convention": {
            "type": "string",
            "const": "fixed-365.2421904-days-not-calendar-birthdays"
          },
          "time_policy": {
            "type": "string",
            "const": "uniform-TT-elapsed-days-divided-by-year-days"
          },
          "timescale_data": {
            "type": "string",
            "const": "bundled-skyfield"
          },
          "utc_output": {
            "type": "string",
            "const": "leap-second-aware-ISO-8601"
          },
          "arc_policy": {
            "type": "string",
            "const": "direct-true-tropical-solar-arc-not-mean-naibod"
          },
          "arc_unwrap": {
            "type": "string",
            "const": "positive-steps-at-most-32-TT-days-total-at-most-152-days"
          },
          "angle_policy": {
            "type": "string",
            "const": "same-ecliptic-arc-added-to-natal-ascendant-and-mc"
          },
          "house_policy": {
            "type": "string",
            "enum": [
              "synthetic-equal-from-directed-ascendant",
              "synthetic-whole-sign-from-directed-ascendant"
            ]
          },
          "location_policy": {
            "type": "string",
            "const": "birth-location-for-natal-angles-no-relocation"
          },
          "sidereal_policy": {
            "type": "string",
            "enum": [
              "tropical-arc-on-natal-sidereal-points-natal-ayanamsa-only",
              "not-applicable"
            ]
          },
          "aspects": {
            "type": "string",
            "const": "not-included"
          },
          "nodes": {
            "type": "string",
            "const": "not-included"
          },
          "speeds": {
            "type": "string",
            "const": "not-included"
          },
          "interpretations": {
            "type": "boolean",
            "const": false
          },
          "practitioner_review": {
            "type": "string",
            "const": "not-completed"
          }
        },
        "required": [
          "physical_chart",
          "source_frame",
          "position_precision",
          "year_convention",
          "time_policy",
          "timescale_data",
          "utc_output",
          "arc_policy",
          "arc_unwrap",
          "angle_policy",
          "house_policy",
          "location_policy",
          "sidereal_policy",
          "aspects",
          "nodes",
          "speeds",
          "interpretations",
          "practitioner_review"
        ],
        "additionalProperties": false
      },
      "SolarArcsResponse": {
        "type": "object",
        "properties": {
          "type": {
            "type": "string",
            "const": "solar_arcs"
          },
          "status": {
            "type": "string",
            "const": "beta"
          },
          "method": {
            "type": "string",
            "const": "true_solar_arc"
          },
          "input": {
            "type": "object",
            "properties": {
              "birth": {
                "$ref": "#/components/schemas/BetaMomentResult"
              },
              "target": {
                "type": "object",
                "properties": {
                  "date": {
                    "$ref": "#/components/schemas/Date"
                  },
                  "time": {
                    "$ref": "#/components/schemas/Time"
                  },
                  "timezone": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 100
                  }
                },
                "required": [
                  "date",
                  "time",
                  "timezone"
                ],
                "additionalProperties": false
              },
              "zodiac": {
                "$ref": "#/components/schemas/Zodiac"
              },
              "ayanamsa": {
                "$ref": "#/components/schemas/AyanamsaResult"
              },
              "house_system": {
                "type": "string",
                "enum": [
                  "equal",
                  "whole_sign"
                ]
              }
            },
            "required": [
              "birth",
              "target",
              "zodiac",
              "ayanamsa",
              "house_system"
            ],
            "additionalProperties": false
          },
          "birth_utc": {
            "$ref": "#/components/schemas/UtcTimestamp"
          },
          "target_utc": {
            "$ref": "#/components/schemas/UtcTimestamp"
          },
          "progressed_utc": {
            "$ref": "#/components/schemas/ProgressedUtcTimestamp"
          },
          "timing": {
            "type": "object",
            "properties": {
              "year_days": {
                "type": "number",
                "const": 365.2421904
              },
              "elapsed_years": {
                "type": "number",
                "minimum": 0,
                "maximum": 152
              },
              "progressed_days": {
                "type": "number",
                "minimum": 0,
                "maximum": 152
              },
              "time_scale": {
                "type": "string",
                "const": "TT"
              },
              "progressed_tt_jd": {
                "type": "number"
              }
            },
            "required": [
              "year_days",
              "elapsed_years",
              "progressed_days",
              "time_scale",
              "progressed_tt_jd"
            ],
            "additionalProperties": false
          },
          "zodiac": {
            "$ref": "#/components/schemas/Zodiac"
          },
          "ayanamsa": {
            "$ref": "#/components/schemas/AyanamsaResult"
          },
          "natal_context": {
            "type": "object",
            "properties": {
              "planets": {
                "$ref": "#/components/schemas/WesternPlanets"
              },
              "angles": {
                "$ref": "#/components/schemas/WesternAngles"
              },
              "houses": {
                "$ref": "#/components/schemas/WesternHouses"
              }
            },
            "required": [
              "planets",
              "angles",
              "houses"
            ],
            "additionalProperties": false
          },
          "metadata": {
            "$ref": "#/components/schemas/SolarArcsMetadata"
          },
          "arc": {
            "type": "object",
            "properties": {
              "degrees": {
                "type": "number",
                "minimum": 0,
                "exclusiveMaximum": 180
              },
              "direction": {
                "type": "string",
                "const": "direct"
              },
              "basis": {
                "type": "string",
                "const": "tropical-apparent-sun"
              },
              "natal_sun_longitude": {
                "type": "number",
                "minimum": 0,
                "exclusiveMaximum": 360
              },
              "progressed_sun_longitude": {
                "type": "number",
                "minimum": 0,
                "exclusiveMaximum": 360
              }
            },
            "required": [
              "degrees",
              "direction",
              "basis",
              "natal_sun_longitude",
              "progressed_sun_longitude"
            ],
            "additionalProperties": false
          },
          "directed_planets": {
            "$ref": "#/components/schemas/WesternPlanets"
          },
          "directed_angles": {
            "$ref": "#/components/schemas/WesternAngles"
          },
          "directed_houses": {
            "$ref": "#/components/schemas/WesternHouses"
          }
        },
        "required": [
          "type",
          "status",
          "method",
          "input",
          "birth_utc",
          "target_utc",
          "progressed_utc",
          "timing",
          "zodiac",
          "ayanamsa",
          "natal_context",
          "metadata",
          "arc",
          "directed_planets",
          "directed_angles",
          "directed_houses"
        ],
        "additionalProperties": false
      },
      "MoonPhaseRequest": {
        "oneOf": [
          {
            "$ref": "#/components/schemas/MoonPhaseInstantRequest"
          },
          {
            "$ref": "#/components/schemas/MoonPhaseCalendarRequest"
          }
        ]
      },
      "MoonPhaseInstantRequest": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "mode",
          "at"
        ],
        "properties": {
          "mode": {
            "type": "string",
            "const": "instant"
          },
          "at": {
            "$ref": "#/components/schemas/CivilTimeInput"
          },
          "display_timezone": {
            "type": "string",
            "minLength": 1,
            "maxLength": 100,
            "default": "UTC"
          }
        }
      },
      "MoonPhaseCalendarRequest": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "mode",
          "start",
          "end"
        ],
        "description": "Start-inclusive/end-exclusive interval, greater than zero and at most 366 elapsed UTC days after civil-time conversion. Both civil dates must be within 1900–2050; UTC coverage is separately checked. Invalid calendars, DST gaps/folds and unavailable timezones return 400.",
        "properties": {
          "mode": {
            "type": "string",
            "const": "calendar"
          },
          "start": {
            "$ref": "#/components/schemas/CivilTimeInput"
          },
          "end": {
            "$ref": "#/components/schemas/CivilTimeInput"
          },
          "display_timezone": {
            "type": "string",
            "minLength": 1,
            "maxLength": 100,
            "default": "UTC"
          },
          "include_ical": {
            "type": "boolean",
            "default": false,
            "description": "Opt in to result.ical: a bounded RFC 5545 UTC point-event export, or null when no events occur. Calendar mode only. No extra quota unit, subscription feed, reminders or external calendar writes."
          }
        }
      },
      "MoonPhaseMetadata": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "frame",
          "timescale_data",
          "phase_definition",
          "illumination_model",
          "interpretations"
        ],
        "properties": {
          "frame": {
            "type": "string",
            "const": "apparent_geocentric_ecliptic_of_date"
          },
          "timescale_data": {
            "type": "string",
            "const": "bundled-skyfield"
          },
          "phase_definition": {
            "type": "string",
            "const": "moon_minus_sun_ecliptic_longitude"
          },
          "illumination_model": {
            "type": "string",
            "const": "spherical_geometric_no_eclipse_shadow"
          },
          "interpretations": {
            "type": "boolean",
            "const": false
          }
        }
      },
      "MoonPhaseSnapshot": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "utc",
          "local",
          "timezone",
          "phase_sector",
          "elongation_degrees",
          "longitude_cycle",
          "illuminated_fraction",
          "model"
        ],
        "properties": {
          "utc": {
            "$ref": "#/components/schemas/UtcTimestamp"
          },
          "local": {
            "type": "string",
            "format": "date-time"
          },
          "timezone": {
            "type": "string",
            "minLength": 1,
            "maxLength": 100
          },
          "phase_sector": {
            "type": "string",
            "enum": [
              "new_moon",
              "waxing_crescent",
              "first_quarter",
              "waxing_gibbous",
              "full_moon",
              "waning_gibbous",
              "last_quarter",
              "waning_crescent"
            ],
            "description": "Nearest 45-degree display sector, not an exact event or measured brightness."
          },
          "elongation_degrees": {
            "type": "number",
            "minimum": 0,
            "exclusiveMaximum": 360,
            "description": "Moon minus Sun ecliptic longitude, not great-circle angular separation."
          },
          "longitude_cycle": {
            "type": "string",
            "enum": [
              "waxing",
              "waning"
            ],
            "description": "Waxing for longitude difference below 180 degrees; not the derivative of illuminated area."
          },
          "illuminated_fraction": {
            "type": "number",
            "minimum": 0,
            "maximum": 1
          },
          "model": {
            "type": "string",
            "const": "de421-geocentric-moon-phase-v1"
          }
        }
      },
      "MoonPhaseEvent": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "phase",
          "target_degrees",
          "utc",
          "local"
        ],
        "properties": {
          "phase": {
            "type": "string",
            "enum": [
              "new_moon",
              "first_quarter",
              "full_moon",
              "last_quarter"
            ]
          },
          "target_degrees": {
            "type": "integer",
            "enum": [
              0,
              90,
              180,
              270
            ]
          },
          "utc": {
            "$ref": "#/components/schemas/UtcTimestamp"
          },
          "local": {
            "type": "string",
            "format": "date-time"
          }
        },
        "oneOf": [
          {
            "type": "object",
            "properties": {
              "phase": {
                "const": "new_moon"
              },
              "target_degrees": {
                "const": 0
              }
            }
          },
          {
            "type": "object",
            "properties": {
              "phase": {
                "const": "first_quarter"
              },
              "target_degrees": {
                "const": 90
              }
            }
          },
          {
            "type": "object",
            "properties": {
              "phase": {
                "const": "full_moon"
              },
              "target_degrees": {
                "const": 180
              }
            }
          },
          {
            "type": "object",
            "properties": {
              "phase": {
                "const": "last_quarter"
              },
              "target_degrees": {
                "const": 270
              }
            }
          }
        ]
      },
      "MoonPhaseCalendar": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "start_utc",
          "end_utc",
          "timezone",
          "events",
          "model",
          "interval",
          "timestamp_resolution_seconds",
          "search_tolerance_seconds"
        ],
        "properties": {
          "start_utc": {
            "$ref": "#/components/schemas/UtcTimestamp"
          },
          "end_utc": {
            "$ref": "#/components/schemas/UtcTimestamp"
          },
          "timezone": {
            "type": "string",
            "minLength": 1,
            "maxLength": 100
          },
          "events": {
            "type": "array",
            "maxItems": 52,
            "items": {
              "$ref": "#/components/schemas/MoonPhaseEvent"
            }
          },
          "model": {
            "type": "string",
            "const": "de421-geocentric-moon-phase-v1"
          },
          "interval": {
            "type": "string",
            "const": "start_inclusive_end_exclusive"
          },
          "timestamp_resolution_seconds": {
            "type": "integer",
            "const": 1
          },
          "search_tolerance_seconds": {
            "type": "number",
            "const": 0.001,
            "description": "Numerical root convergence only; not a physical event-time accuracy guarantee."
          },
          "ical": {
            "description": "Present only for include_ical:true. Save the decoded string as UTF-8 .ics; CRLF and folded content lines are already supplied. Null means no events and no file. UTC DTSTART preserves instants across calendar display timezones. UIDs bind model, phase and reported second; DTSTAMP is export assembly time and can change across calls. No METHOD, recurrence, attendees, organizer, alarms, attachments or subscription URL.",
            "oneOf": [
              {
                "type": "string",
                "minLength": 1,
                "maxLength": 32768
              },
              {
                "type": "null"
              }
            ]
          }
        }
      },
      "MoonPhaseInstantResponse": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "type",
          "status",
          "mode",
          "result",
          "metadata"
        ],
        "properties": {
          "type": {
            "type": "string",
            "const": "moon_phases"
          },
          "status": {
            "type": "string",
            "const": "beta"
          },
          "mode": {
            "type": "string",
            "const": "instant"
          },
          "result": {
            "$ref": "#/components/schemas/MoonPhaseSnapshot"
          },
          "metadata": {
            "$ref": "#/components/schemas/MoonPhaseMetadata"
          }
        }
      },
      "MoonPhaseCalendarResponse": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "type",
          "status",
          "mode",
          "result",
          "metadata"
        ],
        "properties": {
          "type": {
            "type": "string",
            "const": "moon_phases"
          },
          "status": {
            "type": "string",
            "const": "beta"
          },
          "mode": {
            "type": "string",
            "const": "calendar"
          },
          "result": {
            "$ref": "#/components/schemas/MoonPhaseCalendar"
          },
          "metadata": {
            "$ref": "#/components/schemas/MoonPhaseMetadata"
          }
        }
      },
      "MoonPhaseResponse": {
        "oneOf": [
          {
            "$ref": "#/components/schemas/MoonPhaseInstantResponse"
          },
          {
            "$ref": "#/components/schemas/MoonPhaseCalendarResponse"
          }
        ]
      },
      "DavisonRequest": {
        "type": "object",
        "properties": {
          "personA": {
            "$ref": "#/components/schemas/BetaBirthInput"
          },
          "personB": {
            "$ref": "#/components/schemas/BetaBirthInput"
          },
          "zodiac": {
            "$ref": "#/components/schemas/Zodiac",
            "default": "tropical"
          },
          "ayanamsa": {
            "$ref": "#/components/schemas/Ayanamsa",
            "default": "lahiri"
          },
          "house_system": {
            "type": "string",
            "enum": [
              "equal",
              "whole_sign"
            ],
            "default": "equal"
          }
        },
        "required": [
          "personA",
          "personB"
        ],
        "additionalProperties": false,
        "description": "Uncorrected Davison with a uniform-TT time mean and arithmetic latitude/longitude after +180 is canonicalized to -180. Not a shortest-arc/spherical midpoint or corrected-MC chart. No nodes, relocation, Placidus or interpretations. Unknown fields and ambiguous/nonexistent civil times reject. See DAVISON_CONVENTIONS.md."
      },
      "DavisonMetadata": {
        "type": "object",
        "properties": {
          "physical_chart": {
            "type": "boolean",
            "const": true
          },
          "ephemeris": {
            "type": "string",
            "const": "JPL-DE421"
          },
          "source_frame": {
            "type": "string",
            "const": "apparent-geocentric-ecliptic-of-midpoint-date"
          },
          "position_precision": {
            "type": "string",
            "const": "unrounded-binary64"
          },
          "time_policy": {
            "type": "string",
            "const": "uniform-TT-midpoint-no-MC-correction"
          },
          "timescale_data": {
            "type": "string",
            "const": "bundled-skyfield"
          },
          "location_policy": {
            "type": "string",
            "const": "arithmetic-latitude-and-canonical-longitude"
          },
          "longitude_policy": {
            "type": "string",
            "const": "canonical-minus180-inclusive-plus180-exclusive-not-shortest-arc"
          },
          "chart_time_policy": {
            "type": "string",
            "const": "midpoint-Time-object-without-civil-roundtrip"
          },
          "tt_jd_policy": {
            "type": "string",
            "const": "display-only-single-float-not-used-for-chart"
          },
          "utc_output": {
            "type": "string",
            "const": "leap-second-aware-ISO-8601"
          },
          "aspect_policy": {
            "type": "string",
            "const": "existing-natal-longitude-orbs"
          },
          "nodes": {
            "type": "string",
            "const": "not-included"
          },
          "interpretations": {
            "type": "boolean",
            "const": false
          },
          "practitioner_review": {
            "type": "string",
            "const": "not-completed"
          },
          "house_policy": {
            "type": "string",
            "enum": [
              "physical-equal-at-midpoint",
              "physical-whole-sign-at-midpoint"
            ]
          },
          "sidereal_policy": {
            "type": "string",
            "enum": [
              "midpoint-date-ayanamsa",
              "not-applicable"
            ]
          }
        },
        "required": [
          "physical_chart",
          "ephemeris",
          "source_frame",
          "position_precision",
          "time_policy",
          "timescale_data",
          "location_policy",
          "longitude_policy",
          "chart_time_policy",
          "tt_jd_policy",
          "utc_output",
          "aspect_policy",
          "nodes",
          "interpretations",
          "practitioner_review",
          "house_policy",
          "sidereal_policy"
        ],
        "additionalProperties": false
      },
      "DavisonResponse": {
        "type": "object",
        "properties": {
          "type": {
            "type": "string",
            "const": "davison"
          },
          "status": {
            "type": "string",
            "const": "beta"
          },
          "method": {
            "type": "string",
            "const": "uncorrected_tt_arithmetic"
          },
          "input": {
            "type": "object",
            "properties": {
              "personA": {
                "$ref": "#/components/schemas/BetaMomentResult"
              },
              "personB": {
                "$ref": "#/components/schemas/BetaMomentResult"
              },
              "zodiac": {
                "$ref": "#/components/schemas/Zodiac"
              },
              "ayanamsa": {
                "$ref": "#/components/schemas/AyanamsaResult"
              },
              "house_system": {
                "type": "string",
                "enum": [
                  "equal",
                  "whole_sign"
                ]
              }
            },
            "required": [
              "personA",
              "personB",
              "zodiac",
              "ayanamsa",
              "house_system"
            ],
            "additionalProperties": false
          },
          "source_utc": {
            "type": "object",
            "properties": {
              "personA": {
                "$ref": "#/components/schemas/UtcTimestamp"
              },
              "personB": {
                "$ref": "#/components/schemas/UtcTimestamp"
              }
            },
            "required": [
              "personA",
              "personB"
            ],
            "additionalProperties": false
          },
          "zodiac": {
            "$ref": "#/components/schemas/Zodiac"
          },
          "ayanamsa": {
            "$ref": "#/components/schemas/AyanamsaResult"
          },
          "planets": {
            "$ref": "#/components/schemas/WesternPlanets"
          },
          "angles": {
            "$ref": "#/components/schemas/WesternAngles"
          },
          "houses": {
            "$ref": "#/components/schemas/WesternHouses"
          },
          "aspects": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/NatalAspect"
            }
          },
          "metadata": {
            "$ref": "#/components/schemas/DavisonMetadata"
          },
          "midpoint": {
            "type": "object",
            "properties": {
              "utc": {
                "$ref": "#/components/schemas/ProgressedUtcTimestamp"
              },
              "tt_jd": {
                "type": "number",
                "description": "Display-only TT Julian date; never rounded back into chart computation."
              },
              "location": {
                "type": "object",
                "properties": {
                  "lat": {
                    "type": "number",
                    "exclusiveMinimum": -90,
                    "exclusiveMaximum": 90
                  },
                  "lon": {
                    "type": "number",
                    "minimum": -180,
                    "exclusiveMaximum": 180
                  }
                },
                "required": [
                  "lat",
                  "lon"
                ],
                "additionalProperties": false
              }
            },
            "required": [
              "utc",
              "tt_jd",
              "location"
            ],
            "additionalProperties": false
          }
        },
        "required": [
          "type",
          "status",
          "method",
          "input",
          "source_utc",
          "zodiac",
          "ayanamsa",
          "planets",
          "angles",
          "houses",
          "aspects",
          "metadata",
          "midpoint"
        ],
        "additionalProperties": false
      }
    },
    "responses": {
      "InvalidInput": {
        "description": "Invalid request, malformed JSON, out-of-range date/location, unknown model, invalid timezone or ambiguous/nonexistent clock-change time. Invalid attempts reaching quota reservation consume one unit.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            },
            "examples": {
              "typical": {
                "value": {
                  "error": "Invalid request"
                }
              }
            }
          },
          "text/html": {
            "schema": {
              "type": "string",
              "description": "A reverse proxy may return an HTML error page."
            }
          }
        }
      },
      "Unauthorized": {
        "description": "Missing, invalid, revoked API key or unavailable activated key owner. Dashboard cookies do not authenticate calculation routes.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            },
            "examples": {
              "typical": {
                "value": {
                  "error": "Missing API key"
                }
              }
            }
          }
        }
      },
      "ProRequired": {
        "description": "Timeline requires effective Pro entitlement; admission is refused before quota reservation.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            },
            "examples": {
              "typical": {
                "value": {
                  "error": "Pro plan required"
                }
              }
            }
          }
        }
      },
      "Forbidden": {
        "description": "Origin not allowed by production CORS policy. Server-to-server requests can omit Origin.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            },
            "examples": {
              "typical": {
                "value": {
                  "error": "Origin not allowed"
                }
              }
            }
          }
        }
      },
      "NotFound": {
        "description": "Wrong/case-variant/noncanonical or trailing-slash route; public paths have no version prefix.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            },
            "examples": {
              "typical": {
                "value": {
                  "error": "Not found"
                }
              }
            }
          },
          "text/html": {
            "schema": {
              "type": "string",
              "description": "A reverse proxy may return an HTML error page."
            }
          }
        }
      },
      "TooLarge": {
        "description": "Request exceeds the body limit; gateway JSON is capped at 128 KiB. Edge failures may be HTML.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            },
            "examples": {
              "typical": {
                "value": {
                  "error": "Request body too large"
                }
              }
            }
          },
          "text/html": {
            "schema": {
              "type": "string",
              "description": "A reverse proxy may return an HTML error page."
            }
          }
        }
      },
      "Limited": {
        "description": "Monthly quota exhausted, per-user two-request concurrency reached, or nginx rate/connection admission refused. Retry-After: 2 is sent for application per-user concurrency only, not a promise that monthly quota resets in two seconds.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            },
            "examples": {
              "typical": {
                "value": {
                  "error": "API quota exceeded"
                }
              }
            }
          },
          "text/html": {
            "schema": {
              "type": "string",
              "description": "A reverse proxy may return an HTML error page."
            }
          }
        },
        "headers": {
          "Retry-After": {
            "description": "Present for application concurrency rejection as 2 seconds. Other rejection sources may omit it or use a different delay. Do not automatically retry charged calculation attempts.",
            "schema": {
              "type": "string"
            }
          }
        }
      },
      "InternalFailure": {
        "description": "Bounded gateway/database/internal failure. An admitted attempt can still consume quota.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            },
            "examples": {
              "typical": {
                "value": {
                  "error": "Server error"
                }
              }
            }
          },
          "text/html": {
            "schema": {
              "type": "string",
              "description": "A reverse proxy may return an HTML error page."
            }
          }
        }
      },
      "EngineUnavailable": {
        "description": "Engine unavailable, unsuccessful internal server response or invalid upstream JSON. No engine internals are exposed.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            },
            "examples": {
              "typical": {
                "value": {
                  "error": "Birth chart calculation failed"
                }
              }
            }
          },
          "text/html": {
            "schema": {
              "type": "string",
              "description": "A reverse proxy may return an HTML error page."
            }
          }
        }
      },
      "Busy": {
        "description": "Four-request global calculation pool full (Retry-After: 2), maintenance or upstream service unavailable.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            },
            "examples": {
              "typical": {
                "value": {
                  "error": "Astrology service is busy; retry shortly"
                }
              }
            }
          },
          "text/html": {
            "schema": {
              "type": "string",
              "description": "A reverse proxy may return an HTML error page."
            }
          }
        },
        "headers": {
          "Retry-After": {
            "description": "Present for application concurrency rejection as 2 seconds. Other rejection sources may omit it or use a different delay. Do not automatically retry charged calculation attempts.",
            "schema": {
              "type": "string"
            }
          }
        }
      },
      "EngineTimeout": {
        "description": "Application engine timeout: 15 seconds normal, 60 seconds timeline. Timer includes response-body parsing; an admitted timeout consumes quota.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            },
            "examples": {
              "typical": {
                "value": {
                  "error": "Birth chart calculation failed"
                }
              }
            }
          },
          "text/html": {
            "schema": {
              "type": "string",
              "description": "A reverse proxy may return an HTML error page."
            }
          }
        }
      }
    }
  },
  "x-plan-limits": {
    "period": "UTC calendar month",
    "standard": {
      "free": 100,
      "basic": 10000,
      "pro": 100000
    },
    "nakshatra": {
      "pro": 1000
    }
  },
  "x-verification-boundary": "Schemas describe current source behavior; publication of this document is not evidence of a new live deployment or settled Stripe payment."
}
