{
  "openapi": "3.1.0",
  "paths": {
    "/lilavati/v1/panchang": {
      "get": {
        "summary": "Compute Panchang",
        "description": "Compute Panchang for a date (day mode) or for a specific instant\n(instant mode, when ``time`` is provided).",
        "operationId": "compute_panchang_v1_panchang_get",
        "parameters": [
          {
            "name": "date",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "format": "date"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Date (YYYY-MM-DD). Defaults to today.",
              "title": "Date"
            },
            "description": "Date (YYYY-MM-DD). Defaults to today."
          },
          {
            "name": "time",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Optional time (HH:MM or HH:MM:SS, 24-hour, local to the given timezone). When provided, the response reports panchanga values at that exact instant instead of sunrise-anchored day values. Day-only fields (sun, vara, muhurat windows, transition times) will be null in this mode.",
              "examples": [
                "06:00",
                "23:45:30"
              ],
              "title": "Time"
            },
            "description": "Optional time (HH:MM or HH:MM:SS, 24-hour, local to the given timezone). When provided, the response reports panchanga values at that exact instant instead of sunrise-anchored day values. Day-only fields (sun, vara, muhurat windows, transition times) will be null in this mode."
          },
          {
            "name": "include_muhurat",
            "in": "query",
            "required": false,
            "schema": {
              "type": "boolean",
              "description": "Include muhurat windows (ignored in instant mode)",
              "default": true,
              "title": "Include Muhurat"
            },
            "description": "Include muhurat windows (ignored in instant mode)"
          },
          {
            "name": "calendar_system",
            "in": "query",
            "required": false,
            "schema": {
              "$ref": "#/components/schemas/CalendarSystem",
              "description": "Lunar calendar system for māsa: 'amant' (South) or 'purnimant' (North)",
              "default": "amant"
            },
            "description": "Lunar calendar system for māsa: 'amant' (South) or 'purnimant' (North)"
          },
          {
            "name": "lat",
            "in": "query",
            "required": true,
            "schema": {
              "type": "number",
              "maximum": 90,
              "minimum": -90,
              "description": "Latitude",
              "title": "Lat"
            },
            "description": "Latitude"
          },
          {
            "name": "lng",
            "in": "query",
            "required": true,
            "schema": {
              "type": "number",
              "maximum": 180,
              "minimum": -180,
              "description": "Longitude",
              "title": "Lng"
            },
            "description": "Longitude"
          },
          {
            "name": "tz",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "description": "IANA timezone (e.g. 'Asia/Kolkata')",
              "default": "Asia/Kolkata",
              "title": "Tz"
            },
            "description": "IANA timezone (e.g. 'Asia/Kolkata')"
          },
          {
            "name": "altitude",
            "in": "query",
            "required": false,
            "schema": {
              "type": "number",
              "maximum": 8849,
              "minimum": 0,
              "description": "Altitude in meters",
              "default": 0.0,
              "title": "Altitude"
            },
            "description": "Altitude in meters"
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PanchangResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "description": "Unique request identifier",
                "schema": {
                  "type": "string",
                  "example": "req_a1b2c3d4e5f6"
                }
              },
              "X-RateLimit-Limit": {
                "description": "Maximum requests per minute for your tier",
                "schema": {
                  "type": "integer",
                  "example": 100
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests remaining in current window",
                "schema": {
                  "type": "integer",
                  "example": 95
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix timestamp when the rate limit window resets",
                "schema": {
                  "type": "integer",
                  "example": 1711929600
                }
              },
              "X-Cache": {
                "description": "Cache status — HIT (served from cache) or MISS (freshly computed)",
                "schema": {
                  "type": "string",
                  "enum": [
                    "HIT",
                    "MISS"
                  ]
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized — missing or invalid API key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/GatewayError"
                },
                "examples": {
                  "missing_key": {
                    "summary": "Missing API key",
                    "value": {
                      "error": {
                        "code": "MISSING_API_KEY",
                        "message": "X-API-Key header is required",
                        "request_id": "req_a1b2c3d4e5f6"
                      }
                    }
                  },
                  "invalid_key": {
                    "summary": "Invalid API key",
                    "value": {
                      "error": {
                        "code": "INVALID_API_KEY",
                        "message": "API key is invalid or inactive",
                        "request_id": "req_a1b2c3d4e5f6"
                      }
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded",
            "headers": {
              "Retry-After": {
                "description": "Seconds until the rate limit window resets",
                "schema": {
                  "type": "integer",
                  "example": 60
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/GatewayError"
                },
                "example": {
                  "error": {
                    "code": "RATE_LIMIT_EXCEEDED",
                    "message": "Rate limit exceeded. Upgrade at https://vibz.art/developers/pricing",
                    "request_id": "req_a1b2c3d4e5f6"
                  }
                }
              }
            }
          },
          "502": {
            "description": "Compute service unavailable",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/GatewayError"
                },
                "example": {
                  "error": {
                    "code": "COMPUTE_ERROR",
                    "message": "Computation service unavailable",
                    "request_id": "req_a1b2c3d4e5f6"
                  }
                }
              }
            }
          }
        },
        "tags": [
          "Lilavati — Calendar"
        ]
      }
    },
    "/lilavati/v1/festivals": {
      "get": {
        "summary": "Compute Festivals",
        "description": "Compute Hindu festival dates for a year and location.\n\nThe ``calendar_system`` parameter affects Krishna Paksha festival dates.\nShukla Paksha festivals are identical in both Purnimant and Amant systems.\n\nEach festival is enriched with shastric metadata from lilavati's\ncurated set when available — shloka, presiding deity, kathā summary,\nKadambini verse refs. Festivals without a metadata entry return\n``metadata: null`` and the caller falls back gracefully.",
        "operationId": "compute_festivals_v1_festivals_get",
        "parameters": [
          {
            "name": "year",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "maximum": 2100,
              "minimum": 1900,
              "description": "Year. Defaults to current year.",
              "title": "Year"
            },
            "description": "Year. Defaults to current year."
          },
          {
            "name": "calendar_system",
            "in": "query",
            "required": false,
            "schema": {
              "$ref": "#/components/schemas/CalendarSystem",
              "description": "Lunar calendar system: purnimant (North India) or amant (South/West).",
              "default": "purnimant"
            },
            "description": "Lunar calendar system: purnimant (North India) or amant (South/West)."
          },
          {
            "name": "lat",
            "in": "query",
            "required": true,
            "schema": {
              "type": "number",
              "maximum": 90,
              "minimum": -90,
              "description": "Latitude",
              "title": "Lat"
            },
            "description": "Latitude"
          },
          {
            "name": "lng",
            "in": "query",
            "required": true,
            "schema": {
              "type": "number",
              "maximum": 180,
              "minimum": -180,
              "description": "Longitude",
              "title": "Lng"
            },
            "description": "Longitude"
          },
          {
            "name": "tz",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "description": "IANA timezone (e.g. 'Asia/Kolkata')",
              "default": "Asia/Kolkata",
              "title": "Tz"
            },
            "description": "IANA timezone (e.g. 'Asia/Kolkata')"
          },
          {
            "name": "altitude",
            "in": "query",
            "required": false,
            "schema": {
              "type": "number",
              "maximum": 8849,
              "minimum": 0,
              "description": "Altitude in meters",
              "default": 0.0,
              "title": "Altitude"
            },
            "description": "Altitude in meters"
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/EnrichedFestivalInfo"
                  },
                  "title": "Response Compute Festivals V1 Festivals Get"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "description": "Unique request identifier",
                "schema": {
                  "type": "string",
                  "example": "req_a1b2c3d4e5f6"
                }
              },
              "X-RateLimit-Limit": {
                "description": "Maximum requests per minute for your tier",
                "schema": {
                  "type": "integer",
                  "example": 100
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests remaining in current window",
                "schema": {
                  "type": "integer",
                  "example": 95
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix timestamp when the rate limit window resets",
                "schema": {
                  "type": "integer",
                  "example": 1711929600
                }
              },
              "X-Cache": {
                "description": "Cache status — HIT (served from cache) or MISS (freshly computed)",
                "schema": {
                  "type": "string",
                  "enum": [
                    "HIT",
                    "MISS"
                  ]
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized — missing or invalid API key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/GatewayError"
                },
                "examples": {
                  "missing_key": {
                    "summary": "Missing API key",
                    "value": {
                      "error": {
                        "code": "MISSING_API_KEY",
                        "message": "X-API-Key header is required",
                        "request_id": "req_a1b2c3d4e5f6"
                      }
                    }
                  },
                  "invalid_key": {
                    "summary": "Invalid API key",
                    "value": {
                      "error": {
                        "code": "INVALID_API_KEY",
                        "message": "API key is invalid or inactive",
                        "request_id": "req_a1b2c3d4e5f6"
                      }
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded",
            "headers": {
              "Retry-After": {
                "description": "Seconds until the rate limit window resets",
                "schema": {
                  "type": "integer",
                  "example": 60
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/GatewayError"
                },
                "example": {
                  "error": {
                    "code": "RATE_LIMIT_EXCEEDED",
                    "message": "Rate limit exceeded. Upgrade at https://vibz.art/developers/pricing",
                    "request_id": "req_a1b2c3d4e5f6"
                  }
                }
              }
            }
          },
          "502": {
            "description": "Compute service unavailable",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/GatewayError"
                },
                "example": {
                  "error": {
                    "code": "COMPUTE_ERROR",
                    "message": "Computation service unavailable",
                    "request_id": "req_a1b2c3d4e5f6"
                  }
                }
              }
            }
          }
        },
        "tags": [
          "Lilavati — Calendar"
        ]
      }
    },
    "/lilavati/v1/namakarna": {
      "get": {
        "summary": "Namakarna",
        "description": "Compute Namakarna (Vedic naming) data for a birth datetime and location.",
        "operationId": "namakarna_v1_namakarna_get",
        "parameters": [
          {
            "name": "date",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Birth date (YYYY-MM-DD)",
              "title": "Date"
            },
            "description": "Birth date (YYYY-MM-DD)"
          },
          {
            "name": "time",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "description": "Birth time (HH:MM or HH:MM:SS). Defaults to noon.",
              "default": "12:00",
              "title": "Time"
            },
            "description": "Birth time (HH:MM or HH:MM:SS). Defaults to noon."
          },
          {
            "name": "lat",
            "in": "query",
            "required": true,
            "schema": {
              "type": "number",
              "maximum": 90,
              "minimum": -90,
              "description": "Latitude",
              "title": "Lat"
            },
            "description": "Latitude"
          },
          {
            "name": "lng",
            "in": "query",
            "required": true,
            "schema": {
              "type": "number",
              "maximum": 180,
              "minimum": -180,
              "description": "Longitude",
              "title": "Lng"
            },
            "description": "Longitude"
          },
          {
            "name": "tz",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "description": "IANA timezone (e.g. 'Asia/Kolkata')",
              "default": "Asia/Kolkata",
              "title": "Tz"
            },
            "description": "IANA timezone (e.g. 'Asia/Kolkata')"
          },
          {
            "name": "altitude",
            "in": "query",
            "required": false,
            "schema": {
              "type": "number",
              "maximum": 8849,
              "minimum": 0,
              "description": "Altitude in meters",
              "default": 0.0,
              "title": "Altitude"
            },
            "description": "Altitude in meters"
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/NamakarnaResult"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "description": "Unique request identifier",
                "schema": {
                  "type": "string",
                  "example": "req_a1b2c3d4e5f6"
                }
              },
              "X-RateLimit-Limit": {
                "description": "Maximum requests per minute for your tier",
                "schema": {
                  "type": "integer",
                  "example": 100
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests remaining in current window",
                "schema": {
                  "type": "integer",
                  "example": 95
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix timestamp when the rate limit window resets",
                "schema": {
                  "type": "integer",
                  "example": 1711929600
                }
              },
              "X-Cache": {
                "description": "Cache status — HIT (served from cache) or MISS (freshly computed)",
                "schema": {
                  "type": "string",
                  "enum": [
                    "HIT",
                    "MISS"
                  ]
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized — missing or invalid API key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/GatewayError"
                },
                "examples": {
                  "missing_key": {
                    "summary": "Missing API key",
                    "value": {
                      "error": {
                        "code": "MISSING_API_KEY",
                        "message": "X-API-Key header is required",
                        "request_id": "req_a1b2c3d4e5f6"
                      }
                    }
                  },
                  "invalid_key": {
                    "summary": "Invalid API key",
                    "value": {
                      "error": {
                        "code": "INVALID_API_KEY",
                        "message": "API key is invalid or inactive",
                        "request_id": "req_a1b2c3d4e5f6"
                      }
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded",
            "headers": {
              "Retry-After": {
                "description": "Seconds until the rate limit window resets",
                "schema": {
                  "type": "integer",
                  "example": 60
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/GatewayError"
                },
                "example": {
                  "error": {
                    "code": "RATE_LIMIT_EXCEEDED",
                    "message": "Rate limit exceeded. Upgrade at https://vibz.art/developers/pricing",
                    "request_id": "req_a1b2c3d4e5f6"
                  }
                }
              }
            }
          },
          "502": {
            "description": "Compute service unavailable",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/GatewayError"
                },
                "example": {
                  "error": {
                    "code": "COMPUTE_ERROR",
                    "message": "Computation service unavailable",
                    "request_id": "req_a1b2c3d4e5f6"
                  }
                }
              }
            }
          }
        },
        "tags": [
          "Lilavati — Namakarna"
        ]
      }
    },
    "/lilavati/v1/shraddha": {
      "get": {
        "summary": "Compute Shraddha",
        "description": "Compute complete Shraddha timeline from death date.\n\nAll computation is delegated to the Rust panchang-core crate for\nperformance (~4s vs ~70s+ in pure Python).",
        "operationId": "compute_shraddha_v1_shraddha_get",
        "parameters": [
          {
            "name": "date",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Date of death (YYYY-MM-DD)",
              "title": "Date"
            },
            "description": "Date of death (YYYY-MM-DD)"
          },
          {
            "name": "monthly_count",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "maximum": 24,
              "minimum": 1,
              "description": "Number of monthly shraddhas to compute",
              "default": 16,
              "title": "Monthly Count"
            },
            "description": "Number of monthly shraddhas to compute"
          },
          {
            "name": "annual_years",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "maximum": 25,
              "minimum": 1,
              "description": "Number of years of annual shraddha dates",
              "default": 10,
              "title": "Annual Years"
            },
            "description": "Number of years of annual shraddha dates"
          },
          {
            "name": "pitru_paksha_years",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "maximum": 10,
              "minimum": 1,
              "description": "Number of years of Pitru Paksha dates",
              "default": 5,
              "title": "Pitru Paksha Years"
            },
            "description": "Number of years of Pitru Paksha dates"
          },
          {
            "name": "lat",
            "in": "query",
            "required": true,
            "schema": {
              "type": "number",
              "maximum": 90,
              "minimum": -90,
              "description": "Latitude",
              "title": "Lat"
            },
            "description": "Latitude"
          },
          {
            "name": "lng",
            "in": "query",
            "required": true,
            "schema": {
              "type": "number",
              "maximum": 180,
              "minimum": -180,
              "description": "Longitude",
              "title": "Lng"
            },
            "description": "Longitude"
          },
          {
            "name": "tz",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "description": "IANA timezone (e.g. 'Asia/Kolkata')",
              "default": "Asia/Kolkata",
              "title": "Tz"
            },
            "description": "IANA timezone (e.g. 'Asia/Kolkata')"
          },
          {
            "name": "altitude",
            "in": "query",
            "required": false,
            "schema": {
              "type": "number",
              "maximum": 8849,
              "minimum": 0,
              "description": "Altitude in meters",
              "default": 0.0,
              "title": "Altitude"
            },
            "description": "Altitude in meters"
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ShraddhaResult"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "description": "Unique request identifier",
                "schema": {
                  "type": "string",
                  "example": "req_a1b2c3d4e5f6"
                }
              },
              "X-RateLimit-Limit": {
                "description": "Maximum requests per minute for your tier",
                "schema": {
                  "type": "integer",
                  "example": 100
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests remaining in current window",
                "schema": {
                  "type": "integer",
                  "example": 95
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix timestamp when the rate limit window resets",
                "schema": {
                  "type": "integer",
                  "example": 1711929600
                }
              },
              "X-Cache": {
                "description": "Cache status — HIT (served from cache) or MISS (freshly computed)",
                "schema": {
                  "type": "string",
                  "enum": [
                    "HIT",
                    "MISS"
                  ]
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized — missing or invalid API key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/GatewayError"
                },
                "examples": {
                  "missing_key": {
                    "summary": "Missing API key",
                    "value": {
                      "error": {
                        "code": "MISSING_API_KEY",
                        "message": "X-API-Key header is required",
                        "request_id": "req_a1b2c3d4e5f6"
                      }
                    }
                  },
                  "invalid_key": {
                    "summary": "Invalid API key",
                    "value": {
                      "error": {
                        "code": "INVALID_API_KEY",
                        "message": "API key is invalid or inactive",
                        "request_id": "req_a1b2c3d4e5f6"
                      }
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded",
            "headers": {
              "Retry-After": {
                "description": "Seconds until the rate limit window resets",
                "schema": {
                  "type": "integer",
                  "example": 60
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/GatewayError"
                },
                "example": {
                  "error": {
                    "code": "RATE_LIMIT_EXCEEDED",
                    "message": "Rate limit exceeded. Upgrade at https://vibz.art/developers/pricing",
                    "request_id": "req_a1b2c3d4e5f6"
                  }
                }
              }
            }
          },
          "502": {
            "description": "Compute service unavailable",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/GatewayError"
                },
                "example": {
                  "error": {
                    "code": "COMPUTE_ERROR",
                    "message": "Computation service unavailable",
                    "request_id": "req_a1b2c3d4e5f6"
                  }
                }
              }
            }
          }
        },
        "tags": [
          "Lilavati — Shraddha"
        ]
      }
    },
    "/lilavati/v1/vivah-muhurat": {
      "get": {
        "summary": "Compute Vivah Muhurat",
        "description": "Compute auspicious Hindu wedding (Vivah) dates with sub-day windows.\n\nEnforces 13 classical criteria from Muhurta Chintamani, Dharma Sindhu, and\nBrihat Samhita — including Kharmas, Chaturmasa, Shukra/Guru Asta, and\nAmritadi Marana Yoga rejections. Targets parity-or-better with Drik Panchang.",
        "operationId": "compute_vivah_muhurat_v1_vivah_muhurat_get",
        "parameters": [
          {
            "name": "start_date",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "format": "date"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Start of search range (YYYY-MM-DD). Defaults to today.",
              "title": "Start Date"
            },
            "description": "Start of search range (YYYY-MM-DD). Defaults to today."
          },
          {
            "name": "end_date",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "format": "date"
                },
                {
                  "type": "null"
                }
              ],
              "description": "End of search range (YYYY-MM-DD). Defaults to 12 months from start.",
              "title": "End Date"
            },
            "description": "End of search range (YYYY-MM-DD). Defaults to 12 months from start."
          },
          {
            "name": "max_results",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "maximum": 60,
              "minimum": 1,
              "description": "Maximum number of auspicious dates to return.",
              "default": 20,
              "title": "Max Results"
            },
            "description": "Maximum number of auspicious dates to return."
          },
          {
            "name": "calendar_system",
            "in": "query",
            "required": false,
            "schema": {
              "$ref": "#/components/schemas/CalendarSystem",
              "description": "Lunar calendar system (purnimant or amant).",
              "default": "purnimant"
            },
            "description": "Lunar calendar system (purnimant or amant)."
          },
          {
            "name": "include_windows",
            "in": "query",
            "required": false,
            "schema": {
              "type": "boolean",
              "description": "If true, compute window-level sub-muhurats (Drik-style). Slightly slower but much more useful output.",
              "default": true,
              "title": "Include Windows"
            },
            "description": "If true, compute window-level sub-muhurats (Drik-style). Slightly slower but much more useful output."
          },
          {
            "name": "lat",
            "in": "query",
            "required": true,
            "schema": {
              "type": "number",
              "maximum": 90,
              "minimum": -90,
              "description": "Latitude",
              "title": "Lat"
            },
            "description": "Latitude"
          },
          {
            "name": "lng",
            "in": "query",
            "required": true,
            "schema": {
              "type": "number",
              "maximum": 180,
              "minimum": -180,
              "description": "Longitude",
              "title": "Lng"
            },
            "description": "Longitude"
          },
          {
            "name": "tz",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "description": "IANA timezone (e.g. 'Asia/Kolkata')",
              "default": "Asia/Kolkata",
              "title": "Tz"
            },
            "description": "IANA timezone (e.g. 'Asia/Kolkata')"
          },
          {
            "name": "altitude",
            "in": "query",
            "required": false,
            "schema": {
              "type": "number",
              "maximum": 8849,
              "minimum": 0,
              "description": "Altitude in meters",
              "default": 0.0,
              "title": "Altitude"
            },
            "description": "Altitude in meters"
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/VivahMuhuratResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "description": "Unique request identifier",
                "schema": {
                  "type": "string",
                  "example": "req_a1b2c3d4e5f6"
                }
              },
              "X-RateLimit-Limit": {
                "description": "Maximum requests per minute for your tier",
                "schema": {
                  "type": "integer",
                  "example": 100
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests remaining in current window",
                "schema": {
                  "type": "integer",
                  "example": 95
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix timestamp when the rate limit window resets",
                "schema": {
                  "type": "integer",
                  "example": 1711929600
                }
              },
              "X-Cache": {
                "description": "Cache status — HIT (served from cache) or MISS (freshly computed)",
                "schema": {
                  "type": "string",
                  "enum": [
                    "HIT",
                    "MISS"
                  ]
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized — missing or invalid API key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/GatewayError"
                },
                "examples": {
                  "missing_key": {
                    "summary": "Missing API key",
                    "value": {
                      "error": {
                        "code": "MISSING_API_KEY",
                        "message": "X-API-Key header is required",
                        "request_id": "req_a1b2c3d4e5f6"
                      }
                    }
                  },
                  "invalid_key": {
                    "summary": "Invalid API key",
                    "value": {
                      "error": {
                        "code": "INVALID_API_KEY",
                        "message": "API key is invalid or inactive",
                        "request_id": "req_a1b2c3d4e5f6"
                      }
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded",
            "headers": {
              "Retry-After": {
                "description": "Seconds until the rate limit window resets",
                "schema": {
                  "type": "integer",
                  "example": 60
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/GatewayError"
                },
                "example": {
                  "error": {
                    "code": "RATE_LIMIT_EXCEEDED",
                    "message": "Rate limit exceeded. Upgrade at https://vibz.art/developers/pricing",
                    "request_id": "req_a1b2c3d4e5f6"
                  }
                }
              }
            }
          },
          "502": {
            "description": "Compute service unavailable",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/GatewayError"
                },
                "example": {
                  "error": {
                    "code": "COMPUTE_ERROR",
                    "message": "Computation service unavailable",
                    "request_id": "req_a1b2c3d4e5f6"
                  }
                }
              }
            }
          }
        }
      }
    },
    "/lilavati/v1/kundali": {
      "get": {
        "summary": "Kundali",
        "description": "Compute a complete Khona Kundali for a birth event.\n\nInputs:\n  * date / time — birth event in the location's timezone\n  * lat / lng / tz / altitude — provided via ``get_location`` dependency\n  * house_system — Bhāva-Chalit cusp system\n\nOutput: three-layer ``KundaliResult`` (computed / classical / provenance).",
        "operationId": "kundali_v1_kundali_get",
        "parameters": [
          {
            "name": "date",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Birth date (YYYY-MM-DD).",
              "title": "Date"
            },
            "description": "Birth date (YYYY-MM-DD)."
          },
          {
            "name": "time",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Birth time (HH:MM or HH:MM:SS) in the location's timezone.",
              "title": "Time"
            },
            "description": "Birth time (HH:MM or HH:MM:SS) in the location's timezone."
          },
          {
            "name": "house_system",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "description": "One of: placidus, whole_sign, equal, porphyry. Default: placidus.",
              "default": "placidus",
              "title": "House System"
            },
            "description": "One of: placidus, whole_sign, equal, porphyry. Default: placidus."
          },
          {
            "name": "lat",
            "in": "query",
            "required": true,
            "schema": {
              "type": "number",
              "maximum": 90,
              "minimum": -90,
              "description": "Latitude",
              "title": "Lat"
            },
            "description": "Latitude"
          },
          {
            "name": "lng",
            "in": "query",
            "required": true,
            "schema": {
              "type": "number",
              "maximum": 180,
              "minimum": -180,
              "description": "Longitude",
              "title": "Lng"
            },
            "description": "Longitude"
          },
          {
            "name": "tz",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "description": "IANA timezone (e.g. 'Asia/Kolkata')",
              "default": "Asia/Kolkata",
              "title": "Tz"
            },
            "description": "IANA timezone (e.g. 'Asia/Kolkata')"
          },
          {
            "name": "altitude",
            "in": "query",
            "required": false,
            "schema": {
              "type": "number",
              "maximum": 8849,
              "minimum": 0,
              "description": "Altitude in meters",
              "default": 0.0,
              "title": "Altitude"
            },
            "description": "Altitude in meters"
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/KundaliResult"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "description": "Unique request identifier",
                "schema": {
                  "type": "string",
                  "example": "req_a1b2c3d4e5f6"
                }
              },
              "X-RateLimit-Limit": {
                "description": "Maximum requests per minute for your tier",
                "schema": {
                  "type": "integer",
                  "example": 100
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests remaining in current window",
                "schema": {
                  "type": "integer",
                  "example": 95
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix timestamp when the rate limit window resets",
                "schema": {
                  "type": "integer",
                  "example": 1711929600
                }
              },
              "X-Cache": {
                "description": "Cache status — HIT (served from cache) or MISS (freshly computed)",
                "schema": {
                  "type": "string",
                  "enum": [
                    "HIT",
                    "MISS"
                  ]
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized — missing or invalid API key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/GatewayError"
                },
                "examples": {
                  "missing_key": {
                    "summary": "Missing API key",
                    "value": {
                      "error": {
                        "code": "MISSING_API_KEY",
                        "message": "X-API-Key header is required",
                        "request_id": "req_a1b2c3d4e5f6"
                      }
                    }
                  },
                  "invalid_key": {
                    "summary": "Invalid API key",
                    "value": {
                      "error": {
                        "code": "INVALID_API_KEY",
                        "message": "API key is invalid or inactive",
                        "request_id": "req_a1b2c3d4e5f6"
                      }
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded",
            "headers": {
              "Retry-After": {
                "description": "Seconds until the rate limit window resets",
                "schema": {
                  "type": "integer",
                  "example": 60
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/GatewayError"
                },
                "example": {
                  "error": {
                    "code": "RATE_LIMIT_EXCEEDED",
                    "message": "Rate limit exceeded. Upgrade at https://vibz.art/developers/pricing",
                    "request_id": "req_a1b2c3d4e5f6"
                  }
                }
              }
            }
          },
          "502": {
            "description": "Compute service unavailable",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/GatewayError"
                },
                "example": {
                  "error": {
                    "code": "COMPUTE_ERROR",
                    "message": "Computation service unavailable",
                    "request_id": "req_a1b2c3d4e5f6"
                  }
                }
              }
            }
          }
        }
      }
    },
    "/kadambini/v1/cite/{work_slug}/editions": {
      "get": {
        "tags": [
          "Kadambini — Corpus"
        ],
        "summary": "List Work Editions",
        "description": "List every edition for a Work, with slug + source metadata.\n\nUse this to discover pinnable editions for citation. The first-returned\nedition (by adapter rank) is the default when `?edition=...` is omitted\non the verse endpoints — its `is_default` flag is true.",
        "operationId": "list_work_editions_v1_cite__work_slug__editions_get",
        "security": [
          {
            "APIKeyHeader": []
          }
        ],
        "parameters": [
          {
            "name": "work_slug",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Work Slug"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WorkEditionsResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "description": "Unique request identifier",
                "schema": {
                  "type": "string",
                  "example": "req_a1b2c3d4e5f6"
                }
              },
              "X-RateLimit-Limit": {
                "description": "Maximum requests per minute for your tier",
                "schema": {
                  "type": "integer",
                  "example": 100
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests remaining in current window",
                "schema": {
                  "type": "integer",
                  "example": 95
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix timestamp when the rate limit window resets",
                "schema": {
                  "type": "integer",
                  "example": 1711929600
                }
              },
              "X-Cache": {
                "description": "Cache status — HIT (served from cache) or MISS (freshly computed)",
                "schema": {
                  "type": "string",
                  "enum": [
                    "HIT",
                    "MISS"
                  ]
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized — missing or invalid API key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/GatewayError"
                },
                "examples": {
                  "missing_key": {
                    "summary": "Missing API key",
                    "value": {
                      "error": {
                        "code": "MISSING_API_KEY",
                        "message": "X-API-Key header is required",
                        "request_id": "req_a1b2c3d4e5f6"
                      }
                    }
                  },
                  "invalid_key": {
                    "summary": "Invalid API key",
                    "value": {
                      "error": {
                        "code": "INVALID_API_KEY",
                        "message": "API key is invalid or inactive",
                        "request_id": "req_a1b2c3d4e5f6"
                      }
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded",
            "headers": {
              "Retry-After": {
                "description": "Seconds until the rate limit window resets",
                "schema": {
                  "type": "integer",
                  "example": 60
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/GatewayError"
                },
                "example": {
                  "error": {
                    "code": "RATE_LIMIT_EXCEEDED",
                    "message": "Rate limit exceeded. Upgrade at https://vibz.art/developers/pricing",
                    "request_id": "req_a1b2c3d4e5f6"
                  }
                }
              }
            }
          },
          "502": {
            "description": "Compute service unavailable",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/GatewayError"
                },
                "example": {
                  "error": {
                    "code": "COMPUTE_ERROR",
                    "message": "Computation service unavailable",
                    "request_id": "req_a1b2c3d4e5f6"
                  }
                }
              }
            }
          }
        }
      }
    },
    "/kadambini/v1/cite/{work_slug}/{chapter_num}/{verse_num}": {
      "get": {
        "tags": [
          "Kadambini — Corpus"
        ],
        "summary": "Cite Verse",
        "description": "Look up a verse by reference (e.g., /cite/bhagavadgita/2/47).",
        "operationId": "cite_verse_v1_cite__work_slug___chapter_num___verse_num__get",
        "security": [
          {
            "APIKeyHeader": []
          }
        ],
        "parameters": [
          {
            "name": "work_slug",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Work Slug"
            }
          },
          {
            "name": "chapter_num",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "title": "Chapter Num"
            }
          },
          {
            "name": "verse_num",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Verse Num"
            }
          },
          {
            "name": "edition",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Edition slug (optional). When set, filters to that specific edition; when unset, highest-adapter-rank wins.",
              "title": "Edition"
            },
            "description": "Edition slug (optional). When set, filters to that specific edition; when unset, highest-adapter-rank wins."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CiteResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "description": "Unique request identifier",
                "schema": {
                  "type": "string",
                  "example": "req_a1b2c3d4e5f6"
                }
              },
              "X-RateLimit-Limit": {
                "description": "Maximum requests per minute for your tier",
                "schema": {
                  "type": "integer",
                  "example": 100
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests remaining in current window",
                "schema": {
                  "type": "integer",
                  "example": 95
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix timestamp when the rate limit window resets",
                "schema": {
                  "type": "integer",
                  "example": 1711929600
                }
              },
              "X-Cache": {
                "description": "Cache status — HIT (served from cache) or MISS (freshly computed)",
                "schema": {
                  "type": "string",
                  "enum": [
                    "HIT",
                    "MISS"
                  ]
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized — missing or invalid API key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/GatewayError"
                },
                "examples": {
                  "missing_key": {
                    "summary": "Missing API key",
                    "value": {
                      "error": {
                        "code": "MISSING_API_KEY",
                        "message": "X-API-Key header is required",
                        "request_id": "req_a1b2c3d4e5f6"
                      }
                    }
                  },
                  "invalid_key": {
                    "summary": "Invalid API key",
                    "value": {
                      "error": {
                        "code": "INVALID_API_KEY",
                        "message": "API key is invalid or inactive",
                        "request_id": "req_a1b2c3d4e5f6"
                      }
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded",
            "headers": {
              "Retry-After": {
                "description": "Seconds until the rate limit window resets",
                "schema": {
                  "type": "integer",
                  "example": 60
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/GatewayError"
                },
                "example": {
                  "error": {
                    "code": "RATE_LIMIT_EXCEEDED",
                    "message": "Rate limit exceeded. Upgrade at https://vibz.art/developers/pricing",
                    "request_id": "req_a1b2c3d4e5f6"
                  }
                }
              }
            }
          },
          "502": {
            "description": "Compute service unavailable",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/GatewayError"
                },
                "example": {
                  "error": {
                    "code": "COMPUTE_ERROR",
                    "message": "Computation service unavailable",
                    "request_id": "req_a1b2c3d4e5f6"
                  }
                }
              }
            }
          }
        }
      }
    },
    "/kadambini/v1/cite/{work_slug}/{verse_num}": {
      "get": {
        "tags": [
          "Kadambini — Corpus"
        ],
        "summary": "Cite Verse No Chapter",
        "description": "Cite a verse from a work without chapters (stotras, sutras, etc.).",
        "operationId": "cite_verse_no_chapter_v1_cite__work_slug___verse_num__get",
        "security": [
          {
            "APIKeyHeader": []
          }
        ],
        "parameters": [
          {
            "name": "work_slug",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Work Slug"
            }
          },
          {
            "name": "verse_num",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Verse Num"
            }
          },
          {
            "name": "edition",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Edition slug (optional). When set, filters to that specific edition; when unset, highest-adapter-rank wins.",
              "title": "Edition"
            },
            "description": "Edition slug (optional). When set, filters to that specific edition; when unset, highest-adapter-rank wins."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CiteResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "description": "Unique request identifier",
                "schema": {
                  "type": "string",
                  "example": "req_a1b2c3d4e5f6"
                }
              },
              "X-RateLimit-Limit": {
                "description": "Maximum requests per minute for your tier",
                "schema": {
                  "type": "integer",
                  "example": 100
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests remaining in current window",
                "schema": {
                  "type": "integer",
                  "example": 95
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix timestamp when the rate limit window resets",
                "schema": {
                  "type": "integer",
                  "example": 1711929600
                }
              },
              "X-Cache": {
                "description": "Cache status — HIT (served from cache) or MISS (freshly computed)",
                "schema": {
                  "type": "string",
                  "enum": [
                    "HIT",
                    "MISS"
                  ]
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized — missing or invalid API key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/GatewayError"
                },
                "examples": {
                  "missing_key": {
                    "summary": "Missing API key",
                    "value": {
                      "error": {
                        "code": "MISSING_API_KEY",
                        "message": "X-API-Key header is required",
                        "request_id": "req_a1b2c3d4e5f6"
                      }
                    }
                  },
                  "invalid_key": {
                    "summary": "Invalid API key",
                    "value": {
                      "error": {
                        "code": "INVALID_API_KEY",
                        "message": "API key is invalid or inactive",
                        "request_id": "req_a1b2c3d4e5f6"
                      }
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded",
            "headers": {
              "Retry-After": {
                "description": "Seconds until the rate limit window resets",
                "schema": {
                  "type": "integer",
                  "example": 60
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/GatewayError"
                },
                "example": {
                  "error": {
                    "code": "RATE_LIMIT_EXCEEDED",
                    "message": "Rate limit exceeded. Upgrade at https://vibz.art/developers/pricing",
                    "request_id": "req_a1b2c3d4e5f6"
                  }
                }
              }
            }
          },
          "502": {
            "description": "Compute service unavailable",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/GatewayError"
                },
                "example": {
                  "error": {
                    "code": "COMPUTE_ERROR",
                    "message": "Computation service unavailable",
                    "request_id": "req_a1b2c3d4e5f6"
                  }
                }
              }
            }
          }
        }
      }
    },
    "/kadambini/v1/search": {
      "get": {
        "tags": [
          "Kadambini — Corpus"
        ],
        "summary": "Search Corpus",
        "description": "Search verses in the Sanskrit corpus.\n\nModes:\n- fulltext: Search verse text (IAST + SLP1) using Postgres full-text search\n- translation: Search English/Hindi translations\n\nResults ranked by relevance (ts_rank).",
        "operationId": "search_corpus_v1_search_get",
        "security": [
          {
            "APIKeyHeader": []
          }
        ],
        "parameters": [
          {
            "name": "q",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 500,
              "description": "Search query",
              "title": "Q"
            },
            "description": "Search query"
          },
          {
            "name": "mode",
            "in": "query",
            "required": false,
            "schema": {
              "$ref": "#/components/schemas/SearchMode",
              "description": "Search mode",
              "default": "fulltext"
            },
            "description": "Search mode"
          },
          {
            "name": "work",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Filter by work title (partial match)",
              "title": "Work"
            },
            "description": "Filter by work title (partial match)"
          },
          {
            "name": "category",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Filter by work category",
              "title": "Category"
            },
            "description": "Filter by work category"
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "maximum": 100,
              "minimum": 1,
              "default": 10,
              "title": "Limit"
            }
          },
          {
            "name": "offset",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "minimum": 0,
              "default": 0,
              "title": "Offset"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SearchResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "description": "Unique request identifier",
                "schema": {
                  "type": "string",
                  "example": "req_a1b2c3d4e5f6"
                }
              },
              "X-RateLimit-Limit": {
                "description": "Maximum requests per minute for your tier",
                "schema": {
                  "type": "integer",
                  "example": 100
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests remaining in current window",
                "schema": {
                  "type": "integer",
                  "example": 95
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix timestamp when the rate limit window resets",
                "schema": {
                  "type": "integer",
                  "example": 1711929600
                }
              },
              "X-Cache": {
                "description": "Cache status — HIT (served from cache) or MISS (freshly computed)",
                "schema": {
                  "type": "string",
                  "enum": [
                    "HIT",
                    "MISS"
                  ]
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized — missing or invalid API key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/GatewayError"
                },
                "examples": {
                  "missing_key": {
                    "summary": "Missing API key",
                    "value": {
                      "error": {
                        "code": "MISSING_API_KEY",
                        "message": "X-API-Key header is required",
                        "request_id": "req_a1b2c3d4e5f6"
                      }
                    }
                  },
                  "invalid_key": {
                    "summary": "Invalid API key",
                    "value": {
                      "error": {
                        "code": "INVALID_API_KEY",
                        "message": "API key is invalid or inactive",
                        "request_id": "req_a1b2c3d4e5f6"
                      }
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded",
            "headers": {
              "Retry-After": {
                "description": "Seconds until the rate limit window resets",
                "schema": {
                  "type": "integer",
                  "example": 60
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/GatewayError"
                },
                "example": {
                  "error": {
                    "code": "RATE_LIMIT_EXCEEDED",
                    "message": "Rate limit exceeded. Upgrade at https://vibz.art/developers/pricing",
                    "request_id": "req_a1b2c3d4e5f6"
                  }
                }
              }
            }
          },
          "502": {
            "description": "Compute service unavailable",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/GatewayError"
                },
                "example": {
                  "error": {
                    "code": "COMPUTE_ERROR",
                    "message": "Computation service unavailable",
                    "request_id": "req_a1b2c3d4e5f6"
                  }
                }
              }
            }
          }
        }
      }
    },
    "/kadambini/v1/entity": {
      "get": {
        "tags": [
          "Kadambini — Knowledge Graph"
        ],
        "summary": "List Entities",
        "description": "List entities from the knowledge graph, with optional filtering.",
        "operationId": "list_entities_v1_entity_get",
        "security": [
          {
            "APIKeyHeader": []
          }
        ],
        "parameters": [
          {
            "name": "q",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Search by name (partial match)",
              "title": "Q"
            },
            "description": "Search by name (partial match)"
          },
          {
            "name": "entity_type",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Filter by type (deity, rishi, place, etc.)",
              "title": "Entity Type"
            },
            "description": "Filter by type (deity, rishi, place, etc.)"
          },
          {
            "name": "page",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "minimum": 1,
              "default": 1,
              "title": "Page"
            }
          },
          {
            "name": "per_page",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "maximum": 100,
              "minimum": 1,
              "default": 25,
              "title": "Per Page"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/EntityListResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "description": "Unique request identifier",
                "schema": {
                  "type": "string",
                  "example": "req_a1b2c3d4e5f6"
                }
              },
              "X-RateLimit-Limit": {
                "description": "Maximum requests per minute for your tier",
                "schema": {
                  "type": "integer",
                  "example": 100
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests remaining in current window",
                "schema": {
                  "type": "integer",
                  "example": 95
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix timestamp when the rate limit window resets",
                "schema": {
                  "type": "integer",
                  "example": 1711929600
                }
              },
              "X-Cache": {
                "description": "Cache status — HIT (served from cache) or MISS (freshly computed)",
                "schema": {
                  "type": "string",
                  "enum": [
                    "HIT",
                    "MISS"
                  ]
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized — missing or invalid API key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/GatewayError"
                },
                "examples": {
                  "missing_key": {
                    "summary": "Missing API key",
                    "value": {
                      "error": {
                        "code": "MISSING_API_KEY",
                        "message": "X-API-Key header is required",
                        "request_id": "req_a1b2c3d4e5f6"
                      }
                    }
                  },
                  "invalid_key": {
                    "summary": "Invalid API key",
                    "value": {
                      "error": {
                        "code": "INVALID_API_KEY",
                        "message": "API key is invalid or inactive",
                        "request_id": "req_a1b2c3d4e5f6"
                      }
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded",
            "headers": {
              "Retry-After": {
                "description": "Seconds until the rate limit window resets",
                "schema": {
                  "type": "integer",
                  "example": 60
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/GatewayError"
                },
                "example": {
                  "error": {
                    "code": "RATE_LIMIT_EXCEEDED",
                    "message": "Rate limit exceeded. Upgrade at https://vibz.art/developers/pricing",
                    "request_id": "req_a1b2c3d4e5f6"
                  }
                }
              }
            }
          },
          "502": {
            "description": "Compute service unavailable",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/GatewayError"
                },
                "example": {
                  "error": {
                    "code": "COMPUTE_ERROR",
                    "message": "Computation service unavailable",
                    "request_id": "req_a1b2c3d4e5f6"
                  }
                }
              }
            }
          }
        }
      }
    },
    "/kadambini/v1/entity/{entity_id}": {
      "get": {
        "tags": [
          "Kadambini — Knowledge Graph"
        ],
        "summary": "Get Entity",
        "description": "Get a single entity by ID with all aliases and relations.",
        "operationId": "get_entity_v1_entity__entity_id__get",
        "security": [
          {
            "APIKeyHeader": []
          }
        ],
        "parameters": [
          {
            "name": "entity_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Entity Id"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/EntityOut"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "description": "Unique request identifier",
                "schema": {
                  "type": "string",
                  "example": "req_a1b2c3d4e5f6"
                }
              },
              "X-RateLimit-Limit": {
                "description": "Maximum requests per minute for your tier",
                "schema": {
                  "type": "integer",
                  "example": 100
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests remaining in current window",
                "schema": {
                  "type": "integer",
                  "example": 95
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix timestamp when the rate limit window resets",
                "schema": {
                  "type": "integer",
                  "example": 1711929600
                }
              },
              "X-Cache": {
                "description": "Cache status — HIT (served from cache) or MISS (freshly computed)",
                "schema": {
                  "type": "string",
                  "enum": [
                    "HIT",
                    "MISS"
                  ]
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized — missing or invalid API key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/GatewayError"
                },
                "examples": {
                  "missing_key": {
                    "summary": "Missing API key",
                    "value": {
                      "error": {
                        "code": "MISSING_API_KEY",
                        "message": "X-API-Key header is required",
                        "request_id": "req_a1b2c3d4e5f6"
                      }
                    }
                  },
                  "invalid_key": {
                    "summary": "Invalid API key",
                    "value": {
                      "error": {
                        "code": "INVALID_API_KEY",
                        "message": "API key is invalid or inactive",
                        "request_id": "req_a1b2c3d4e5f6"
                      }
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded",
            "headers": {
              "Retry-After": {
                "description": "Seconds until the rate limit window resets",
                "schema": {
                  "type": "integer",
                  "example": 60
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/GatewayError"
                },
                "example": {
                  "error": {
                    "code": "RATE_LIMIT_EXCEEDED",
                    "message": "Rate limit exceeded. Upgrade at https://vibz.art/developers/pricing",
                    "request_id": "req_a1b2c3d4e5f6"
                  }
                }
              }
            }
          },
          "502": {
            "description": "Compute service unavailable",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/GatewayError"
                },
                "example": {
                  "error": {
                    "code": "COMPUTE_ERROR",
                    "message": "Computation service unavailable",
                    "request_id": "req_a1b2c3d4e5f6"
                  }
                }
              }
            }
          }
        }
      }
    },
    "/kadambini/v1/ner": {
      "post": {
        "tags": [
          "Kadambini — NER"
        ],
        "summary": "Predict Ner",
        "description": "Run NER on a single Sanskrit text (IAST or Devanagari).\n\nReturns entities with type, confidence score, and word-level positions.\n\nEntity types: DEITY, PERSON, RISHI, PLACE, TEXT, CONCEPT,\nCELESTIAL, FLORA, LINEAGE, MANTRA.",
        "operationId": "predict_ner_v1_ner_post",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/NerRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/NerResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "description": "Unique request identifier",
                "schema": {
                  "type": "string",
                  "example": "req_a1b2c3d4e5f6"
                }
              },
              "X-RateLimit-Limit": {
                "description": "Maximum requests per minute for your tier",
                "schema": {
                  "type": "integer",
                  "example": 100
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests remaining in current window",
                "schema": {
                  "type": "integer",
                  "example": 95
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix timestamp when the rate limit window resets",
                "schema": {
                  "type": "integer",
                  "example": 1711929600
                }
              },
              "X-Cache": {
                "description": "Cache status — HIT (served from cache) or MISS (freshly computed)",
                "schema": {
                  "type": "string",
                  "enum": [
                    "HIT",
                    "MISS"
                  ]
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized — missing or invalid API key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/GatewayError"
                },
                "examples": {
                  "missing_key": {
                    "summary": "Missing API key",
                    "value": {
                      "error": {
                        "code": "MISSING_API_KEY",
                        "message": "X-API-Key header is required",
                        "request_id": "req_a1b2c3d4e5f6"
                      }
                    }
                  },
                  "invalid_key": {
                    "summary": "Invalid API key",
                    "value": {
                      "error": {
                        "code": "INVALID_API_KEY",
                        "message": "API key is invalid or inactive",
                        "request_id": "req_a1b2c3d4e5f6"
                      }
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded",
            "headers": {
              "Retry-After": {
                "description": "Seconds until the rate limit window resets",
                "schema": {
                  "type": "integer",
                  "example": 60
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/GatewayError"
                },
                "example": {
                  "error": {
                    "code": "RATE_LIMIT_EXCEEDED",
                    "message": "Rate limit exceeded. Upgrade at https://vibz.art/developers/pricing",
                    "request_id": "req_a1b2c3d4e5f6"
                  }
                }
              }
            }
          },
          "502": {
            "description": "Compute service unavailable",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/GatewayError"
                },
                "example": {
                  "error": {
                    "code": "COMPUTE_ERROR",
                    "message": "Computation service unavailable",
                    "request_id": "req_a1b2c3d4e5f6"
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "APIKeyHeader": []
          }
        ]
      }
    },
    "/kadambini/v1/ner/batch": {
      "post": {
        "tags": [
          "Kadambini — NER"
        ],
        "summary": "Predict Ner Batch",
        "description": "Run NER on a batch of texts (up to 64). More efficient than single calls.",
        "operationId": "predict_ner_batch_v1_ner_batch_post",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/NerBatchRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/NerBatchResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "description": "Unique request identifier",
                "schema": {
                  "type": "string",
                  "example": "req_a1b2c3d4e5f6"
                }
              },
              "X-RateLimit-Limit": {
                "description": "Maximum requests per minute for your tier",
                "schema": {
                  "type": "integer",
                  "example": 100
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests remaining in current window",
                "schema": {
                  "type": "integer",
                  "example": 95
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix timestamp when the rate limit window resets",
                "schema": {
                  "type": "integer",
                  "example": 1711929600
                }
              },
              "X-Cache": {
                "description": "Cache status — HIT (served from cache) or MISS (freshly computed)",
                "schema": {
                  "type": "string",
                  "enum": [
                    "HIT",
                    "MISS"
                  ]
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized — missing or invalid API key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/GatewayError"
                },
                "examples": {
                  "missing_key": {
                    "summary": "Missing API key",
                    "value": {
                      "error": {
                        "code": "MISSING_API_KEY",
                        "message": "X-API-Key header is required",
                        "request_id": "req_a1b2c3d4e5f6"
                      }
                    }
                  },
                  "invalid_key": {
                    "summary": "Invalid API key",
                    "value": {
                      "error": {
                        "code": "INVALID_API_KEY",
                        "message": "API key is invalid or inactive",
                        "request_id": "req_a1b2c3d4e5f6"
                      }
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded",
            "headers": {
              "Retry-After": {
                "description": "Seconds until the rate limit window resets",
                "schema": {
                  "type": "integer",
                  "example": 60
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/GatewayError"
                },
                "example": {
                  "error": {
                    "code": "RATE_LIMIT_EXCEEDED",
                    "message": "Rate limit exceeded. Upgrade at https://vibz.art/developers/pricing",
                    "request_id": "req_a1b2c3d4e5f6"
                  }
                }
              }
            }
          },
          "502": {
            "description": "Compute service unavailable",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/GatewayError"
                },
                "example": {
                  "error": {
                    "code": "COMPUTE_ERROR",
                    "message": "Computation service unavailable",
                    "request_id": "req_a1b2c3d4e5f6"
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "APIKeyHeader": []
          }
        ]
      }
    }
  },
  "components": {
    "schemas": {
      "AlternateObservance": {
        "properties": {
          "date": {
            "type": "string",
            "format": "date",
            "title": "Date",
            "description": "Alternate observance date"
          },
          "sunrise": {
            "anyOf": [
              {
                "type": "string",
                "format": "date-time"
              },
              {
                "type": "null"
              }
            ],
            "title": "Sunrise",
            "description": "Sunrise on alternate date"
          },
          "priority": {
            "type": "string",
            "title": "Priority",
            "description": "Priority rule that produced this alternate (e.g. 'paraviddha')"
          },
          "reasoning": {
            "type": "string",
            "title": "Reasoning",
            "description": "Why this alternate date is valid"
          }
        },
        "type": "object",
        "required": [
          "date",
          "priority",
          "reasoning"
        ],
        "title": "AlternateObservance",
        "description": "A secondary observance date produced by the opposite convention.\n\nWhen the primary (configured) observance rule differs from a widely-used\nalternate convention, this field carries the alternate date so callers can\nsurface both to users. Example: if a festival is configured with\n``priority=vyapti`` and the vyapti check picks the earlier day, the\nparaviddha alternate (udayatithi day) is exposed here."
      },
      "BirthInfo": {
        "properties": {
          "date": {
            "type": "string",
            "title": "Date",
            "description": "Birth date in ISO 8601 (YYYY-MM-DD)."
          },
          "time": {
            "type": "string",
            "title": "Time",
            "description": "Birth time in 24h ISO 8601 (HH:MM:SS)."
          },
          "location": {
            "$ref": "#/components/schemas/Location",
            "description": "Geographic location with timezone."
          },
          "jd_ut": {
            "type": "number",
            "title": "Jd Ut",
            "description": "Julian Day in UT, useful for rendering audit logs."
          }
        },
        "type": "object",
        "required": [
          "date",
          "time",
          "location",
          "jd_ut"
        ],
        "title": "BirthInfo",
        "description": "Birth-event metadata round-tripped into the result for renderers."
      },
      "BirthPanchanga": {
        "properties": {
          "tithi_index": {
            "type": "integer",
            "maximum": 30.0,
            "minimum": 1.0,
            "title": "Tithi Index",
            "description": "Tithi number 1..30 (Pratipada=1, Pūrṇimā=15, Amāvāsyā=30)."
          },
          "tithi_name": {
            "type": "string",
            "title": "Tithi Name",
            "description": "Sanskrit tithi name (e.g. 'Saptamī')."
          },
          "paksha": {
            "type": "string",
            "title": "Paksha",
            "description": "'Shukla' | 'Krishna'."
          },
          "nakshatra_index": {
            "type": "integer",
            "maximum": 26.0,
            "minimum": 0.0,
            "title": "Nakshatra Index",
            "description": "Nakshatra index 0..26."
          },
          "nakshatra_name": {
            "type": "string",
            "title": "Nakshatra Name",
            "description": "Sanskrit nakshatra name (Moon's nakshatra)."
          },
          "pada": {
            "type": "integer",
            "maximum": 4.0,
            "minimum": 1.0,
            "title": "Pada"
          },
          "yoga_index": {
            "type": "integer",
            "maximum": 27.0,
            "minimum": 1.0,
            "title": "Yoga Index",
            "description": "Yoga number 1..27."
          },
          "yoga_name": {
            "type": "string",
            "title": "Yoga Name",
            "description": "Sanskrit yoga name."
          },
          "karana_index": {
            "type": "integer",
            "maximum": 11.0,
            "minimum": 1.0,
            "title": "Karana Index",
            "description": "Karana number 1..11 (Bava=1 … Naga=11)."
          },
          "karana_name": {
            "type": "string",
            "title": "Karana Name",
            "description": "Sanskrit karana name."
          },
          "vara_index": {
            "type": "integer",
            "maximum": 6.0,
            "minimum": 0.0,
            "title": "Vara Index",
            "description": "Weekday 0=Sunday … 6=Saturday."
          },
          "vara_name": {
            "type": "string",
            "title": "Vara Name",
            "description": "English weekday name."
          }
        },
        "type": "object",
        "required": [
          "tithi_index",
          "tithi_name",
          "paksha",
          "nakshatra_index",
          "nakshatra_name",
          "pada",
          "yoga_index",
          "yoga_name",
          "karana_index",
          "karana_name",
          "vara_index",
          "vara_name"
        ],
        "title": "BirthPanchanga",
        "description": "The five Pañcāṅga elements at the exact birth instant.\n\nUseful for renderers that want to surface \"your birth Tithi was Saptamī\"\nand for downstream rules that key on birth-Tithi or birth-Nakṣatra."
      },
      "CalendarSystem": {
        "type": "string",
        "enum": [
          "amant",
          "purnimant"
        ],
        "title": "CalendarSystem",
        "description": "Hindu lunar calendar system."
      },
      "ClassicalLayer": {
        "properties": {
          "rules_fired": {
            "items": {
              "$ref": "#/components/schemas/RuleFired"
            },
            "type": "array",
            "title": "Rules Fired"
          }
        },
        "type": "object",
        "title": "ClassicalLayer",
        "description": "Rule firings only. No verse text. No citation pointers. No prose."
      },
      "ComputedLayer": {
        "properties": {
          "birth": {
            "$ref": "#/components/schemas/BirthInfo"
          },
          "ayanamsa": {
            "type": "number",
            "title": "Ayanamsa",
            "description": "Lahiri ayanamsa value (degrees) at birth jd."
          },
          "lagna": {
            "$ref": "#/components/schemas/LagnaPosition"
          },
          "planets": {
            "items": {
              "$ref": "#/components/schemas/PlanetPosition"
            },
            "type": "array",
            "maxItems": 9,
            "minItems": 9,
            "title": "Planets"
          },
          "d1_chart": {
            "additionalProperties": {
              "items": {
                "type": "string"
              },
              "type": "array"
            },
            "type": "object",
            "title": "D1 Chart",
            "description": "House (1..12) → list of English graha names occupying that house in D-1."
          },
          "d2_chart": {
            "additionalProperties": {
              "items": {
                "type": "string"
              },
              "type": "array"
            },
            "type": "object",
            "title": "D2 Chart",
            "description": "D-2 (Hora) — wealth indications."
          },
          "d3_chart": {
            "additionalProperties": {
              "items": {
                "type": "string"
              },
              "type": "array"
            },
            "type": "object",
            "title": "D3 Chart",
            "description": "D-3 (Drekkana) — siblings, courage."
          },
          "d7_chart": {
            "additionalProperties": {
              "items": {
                "type": "string"
              },
              "type": "array"
            },
            "type": "object",
            "title": "D7 Chart",
            "description": "D-7 (Saptamsha) — children, progeny."
          },
          "d9_chart": {
            "additionalProperties": {
              "items": {
                "type": "string"
              },
              "type": "array"
            },
            "type": "object",
            "title": "D9 Chart",
            "description": "House (1..12) → list of English graha names occupying that house in D-9."
          },
          "d10_chart": {
            "additionalProperties": {
              "items": {
                "type": "string"
              },
              "type": "array"
            },
            "type": "object",
            "title": "D10 Chart",
            "description": "D-10 (Dasamsa) — career, profession."
          },
          "d12_chart": {
            "additionalProperties": {
              "items": {
                "type": "string"
              },
              "type": "array"
            },
            "type": "object",
            "title": "D12 Chart",
            "description": "D-12 (Dvadasamsa) — parents, lineage."
          },
          "d30_chart": {
            "additionalProperties": {
              "items": {
                "type": "string"
              },
              "type": "array"
            },
            "type": "object",
            "title": "D30 Chart",
            "description": "D-30 (Trimsamsa) — character, hidden weaknesses."
          },
          "dasha_tree": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/DashaPeriod"
              },
              {
                "type": "null"
              }
            ],
            "description": "Vimshottari dasha tree (3 levels). Populated by orchestrator."
          },
          "sade_sati": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/SadeSatiInfo"
              },
              {
                "type": "null"
              }
            ],
            "description": "Sade Sati status — *transit* fact, recomputed at request time."
          },
          "birth_panchanga": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/BirthPanchanga"
              },
              {
                "type": "null"
              }
            ],
            "description": "The five Pañcāṅga elements at the birth instant."
          }
        },
        "type": "object",
        "required": [
          "birth",
          "ayanamsa",
          "lagna",
          "planets",
          "d1_chart",
          "d9_chart"
        ],
        "title": "ComputedLayer",
        "description": "The deterministic, Swiss-Ephemeris-derived facts of a chart.\n\nEvery field here is verifiable: feed the same (jd, lat, lng) into\nany other Swiss Ephemeris-based engine and you should get identical\nnumbers (up to ayanamsa/house-system choice)."
      },
      "DashaPeriod": {
        "properties": {
          "lord": {
            "type": "string",
            "title": "Lord",
            "description": "English graha name owning this period."
          },
          "lord_sanskrit": {
            "type": "string",
            "title": "Lord Sanskrit",
            "description": "Sanskrit graha name owning this period."
          },
          "start_jd": {
            "type": "number",
            "title": "Start Jd",
            "description": "Julian Day (UT) when this period begins."
          },
          "end_jd": {
            "type": "number",
            "title": "End Jd",
            "description": "Julian Day (UT) when this period ends."
          },
          "start_iso": {
            "type": "string",
            "title": "Start Iso",
            "description": "ISO 8601 UTC start timestamp (renderer convenience)."
          },
          "end_iso": {
            "type": "string",
            "title": "End Iso",
            "description": "ISO 8601 UTC end timestamp."
          },
          "sub_periods": {
            "items": {
              "$ref": "#/components/schemas/DashaPeriod"
            },
            "type": "array",
            "title": "Sub Periods",
            "description": "Sub-periods. Empty for leaf nodes."
          }
        },
        "type": "object",
        "required": [
          "lord",
          "lord_sanskrit",
          "start_jd",
          "end_jd",
          "start_iso",
          "end_iso"
        ],
        "title": "DashaPeriod",
        "description": "One node of the Vimshottari dasha tree.\n\nChildren are themselves `DashaPeriod`s, allowing the same model to\nrepresent Mahadasha → Antardasha → Pratyantar Dasha (3 levels deep\nin v1; the schema supports arbitrary depth for forward-compat)."
      },
      "EkadashiInfo": {
        "properties": {
          "metadata": {
            "$ref": "#/components/schemas/EkadashiMetadata"
          },
          "lunar_month": {
            "type": "string",
            "title": "Lunar Month",
            "description": "Resolved lunar month name (or 'adhik')."
          },
          "paksha": {
            "type": "string",
            "title": "Paksha",
            "description": "'shukla' or 'krishna'."
          },
          "is_adhik": {
            "type": "boolean",
            "title": "Is Adhik",
            "description": "True when this is the Adhik-māsa special ekādaśī.",
            "default": false
          }
        },
        "type": "object",
        "required": [
          "metadata",
          "lunar_month",
          "paksha"
        ],
        "title": "EkadashiInfo",
        "description": "The full ekādaśī enrichment lilavati's /panchang attaches when the\ncurrent tithi is Ekādaśī.\n\nCombines metadata from :file:`ekadashis.yaml` with the contextual\nfields the caller needs at render-time (the resolved month + paksha\n+ adhik flag)."
      },
      "EkadashiMetadata": {
        "properties": {
          "id": {
            "type": "string",
            "title": "Id",
            "description": "Stable kebab-id, e.g. 'kamada'."
          },
          "name_iast": {
            "type": "string",
            "title": "Name Iast",
            "description": "IAST, e.g. 'Kāmadā'."
          },
          "name_hi": {
            "type": "string",
            "title": "Name Hi",
            "description": "Devanagari name, e.g. 'कामदा एकादशी'."
          },
          "name_en": {
            "type": "string",
            "title": "Name En",
            "description": "English title, e.g. 'Kāmadā Ekādaśī'."
          },
          "presiding_deity": {
            "type": "string",
            "title": "Presiding Deity",
            "description": "Specific form of Viṣṇu invoked."
          },
          "significance": {
            "type": "string",
            "title": "Significance",
            "description": "1–3 sentence kathā summary."
          },
          "verse_refs": {
            "items": {
              "type": "string"
            },
            "type": "array",
            "title": "Verse Refs",
            "description": "Kadambini URNs, optional."
          },
          "special_rules": {
            "anyOf": [
              {
                "items": {
                  "type": "string"
                },
                "type": "array"
              },
              {
                "type": "null"
              }
            ],
            "title": "Special Rules",
            "description": "Per-ekadashi vrat overrides. When ``null``, the universal rules apply (no grains, single sattvic meal, vigil, dvādaśī pāraṇa)."
          }
        },
        "additionalProperties": false,
        "type": "object",
        "required": [
          "id",
          "name_iast",
          "name_hi",
          "name_en",
          "presiding_deity",
          "significance"
        ],
        "title": "EkadashiMetadata",
        "description": "Shastric metadata for a single Ekādaśī.\n\nIndexed in :file:`ekadashis.yaml` by ``(month, paksha)``. Adhik-māsa\nentries use the special month value ``\"adhik\"`` and take precedence\nwhen ``panchang.MasaInfo.is_adhik`` is true."
      },
      "EnrichedFestivalInfo": {
        "properties": {
          "id": {
            "type": "string",
            "title": "Id",
            "description": "Festival identifier (e.g. 'diwali')"
          },
          "name": {
            "type": "string",
            "title": "Name",
            "description": "Festival display name"
          },
          "date": {
            "type": "string",
            "format": "date",
            "title": "Date",
            "description": "Festival date"
          },
          "sunrise": {
            "anyOf": [
              {
                "type": "string",
                "format": "date-time"
              },
              {
                "type": "null"
              }
            ],
            "title": "Sunrise",
            "description": "Sunrise time on festival day"
          },
          "tithi_at_sunrise": {
            "type": "integer",
            "maximum": 30.0,
            "minimum": 0.0,
            "title": "Tithi At Sunrise",
            "description": "Tithi number at sunrise"
          },
          "lunar_month": {
            "type": "string",
            "title": "Lunar Month",
            "description": "Lunar month name"
          },
          "is_adhik_month": {
            "type": "boolean",
            "title": "Is Adhik Month",
            "description": "Whether in Adhik month",
            "default": false
          },
          "reasoning": {
            "type": "string",
            "title": "Reasoning",
            "description": "Explanation of date determination"
          },
          "priority_applied": {
            "type": "string",
            "title": "Priority Applied",
            "description": "Observance rule applied — one of: paraviddha, puurvaviddha, vyapti, sankranti, nakshatra_at_sunrise.",
            "default": "paraviddha"
          },
          "kaala_applied": {
            "type": "string",
            "title": "Kaala Applied",
            "description": "Kaala (time-window) checked for vyapti resolution; empty when not applicable",
            "default": ""
          },
          "alternate": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/AlternateObservance"
              },
              {
                "type": "null"
              }
            ],
            "description": "Alternate date produced by the opposing convention, if one exists"
          },
          "metadata": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/FestivalMetadata"
              },
              {
                "type": "null"
              }
            ],
            "description": "Shastric metadata from lilavati's curated set. ``null`` when the festival has no entry in festival_metadata.yaml — caller falls back gracefully."
          }
        },
        "type": "object",
        "required": [
          "id",
          "name",
          "date",
          "tithi_at_sunrise",
          "lunar_month",
          "reasoning"
        ],
        "title": "EnrichedFestivalInfo",
        "description": "Festival info from panchang plus shastric metadata layered on top.\n\nInherits every field from panchang's :class:`FestivalInfo` (date,\ntithi, lunar_month, reasoning, …). Adds optional shastric fields."
      },
      "FestivalMetadata": {
        "properties": {
          "shloka": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Shloka",
            "description": "Nirṇaya / pramāṇa shloka in Devanagari. Multi-line block when the canonical reference spans multiple verses."
          },
          "shloka_iast": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Shloka Iast",
            "description": "IAST transliteration of the shloka, when available."
          },
          "shloka_translation_en": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Shloka Translation En",
            "description": "English translation of the shloka, when available."
          },
          "presiding_deity": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Presiding Deity",
            "description": "Specific devatā invoked, e.g. 'Lakṣmī-Nārāyaṇa'."
          },
          "significance": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Significance",
            "description": "1–3 sentence shastric summary of why this day matters."
          },
          "verse_refs": {
            "items": {
              "type": "string"
            },
            "type": "array",
            "title": "Verse Refs",
            "description": "Kadambini URNs (e.g. 'urn:cts:sansktLit:bhagavadgita.verse:9.26'). Resolve via the /kadambini/v1/cite endpoint."
          },
          "sources": {
            "items": {
              "type": "string"
            },
            "type": "array",
            "title": "Sources",
            "description": "Textual / dharmaśāstra authorities cited."
          }
        },
        "additionalProperties": false,
        "type": "object",
        "title": "FestivalMetadata",
        "description": "Shastric metadata for a festival.\n\nAll fields are optional. A festival with no metadata entry returns\nevery field as ``None`` / empty."
      },
      "GrahaYuddha": {
        "properties": {
          "opponent": {
            "type": "string",
            "title": "Opponent",
            "description": "English name of the warring graha."
          },
          "separation_degrees": {
            "type": "number",
            "maximum": 1.0,
            "minimum": 0.0,
            "title": "Separation Degrees",
            "description": "Angular separation in degrees (≤ 1° for war to occur)."
          },
          "role": {
            "type": "string",
            "title": "Role",
            "description": "'winner' (lower longitude) or 'loser' per Sūrya Siddhānta."
          }
        },
        "type": "object",
        "required": [
          "opponent",
          "separation_degrees",
          "role"
        ],
        "title": "GrahaYuddha",
        "description": "One graha's engagement in graha-yuddha (planetary war)."
      },
      "HTTPValidationError": {
        "properties": {
          "detail": {
            "items": {
              "$ref": "#/components/schemas/ValidationError"
            },
            "type": "array",
            "title": "Detail"
          }
        },
        "type": "object",
        "title": "HTTPValidationError"
      },
      "KaranaInfo": {
        "properties": {
          "number": {
            "type": "integer",
            "maximum": 11.0,
            "minimum": 1.0,
            "title": "Number",
            "description": "Karana number (1-11)"
          },
          "name": {
            "type": "string",
            "title": "Name",
            "description": "Karana name (e.g. 'Bava')"
          },
          "start": {
            "anyOf": [
              {
                "type": "string",
                "format": "date-time"
              },
              {
                "type": "null"
              }
            ],
            "title": "Start",
            "description": "Karana start time (UTC)"
          },
          "end": {
            "anyOf": [
              {
                "type": "string",
                "format": "date-time"
              },
              {
                "type": "null"
              }
            ],
            "title": "End",
            "description": "Karana end time (UTC)"
          }
        },
        "type": "object",
        "required": [
          "number",
          "name"
        ],
        "title": "KaranaInfo",
        "description": "Karana (half-tithi) information."
      },
      "KundaliResult": {
        "properties": {
          "computed": {
            "$ref": "#/components/schemas/ComputedLayer"
          },
          "classical": {
            "$ref": "#/components/schemas/ClassicalLayer"
          },
          "provenance": {
            "$ref": "#/components/schemas/Provenance"
          }
        },
        "type": "object",
        "required": [
          "computed",
          "classical",
          "provenance"
        ],
        "title": "KundaliResult",
        "description": "Complete kundali computation result, structured per spec §5.4.\n\nThree labelled layers — the Khona \"transparency\" wedge:\n  * `computed`  — Swiss Ephemeris deterministic facts\n  * `classical` — which BPHS / Phaladeepika / Muhurta Chintamani rules fired\n  * `provenance` — compute-stack metadata for /transparency\n\nStudio is the only consumer that resolves rule_keys → verses + prose."
      },
      "LagnaPosition": {
        "properties": {
          "rashi": {
            "type": "string",
            "title": "Rashi",
            "description": "Sanskrit rashi name (e.g. 'Vrishabha')."
          },
          "rashi_index": {
            "type": "integer",
            "maximum": 11.0,
            "minimum": 0.0,
            "title": "Rashi Index",
            "description": "Rashi index 0..11 (0 = Mesha)."
          },
          "longitude": {
            "type": "number",
            "exclusiveMaximum": 360.0,
            "minimum": 0.0,
            "title": "Longitude",
            "description": "Sidereal longitude in degrees."
          },
          "degree_in_rashi": {
            "type": "number",
            "exclusiveMaximum": 30.0,
            "minimum": 0.0,
            "title": "Degree In Rashi",
            "description": "Degrees within the rashi."
          },
          "nakshatra": {
            "type": "string",
            "title": "Nakshatra",
            "description": "Sanskrit nakshatra name at the Lagna point."
          },
          "nakshatra_index": {
            "type": "integer",
            "maximum": 26.0,
            "minimum": 0.0,
            "title": "Nakshatra Index"
          },
          "pada": {
            "type": "integer",
            "maximum": 4.0,
            "minimum": 1.0,
            "title": "Pada"
          },
          "bhava_cusps": {
            "items": {
              "type": "number"
            },
            "type": "array",
            "maxItems": 12,
            "minItems": 12,
            "title": "Bhava Cusps",
            "description": "12 sidereal house cusps (degrees), index 0 = 1st bhāva."
          },
          "house_system": {
            "type": "string",
            "title": "House System",
            "description": "Swiss Ephemeris hsys letter.",
            "default": "P"
          },
          "mc_longitude": {
            "type": "number",
            "title": "Mc Longitude",
            "description": "Sidereal Midheaven longitude."
          }
        },
        "type": "object",
        "required": [
          "rashi",
          "rashi_index",
          "longitude",
          "degree_in_rashi",
          "nakshatra",
          "nakshatra_index",
          "pada",
          "bhava_cusps",
          "mc_longitude"
        ],
        "title": "LagnaPosition",
        "description": "The sidereal Lagna and its bhāva-cusp envelope."
      },
      "Location": {
        "properties": {
          "lat": {
            "type": "number",
            "maximum": 90.0,
            "minimum": -90.0,
            "title": "Lat",
            "description": "Latitude in decimal degrees"
          },
          "lng": {
            "type": "number",
            "maximum": 180.0,
            "minimum": -180.0,
            "title": "Lng",
            "description": "Longitude in decimal degrees"
          },
          "altitude": {
            "type": "number",
            "minimum": 0.0,
            "title": "Altitude",
            "description": "Altitude in meters above sea level",
            "default": 0.0
          },
          "tz": {
            "type": "string",
            "title": "Tz",
            "description": "IANA timezone string (e.g. 'Asia/Kolkata')",
            "default": "UTC"
          }
        },
        "type": "object",
        "required": [
          "lat",
          "lng"
        ],
        "title": "Location",
        "description": "Geographic location for calendar computations."
      },
      "MasaInfo": {
        "properties": {
          "number": {
            "type": "integer",
            "maximum": 12.0,
            "minimum": 1.0,
            "title": "Number",
            "description": "Month number (1=Chaitra, 12=Phālguna)"
          },
          "name": {
            "type": "string",
            "title": "Name",
            "description": "Month name in IAST (e.g. 'Vaiśākha')"
          },
          "is_adhik": {
            "type": "boolean",
            "title": "Is Adhik",
            "description": "Whether this is an Adhik (intercalary) month",
            "default": false
          },
          "paksha": {
            "$ref": "#/components/schemas/Paksha",
            "description": "Śukla (waxing) or Kṛṣṇa (waning) fortnight"
          }
        },
        "type": "object",
        "required": [
          "number",
          "name",
          "paksha"
        ],
        "title": "MasaInfo",
        "description": "Hindu lunar month (māsa) for the current date."
      },
      "NakshatraInfo": {
        "properties": {
          "number": {
            "type": "integer",
            "maximum": 27.0,
            "minimum": 1.0,
            "title": "Number",
            "description": "Nakshatra number (1-27)"
          },
          "name": {
            "type": "string",
            "title": "Name",
            "description": "Nakshatra name (e.g. 'Rohini')"
          },
          "pada": {
            "type": "integer",
            "maximum": 4.0,
            "minimum": 1.0,
            "title": "Pada",
            "description": "Pada (quarter) 1-4"
          },
          "lord": {
            "type": "string",
            "title": "Lord",
            "description": "Ruling planet"
          },
          "start": {
            "anyOf": [
              {
                "type": "string",
                "format": "date-time"
              },
              {
                "type": "null"
              }
            ],
            "title": "Start",
            "description": "Nakshatra start time (UTC)"
          },
          "end": {
            "anyOf": [
              {
                "type": "string",
                "format": "date-time"
              },
              {
                "type": "null"
              }
            ],
            "title": "End",
            "description": "Nakshatra end time (UTC)"
          }
        },
        "type": "object",
        "required": [
          "number",
          "name",
          "pada",
          "lord"
        ],
        "title": "NakshatraInfo",
        "description": "Nakshatra (lunar mansion) information."
      },
      "NamakarnaResult": {
        "properties": {
          "nakshatra_index": {
            "type": "integer",
            "maximum": 26.0,
            "minimum": 0.0,
            "title": "Nakshatra Index",
            "description": "Nakshatra index (0-26)"
          },
          "nakshatra_name": {
            "type": "string",
            "title": "Nakshatra Name",
            "description": "Nakshatra name (e.g. 'Ashwini')"
          },
          "pada": {
            "type": "integer",
            "maximum": 4.0,
            "minimum": 1.0,
            "title": "Pada",
            "description": "Pada (quarter) 1-4"
          },
          "nakshatra_lord": {
            "type": "string",
            "title": "Nakshatra Lord",
            "description": "Nakshatra lord / Vimshottari Dasha ruler"
          },
          "nakshatra_devata": {
            "type": "string",
            "title": "Nakshatra Devata",
            "description": "Presiding deity of the Nakshatra"
          },
          "syllable_latin": {
            "type": "string",
            "title": "Syllable Latin",
            "description": "Starting syllable in Latin script (e.g. 'Chu')"
          },
          "syllable_devanagari": {
            "type": "string",
            "title": "Syllable Devanagari",
            "description": "Starting syllable in Devanagari (e.g. 'चु')"
          },
          "rashi_name": {
            "type": "string",
            "title": "Rashi Name",
            "description": "Rashi (zodiac sign) from Navamsha mapping"
          },
          "rashi_index": {
            "type": "integer",
            "maximum": 11.0,
            "minimum": 0.0,
            "title": "Rashi Index",
            "description": "Rashi index (0-11)"
          },
          "masa_devata": {
            "type": "string",
            "title": "Masa Devata",
            "description": "Month deity name (from Gargya)"
          },
          "masa_devata_devanagari": {
            "type": "string",
            "title": "Masa Devata Devanagari",
            "description": "Month deity name in Devanagari"
          },
          "lunar_month_name": {
            "type": "string",
            "title": "Lunar Month Name",
            "description": "Lunar month name (e.g. 'Chaitra')"
          }
        },
        "type": "object",
        "required": [
          "nakshatra_index",
          "nakshatra_name",
          "pada",
          "nakshatra_lord",
          "nakshatra_devata",
          "syllable_latin",
          "syllable_devanagari",
          "rashi_name",
          "rashi_index",
          "masa_devata",
          "masa_devata_devanagari",
          "lunar_month_name"
        ],
        "title": "NamakarnaResult",
        "description": "Complete Namakarna (Vedic naming) computation result.\n\nContains all data needed for the Namakarna Samskara:\nthe Nakshatra, Pada, starting syllable (Swar), Rashi,\nand Masa Devata for a given birth datetime and location."
      },
      "Paksha": {
        "type": "string",
        "enum": [
          "Shukla",
          "Krishna"
        ],
        "title": "Paksha",
        "description": "Lunar fortnight — Shukla (waxing) or Krishna (waning)."
      },
      "PanchangResponse": {
        "properties": {
          "date": {
            "type": "string",
            "title": "Date",
            "description": "Date in ISO format (YYYY-MM-DD)"
          },
          "location": {
            "$ref": "#/components/schemas/Location"
          },
          "instant": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Instant",
            "description": "Resolved ISO datetime for instant-mode requests (includes tz offset). ``null`` for day-mode requests."
          },
          "tithi": {
            "$ref": "#/components/schemas/TithiInfo"
          },
          "nakshatra": {
            "$ref": "#/components/schemas/NakshatraInfo"
          },
          "yoga": {
            "$ref": "#/components/schemas/YogaInfo"
          },
          "karana": {
            "$ref": "#/components/schemas/KaranaInfo"
          },
          "masa": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/MasaInfo"
              },
              {
                "type": "null"
              }
            ]
          },
          "samvat": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/SamvatInfo"
              },
              {
                "type": "null"
              }
            ]
          },
          "sun": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/SunData"
              },
              {
                "type": "null"
              }
            ]
          },
          "vara": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/VaraInfo"
              },
              {
                "type": "null"
              }
            ]
          },
          "rahu_kalam": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/TimeWindow"
              },
              {
                "type": "null"
              }
            ]
          },
          "yama_gandam": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/TimeWindow"
              },
              {
                "type": "null"
              }
            ]
          },
          "gulika_kalam": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/TimeWindow"
              },
              {
                "type": "null"
              }
            ]
          },
          "abhijit_muhurat": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/TimeWindow"
              },
              {
                "type": "null"
              }
            ]
          },
          "ekadashi": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/EkadashiInfo"
              },
              {
                "type": "null"
              }
            ],
            "description": "Resolved Ekādaśī metadata when today's tithi is Ekādaśī. Includes presiding deity, kathā summary, vrat overrides, and Kadambini verse refs. ``null`` for non-Ekādaśī days OR when lilavati's metadata table doesn't cover the (month, paksha) combination yet."
          }
        },
        "type": "object",
        "required": [
          "date",
          "location",
          "tithi",
          "nakshatra",
          "yoga",
          "karana"
        ],
        "title": "PanchangResponse",
        "description": "Unified Panchang response.\n\nShape is the same in both modes. Day-mode populates every field; instant-\nmode populates only the panchanga elements (tithi/nakshatra/yoga/karana)\nplus the lightweight location/date context. Day-only fields (``sun``,\n``vara``, muhurat windows) are ``null`` in instant mode.\n\nClients can detect mode via ``instant is not None``."
      },
      "PlanetPosition": {
        "properties": {
          "name": {
            "type": "string",
            "title": "Name",
            "description": "Sanskrit graha name (e.g. 'Surya')."
          },
          "name_en": {
            "type": "string",
            "title": "Name En",
            "description": "English name (e.g. 'Sun')."
          },
          "longitude": {
            "type": "number",
            "exclusiveMaximum": 360.0,
            "minimum": 0.0,
            "title": "Longitude",
            "description": "Sidereal longitude in degrees."
          },
          "rashi": {
            "type": "string",
            "title": "Rashi",
            "description": "Sanskrit rashi name."
          },
          "rashi_index": {
            "type": "integer",
            "maximum": 11.0,
            "minimum": 0.0,
            "title": "Rashi Index"
          },
          "degree_in_rashi": {
            "type": "number",
            "exclusiveMaximum": 30.0,
            "minimum": 0.0,
            "title": "Degree In Rashi"
          },
          "nakshatra": {
            "type": "string",
            "title": "Nakshatra",
            "description": "Sanskrit nakshatra name."
          },
          "nakshatra_index": {
            "type": "integer",
            "maximum": 26.0,
            "minimum": 0.0,
            "title": "Nakshatra Index"
          },
          "pada": {
            "type": "integer",
            "maximum": 4.0,
            "minimum": 1.0,
            "title": "Pada"
          },
          "house": {
            "type": "integer",
            "maximum": 12.0,
            "minimum": 1.0,
            "title": "House",
            "description": "Bhāva from Lagna, whole-sign convention."
          },
          "speed": {
            "type": "number",
            "title": "Speed",
            "description": "Daily motion in degrees (negative ⇒ retrograde)."
          },
          "retrograde": {
            "type": "boolean",
            "title": "Retrograde",
            "description": "True if the graha is in apparent retrograde motion."
          },
          "dignity": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Dignity",
            "description": "Classical dignity: 'exalted' / 'debilitated' / 'own_sign' / null."
          },
          "combust": {
            "type": "boolean",
            "title": "Combust",
            "description": "True when within the classical combustion arc of the Sun. Per BPHS Ch 5: Moon 12°, Mars 17°, Mercury 14° (12° rx), Jupiter 11°, Venus 10° (8° rx), Saturn 15°. Sun and the lunar nodes are never marked combust (Sun cannot combust itself; nodes have no luminosity to be eclipsed).",
            "default": false
          },
          "aspected_houses": {
            "items": {
              "type": "integer"
            },
            "type": "array",
            "title": "Aspected Houses",
            "description": "Bhāvas (1..12) this graha aspects via graha-dṛṣṭi: the universal 7th-house aspect (every graha) plus special aspects per BPHS Ch 26 — Mars 4/7/8, Jupiter 5/7/9, Saturn 3/7/10. Rāhu and Ketu emit the universal 7th only; we do not assert the contested 5/9 node aspects."
          },
          "aspected_grahas": {
            "items": {
              "type": "string"
            },
            "type": "array",
            "title": "Aspected Grahas",
            "description": "English names of grahas that this graha aspects (i.e. occupy houses in `aspected_houses`)."
          },
          "graha_yuddha": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/GrahaYuddha"
              },
              {
                "type": "null"
              }
            ],
            "description": "Set when this graha is engaged in graha-yuddha (planetary war): two non-luminary grahas within 1° in the same rashi. Per Sūrya Siddhānta, the graha with smaller longitude wins. Sun, Moon, Rāhu, and Ketu never participate in war."
          }
        },
        "type": "object",
        "required": [
          "name",
          "name_en",
          "longitude",
          "rashi",
          "rashi_index",
          "degree_in_rashi",
          "nakshatra",
          "nakshatra_index",
          "pada",
          "house",
          "speed",
          "retrograde"
        ],
        "title": "PlanetPosition",
        "description": "One graha's position + classical attributes at the moment of birth."
      },
      "Provenance": {
        "properties": {
          "ephemeris": {
            "type": "string",
            "title": "Ephemeris",
            "description": "Ephemeris source.",
            "default": "swisseph_de431_moshier"
          },
          "ayanamsa_method": {
            "type": "string",
            "title": "Ayanamsa Method",
            "description": "Ayanamsa standard.",
            "default": "lahiri_sri1956"
          },
          "computed_at": {
            "type": "string",
            "title": "Computed At",
            "description": "UTC ISO 8601 timestamp at compute time."
          },
          "lilavati_version": {
            "type": "string",
            "title": "Lilavati Version",
            "description": "lilavati package version."
          },
          "panchang_version": {
            "type": "string",
            "title": "Panchang Version",
            "description": "panchang package version."
          }
        },
        "type": "object",
        "required": [
          "computed_at",
          "lilavati_version",
          "panchang_version"
        ],
        "title": "Provenance",
        "description": "Compute-stack provenance for the `/transparency` page + PDF footer."
      },
      "RuleFired": {
        "properties": {
          "key": {
            "type": "string",
            "title": "Key",
            "description": "Rule key (e.g. 'jupiter_1h', 'gajakesari_yoga')."
          },
          "triggers": {
            "items": {
              "type": "string"
            },
            "type": "array",
            "title": "Triggers",
            "description": "Downstream rule_keys this firing triggers (e.g. ['mangal_dosha'])."
          },
          "context": {
            "additionalProperties": true,
            "type": "object",
            "title": "Context",
            "description": "Rule-specific parameters (e.g. {'severity': 'moderate'})."
          }
        },
        "type": "object",
        "required": [
          "key"
        ],
        "title": "RuleFired",
        "description": "One classical rule that fired against the computed chart.\n\nCarries only the `key`. Studio resolves the verse pointers + prose\nagainst `apps/shell/content/kundali/{rule-refs,interpretations}.yaml`,\nand Kadambini /cite returns the verse content at render time."
      },
      "SadeSatiInfo": {
        "properties": {
          "status": {
            "type": "string",
            "title": "Status",
            "description": "One of: 'pre' | 'active' | 'post' | 'none'."
          },
          "phase": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "title": "Phase",
            "description": "1, 2, or 3 if active. Else None."
          },
          "until": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Until",
            "description": "ISO 8601 date when this status ends."
          }
        },
        "type": "object",
        "required": [
          "status"
        ],
        "title": "SadeSatiInfo",
        "description": "Saturn's 7.5-year transit through 12th/1st/2nd from natal Moon."
      },
      "SamvatInfo": {
        "properties": {
          "vikram": {
            "type": "integer",
            "title": "Vikram",
            "description": "Vikram Saṃvat year (CE + 57)"
          },
          "shaka": {
            "type": "integer",
            "title": "Shaka",
            "description": "Śaka Saṃvat year (CE − 78)"
          },
          "samvatsara_name": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Samvatsara Name",
            "description": "60-year Jovian cycle year name"
          }
        },
        "type": "object",
        "required": [
          "vikram",
          "shaka"
        ],
        "title": "SamvatInfo",
        "description": "Hindu era year (saṃvatsara) information."
      },
      "ShraddhaDate": {
        "properties": {
          "date": {
            "type": "string",
            "title": "Date",
            "description": "Gregorian date (YYYY-MM-DD)"
          },
          "tithi_name": {
            "type": "string",
            "title": "Tithi Name",
            "description": "Tithi name (e.g. 'Krishna Saptami')"
          },
          "tithi_number": {
            "type": "integer",
            "maximum": 30.0,
            "minimum": 1.0,
            "title": "Tithi Number"
          },
          "paksha": {
            "type": "string",
            "title": "Paksha",
            "description": "Shukla or Krishna"
          },
          "nakshatra_name": {
            "type": "string",
            "title": "Nakshatra Name",
            "description": "Nakshatra at sunrise"
          },
          "masa": {
            "type": "string",
            "title": "Masa",
            "description": "Lunar month name"
          },
          "vara": {
            "type": "string",
            "title": "Vara",
            "description": "Day of the week"
          }
        },
        "type": "object",
        "required": [
          "date",
          "tithi_name",
          "tithi_number",
          "paksha",
          "nakshatra_name",
          "masa",
          "vara"
        ],
        "title": "ShraddhaDate",
        "description": "A single shraddha occurrence."
      },
      "ShraddhaResult": {
        "properties": {
          "death_date": {
            "type": "string",
            "title": "Death Date",
            "description": "Death date (YYYY-MM-DD)"
          },
          "death_tithi": {
            "type": "string",
            "title": "Death Tithi",
            "description": "Tithi at time of death"
          },
          "death_tithi_number": {
            "type": "integer",
            "maximum": 30.0,
            "minimum": 1.0,
            "title": "Death Tithi Number"
          },
          "death_paksha": {
            "type": "string",
            "title": "Death Paksha"
          },
          "death_nakshatra": {
            "type": "string",
            "title": "Death Nakshatra"
          },
          "death_masa": {
            "type": "string",
            "title": "Death Masa"
          },
          "teesra": {
            "type": "string",
            "title": "Teesra",
            "description": "Day 3 (YYYY-MM-DD)"
          },
          "dashama": {
            "type": "string",
            "title": "Dashama",
            "description": "Day 10 (YYYY-MM-DD)"
          },
          "terahvin": {
            "type": "string",
            "title": "Terahvin",
            "description": "Day 13 (YYYY-MM-DD)"
          },
          "monthly_shraddhas": {
            "items": {
              "$ref": "#/components/schemas/ShraddhaDate"
            },
            "type": "array",
            "title": "Monthly Shraddhas",
            "description": "Monthly shraddha dates"
          },
          "annual_shraddhas": {
            "items": {
              "$ref": "#/components/schemas/ShraddhaDate"
            },
            "type": "array",
            "title": "Annual Shraddhas",
            "description": "Annual shraddha dates for next N years"
          },
          "pitru_paksha_dates": {
            "items": {
              "$ref": "#/components/schemas/ShraddhaDate"
            },
            "type": "array",
            "title": "Pitru Paksha Dates",
            "description": "Pitru Paksha shraddha dates for next N years"
          }
        },
        "type": "object",
        "required": [
          "death_date",
          "death_tithi",
          "death_tithi_number",
          "death_paksha",
          "death_nakshatra",
          "death_masa",
          "teesra",
          "dashama",
          "terahvin",
          "monthly_shraddhas",
          "annual_shraddhas",
          "pitru_paksha_dates"
        ],
        "title": "ShraddhaResult",
        "description": "Complete shraddha timeline computation."
      },
      "SunData": {
        "properties": {
          "sunrise": {
            "type": "string",
            "format": "date-time",
            "title": "Sunrise",
            "description": "Sunrise time (local timezone)"
          },
          "sunset": {
            "type": "string",
            "format": "date-time",
            "title": "Sunset",
            "description": "Sunset time (local timezone)"
          },
          "day_duration_hours": {
            "type": "number",
            "title": "Day Duration Hours",
            "description": "Duration of daytime in hours"
          },
          "sunrise_jd": {
            "type": "number",
            "title": "Sunrise Jd",
            "description": "Sunrise Julian Day (internal)",
            "default": 0.0
          },
          "sunset_jd": {
            "type": "number",
            "title": "Sunset Jd",
            "description": "Sunset Julian Day (internal)",
            "default": 0.0
          }
        },
        "type": "object",
        "required": [
          "sunrise",
          "sunset",
          "day_duration_hours"
        ],
        "title": "SunData",
        "description": "Sunrise, sunset, and related solar data for a location and date."
      },
      "TimeWindow": {
        "properties": {
          "name": {
            "type": "string",
            "title": "Name",
            "description": "Window name (e.g. 'Rahu Kalam')"
          },
          "start": {
            "type": "string",
            "format": "date-time",
            "title": "Start",
            "description": "Start time (local timezone)"
          },
          "end": {
            "type": "string",
            "format": "date-time",
            "title": "End",
            "description": "End time (local timezone)"
          },
          "is_auspicious": {
            "type": "boolean",
            "title": "Is Auspicious",
            "description": "Whether this window is auspicious"
          }
        },
        "type": "object",
        "required": [
          "name",
          "start",
          "end",
          "is_auspicious"
        ],
        "title": "TimeWindow",
        "description": "A named time window with start and end times."
      },
      "TithiInfo": {
        "properties": {
          "number": {
            "type": "integer",
            "maximum": 30.0,
            "minimum": 1.0,
            "title": "Number",
            "description": "Tithi number (1-30)"
          },
          "name": {
            "type": "string",
            "title": "Name",
            "description": "Tithi name (e.g. 'Ashtami')"
          },
          "paksha": {
            "$ref": "#/components/schemas/Paksha",
            "description": "Shukla (waxing) or Krishna (waning)"
          },
          "start": {
            "anyOf": [
              {
                "type": "string",
                "format": "date-time"
              },
              {
                "type": "null"
              }
            ],
            "title": "Start",
            "description": "Tithi start time (UTC)"
          },
          "end": {
            "anyOf": [
              {
                "type": "string",
                "format": "date-time"
              },
              {
                "type": "null"
              }
            ],
            "title": "End",
            "description": "Tithi end time (UTC)"
          }
        },
        "type": "object",
        "required": [
          "number",
          "name",
          "paksha"
        ],
        "title": "TithiInfo",
        "description": "Tithi (lunar day) information."
      },
      "ValidationError": {
        "properties": {
          "loc": {
            "items": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "integer"
                }
              ]
            },
            "type": "array",
            "title": "Location"
          },
          "msg": {
            "type": "string",
            "title": "Message"
          },
          "type": {
            "type": "string",
            "title": "Error Type"
          },
          "input": {
            "title": "Input"
          },
          "ctx": {
            "type": "object",
            "title": "Context"
          }
        },
        "type": "object",
        "required": [
          "loc",
          "msg",
          "type"
        ],
        "title": "ValidationError"
      },
      "VaraInfo": {
        "properties": {
          "number": {
            "type": "integer",
            "maximum": 6.0,
            "minimum": 0.0,
            "title": "Number",
            "description": "Weekday number (0=Sunday)"
          },
          "name": {
            "type": "string",
            "title": "Name",
            "description": "Sanskrit weekday name"
          },
          "english": {
            "type": "string",
            "title": "English",
            "description": "English weekday name"
          }
        },
        "type": "object",
        "required": [
          "number",
          "name",
          "english"
        ],
        "title": "VaraInfo",
        "description": "Vara (weekday) information."
      },
      "VivahDateDetail": {
        "properties": {
          "date": {
            "type": "string",
            "format": "date",
            "title": "Date",
            "description": "Auspicious date"
          },
          "score": {
            "type": "integer",
            "maximum": 100.0,
            "minimum": 0.0,
            "title": "Score",
            "description": "Composite score (0-100)"
          },
          "day": {
            "type": "string",
            "title": "Day",
            "description": "English weekday name"
          },
          "tithi": {
            "type": "string",
            "title": "Tithi",
            "description": "Tithi name at sunrise"
          },
          "tithi_number": {
            "type": "integer",
            "title": "Tithi Number",
            "description": "Tithi number (1-30)"
          },
          "nakshatra": {
            "type": "string",
            "title": "Nakshatra",
            "description": "Nakshatra at sunrise"
          },
          "nakshatra_number": {
            "type": "integer",
            "title": "Nakshatra Number",
            "description": "Nakshatra number (1-27)"
          },
          "nakshatra_pada": {
            "type": "integer",
            "title": "Nakshatra Pada",
            "description": "Nakshatra pada (1-4) at sunrise"
          },
          "yoga": {
            "type": "string",
            "title": "Yoga",
            "description": "Yoga at sunrise"
          },
          "karana": {
            "type": "string",
            "title": "Karana",
            "description": "Karana at sunrise"
          },
          "sunrise": {
            "type": "string",
            "title": "Sunrise",
            "description": "Sunrise time (local timezone ISO)"
          },
          "sunset": {
            "type": "string",
            "title": "Sunset",
            "description": "Sunset time (local timezone ISO)"
          },
          "amritadi_yoga": {
            "type": "string",
            "title": "Amritadi Yoga",
            "description": "Amritadi yoga: Amrita / Siddha / Marana"
          },
          "reasons_good": {
            "items": {
              "type": "string"
            },
            "type": "array",
            "title": "Reasons Good",
            "description": "Why this date is auspicious"
          },
          "reasons_avoid": {
            "items": {
              "type": "string"
            },
            "type": "array",
            "title": "Reasons Avoid",
            "description": "Warnings or caveats"
          },
          "windows": {
            "items": {
              "$ref": "#/components/schemas/VivahWindowDetail"
            },
            "type": "array",
            "title": "Windows",
            "description": "Auspicious sub-windows within the day"
          }
        },
        "type": "object",
        "required": [
          "date",
          "score",
          "day",
          "tithi",
          "tithi_number",
          "nakshatra",
          "nakshatra_number",
          "nakshatra_pada",
          "yoga",
          "karana",
          "sunrise",
          "sunset",
          "amritadi_yoga",
          "reasons_good",
          "reasons_avoid"
        ],
        "title": "VivahDateDetail",
        "description": "A single auspicious vivah date with scoring, reasoning, and windows."
      },
      "VivahMuhuratResponse": {
        "properties": {
          "start_date": {
            "type": "string",
            "format": "date",
            "title": "Start Date"
          },
          "end_date": {
            "type": "string",
            "format": "date",
            "title": "End Date"
          },
          "location": {
            "type": "string",
            "title": "Location",
            "description": "Location description (lat, lng)"
          },
          "total_dates_evaluated": {
            "type": "integer",
            "title": "Total Dates Evaluated"
          },
          "auspicious_count": {
            "type": "integer",
            "title": "Auspicious Count"
          },
          "dates": {
            "items": {
              "$ref": "#/components/schemas/VivahDateDetail"
            },
            "type": "array",
            "title": "Dates"
          }
        },
        "type": "object",
        "required": [
          "start_date",
          "end_date",
          "location",
          "total_dates_evaluated",
          "auspicious_count",
          "dates"
        ],
        "title": "VivahMuhuratResponse",
        "description": "Response from the vivah muhurat endpoint."
      },
      "VivahWindowDetail": {
        "properties": {
          "start": {
            "type": "string",
            "format": "date-time",
            "title": "Start",
            "description": "Window start (local timezone)"
          },
          "end": {
            "type": "string",
            "format": "date-time",
            "title": "End",
            "description": "Window end (local timezone)"
          },
          "duration_minutes": {
            "type": "integer",
            "title": "Duration Minutes",
            "description": "Window duration in minutes"
          },
          "tithi": {
            "type": "string",
            "title": "Tithi",
            "description": "Tithi during this window"
          },
          "nakshatra": {
            "type": "string",
            "title": "Nakshatra",
            "description": "Nakshatra during this window"
          },
          "nakshatra_pada": {
            "type": "integer",
            "title": "Nakshatra Pada",
            "description": "Nakshatra pada (1-4)"
          },
          "yoga": {
            "type": "string",
            "title": "Yoga",
            "description": "Yoga during this window"
          },
          "karana": {
            "type": "string",
            "title": "Karana",
            "description": "Karana during this window"
          },
          "reasoning": {
            "type": "string",
            "title": "Reasoning",
            "description": "Why this window is auspicious"
          }
        },
        "type": "object",
        "required": [
          "start",
          "end",
          "duration_minutes",
          "tithi",
          "nakshatra",
          "nakshatra_pada",
          "yoga",
          "karana",
          "reasoning"
        ],
        "title": "VivahWindowDetail",
        "description": "An auspicious sub-window within a day."
      },
      "YogaInfo": {
        "properties": {
          "number": {
            "type": "integer",
            "maximum": 27.0,
            "minimum": 1.0,
            "title": "Number",
            "description": "Yoga number (1-27)"
          },
          "name": {
            "type": "string",
            "title": "Name",
            "description": "Yoga name (e.g. 'Siddhi')"
          },
          "start": {
            "anyOf": [
              {
                "type": "string",
                "format": "date-time"
              },
              {
                "type": "null"
              }
            ],
            "title": "Start",
            "description": "Yoga start time (UTC)"
          },
          "end": {
            "anyOf": [
              {
                "type": "string",
                "format": "date-time"
              },
              {
                "type": "null"
              }
            ],
            "title": "End",
            "description": "Yoga end time (UTC)"
          }
        },
        "type": "object",
        "required": [
          "number",
          "name"
        ],
        "title": "YogaInfo",
        "description": "Yoga (Sun-Moon combination) information."
      },
      "CiteResponse": {
        "properties": {
          "work": {
            "type": "string",
            "title": "Work"
          },
          "work_slug": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Work Slug"
          },
          "work_category": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Work Category"
          },
          "authority_tier": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Authority Tier"
          },
          "edition": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/EditionOut"
              },
              {
                "type": "null"
              }
            ]
          },
          "chapter": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Chapter"
          },
          "verse": {
            "$ref": "#/components/schemas/VerseOut"
          },
          "translations": {
            "items": {
              "$ref": "#/components/schemas/TranslationOut"
            },
            "type": "array",
            "title": "Translations"
          },
          "commentaries": {
            "items": {
              "$ref": "#/components/schemas/CommentaryOut"
            },
            "type": "array",
            "title": "Commentaries"
          },
          "interpretations": {
            "items": {
              "$ref": "#/components/schemas/InterpretationOut"
            },
            "type": "array",
            "title": "Interpretations"
          }
        },
        "type": "object",
        "required": [
          "work",
          "verse",
          "translations",
          "commentaries",
          "interpretations"
        ],
        "title": "CiteResponse"
      },
      "CommentaryOut": {
        "properties": {
          "commentator": {
            "type": "string",
            "title": "Commentator"
          },
          "content_sanskrit": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Content Sanskrit"
          },
          "content_iast": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Content Iast"
          },
          "content_translation": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Content Translation"
          },
          "translation_language": {
            "type": "string",
            "title": "Translation Language",
            "default": "english"
          },
          "sampradaya": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Sampradaya"
          }
        },
        "type": "object",
        "required": [
          "commentator"
        ],
        "title": "CommentaryOut"
      },
      "EditionListItem": {
        "properties": {
          "slug": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Slug"
          },
          "source_name": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Source Name"
          },
          "adapter_name": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Adapter Name"
          },
          "source_url": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Source Url"
          },
          "language": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Language"
          },
          "verse_count": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "title": "Verse Count"
          },
          "quality_tier": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Quality Tier"
          },
          "is_default": {
            "type": "boolean",
            "title": "Is Default",
            "default": false
          }
        },
        "type": "object",
        "title": "EditionListItem",
        "description": "Lighter edition shape used by the list-editions endpoint."
      },
      "EditionOut": {
        "properties": {
          "slug": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Slug"
          },
          "source_name": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Source Name"
          },
          "adapter_name": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Adapter Name"
          },
          "source_url": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Source Url"
          },
          "language": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Language"
          },
          "quality_tier": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Quality Tier"
          }
        },
        "type": "object",
        "title": "EditionOut",
        "description": "Source edition metadata — tells callers which version of the Work\nthe cite result came from. Clients embedding /cite URLs should pin to\nan edition slug if they want deterministic content across future\ncorpus re-ingests.\n\n`quality_tier` signals trust-grade:\n  canonical    — sampradayic, citation-grade (Gita Press, acharya bhashyas)\n  reference    — scholarly accurate (DCS, SARIT, critical editions)\n  archive      — raw ingest, OCR quality varies\n  experimental — unvetted / in-progress"
      },
      "EntityAliasOut": {
        "properties": {
          "alias": {
            "type": "string",
            "title": "Alias"
          },
          "alias_iast": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Alias Iast"
          },
          "language": {
            "type": "string",
            "title": "Language",
            "default": "sanskrit"
          },
          "source_work": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Source Work"
          }
        },
        "type": "object",
        "required": [
          "alias"
        ],
        "title": "EntityAliasOut"
      },
      "EntityListResponse": {
        "properties": {
          "entities": {
            "items": {
              "$ref": "#/components/schemas/EntityOut"
            },
            "type": "array",
            "title": "Entities"
          },
          "total": {
            "type": "integer",
            "title": "Total"
          },
          "page": {
            "type": "integer",
            "title": "Page"
          },
          "per_page": {
            "type": "integer",
            "title": "Per Page"
          }
        },
        "type": "object",
        "required": [
          "entities",
          "total",
          "page",
          "per_page"
        ],
        "title": "EntityListResponse"
      },
      "EntityOut": {
        "properties": {
          "id": {
            "type": "string",
            "title": "Id"
          },
          "canonical_name": {
            "type": "string",
            "title": "Canonical Name"
          },
          "name_sanskrit": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Name Sanskrit"
          },
          "name_iast": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Name Iast"
          },
          "entity_type": {
            "type": "string",
            "title": "Entity Type"
          },
          "entity_subtype": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Entity Subtype"
          },
          "description": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Description"
          },
          "mention_count": {
            "type": "integer",
            "title": "Mention Count",
            "default": 0
          },
          "text_count": {
            "type": "integer",
            "title": "Text Count",
            "default": 0
          },
          "tags": {
            "anyOf": [
              {
                "items": {
                  "type": "string"
                },
                "type": "array"
              },
              {
                "type": "null"
              }
            ],
            "title": "Tags"
          },
          "aliases": {
            "items": {
              "$ref": "#/components/schemas/EntityAliasOut"
            },
            "type": "array",
            "title": "Aliases"
          },
          "relations": {
            "items": {
              "$ref": "#/components/schemas/EntityRelationOut"
            },
            "type": "array",
            "title": "Relations"
          }
        },
        "type": "object",
        "required": [
          "id",
          "canonical_name",
          "entity_type",
          "aliases",
          "relations"
        ],
        "title": "EntityOut"
      },
      "EntityRelationOut": {
        "properties": {
          "predicate": {
            "type": "string",
            "title": "Predicate"
          },
          "target_name": {
            "type": "string",
            "title": "Target Name"
          },
          "target_type": {
            "type": "string",
            "title": "Target Type"
          },
          "confidence": {
            "type": "number",
            "title": "Confidence",
            "default": 1.0
          }
        },
        "type": "object",
        "required": [
          "predicate",
          "target_name",
          "target_type"
        ],
        "title": "EntityRelationOut"
      },
      "HealthResponse": {
        "properties": {
          "status": {
            "type": "string",
            "title": "Status",
            "default": "ok"
          },
          "ner_model_loaded": {
            "type": "boolean",
            "title": "Ner Model Loaded",
            "default": false
          },
          "database": {
            "type": "boolean",
            "title": "Database",
            "default": false
          }
        },
        "type": "object",
        "title": "HealthResponse"
      },
      "InterpretationOut": {
        "properties": {
          "summary": {
            "type": "string",
            "title": "Summary"
          },
          "summary_sanskrit": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Summary Sanskrit"
          },
          "detailed": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Detailed"
          },
          "interpreter": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Interpreter"
          },
          "sampradaya": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Sampradaya"
          },
          "confidence": {
            "type": "number",
            "title": "Confidence",
            "default": 1.0
          }
        },
        "type": "object",
        "required": [
          "summary"
        ],
        "title": "InterpretationOut"
      },
      "NerBatchRequest": {
        "properties": {
          "texts": {
            "items": {
              "type": "string"
            },
            "type": "array",
            "maxItems": 64,
            "minItems": 1,
            "title": "Texts"
          },
          "threshold": {
            "type": "number",
            "maximum": 1.0,
            "minimum": 0.0,
            "title": "Threshold",
            "default": 0.5
          }
        },
        "type": "object",
        "required": [
          "texts"
        ],
        "title": "NerBatchRequest"
      },
      "NerBatchResponse": {
        "properties": {
          "results": {
            "items": {
              "$ref": "#/components/schemas/NerResponse"
            },
            "type": "array",
            "title": "Results"
          },
          "model": {
            "type": "string",
            "title": "Model"
          }
        },
        "type": "object",
        "required": [
          "results",
          "model"
        ],
        "title": "NerBatchResponse"
      },
      "NerEntity": {
        "properties": {
          "text": {
            "type": "string",
            "title": "Text"
          },
          "type": {
            "type": "string",
            "title": "Type"
          },
          "score": {
            "type": "number",
            "title": "Score"
          },
          "start": {
            "type": "integer",
            "title": "Start"
          },
          "end": {
            "type": "integer",
            "title": "End"
          }
        },
        "type": "object",
        "required": [
          "text",
          "type",
          "score",
          "start",
          "end"
        ],
        "title": "NerEntity"
      },
      "NerRequest": {
        "properties": {
          "text": {
            "type": "string",
            "maxLength": 10000,
            "minLength": 1,
            "title": "Text"
          },
          "threshold": {
            "type": "number",
            "maximum": 1.0,
            "minimum": 0.0,
            "title": "Threshold",
            "default": 0.5
          }
        },
        "type": "object",
        "required": [
          "text"
        ],
        "title": "NerRequest"
      },
      "NerResponse": {
        "properties": {
          "entities": {
            "items": {
              "$ref": "#/components/schemas/NerEntity"
            },
            "type": "array",
            "title": "Entities"
          },
          "text": {
            "type": "string",
            "title": "Text"
          },
          "model": {
            "type": "string",
            "title": "Model"
          }
        },
        "type": "object",
        "required": [
          "entities",
          "text",
          "model"
        ],
        "title": "NerResponse"
      },
      "SearchHit": {
        "properties": {
          "verse_id": {
            "type": "string",
            "title": "Verse Id"
          },
          "verse_number": {
            "type": "string",
            "title": "Verse Number"
          },
          "content_snippet": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Content Snippet"
          },
          "work_title": {
            "type": "string",
            "title": "Work Title"
          },
          "work_category": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Work Category"
          },
          "chapter_title": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Chapter Title"
          },
          "rank": {
            "anyOf": [
              {
                "type": "number"
              },
              {
                "type": "null"
              }
            ],
            "title": "Rank"
          }
        },
        "type": "object",
        "required": [
          "verse_id",
          "verse_number",
          "work_title"
        ],
        "title": "SearchHit"
      },
      "SearchMode": {
        "type": "string",
        "enum": [
          "fulltext",
          "translation"
        ],
        "title": "SearchMode"
      },
      "SearchResponse": {
        "properties": {
          "query": {
            "type": "string",
            "title": "Query"
          },
          "mode": {
            "type": "string",
            "title": "Mode"
          },
          "hits": {
            "items": {
              "$ref": "#/components/schemas/SearchHit"
            },
            "type": "array",
            "title": "Hits"
          },
          "total": {
            "type": "integer",
            "title": "Total"
          }
        },
        "type": "object",
        "required": [
          "query",
          "mode",
          "hits",
          "total"
        ],
        "title": "SearchResponse"
      },
      "TranslationOut": {
        "properties": {
          "language": {
            "type": "string",
            "title": "Language"
          },
          "content": {
            "type": "string",
            "title": "Content"
          },
          "translator": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Translator"
          }
        },
        "type": "object",
        "required": [
          "language",
          "content"
        ],
        "title": "TranslationOut"
      },
      "VerseOut": {
        "properties": {
          "id": {
            "type": "string",
            "title": "Id"
          },
          "verse_number": {
            "type": "string",
            "title": "Verse Number"
          },
          "content_devanagari": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Content Devanagari"
          },
          "content_iast": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Content Iast"
          },
          "content_slp1": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Content Slp1"
          },
          "meter": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Meter"
          }
        },
        "type": "object",
        "required": [
          "id",
          "verse_number"
        ],
        "title": "VerseOut"
      },
      "WorkEditionsResponse": {
        "properties": {
          "work": {
            "type": "string",
            "title": "Work"
          },
          "work_slug": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Work Slug"
          },
          "editions": {
            "items": {
              "$ref": "#/components/schemas/EditionListItem"
            },
            "type": "array",
            "title": "Editions"
          }
        },
        "type": "object",
        "required": [
          "work",
          "editions"
        ],
        "title": "WorkEditionsResponse"
      },
      "GatewayError": {
        "type": "object",
        "required": [
          "error"
        ],
        "properties": {
          "error": {
            "type": "object",
            "required": [
              "code",
              "message",
              "request_id"
            ],
            "properties": {
              "code": {
                "type": "string",
                "description": "Machine-readable error code",
                "example": "INVALID_API_KEY"
              },
              "message": {
                "type": "string",
                "description": "Human-readable error message",
                "example": "API key is invalid or inactive"
              },
              "request_id": {
                "type": "string",
                "description": "Unique request identifier for debugging",
                "example": "req_a1b2c3d4e5f6"
              }
            }
          }
        }
      }
    },
    "securitySchemes": {
      "ApiKeyAuth": {
        "type": "apiKey",
        "in": "header",
        "name": "X-API-Key",
        "description": "API key (format: `vz_live_...`). Get one at https://vibz.art/developers"
      }
    }
  },
  "info": {
    "title": "vibz.art API",
    "description": "\nAncient Wisdom. Modern Code.\n\nThe vibz.art API provides computation engines and knowledge infrastructure built from primary Sanskrit texts.\n\n## Authentication\n\nAll endpoints require an API key passed via the `X-API-Key` header:\n\n```bash\ncurl -H \"X-API-Key: vz_live_YOUR_KEY\" https://api.vibz.art/lilavati/v1/panchang?lat=28.61&lng=77.20\n```\n\n## Rate Limits\n\nEvery response includes rate limit headers:\n\n| Header | Description |\n|--------|-------------|\n| `X-RateLimit-Limit` | Requests allowed per minute |\n| `X-RateLimit-Remaining` | Requests remaining in current window |\n| `X-RateLimit-Reset` | Unix timestamp when the window resets |\n\n| Tier | Requests/min | Requests/month | Price |\n|------|-------------|----------------|-------|\n| Free | 20 | 1,000 | $0 |\n| Dev | 100 | 50,000 | $29/mo |\n| Pro | 500 | 500,000 | $149/mo |\n| Business | 2,000 | Unlimited | Custom |\n\n## Caching\n\nDeterministic endpoints are cached. The `X-Cache` header indicates cache status:\n- `X-Cache: HIT` — served from cache\n- `X-Cache: MISS` — computed fresh\n\n| Endpoint | Cache TTL |\n|----------|-----------|\n| `/lilavati/v1/panchang` | 24 hours |\n| `/lilavati/v1/festivals` | 7 days |\n| `/lilavati/v1/shraddha` | 24 hours |\n| `/lilavati/v1/namakarna` | No cache (unique per birth time) |\n| `/kadambini/v1/cite` | 7 days (corpus is append-only) |\n| `/kadambini/v1/search` | 1 hour |\n| `/kadambini/v1/entity` | 24 hours |\n| `/kadambini/v1/ner` | No cache (model inference) |\n",
    "version": "0.1.0",
    "contact": {
      "name": "vibz.art",
      "url": "https://vibz.art",
      "email": "api@vibz.art"
    },
    "license": {
      "name": "Proprietary",
      "url": "https://vibz.art/terms"
    }
  },
  "servers": [
    {
      "url": "https://api.vibz.art",
      "description": "Production"
    }
  ],
  "tags": [
    {
      "name": "Lilavati — Calendar",
      "description": "Hindu calendar computation — Panchang (5 elements), festivals, muhurat windows. Powered by Swiss Ephemeris with Lahiri ayanamsa."
    },
    {
      "name": "Lilavati — Namakarna",
      "description": "Vedic birth naming computation — nakshatra, pada, starting syllables from birth datetime and location."
    },
    {
      "name": "Lilavati — Shraddha",
      "description": "Bereavement ceremony timeline — death anniversary dates computed from tithi matching across lunar months."
    },
    {
      "name": "Kadambini — NER",
      "description": "Sanskrit named entity recognition — 10-class entity detection (deity, rishi, place, concept, etc.) powered by panini-ner (XLM-RoBERTa, 0.983 F1). Accepts IAST or Devanagari."
    },
    {
      "name": "Kadambini — Corpus",
      "description": "Sanskrit corpus access — verse lookup with translations and commentaries, full-text search over 600K+ verses using Postgres tsvector."
    },
    {
      "name": "Kadambini — Knowledge Graph",
      "description": "Knowledge graph entities — deities, rishis, places, concepts with aliases, relations, and verse citations from primary Sanskrit texts."
    }
  ],
  "security": [
    {
      "ApiKeyAuth": []
    }
  ]
}