{
  "openapi": "3.1.0",
  "info": {
    "title": "Roefs Grondwerken: openbare pagina’s voor AI-assistenten",
    "version": "1.0.0",
    "summary": "Alleen-lezen toegang tot diensten, prijzen, werkgebied en kennisbank, in Markdown.",
    "description": "Roefs Grondwerken is een grondwerkbedrijf uit Geleen (riolering, camera-inspectie, betonboren tot Ø200 mm, grondwerk, bestrating, klein sloopwerk en tuinvoorbereiding in Zuid-Limburg). Deze beschrijving bevat alleen openbare GET-verzoeken op de website; er is geen API voor offerteaanvragen of afspraken en er is geen authenticatie nodig. Een offerte vraagt de klant zelf aan via het formulier op /contact, dat met de queryparameters `type`, `locatie` en `onderwerp` vooraf kan worden ingevuld. Fouten op /api-paden komen terug als JSON (schema ApiError).",
    "contact": {
      "name": "Roefs Grondwerken",
      "email": "info@roefsgrondwerken.nl",
      "url": "https://roefsgrondwerken.nl/docs"
    }
  },
  "externalDocs": {
    "description": "Uitleg voor AI-assistenten",
    "url": "https://roefsgrondwerken.nl/docs"
  },
  "servers": [
    {
      "url": "https://roefsgrondwerken.nl"
    }
  ],
  "security": [],
  "tags": [
    {
      "name": "Overzicht",
      "description": "Overzichtsbestanden van de hele site."
    },
    {
      "name": "Diensten",
      "description": "Diensten, prijzen en voorwaarden."
    },
    {
      "name": "Kennisbank",
      "description": "Artikelen van Dante Hoenjet."
    },
    {
      "name": "Werkgebied",
      "description": "Plaatsen in Zuid-Limburg en Maasmechelen."
    },
    {
      "name": "Contact",
      "description": "Contactgegevens en offerte aanvragen."
    }
  ],
  "paths": {
    "/": {
      "get": {
        "operationId": "getSiteOverview",
        "tags": [
          "Overzicht"
        ],
        "summary": "Overzicht van Roefs Grondwerken",
        "description": "Wie Roefs Grondwerken is, wanneer u ze inschakelt, diensten, prijzen, werkgebied en toezeggingen. Stuur de header `Accept: text/markdown` voor de Markdown-versie (met `Vary: Accept`); zonder die header komt de gewone HTML-pagina.",
        "responses": {
          "200": {
            "$ref": "#/components/responses/Page",
            "description": "Overzicht van Roefs Grondwerken"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          }
        }
      }
    },
    "/llms.txt": {
      "get": {
        "operationId": "getLlmsTxt",
        "tags": [
          "Overzicht"
        ],
        "summary": "Leeswijzer voor AI-assistenten (llms.txt)",
        "description": "Korte leeswijzer volgens llmstxt.org, opgebouwd uit dezelfde gegevens als de website.",
        "responses": {
          "200": {
            "description": "Leeswijzer voor AI-assistenten (llms.txt)",
            "content": {
              "text/plain": {
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        }
      }
    },
    "/llms-full.txt": {
      "get": {
        "operationId": "getLlmsFullTxt",
        "tags": [
          "Overzicht"
        ],
        "summary": "Uitgebreide leeswijzer met alle vragen en antwoorden",
        "description": "De leeswijzer plus alle zichtbare vragen en antwoorden en een samenvatting van elk artikel.",
        "responses": {
          "200": {
            "description": "Uitgebreide leeswijzer met alle vragen en antwoorden",
            "content": {
              "text/plain": {
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        }
      }
    },
    "/sitemap.xml": {
      "get": {
        "operationId": "getSitemap",
        "tags": [
          "Overzicht"
        ],
        "summary": "Sitemap met alle openbare pagina’s",
        "description": "XML-sitemap met de canonieke openbare pagina’s, artikelen en projecten.",
        "responses": {
          "200": {
            "description": "Sitemap met alle openbare pagina’s",
            "content": {
              "application/xml": {
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        }
      }
    },
    "/diensten": {
      "get": {
        "operationId": "listServices",
        "tags": [
          "Diensten"
        ],
        "summary": "Alle diensten",
        "description": "Overzicht van alle diensten met een korte omschrijving. Stuur de header `Accept: text/markdown` voor de Markdown-versie (met `Vary: Accept`); zonder die header komt de gewone HTML-pagina.",
        "responses": {
          "200": {
            "$ref": "#/components/responses/Page",
            "description": "Alle diensten"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          }
        }
      }
    },
    "/diensten/{service}": {
      "get": {
        "operationId": "getService",
        "tags": [
          "Diensten"
        ],
        "summary": "Eén dienst",
        "description": "Omschrijving, prijsindicatie, werkzaamheden, werkwijze en veelgestelde vragen van één dienst. Stuur de header `Accept: text/markdown` voor de Markdown-versie (met `Vary: Accept`); zonder die header komt de gewone HTML-pagina.",
        "parameters": [
          {
            "name": "service",
            "in": "path",
            "required": true,
            "description": "De dienst, zoals in de URL.",
            "schema": {
              "type": "string",
              "enum": [
                "riolering",
                "betonboren",
                "grondwerk",
                "bestrating",
                "sloopwerk",
                "tuinaanleg",
                "rioolinspectie"
              ]
            }
          }
        ],
        "responses": {
          "200": {
            "$ref": "#/components/responses/Page",
            "description": "Eén dienst"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          }
        }
      }
    },
    "/diensten/betonboren/prijslijst": {
      "get": {
        "operationId": "getDrillingPriceList",
        "tags": [
          "Diensten"
        ],
        "summary": "Prijslijst betonboringen",
        "description": "Alle prijzen per boring van Ø50 tot Ø200 mm in metselwerk en beton, all-in, met de korting bij meerdere gaten. Stuur de header `Accept: text/markdown` voor de Markdown-versie (met `Vary: Accept`); zonder die header komt de gewone HTML-pagina.",
        "responses": {
          "200": {
            "$ref": "#/components/responses/Page",
            "description": "Prijslijst betonboringen"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          }
        }
      }
    },
    "/blog": {
      "get": {
        "operationId": "listGuides",
        "tags": [
          "Kennisbank"
        ],
        "summary": "Alle artikelen in de kennisbank",
        "description": "Alle artikelen per onderwerp, met een korte omschrijving. Stuur de header `Accept: text/markdown` voor de Markdown-versie (met `Vary: Accept`); zonder die header komt de gewone HTML-pagina.",
        "responses": {
          "200": {
            "$ref": "#/components/responses/Page",
            "description": "Alle artikelen in de kennisbank"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          }
        }
      }
    },
    "/blog/{slug}": {
      "get": {
        "operationId": "getGuide",
        "tags": [
          "Kennisbank"
        ],
        "summary": "Eén artikel",
        "description": "Het volledige artikel met kernpunt, secties, tabellen, controlelijst, veelgestelde vragen en bronnen. Stuur de header `Accept: text/markdown` voor de Markdown-versie (met `Vary: Accept`); zonder die header komt de gewone HTML-pagina.",
        "parameters": [
          {
            "name": "slug",
            "in": "path",
            "required": true,
            "description": "Het artikel, zoals in de URL.",
            "schema": {
              "type": "string",
              "enum": [
                "afschot-riolering",
                "asbest-in-oudere-woningen-voor-sloop",
                "bestaande-klinkers-hergebruiken",
                "bestrating-aansluiten-op-dorpel-en-gevel",
                "bestrating-oplevering-controleren",
                "bestrating-voor-zwaar-verkeer",
                "beton-uitbreken-en-puin-afvoeren",
                "betonboren-voorbereiden",
                "betonvloer-verwijderen-bij-renovatie",
                "bomen-behouden-bij-tuinaanleg",
                "boomwortels-in-rioolbuizen",
                "boren-in-gewapend-beton",
                "bouwplaats-voorbereiden-voor-efficient-werk",
                "bouwput-en-fundering-voor-aanbouw",
                "camera-inspectie-riool-kosten",
                "diamantboren-metselwerk-of-beton",
                "diameter-kernboring-bepalen",
                "draagmuur-of-niet-dragende-muur",
                "drainage-in-de-tuin-aanleggen",
                "duurzaam-slopen-en-afval-scheiden",
                "fundering-onder-oprit-en-terras",
                "fundering-uitgraven-voor-aanbouw",
                "gat-boren-voor-airco-diameter",
                "gat-boren-voor-wtw",
                "gazon-voorbereiden-voor-graszoden",
                "graafwerk-smalle-achterom",
                "gresbuis-riolering-vervangen",
                "grondwerk-voor-nieuwbouwwoning",
                "hemelwater-afkoppelen-woning-en-tuin",
                "hoeveel-grond-afvoeren-berekenen",
                "hoogteverschillen-oplossen-met-keerwanden",
                "kapotte-riolering-verzekering",
                "kelder-waterdicht-maken",
                "kernboring-voor-afzuigkap-en-ventilatie",
                "keuken-badkamer-strippen-werkafspraken",
                "kleine-sloopwerken-voorbereiden",
                "kruipruimte-ventilatie-gaten-boren",
                "mantelbuizen-tuinverlichting-voorbereiden",
                "meerdere-kernboringen-installateurs",
                "nieuwbouwtuin-bodem-voorbereiden",
                "nooit-door-toilet-spoelen",
                "oprit-bestraten",
                "oprit-herstellen-of-opnieuw-bestraten",
                "opsluitbanden-bij-bestrating",
                "oude-rioolbuizen-vervangen",
                "perceel-bouwrijp-maken",
                "plassen-op-terras-na-regen",
                "regenpijp-aansluiten-op-riool",
                "riolering-aanleggen",
                "riolering-onder-oprit-vervangen",
                "rioolaansluiting-voor-aanbouw",
                "rioollucht-in-tuin-zonder-verstopping",
                "rioolwater-komt-terug-in-huis",
                "schone-en-vervuilde-grond-herkennen",
                "schuur-slopen-fundering-behouden",
                "signalen-hoofdriool-verstopt",
                "sleuf-aanvullen-na-leidingwerk",
                "straatkolk-en-inspectieput-plaatsen",
                "tegels-verwijderen-vloerverwarming-behouden",
                "tuin-afgraven-en-ophogen",
                "tuinrenovatie-plannen-en-voorbereiden",
                "twee-gaten-monoblock-airco-boren",
                "verschillende-soorten-klinkers-kiezen",
                "verstopte-afvoer-voorkomen",
                "waterdoorlatende-bestrating-wanneer-geschikt",
                "woning-voorbereiden-op-sloopwerk",
                "zandbed-aanleggen-en-verdichten",
                "zwarte-grond-of-teelaarde"
              ]
            }
          }
        ],
        "responses": {
          "200": {
            "$ref": "#/components/responses/Page",
            "description": "Eén artikel"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          }
        }
      }
    },
    "/werkgebied": {
      "get": {
        "operationId": "listServiceAreas",
        "tags": [
          "Werkgebied"
        ],
        "summary": "Het werkgebied",
        "description": "Alle plaatsen en regio’s waar Roefs Grondwerken werkt. Stuur de header `Accept: text/markdown` voor de Markdown-versie (met `Vary: Accept`); zonder die header komt de gewone HTML-pagina.",
        "responses": {
          "200": {
            "$ref": "#/components/responses/Page",
            "description": "Het werkgebied"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          }
        }
      }
    },
    "/werkgebied/{area}": {
      "get": {
        "operationId": "getServiceArea",
        "tags": [
          "Werkgebied"
        ],
        "summary": "Eén plaats of regio",
        "description": "Werkzaamheden, lokale aandachtspunten en veelgestelde vragen voor één plaats of regio. Stuur de header `Accept: text/markdown` voor de Markdown-versie (met `Vary: Accept`); zonder die header komt de gewone HTML-pagina.",
        "parameters": [
          {
            "name": "area",
            "in": "path",
            "required": true,
            "description": "De plaats of regio, zoals in de URL.",
            "schema": {
              "type": "string",
              "enum": [
                "beek-stein",
                "geleen",
                "heerlen",
                "kerkrade",
                "maasmechelen",
                "maastricht",
                "meerssen",
                "sittard-geleen"
              ]
            }
          }
        ],
        "responses": {
          "200": {
            "$ref": "#/components/responses/Page",
            "description": "Eén plaats of regio"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          }
        }
      }
    },
    "/contact": {
      "get": {
        "operationId": "getContactInfo",
        "tags": [
          "Contact"
        ],
        "summary": "Contactgegevens en offerte aanvragen",
        "description": "Telefoon, e-mail, bereikbaarheid en hoe een klant een offerte aanvraagt. Stuur de header `Accept: text/markdown` voor de Markdown-versie (met `Vary: Accept`); zonder die header komt de gewone HTML-pagina.",
        "responses": {
          "200": {
            "$ref": "#/components/responses/Page",
            "description": "Contactgegevens en offerte aanvragen"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "MarkdownPage": {
        "type": "string",
        "contentMediaType": "text/markdown",
        "description": "De pagina als Markdown, met onderaan de link naar de HTML-versie, llms.txt en de sitemap."
      },
      "HtmlPage": {
        "type": "string",
        "contentMediaType": "text/html",
        "description": "De HTML-pagina."
      },
      "ApiError": {
        "type": "object",
        "description": "Foutmelding op een /api-pad dat niet bestaat.",
        "required": [
          "error"
        ],
        "properties": {
          "error": {
            "type": "object",
            "required": [
              "status",
              "code",
              "message",
              "hint",
              "docs"
            ],
            "properties": {
              "status": {
                "type": "integer",
                "description": "HTTP-status, bijvoorbeeld 404."
              },
              "code": {
                "type": "string",
                "enum": [
                  "not_found"
                ],
                "description": "Vaste foutcode."
              },
              "message": {
                "type": "string",
                "description": "Wat er misging."
              },
              "hint": {
                "type": "string",
                "description": "Hoe het wel kan."
              },
              "docs": {
                "type": "string",
                "format": "uri",
                "description": "Uitleg voor AI-assistenten."
              }
            }
          }
        }
      }
    },
    "responses": {
      "Page": {
        "description": "De pagina, als Markdown of HTML afhankelijk van de Accept-header.",
        "headers": {
          "Vary": {
            "description": "Altijd `Accept` bij de Markdown-versie.",
            "schema": {
              "type": "string"
            }
          },
          "Link": {
            "description": "Bij de Markdown-versie: de canonieke HTML-pagina (rel=\"canonical\").",
            "schema": {
              "type": "string"
            }
          }
        },
        "content": {
          "text/markdown": {
            "schema": {
              "$ref": "#/components/schemas/MarkdownPage"
            }
          },
          "text/html": {
            "schema": {
              "$ref": "#/components/schemas/HtmlPage"
            }
          }
        }
      },
      "NotFound": {
        "description": "De pagina bestaat niet. Met `Accept: text/markdown` een korte uitleg in Markdown met links naar llms.txt en de sitemap.",
        "content": {
          "text/markdown": {
            "schema": {
              "$ref": "#/components/schemas/MarkdownPage"
            }
          },
          "text/html": {
            "schema": {
              "$ref": "#/components/schemas/HtmlPage"
            }
          }
        }
      }
    }
  }
}