{
  "openapi": "3.1.0",
  "info": {
    "title": "Your Love Page public API",
    "version": "1.0.0",
    "summary": "Read-only public endpoints for yourlovepage.online.",
    "description": "Your Love Page is a builder for personal, single-page romantic websites. This description covers the public, unauthenticated, read-only endpoints only. There is deliberately no endpoint that creates, edits, publishes, lists, or reads somebody's love page: pages are private to the person who made them and to whoever holds the link, and publishing is tied to that person's account and payment. Every indexable HTML page on the site is additionally available as Markdown via `Accept: text/markdown` or by appending `.md` to the path, per acceptmarkdown.com.",
    "termsOfService": "https://www.yourlovepage.online/terms",
    "contact": {
      "name": "Your Love Page support",
      "email": "love@yourlovepage.online",
      "url": "https://www.yourlovepage.online/contact"
    }
  },
  "externalDocs": {
    "description": "Your Love Page API reference",
    "url": "https://www.yourlovepage.online/docs/api"
  },
  "servers": [
    {
      "url": "https://www.yourlovepage.online",
      "description": "Production"
    }
  ],
  "tags": [
    { "name": "Catalogue", "description": "What the builder can make." },
    { "name": "Media", "description": "Share-preview image rendering." }
  ],
  "security": [],
  "paths": {
    "/api/templates": {
      "get": {
        "operationId": "listTemplates",
        "summary": "List page templates and occasions",
        "description": "Returns every template the builder offers and every occasion it is organised around. Takes no parameters. Prices are intentionally excluded: they are resolved per visitor at the edge (INR inside India, USD elsewhere) and localized again by the payment provider at checkout, so quote https://www.yourlovepage.online/pricing instead. Cached for one hour in the browser and one day at the edge; CORS is open.",
        "tags": ["Catalogue"],
        "security": [],
        "responses": {
          "200": {
            "description": "The template and occasion catalogue.",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/TemplateCatalogue" }
              }
            }
          }
        }
      }
    },
    "/api/og": {
      "get": {
        "operationId": "resolveOpenGraphImage",
        "summary": "Resolve a 1200x630 share-preview image",
        "description": "Redirects to an immutable 1200x630 PNG Open Graph card used when a page link is unfurled. The optional occasion parameter selects the card; unknown values use the general love-message card.",
        "tags": ["Media"],
        "security": [],
        "parameters": [
          {
            "in": "query",
            "name": "occasion",
            "required": false,
            "description": "Occasion-specific card to use.",
            "schema": {
              "type": "string",
              "default": "love_message",
              "enum": ["ask_out", "birthday", "anniversary", "monthsary", "proposal", "love_message"]
            }
          }
        ],
        "responses": {
          "302": {
            "description": "Redirect to the immutable PNG card."
          }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "TemplateCatalogue": {
        "type": "object",
        "required": ["site", "documentation", "pricing", "templates", "occasions"],
        "properties": {
          "site": { "type": "string", "format": "uri", "examples": ["https://www.yourlovepage.online"] },
          "documentation": { "type": "string", "format": "uri" },
          "pricing": {
            "type": "string",
            "format": "uri",
            "description": "Where to read current, visitor-localized prices."
          },
          "templates": {
            "type": "array",
            "items": { "$ref": "#/components/schemas/Template" }
          },
          "occasions": {
            "type": "array",
            "items": { "$ref": "#/components/schemas/Occasion" }
          }
        }
      },
      "Template": {
        "type": "object",
        "required": ["id", "name", "description", "tier", "collection", "demo", "create"],
        "properties": {
          "id": { "type": "string", "examples": ["netflix-love"] },
          "name": { "type": "string", "examples": ["LoveFlix (Netflix theme)"] },
          "description": { "type": "string" },
          "tier": {
            "type": "string",
            "enum": ["free", "premium"],
            "description": "free templates publish without payment; premium templates need the one-time payment to stay live permanently."
          },
          "collection": {
            "type": "string",
            "enum": ["standard", "premiere"],
            "description": "Display grouping only."
          },
          "demo": { "type": "string", "format": "uri", "description": "Interactive demo of the template." },
          "create": { "type": "string", "format": "uri", "description": "Opens the editor on this template." }
        }
      },
      "Occasion": {
        "type": "object",
        "required": ["id", "name", "description", "subtypes"],
        "properties": {
          "id": { "type": "string", "examples": ["ask_out"] },
          "name": { "type": "string", "examples": ["Ask Them Out"] },
          "description": { "type": "string" },
          "subtypes": {
            "type": "array",
            "items": { "$ref": "#/components/schemas/OccasionSubtype" }
          }
        }
      },
      "OccasionSubtype": {
        "type": "object",
        "required": ["id", "name", "description"],
        "properties": {
          "id": { "type": "string", "examples": ["valentines"] },
          "name": { "type": "string", "examples": ["Valentine"] },
          "description": { "type": "string" }
        }
      }
    }
  }
}
