{
  "openapi": "3.0.3",
  "info": {
    "title": "Healersworld Temple API",
    "version": "1.0.0",
    "description": "Authenticated, paginated temple directory. Coverage varies; schedules are not live. Successful 200 responses consume one request across all keys. No automatic overage billing. Keep photo licences and attribution with images.",
    "termsOfService": "https://www.healersworld.in/temple-api/terms",
    "contact": {
      "email": "support@healersworld.in",
      "url": "https://www.healersworld.in/temple-api/support"
    }
  },
  "servers": [
    {
      "url": "https://www.healersworld.in"
    }
  ],
  "security": [
    {
      "TempleApiKey": []
    }
  ],
  "paths": {
    "/api/v1/temples": {
      "get": {
        "operationId": "listTemples",
        "summary": "Search and filter temple summaries",
        "parameters": [
          {
            "name": "q",
            "in": "query",
            "description": "Search name, aliases, locality, description and deity; all words must match.",
            "schema": {
              "type": "string",
              "maxLength": 100
            }
          },
          {
            "name": "category",
            "in": "query",
            "description": "Curated deity category.",
            "schema": {
              "type": "string",
              "enum": [
                "shiva",
                "hanuman",
                "ram",
                "krishna",
                "vishnu",
                "ganesha",
                "devi",
                "surya"
              ]
            }
          },
          {
            "name": "state",
            "in": "query",
            "description": "Exact case-insensitive state name from /meta.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "deity",
            "in": "query",
            "description": "Exact case-insensitive deity name from /meta.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "page",
            "in": "query",
            "description": "Page number. Values beyond the last page resolve to the last page.",
            "schema": {
              "type": "integer",
              "default": 1,
              "minimum": 1,
              "maximum": 999999
            }
          },
          {
            "name": "limit",
            "in": "query",
            "description": "Records per page.",
            "schema": {
              "type": "integer",
              "default": 12,
              "minimum": 1,
              "maximum": 24
            }
          },
          {
            "name": "sort",
            "in": "query",
            "description": "Nearby requires lat and lon. Supplying coordinates always sorts by distance.",
            "schema": {
              "type": "string",
              "enum": [
                "featured",
                "name",
                "nearby"
              ],
              "default": "featured"
            }
          },
          {
            "name": "lat",
            "in": "query",
            "description": "Latitude; longitude also required.",
            "schema": {
              "type": "number",
              "minimum": -90,
              "maximum": 90
            }
          },
          {
            "name": "lon",
            "in": "query",
            "description": "Longitude; latitude also required.",
            "schema": {
              "type": "number",
              "minimum": -180,
              "maximum": 180
            }
          },
          {
            "name": "radius",
            "in": "query",
            "description": "Kilometres; requires both coordinates.",
            "schema": {
              "type": "number",
              "minimum": 1,
              "maximum": 2000,
              "default": 100
            }
          },
          {
            "name": "reviewed",
            "in": "query",
            "description": "Only reviewed visitor guides.",
            "schema": {
              "type": "string",
              "enum": [
                "1"
              ]
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful response; consumes one request",
            "headers": {
              "X-Quota-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "Requests per paid billing cycle"
              },
              "X-Quota-Remaining": {
                "schema": {
                  "type": "integer"
                },
                "description": "Requests left after this response"
              },
              "X-Quota-Reset": {
                "schema": {
                  "type": "integer"
                },
                "description": "Paid cycle end, Unix seconds"
              },
              "X-RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "Requests per fixed minute, shared by account keys"
              },
              "X-RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                },
                "description": "Requests left this minute"
              },
              "X-RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                },
                "description": "Next fixed minute, Unix seconds"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TempleList"
                }
              }
            }
          },
          "400": {
            "description": "Invalid or duplicate filters",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Missing, invalid or revoked API key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "No paid live subscription cycle",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Temple not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit or cycle allowance reached",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds until retry"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "Billing verification temporarily unavailable",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/temples/meta": {
      "get": {
        "operationId": "getTempleMetadata",
        "summary": "Coverage and filter values",
        "parameters": [],
        "responses": {
          "200": {
            "description": "Successful response; consumes one request",
            "headers": {
              "X-Quota-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "Requests per paid billing cycle"
              },
              "X-Quota-Remaining": {
                "schema": {
                  "type": "integer"
                },
                "description": "Requests left after this response"
              },
              "X-Quota-Reset": {
                "schema": {
                  "type": "integer"
                },
                "description": "Paid cycle end, Unix seconds"
              },
              "X-RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "Requests per fixed minute, shared by account keys"
              },
              "X-RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                },
                "description": "Requests left this minute"
              },
              "X-RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                },
                "description": "Next fixed minute, Unix seconds"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Metadata"
                }
              }
            }
          },
          "400": {
            "description": "Invalid or duplicate filters",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Missing, invalid or revoked API key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "No paid live subscription cycle",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Temple not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit or cycle allowance reached",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds until retry"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "Billing verification temporarily unavailable",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/temples/{identifier}": {
      "get": {
        "operationId": "getTemple",
        "summary": "Get a complete temple record",
        "parameters": [
          {
            "name": "identifier",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "example": "kashi-vishwanath-temple",
            "description": "Temple slug or stable record ID (Wikidata where available)."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful response; consumes one request",
            "headers": {
              "X-Quota-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "Requests per paid billing cycle"
              },
              "X-Quota-Remaining": {
                "schema": {
                  "type": "integer"
                },
                "description": "Requests left after this response"
              },
              "X-Quota-Reset": {
                "schema": {
                  "type": "integer"
                },
                "description": "Paid cycle end, Unix seconds"
              },
              "X-RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "Requests per fixed minute, shared by account keys"
              },
              "X-RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                },
                "description": "Requests left this minute"
              },
              "X-RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                },
                "description": "Next fixed minute, Unix seconds"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Temple"
                }
              }
            }
          },
          "400": {
            "description": "Invalid or duplicate filters",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Missing, invalid or revoked API key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "No paid live subscription cycle",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Temple not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit or cycle allowance reached",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds until retry"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "Billing verification temporarily unavailable",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "TempleApiKey": {
        "type": "http",
        "scheme": "bearer",
        "bearerFormat": "hwt_live_...",
        "description": "Generate a secret API key in the dashboard after a verified payment. Send only in Authorization header."
      }
    },
    "schemas": {
      "Error": {
        "type": "object",
        "required": [
          "error",
          "code"
        ],
        "properties": {
          "error": {
            "type": "string"
          },
          "code": {
            "type": "string"
          }
        }
      },
      "Image": {
        "type": "object",
        "properties": {
          "url": {
            "type": "string"
          },
          "sourceUrl": {
            "type": "string"
          },
          "credit": {
            "type": "string"
          },
          "license": {
            "type": "string"
          },
          "licenseUrl": {
            "type": "string"
          },
          "kind": {
            "type": "string"
          },
          "alt": {
            "type": "string"
          }
        }
      },
      "TempleSummary": {
        "type": "object",
        "required": [
          "id",
          "slug",
          "name",
          "state",
          "area",
          "deities",
          "categories",
          "coordinates",
          "reviewStatus"
        ],
        "properties": {
          "id": {
            "type": "string"
          },
          "slug": {
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "state": {
            "type": "string"
          },
          "area": {
            "type": "string"
          },
          "description": {
            "type": "string"
          },
          "deities": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "categories": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "coordinates": {
            "type": "object",
            "required": [
              "lat",
              "lon"
            ],
            "properties": {
              "lat": {
                "type": "number"
              },
              "lon": {
                "type": "number"
              }
            }
          },
          "reviewStatus": {
            "type": "string",
            "enum": [
              "source-listed",
              "reviewed-guide"
            ]
          },
          "reviewedAt": {
            "type": "string",
            "nullable": true
          },
          "image": {
            "allOf": [
              {
                "$ref": "#/components/schemas/Image"
              }
            ],
            "nullable": true
          },
          "distanceKm": {
            "type": "number",
            "description": "Present only for nearby searches."
          }
        }
      },
      "Temple": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "slug": {
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "state": {
            "type": "string"
          },
          "area": {
            "type": "string"
          },
          "description": {
            "type": "string"
          },
          "deities": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "coordinates": {
            "type": "object",
            "required": [
              "lat",
              "lon"
            ],
            "properties": {
              "lat": {
                "type": "number"
              },
              "lon": {
                "type": "number"
              }
            }
          },
          "reviewStatus": {
            "type": "string",
            "enum": [
              "source-listed",
              "reviewed-guide"
            ]
          },
          "reviewedAt": {
            "type": "string",
            "nullable": true
          },
          "image": {
            "allOf": [
              {
                "$ref": "#/components/schemas/Image"
              }
            ],
            "nullable": true
          },
          "country": {
            "type": "string"
          },
          "aliases": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "officialWebsite": {
            "type": "string",
            "nullable": true
          },
          "history": {
            "type": "string",
            "nullable": true
          },
          "visit": {
            "type": "object",
            "properties": {
              "planning": {
                "type": "string",
                "nullable": true
              },
              "offerings": {
                "type": "string",
                "nullable": true
              },
              "rules": {
                "type": "string",
                "nullable": true
              },
              "timings": {
                "type": "string",
                "nullable": true
              },
              "steps": {
                "type": "array",
                "items": {
                  "type": "string"
                }
              }
            }
          },
          "sources": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "url": {
                  "type": "string"
                },
                "title": {
                  "type": "string"
                },
                "kind": {
                  "type": "string"
                },
                "license": {
                  "type": "string"
                },
                "retrievedAt": {
                  "type": "string"
                },
                "checkedAt": {
                  "type": "string"
                },
                "fields": {
                  "type": "array",
                  "items": {
                    "type": "string"
                  }
                }
              }
            }
          },
          "rights": {
            "type": "object",
            "properties": {
              "facts": {
                "type": "string"
              },
              "editorial": {
                "type": "string"
              },
              "images": {
                "type": "string"
              }
            }
          }
        }
      },
      "TempleList": {
        "type": "object",
        "properties": {
          "items": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/TempleSummary"
            }
          },
          "total": {
            "type": "integer"
          },
          "page": {
            "type": "integer"
          },
          "limit": {
            "type": "integer"
          },
          "pages": {
            "type": "integer"
          },
          "hasNext": {
            "type": "boolean"
          },
          "updatedAt": {
            "type": "string"
          },
          "schemaVersion": {
            "type": "string"
          }
        }
      },
      "Metadata": {
        "type": "object",
        "properties": {
          "total": {
            "type": "integer"
          },
          "states": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "deities": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "categories": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "key": {
                  "type": "string"
                },
                "label": {
                  "type": "string"
                },
                "count": {
                  "type": "integer"
                }
              }
            }
          },
          "reviewedGuides": {
            "type": "integer"
          },
          "updatedAt": {
            "type": "string"
          },
          "schemaVersion": {
            "type": "string"
          }
        }
      }
    }
  }
}
