{"openapi":"3.1.0","info":{"title":"Notenstrauss Public API","version":"1.0.0","description":"Public read APIs and contact submission for notenstrauss.de — Live-Musik and Musikunterricht in Grünstadt (Pfalz). See /developers for auth notes and examples.","contact":{"name":"Notenstrauss","email":"kontakt@notenstrauss.de","url":"https://notenstrauss.de/kontakt"}},"servers":[{"url":"https://notenstrauss.de"}],"tags":[{"name":"content","description":"Site content and navigation"},{"name":"media","description":"Videos and media listings"},{"name":"contact","description":"Contact and booking requests"},{"name":"agents","description":"Agent-oriented markdown and discovery"}],"paths":{"/api/site-content":{"get":{"operationId":"getSiteContent","summary":"Fetch navigation or site chrome content","description":"Returns structured navigation items from the CMS. Use id=navbar for the main menu.","tags":["content"],"parameters":[{"name":"id","in":"query","required":true,"schema":{"type":"string","enum":["navbar"]},"description":"Content block identifier"}],"responses":{"200":{"description":"Site content payload","content":{"application/json":{"schema":{"type":"object","properties":{"content":{"type":"object","nullable":true,"properties":{"items":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"label":{"type":"string"},"href":{"type":"string"},"order":{"type":"integer"}}}},"ctaLabel":{"type":"string"},"ctaHref":{"type":"string"}}}}}}}},"400":{"$ref":"#/components/responses/BadRequest"}}}},"/api/video-list":{"get":{"operationId":"listVideos","summary":"Paginated YouTube performance videos","tags":["media"],"parameters":[{"name":"page","in":"query","schema":{"type":"integer","minimum":1,"default":1}},{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":36,"default":18}}],"responses":{"200":{"description":"Video page","content":{"application/json":{"schema":{"type":"object","required":["docs","totalDocs","hasNextPage"],"properties":{"docs":{"type":"array","items":{"$ref":"#/components/schemas/VideoSummary"}},"totalDocs":{"type":"integer"},"hasNextPage":{"type":"boolean"},"nextPage":{"type":"integer","nullable":true}}}}}}}}},"/api/contact":{"post":{"operationId":"submitContact","summary":"Submit a contact or booking inquiry","description":"Requires a valid Cloudflare Turnstile token when Turnstile is enabled. Phone number is mandatory.","tags":["contact"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ContactRequest"}}}},"responses":{"200":{"description":"Message accepted","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"403":{"$ref":"#/components/responses/Forbidden"},"500":{"$ref":"#/components/responses/ServerError"}}}},"/api/markdown":{"get":{"operationId":"getHomepageMarkdown","summary":"Homepage as markdown","tags":["agents"],"responses":{"200":{"description":"Markdown homepage","content":{"text/markdown":{"schema":{"type":"string"}}}}}}},"/api/markdown/{path}":{"get":{"operationId":"getPageMarkdown","summary":"Any public page as markdown","tags":["agents"],"parameters":[{"name":"path","in":"path","required":true,"schema":{"type":"string"},"description":"Page path without leading slash, e.g. livemusik or kontakt"}],"responses":{"200":{"description":"Markdown page","content":{"text/markdown":{"schema":{"type":"string"}}}},"404":{"$ref":"#/components/responses/NotFound"}}}},"/api/graphql":{"post":{"operationId":"graphqlQuery","summary":"Payload CMS GraphQL endpoint (read-only public queries)","description":"GraphQL API backed by Payload CMS. Introspection may be limited; see /api/graphql/schema for SDL.","tags":["content"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"query":{"type":"string"},"variables":{"type":"object","additionalProperties":true},"operationName":{"type":"string"}},"required":["query"]}}}},"responses":{"200":{"description":"GraphQL result","content":{"application/json":{"schema":{"type":"object"}}}},"429":{"$ref":"#/components/responses/RateLimited"}}}},"/api/graphql/schema":{"get":{"operationId":"getGraphqlSchema","summary":"GraphQL schema (SDL) for tooling and agents","tags":["content"],"responses":{"200":{"description":"GraphQL schema definition","content":{"text/plain":{"schema":{"type":"string"}},"application/json":{"schema":{"type":"object","properties":{"schema":{"type":"string"},"endpoint":{"type":"string"}}}}}}}}},"/llms.txt":{"get":{"operationId":"getLlmsTxt","summary":"Agent index (llms.txt)","tags":["agents"],"responses":{"200":{"description":"llms.txt navigation index","content":{"text/plain":{"schema":{"type":"string"}}}}}}}},"components":{"schemas":{"VideoSummary":{"type":"object","properties":{"id":{"type":"string","description":"YouTube video ID"},"title":{"type":"string"},"description":{"type":"string"},"publishedAt":{"type":"string","format":"date-time"},"thumbnailUrl":{"type":"string","format":"uri"}}},"ContactRequest":{"type":"object","required":["phone"],"properties":{"formType":{"type":"string","enum":["booking","lesson","normal"],"default":"normal"},"turnstileToken":{"type":"string"},"phone":{"type":"string"},"email":{"type":"string","format":"email"},"name":{"type":"string"},"firstName":{"type":"string"},"lastName":{"type":"string"},"message":{"type":"string"},"postalCode":{"type":"string"},"date":{"type":"string"},"time":{"type":"string"},"offer":{"type":"string"},"fromPath":{"type":"string"},"videoId":{"type":"string"},"songTitle":{"type":"string"}}},"ErrorResponse":{"type":"object","properties":{"error":{"type":"string"},"code":{"type":"string"},"hint":{"type":"string"}}}},"responses":{"BadRequest":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"Forbidden":{"description":"Security check failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"NotFound":{"description":"Resource not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"ServerError":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"RateLimited":{"description":"Rate limit exceeded","headers":{"RateLimit-Limit":{"schema":{"type":"integer"}},"RateLimit-Remaining":{"schema":{"type":"integer"}},"RateLimit-Reset":{"schema":{"type":"integer"}},"Retry-After":{"schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}}