{
  "openapi": "3.1.1",
  "info": {
    "title": "Lynor Public Website API",
    "version": "1.0.0",
    "description": "Read-only access to Lynor\u2019s public website content. No authentication is required. This is not the private Lynor product API and cannot initiate calls, bookings or account changes. Unknown API paths return JSON errors with HTTP 404.",
    "contact": {
      "name": "Lynor",
      "url": "https://lynor.io/contact"
    }
  },
  "servers": [
    {
      "url": "https://lynor.io",
      "description": "Production website (may redirect to the canonical www hostname)."
    }
  ],
  "security": [],
  "tags": [
    {
      "name": "Public content",
      "description": "Public website information only."
    }
  ],
  "paths": {
    "/api/v1/site": {
      "get": {
        "operationId": "getSiteInfo",
        "summary": "Get public site information, discovery links and CLI distribution information.",
        "tags": [
          "Public content"
        ],
        "parameters": [],
        "responses": {
          "200": {
            "description": "Success.",
            "headers": {
              "Vary": {
                "schema": {
                  "type": "string"
                },
                "description": "Includes Accept."
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Site"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/ApiError"
          },
          "404": {
            "$ref": "#/components/responses/ApiError"
          },
          "405": {
            "$ref": "#/components/responses/ApiError"
          },
          "406": {
            "$ref": "#/components/responses/ApiError"
          },
          "500": {
            "$ref": "#/components/responses/ApiError"
          }
        }
      },
      "head": {
        "operationId": "getSiteInfoHeaders",
        "summary": "Same status and headers as GET, without a response body.",
        "parameters": [],
        "responses": {
          "200": {
            "description": "No response body."
          },
          "400": {
            "description": "No response body."
          },
          "404": {
            "description": "No response body."
          },
          "405": {
            "description": "No response body."
          },
          "406": {
            "description": "No response body."
          },
          "500": {
            "description": "No response body."
          }
        }
      },
      "options": {
        "operationId": "getSiteInfoOptions",
        "summary": "Discover the read-only methods supported by this API.",
        "responses": {
          "204": {
            "description": "CORS preflight; no response body.",
            "headers": {
              "Access-Control-Allow-Origin": {
                "schema": {
                  "type": "string"
                },
                "example": "*"
              },
              "Access-Control-Allow-Methods": {
                "schema": {
                  "type": "string"
                },
                "example": "GET, HEAD, OPTIONS"
              }
            }
          }
        }
      }
    },
    "/api/v1/pages": {
      "get": {
        "operationId": "listPages",
        "summary": "List the available public pages and their direct Markdown URLs.",
        "tags": [
          "Public content"
        ],
        "parameters": [],
        "responses": {
          "200": {
            "description": "Success.",
            "headers": {
              "Vary": {
                "schema": {
                  "type": "string"
                },
                "description": "Includes Accept."
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "pages"
                  ],
                  "properties": {
                    "pages": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/PageSummary"
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/ApiError"
          },
          "404": {
            "$ref": "#/components/responses/ApiError"
          },
          "405": {
            "$ref": "#/components/responses/ApiError"
          },
          "406": {
            "$ref": "#/components/responses/ApiError"
          },
          "500": {
            "$ref": "#/components/responses/ApiError"
          }
        }
      },
      "head": {
        "operationId": "listPagesHeaders",
        "summary": "Same status and headers as GET, without a response body.",
        "parameters": [],
        "responses": {
          "200": {
            "description": "No response body."
          },
          "400": {
            "description": "No response body."
          },
          "404": {
            "description": "No response body."
          },
          "405": {
            "description": "No response body."
          },
          "406": {
            "description": "No response body."
          },
          "500": {
            "description": "No response body."
          }
        }
      },
      "options": {
        "operationId": "listPagesOptions",
        "summary": "Discover the read-only methods supported by this API.",
        "responses": {
          "204": {
            "description": "CORS preflight; no response body.",
            "headers": {
              "Access-Control-Allow-Origin": {
                "schema": {
                  "type": "string"
                },
                "example": "*"
              },
              "Access-Control-Allow-Methods": {
                "schema": {
                  "type": "string"
                },
                "example": "GET, HEAD, OPTIONS"
              }
            }
          }
        }
      }
    },
    "/api/v1/content": {
      "get": {
        "operationId": "getPageContent",
        "summary": "Read the Markdown representation of one public page. No callback requests or private customer data are exposed.",
        "tags": [
          "Public content"
        ],
        "parameters": [
          {
            "name": "path",
            "in": "query",
            "required": true,
            "description": "A site-relative page path returned by listPages. Query strings and fragments are not supported.",
            "schema": {
              "type": "string",
              "pattern": "^/(?!/)[^?#]*$",
              "minLength": 1
            },
            "example": "/pricing"
          }
        ],
        "responses": {
          "200": {
            "description": "Success.",
            "headers": {
              "Vary": {
                "schema": {
                  "type": "string"
                },
                "description": "Includes Accept."
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PageContent"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/ApiError"
          },
          "404": {
            "$ref": "#/components/responses/ApiError"
          },
          "405": {
            "$ref": "#/components/responses/ApiError"
          },
          "406": {
            "$ref": "#/components/responses/ApiError"
          },
          "500": {
            "$ref": "#/components/responses/ApiError"
          }
        }
      },
      "head": {
        "operationId": "getPageContentHeaders",
        "summary": "Same status and headers as GET, without a response body.",
        "parameters": [
          {
            "name": "path",
            "in": "query",
            "required": true,
            "description": "A site-relative page path returned by listPages. Query strings and fragments are not supported.",
            "schema": {
              "type": "string",
              "pattern": "^/(?!/)[^?#]*$",
              "minLength": 1
            },
            "example": "/pricing"
          }
        ],
        "responses": {
          "200": {
            "description": "No response body."
          },
          "400": {
            "description": "No response body."
          },
          "404": {
            "description": "No response body."
          },
          "405": {
            "description": "No response body."
          },
          "406": {
            "description": "No response body."
          },
          "500": {
            "description": "No response body."
          }
        }
      },
      "options": {
        "operationId": "getPageContentOptions",
        "summary": "Discover the read-only methods supported by this API.",
        "responses": {
          "204": {
            "description": "CORS preflight; no response body.",
            "headers": {
              "Access-Control-Allow-Origin": {
                "schema": {
                  "type": "string"
                },
                "example": "*"
              },
              "Access-Control-Allow-Methods": {
                "schema": {
                  "type": "string"
                },
                "example": "GET, HEAD, OPTIONS"
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "RecoveryLinks": {
        "type": "object",
        "required": [
          "docs",
          "sitemap",
          "llms",
          "openapi"
        ],
        "properties": {
          "docs": {
            "type": "string",
            "format": "uri"
          },
          "sitemap": {
            "type": "string",
            "format": "uri"
          },
          "llms": {
            "type": "string",
            "format": "uri"
          },
          "openapi": {
            "type": "string",
            "format": "uri"
          }
        },
        "additionalProperties": false
      },
      "PageSummary": {
        "type": "object",
        "required": [
          "path",
          "url",
          "markdown_url",
          "title",
          "description",
          "language"
        ],
        "properties": {
          "path": {
            "type": "string"
          },
          "url": {
            "type": "string",
            "format": "uri"
          },
          "markdown_url": {
            "type": "string",
            "format": "uri"
          },
          "title": {
            "type": "string"
          },
          "description": {
            "type": "string"
          },
          "language": {
            "type": "string",
            "enum": [
              "en",
              "fr"
            ]
          }
        }
      },
      "PageContent": {
        "allOf": [
          {
            "$ref": "#/components/schemas/PageSummary"
          },
          {
            "type": "object",
            "required": [
              "markdown"
            ],
            "properties": {
              "markdown": {
                "type": "string",
                "minLength": 20
              }
            }
          }
        ]
      },
      "Error": {
        "type": "object",
        "required": [
          "error"
        ],
        "properties": {
          "error": {
            "type": "object",
            "required": [
              "code",
              "message",
              "hint",
              "links"
            ],
            "properties": {
              "code": {
                "type": "string",
                "enum": [
                  "NOT_FOUND",
                  "INVALID_REQUEST",
                  "METHOD_NOT_ALLOWED",
                  "NOT_ACCEPTABLE",
                  "INTERNAL_ERROR"
                ]
              },
              "message": {
                "type": "string"
              },
              "hint": {
                "type": "string"
              },
              "links": {
                "$ref": "#/components/schemas/RecoveryLinks"
              }
            },
            "additionalProperties": false
          }
        },
        "additionalProperties": false
      },
      "Site": {
        "type": "object",
        "required": [
          "name",
          "url",
          "description",
          "languages",
          "api_version",
          "read_only",
          "links",
          "cli"
        ],
        "properties": {
          "name": {
            "type": "string"
          },
          "url": {
            "type": "string",
            "format": "uri"
          },
          "description": {
            "type": "string"
          },
          "languages": {
            "type": "array",
            "items": {
              "type": "string",
              "enum": [
                "en",
                "fr"
              ]
            }
          },
          "api_version": {
            "type": "string"
          },
          "read_only": {
            "type": "boolean",
            "const": true
          },
          "links": {
            "type": "object",
            "additionalProperties": {
              "type": "string",
              "format": "uri"
            }
          },
          "cli": {
            "type": "object",
            "required": [
              "name",
              "version",
              "download",
              "documentation",
              "source",
              "registry_published"
            ],
            "properties": {
              "name": {
                "type": "string"
              },
              "version": {
                "type": "string"
              },
              "download": {
                "type": "string",
                "format": "uri"
              },
              "documentation": {
                "type": "string",
                "format": "uri"
              },
              "source": {
                "type": "string",
                "format": "uri"
              },
              "registry_published": {
                "type": "boolean"
              }
            }
          }
        }
      }
    },
    "responses": {
      "ApiError": {
        "description": "Structured error with a stable code, human-readable message, resolution hint and discovery links.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            }
          }
        }
      }
    }
  },
  "externalDocs": {
    "description": "Agent guide and Markdown negotiation",
    "url": "https://lynor.io/agents.md"
  }
}
