{
  "openapi": "3.1.0",
  "info": {
    "title": "Panigrahana Weddings — Enquiry API",
    "version": "1.0.0",
    "summary": "Submit a wedding planning or decor enquiry and receive a reference.",
    "description": "Public, unauthenticated and write-only. Intended for an AI assistant acting for a couple. A 201 means the enquiry is stored; any other status means it is not. Submitting creates neither a booking nor a price quote: the studio replies within 24 hours and pricing follows a scoping conversation.",
    "contact": {
      "name": "Panigrahana Weddings",
      "email": "info@panigrahana.com",
      "url": "https://panigrahana.com/for-ai-agents.html"
    },
    "license": {
      "name": "Public endpoint. No licence over response content is implied.",
      "identifier": "LicenseRef-panigrahana-public-endpoint"
    }
  },
  "servers": [
    {
      "url": "https://panigrahana.com"
    }
  ],
  "externalDocs": {
    "description": "How to reach the studio, for AI assistants",
    "url": "https://panigrahana.com/for-ai-agents.html"
  },
  "paths": {
    "/api/enquiry": {
      "get": {
        "operationId": "enquiryInstructions",
        "summary": "Plain-text instructions for the enquiry endpoint",
        "responses": {
          "200": {
            "description": "Field list, status meanings and fallbacks.",
            "content": {
              "text/plain": {}
            }
          }
        }
      },
      "post": {
        "operationId": "submitEnquiry",
        "summary": "Submit a wedding enquiry",
        "description": "Returns a JSON receipt carrying a reference. Returned only after the studio's own pipeline confirms the enquiry is stored or delivered. A 503 means it was NOT stored and must not be reported as sent. Rate limit: 5 per hour and 20 per day per source address.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/Enquiry"
              }
            },
            "application/x-www-form-urlencoded": {
              "schema": {
                "$ref": "#/components/schemas/Enquiry"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Stored. A planner replies within 24 hours.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Receipt"
                }
              }
            }
          },
          "202": {
            "description": "Accepted and not forwarded (spam heuristics).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Receipt"
                }
              }
            }
          },
          "400": {
            "description": "Rejected and not stored. The body lists every field problem.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "405": {
            "description": "Method not allowed."
          },
          "413": {
            "description": "Body larger than 32 KB. Not stored."
          },
          "429": {
            "description": "Rate limited. Not stored.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "503": {
            "description": "NOT stored. Fall back to WhatsApp or email.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          }
        }
      },
      "options": {
        "operationId": "enquiryPreflight",
        "summary": "CORS preflight",
        "responses": {
          "204": {
            "description": "CORS headers only."
          }
        }
      }
    },
    "/llms.txt": {
      "get": {
        "operationId": "getLlmsTxt",
        "summary": "Company facts, service scope and page index, as plain text",
        "responses": {
          "200": {
            "description": "Markdown-flavoured plain text.",
            "content": {
              "text/plain": {}
            }
          }
        }
      }
    },
    "/sitemap-index.xml": {
      "get": {
        "operationId": "getSitemapIndex",
        "summary": "Index of every sitemap on the domain",
        "responses": {
          "200": {
            "description": "XML sitemap index.",
            "content": {
              "application/xml": {}
            }
          }
        }
      }
    },
    "/data/venue-cost-registry-2026.json": {
      "get": {
        "operationId": "getVenueCostRegistryJson",
        "summary": "Venue cost registry — capacity, rooms and recorded price references",
        "description": "Open dataset, CC BY 4.0, generated by scripts/generate-open-data.js. One row per venue with a public page on this site. Documented at https://panigrahana.com/open-data.html",
        "responses": {
          "200": {
            "description": "Dataset envelope with a rows array.",
            "content": {
              "application/json": {}
            }
          }
        }
      }
    },
    "/data/venue-cost-registry-2026.csv": {
      "get": {
        "operationId": "getVenueCostRegistryCsv",
        "summary": "The same registry as CSV",
        "responses": {
          "200": {
            "description": "CSV with a leading attribution comment line.",
            "content": {
              "text/csv": {}
            }
          }
        }
      }
    },
    "/.well-known/agent-card.json": {
      "get": {
        "operationId": "getAgentCard",
        "summary": "A2A agent card for this business",
        "responses": {
          "200": {
            "description": "A2A v1.0 agent card.",
            "content": {
              "application/json": {}
            }
          }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "Enquiry": {
        "type": "object",
        "required": [
          "name",
          "contact_whatsapp"
        ],
        "additionalProperties": false,
        "properties": {
          "name": {
            "type": "string",
            "minLength": 2,
            "maxLength": 100
          },
          "contact_whatsapp": {
            "type": "string",
            "pattern": "^[+]?[0-9 ().-]{7,20}$",
            "description": "Required. 7 to 15 digits including the country code."
          },
          "email": {
            "type": "string",
            "format": "email",
            "maxLength": 120
          },
          "city": {
            "type": "string",
            "maxLength": 80,
            "enum": [
              "Bangalore",
              "Karnataka",
              "Goa",
              "Kerala",
              "other"
            ],
            "description": "Wedding city or region. Served: Bangalore and around (including Coorg), Goa, Kerala."
          },
          "wedding_dates": {
            "type": "string",
            "maxLength": 100,
            "description": "Free text. 'Nov 2027' and 'not decided' are both fine."
          },
          "guests": {
            "type": "integer",
            "minimum": 1,
            "maximum": 5000
          },
          "budget_band": {
            "type": "string",
            "maxLength": 40,
            "description": "Free text, for example '40-75-lakh'. Indicative total wedding budget, not a price for services."
          },
          "services": {
            "type": "array",
            "maxItems": 10,
            "items": {
              "type": "string",
              "enum": [
                "planning",
                "decor",
                "both"
              ]
            }
          },
          "message": {
            "type": "string",
            "maxLength": 4000
          },
          "agent_name": {
            "type": "string",
            "maxLength": 80,
            "description": "Name of the AI assistant submitting. Recorded as an unverified claim."
          },
          "principal_name": {
            "type": "string",
            "maxLength": 80,
            "description": "Name of the person the assistant acts for. Recorded as an unverified claim."
          },
          "source_url": {
            "type": "string",
            "format": "uri",
            "maxLength": 300,
            "description": "The page being read when the enquiry was raised."
          },
          "enquiry_request_id": {
            "type": "string",
            "maxLength": 64,
            "description": "Optional idempotency key. Echoed back as the reference so a retry can be deduplicated."
          },
          "website": {
            "type": "string",
            "maxLength": 200,
            "description": "Honeypot. Must be absent or empty; a filled value is dropped silently."
          }
        }
      },
      "Receipt": {
        "type": "object",
        "required": [
          "ok",
          "reference",
          "next",
          "whatsapp"
        ],
        "properties": {
          "ok": {
            "type": "boolean",
            "const": true
          },
          "reference": {
            "type": "string",
            "description": "Quote this when following up."
          },
          "next": {
            "type": "string",
            "examples": [
              "A planner replies on WhatsApp within 24 hours"
            ]
          },
          "whatsapp": {
            "type": "string",
            "format": "uri",
            "examples": [
              "https://wa.me/917766940021"
            ]
          }
        }
      },
      "Problem": {
        "type": "object",
        "required": [
          "ok"
        ],
        "properties": {
          "ok": {
            "type": "boolean",
            "const": false
          },
          "error": {
            "type": "string",
            "enum": [
              "validation_failed",
              "rate_limited",
              "not_delivered",
              "payload_too_large",
              "malformed_json",
              "not_an_object",
              "method_not_allowed"
            ]
          },
          "errors": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Every field problem, listed together."
          },
          "retry_after_seconds": {
            "type": "integer"
          },
          "fallback": {
            "type": "object",
            "properties": {
              "whatsapp": {
                "type": "string",
                "format": "uri"
              },
              "email": {
                "type": "string",
                "format": "email"
              }
            }
          }
        }
      }
    }
  }
}
