{
  "openapi": "3.1.1",
  "info": {
    "title": "maltelandwehr.de content API",
    "version": "2026-10-02",
    "summary": "The public pages and machine-readable files of maltelandwehr.de, described as an API.",
    "description": "maltelandwehr.de is a static website, and the pages are the API. Every resource below is fetched with an unauthenticated HTTP GET, returns the same bytes to every caller, and is free to read, quote and cache. Responses carry Access-Control-Allow-Origin: *, so a browser-based agent can read them cross-origin. HTML pages revalidate every ten minutes.\n\nAgents that want the content without parsing HTML should start at /llms.txt for the map, /llms-full.txt for the whole text, and /person.jsonld for the Malte Landwehr entity. Every page is also available as Markdown: send Accept: text/markdown to the page URL, or fetch the page path with .md in place of the trailing slash (/speaker.md for /speaker/, /index.md for the home page). Four protocol endpoints sit outside this description, because they take a POST rather than a GET: an MCP server at /mcp (card at /.well-known/mcp/server-card.json), an A2A agent at /a2a (card at /.well-known/agent-card.json), and a free checkout for the speaker bio over UCP at /ucp (profile at /.well-known/ucp) and over ACP at /acp (discovery at /.well-known/acp.json). All four read the same published files and need no authentication. One resource is protected: /birthdate, with an OAuth 2.0 token for the scope profile:birthdate. Any client can register and get one. /auth.md explains how.",
    "contact": {
      "name": "Malte Landwehr",
      "url": "https://www.maltelandwehr.de/imprint/"
    },
    "license": {
      "name": "All rights reserved. Quoting with attribution is welcome.",
      "identifier": "LicenseRef-maltelandwehr-de"
    }
  },
  "servers": [
    {
      "url": "https://www.maltelandwehr.de",
      "description": "Canonical host. The apex domain redirects here."
    }
  ],
  "security": [],
  "tags": [
    {
      "name": "Entity",
      "description": "Machine-readable facts about Malte Landwehr."
    },
    {
      "name": "Pages",
      "description": "The website itself, as HTML."
    },
    {
      "name": "Articles",
      "description": "The articles published on this site."
    },
    {
      "name": "Discovery",
      "description": "Index and manifest files for crawlers and agents."
    },
    {
      "name": "Media",
      "description": "Images offered for reuse."
    }
  ],
  "paths": {
    "/person.jsonld": {
      "get": {
        "tags": [
          "Entity"
        ],
        "operationId": "getPersonEntity",
        "summary": "The Malte Landwehr Person entity",
        "description": "schema.org Person as JSON-LD: name, job title, employer, press photo and the full list of verified profiles on other platforms. The same node, with the same @id, is embedded in the home page. This file is the copy to fetch when you do not want to parse HTML.",
        "responses": {
          "200": {
            "description": "The Person entity.",
            "content": {
              "application/ld+json": {
                "schema": {
                  "$ref": "#/components/schemas/Person"
                }
              }
            }
          }
        }
      }
    },
    "/birthdate": {
      "get": {
        "tags": [
          "Entity"
        ],
        "operationId": "getBirthdate",
        "summary": "Malte Landwehr's date of birth",
        "description": "JSON. A schema.org Person with birthDate. The one resource on this site that needs an OAuth 2.0 access token. There are no accounts. Any client can register at /oauth/register and get a token.",
        "security": [
          {
            "oauth": [
              "profile:birthdate"
            ]
          }
        ],
        "responses": {
          "200": {
            "description": "The date of birth.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "@type": {
                      "const": "Person"
                    },
                    "name": {
                      "type": "string"
                    },
                    "birthDate": {
                      "type": "string",
                      "format": "date"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "No token, or the token is invalid or has expired. WWW-Authenticate points at the protected resource metadata."
          },
          "403": {
            "description": "The token lacks the profile:birthdate scope."
          }
        }
      }
    },
    "/llms.txt": {
      "get": {
        "tags": [
          "Discovery"
        ],
        "operationId": "getLlmsTxt",
        "summary": "Short index of the site for language models",
        "description": "Markdown. What the site covers, the key facts about Malte Landwehr, and an annotated link to every page worth reading. Start here.",
        "responses": {
          "200": {
            "description": "The index.",
            "content": {
              "text/plain": {
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        }
      }
    },
    "/llms-full.txt": {
      "get": {
        "tags": [
          "Discovery"
        ],
        "operationId": "getLlmsFullTxt",
        "summary": "The full text of the site in one file",
        "description": "Markdown. Every indexable page of this site, converted from the published HTML, in sitemap order. Roughly 55,000 words. Fetch this instead of crawling the pages one by one.",
        "responses": {
          "200": {
            "description": "The whole site as text.",
            "content": {
              "text/plain": {
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        }
      }
    },
    "/AGENTS.md": {
      "get": {
        "tags": [
          "Discovery"
        ],
        "operationId": "getAgentsMd",
        "summary": "Instructions for agents reading this site",
        "description": "Markdown. How to work with this site: start at /llms.txt, take /llms-full.txt instead of crawling, and the full list of machine-readable resources.",
        "responses": {
          "200": {
            "description": "The file.",
            "content": {
              "text/markdown": {
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        }
      }
    },
    "/auth.md": {
      "get": {
        "tags": [
          "Discovery"
        ],
        "operationId": "getAuthMd",
        "summary": "How authentication works here",
        "description": "Markdown. Nothing on this site needs authentication except /birthdate. Explains the OAuth 2.0 flow for that one resource: discovery, client registration, both grants and the token.",
        "responses": {
          "200": {
            "description": "The file.",
            "content": {
              "text/markdown": {
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        }
      }
    },
    "/sitemap.xml": {
      "get": {
        "tags": [
          "Discovery"
        ],
        "operationId": "getSitemap",
        "summary": "Every indexable URL",
        "responses": {
          "200": {
            "description": "XML sitemap.",
            "content": {
              "application/xml": {
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        }
      }
    },
    "/robots.txt": {
      "get": {
        "tags": [
          "Discovery"
        ],
        "operationId": "getRobotsTxt",
        "summary": "Crawling rules and content signals",
        "description": "Everything is allowed, for search, for AI input and for AI training. The major AI crawlers are named in the same group as the wildcard, so they get the same rules. So is the shared AI training policy token __usage_ai-training, which Google, Anthropic, Microsoft and OpenAI announced they will honor. Two lines say so explicitly: Content-Signal in the Cloudflare vocabulary and Content-Usage in the IETF AIPREF vocabulary.",
        "responses": {
          "200": {
            "description": "robots.txt.",
            "content": {
              "text/plain": {
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        }
      }
    },
    "/.well-known/ard.json": {
      "get": {
        "tags": [
          "Discovery"
        ],
        "operationId": "getArdManifest",
        "summary": "Agentic Resource Discovery manifest",
        "description": "The ARD manifest, listing the resources on this site that are meant for agents, each with the questions it answers. Also served at /.well-known/ai-catalog.json, byte for byte identical, under the older filename from the same spec.",
        "responses": {
          "200": {
            "description": "ARD manifest.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        }
      }
    },
    "/.well-known/poppy.json": {
      "get": {
        "tags": [
          "Discovery"
        ],
        "operationId": "getPoppyManifest",
        "summary": "Personal Agent Protocol discovery document",
        "description": "The Personal Agent Protocol (Poppy) manifest, version 0.1. It declares the website only, with no browser session endpoint, so a personal agent browses this site as an ordinary signed-out visitor. There is no Poppy sign-in, session or company agent here.",
        "responses": {
          "200": {
            "description": "Poppy manifest.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        }
      }
    },
    "/.well-known/agent-skills/index.json": {
      "get": {
        "tags": [
          "Discovery"
        ],
        "operationId": "getAgentSkillsIndex",
        "summary": "Agent Skills discovery index",
        "description": "The Agent Skills Discovery index (schema 0.2.0), listing the skills this site publishes for agents. Each entry names a SKILL.md, describes what it is for, and carries the SHA-256 digest of that file so a client can verify what it downloaded. The skills are reading instructions: this site is a set of documents, so every skill tells an agent which URL to fetch for a question and how to cite the answer.",
        "responses": {
          "200": {
            "description": "The skills index.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        }
      }
    },
    "/.well-known/agent-skills/{skill}/SKILL.md": {
      "get": {
        "tags": [
          "Discovery"
        ],
        "operationId": "getAgentSkill",
        "summary": "One agent skill",
        "description": "Markdown with YAML frontmatter, in the Agent Skills format. The frontmatter carries the skill name and description; the body tells an agent which URLs on this site answer which questions, and how to cite them. Listed in /.well-known/agent-skills/index.json with a SHA-256 digest.",
        "parameters": [
          {
            "name": "skill",
            "in": "path",
            "required": true,
            "description": "The skill name, as listed in the discovery index.",
            "schema": {
              "type": "string",
              "enum": [
                "maltelandwehr-de",
                "malte-landwehr",
                "malte-landwehr-speaker",
                "malte-landwehr-awards",
                "malte-landwehr-articles",
                "seo-podcasts",
                "ai-search-statistics"
              ]
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The skill file.",
            "content": {
              "text/markdown": {
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        }
      }
    },
    "/": {
      "get": {
        "tags": [
          "Pages"
        ],
        "operationId": "getHome",
        "summary": "Home page and CV",
        "description": "Full CV from 2003 to today, key facts, awards and the list of profiles that belong to this entity. Carries the canonical Person markup in a JSON-LD block.",
        "responses": {
          "200": {
            "$ref": "#/components/responses/HtmlPage"
          }
        }
      }
    },
    "/speaker/": {
      "get": {
        "tags": [
          "Pages"
        ],
        "operationId": "getSpeakerProfile",
        "summary": "Speaker profile",
        "description": "Every talk since 2010 by year, with conference, city and title, plus a ready to use speaker bio and a print-quality press photo for organisers.",
        "responses": {
          "200": {
            "$ref": "#/components/responses/HtmlPage"
          }
        }
      }
    },
    "/articles/": {
      "get": {
        "tags": [
          "Articles"
        ],
        "operationId": "listArticles",
        "summary": "Index of everything Malte Landwehr has written or appeared in",
        "description": "Articles on this site, external essays, talks on video, podcasts, TV, radio and print coverage, interviews, quotes and a book.",
        "responses": {
          "200": {
            "$ref": "#/components/responses/HtmlPage"
          }
        }
      }
    },
    "/articles/{slug}/": {
      "get": {
        "tags": [
          "Articles"
        ],
        "operationId": "getArticle",
        "summary": "One article",
        "description": "The article as HTML, with schema.org Article and BreadcrumbList JSON-LD in the head. Slugs are permanent: a title can change, the URL does not. Articles carry no publication date, by choice.",
        "parameters": [
          {
            "name": "slug",
            "in": "path",
            "required": true,
            "description": "The article slug. The full list is in /sitemap.xml and /llms.txt.",
            "schema": {
              "type": "string",
              "enum": [
                "ai-agents-digital-economy",
                "decision-engine-optimisation",
                "agentism",
                "seo-tool-acquisitions-und-consolidation",
                "peec-ai-vs-profound-the-ultimate-aeo-platform-battle-for-2026",
                "llms.txt",
                "was-ki-besser-kann-als-menschen",
                "prompts-verkaufen",
                "explaining-persuading-and-presenting",
                "erklaeren-ueberzeugen-und-praesentieren",
                "user-migration",
                "software-development"
              ]
            },
            "example": "agentism"
          }
        ],
        "responses": {
          "200": {
            "$ref": "#/components/responses/HtmlPage"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          }
        }
      }
    },
    "/awards/": {
      "get": {
        "tags": [
          "Pages"
        ],
        "operationId": "getAwards",
        "summary": "Awards and recognition",
        "description": "Awards, certificates and research grants won by Malte Landwehr, and the awards won with Peec AI.",
        "responses": {
          "200": {
            "$ref": "#/components/responses/HtmlPage"
          }
        }
      }
    },
    "/press/": {
      "get": {
        "tags": [
          "Pages"
        ],
        "operationId": "getPress",
        "summary": "Press coverage",
        "description": "Where Malte Landwehr has been quoted, interviewed or covered in newspapers, magazines, the trade press, TV, radio and podcasts since 2008.",
        "responses": {
          "200": {
            "$ref": "#/components/responses/HtmlPage"
          }
        }
      }
    },
    "/presse/": {
      "get": {
        "tags": [
          "Pages"
        ],
        "operationId": "getPresse",
        "summary": "Press coverage, in German",
        "description": "The German version of the press page: the same coverage, described in German.",
        "responses": {
          "200": {
            "$ref": "#/components/responses/HtmlPage"
          }
        }
      }
    },
    "/reddit/": {
      "get": {
        "tags": [
          "Pages"
        ],
        "operationId": "getReddit",
        "summary": "Reddit activity",
        "description": "What Malte Landwehr posts as u/maltelandwehr, where other users cite his work, and his most-upvoted answers.",
        "responses": {
          "200": {
            "$ref": "#/components/responses/HtmlPage"
          }
        }
      }
    },
    "/seo-podcasts/": {
      "get": {
        "tags": [
          "Pages"
        ],
        "operationId": "getSeoPodcasts",
        "summary": "The best SEO podcasts",
        "description": "Thirteen SEO and AI search podcasts worth subscribing to, with the host of each show, what it is good at, and one recommended episode. Curated by Malte Landwehr, who has been a guest on all of them.",
        "responses": {
          "200": {
            "$ref": "#/components/responses/HtmlPage"
          }
        }
      }
    },
    "/ai-search-statistics/": {
      "get": {
        "tags": [
          "Pages"
        ],
        "operationId": "getAiSearchStatistics",
        "summary": "594 AI search statistics for 2026",
        "description": "594 statistics on AI search in 33 sections, each with a named source and, for most, a link and the date it was measured: adoption, zero-click rates and CTR, Google AI Overviews and AI Mode, which domains answer engines cite, query fan-outs, how AI agents read a site, AI shopping, AI referral traffic and its value, tests and case studies, and B2B and consumer buying behaviour.",
        "responses": {
          "200": {
            "$ref": "#/components/responses/HtmlPage"
          }
        }
      }
    },
    "/enterprise-seo/": {
      "get": {
        "tags": [
          "Pages"
        ],
        "operationId": "getEnterpriseSeoFaq",
        "summary": "Enterprise SEO FAQ",
        "description": "Seventeen questions on Enterprise SEO answered by Malte Landwehr: definition, cost, in-house team vs. agency, ROI, tools, buy-in, governance, ownership, crawl budget, international SEO, quality assurance at scale, and hiring an Enterprise SEO lead.",
        "responses": {
          "200": {
            "$ref": "#/components/responses/HtmlPage"
          }
        }
      }
    },
    "/ai-search/": {
      "get": {
        "tags": [
          "Pages"
        ],
        "operationId": "getAiSearchFaq",
        "summary": "AI Search FAQ",
        "description": "Eighty-two questions on AI search, GEO and AEO answered by Malte Landwehr: how answer engines ground their answers, fanout queries, which engines to track, what gets cited, llms.txt, off-page sources and digital PR, prompt tracking and KPIs, AI-generated content, who owns GEO, brand perception, AI shopping and agentic commerce, and zero click.",
        "responses": {
          "200": {
            "$ref": "#/components/responses/HtmlPage"
          }
        }
      }
    },
    "/imprint/": {
      "get": {
        "tags": [
          "Pages"
        ],
        "operationId": "getImprint",
        "summary": "Imprint",
        "description": "Legal notice and contact details. Marked noindex, follow.",
        "responses": {
          "200": {
            "$ref": "#/components/responses/HtmlPage"
          }
        }
      }
    },
    "/assets/img/malte-landwehr-press-photo.jpg": {
      "get": {
        "tags": [
          "Media"
        ],
        "operationId": "getPressPhoto",
        "summary": "Press photo",
        "description": "Print-quality portrait, 1278 x 1491 JPEG. Free to use for events and publications.",
        "responses": {
          "200": {
            "description": "The photo.",
            "content": {
              "image/jpeg": {
                "schema": {
                  "type": "string",
                  "format": "binary"
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "responses": {
      "HtmlPage": {
        "description": "The page as HTML5, with a self-referencing canonical, Open Graph tags and schema.org JSON-LD in the head. A request with Accept: text/markdown gets the same page as Markdown instead, with YAML frontmatter (title, description, url, lang). That response carries Vary: Accept and a Link header with rel=\"canonical\" pointing at the HTML page.",
        "content": {
          "text/html": {
            "schema": {
              "type": "string"
            }
          },
          "text/markdown": {
            "schema": {
              "type": "string"
            }
          }
        }
      },
      "NotFound": {
        "description": "No such page. The site returns a real 404 for content that no longer exists rather than redirecting somewhere misleading.",
        "content": {
          "text/html": {
            "schema": {
              "type": "string"
            }
          }
        }
      }
    },
    "schemas": {
      "Person": {
        "type": "object",
        "description": "A schema.org Person node, serialised as JSON-LD.",
        "required": [
          "@context",
          "@type",
          "@id",
          "name"
        ],
        "properties": {
          "@context": {
            "const": "https://schema.org"
          },
          "@type": {
            "const": "Person"
          },
          "@id": {
            "type": "string",
            "format": "uri",
            "description": "The stable identifier for this entity across the whole site.",
            "const": "https://www.maltelandwehr.de/#person"
          },
          "name": {
            "type": "string"
          },
          "jobTitle": {
            "type": "string"
          },
          "url": {
            "type": "string",
            "format": "uri"
          },
          "image": {
            "type": "string",
            "format": "uri"
          },
          "worksFor": {
            "type": "object",
            "properties": {
              "@type": {
                "const": "Organization"
              },
              "name": {
                "type": "string"
              },
              "url": {
                "type": "string",
                "format": "uri"
              }
            }
          },
          "sameAs": {
            "type": "array",
            "description": "Verified profiles and identifiers that belong to this entity.",
            "items": {
              "type": "string",
              "format": "uri"
            }
          }
        }
      }
    },
    "securitySchemes": {
      "oauth": {
        "type": "oauth2",
        "description": "Only /birthdate uses this. Register a client at /oauth/register (RFC 7591) first. Metadata: /.well-known/oauth-authorization-server.",
        "flows": {
          "authorizationCode": {
            "authorizationUrl": "https://www.maltelandwehr.de/oauth/authorize",
            "tokenUrl": "https://www.maltelandwehr.de/oauth/token",
            "scopes": {
              "profile:birthdate": "Read Malte Landwehr's date of birth."
            }
          },
          "clientCredentials": {
            "tokenUrl": "https://www.maltelandwehr.de/oauth/token",
            "scopes": {
              "profile:birthdate": "Read Malte Landwehr's date of birth."
            }
          }
        }
      }
    }
  }
}
