API Documentation
Machine-readable discovery via /.well-known/api-catalog (RFC 9727); OpenAPI spec at /api/openapi.json.
POST /api/contact
Contact & Lead Capture
Submits a contact form as a sales lead. Accepts application/json or form-encoded bodies with firstName, lastName, email, phone, and an optional message; JSON posts may also carry a structured configuration object (for example, a Fireplace Builder design).
JSON posts receive { ok: true } on success; form-encoded (no-JS) posts receive a 303 redirect back to /contact. Errors return 400 (invalid input), 429 (rate limited to 5 submissions per minute per IP), or 502 (upstream failure).
GET /api/reviews
Live Google Reviews
Returns the current Google reviews for the business: fetchedAt (ISO timestamp), aggregate (average rating and review count), and the reviews array with reviewer, rating, date, text, and source URL.
Responses are served from a cache seeded at build time and refreshed in the background at most every 15 minutes, so the endpoint never returns an empty set. Rate limited to 30 requests per minute per IP.
GET /api/search
Site Search
Searches pages, products, and blog posts with a q query parameter (2-80 characters). Terms are AND-matched against titles, slugs, and descriptions, ranked by title hits; returns up to 8 results with title, href, kind (Page, Product, or Blog), and blurb.
Rate limited to 60 requests per minute per IP. Queries shorter than 2 characters return an empty results array.
