Deutsch · English

Öffentliche APIs

Basis-URL für alle Routen: https://www.ostheimer.at. Maschinenlesbare Kurzübersicht zusätzlich unter /llms.txt.

1. API-Keys und Berechtigungen

Viele Endpunkte erfordern einen API-Key. Keys werden im Dashboard unter Einstellungen → Public API Clients angelegt; der Klartext-Key wird nur einmal angezeigt.

Übertragung:

  • Authorization: Bearer <API_KEY>
  • oder x-api-key: <API_KEY>

Optional kann ein einzelner Umgebungs-Key (PUBLIC_AGENT_API_KEY) mit konfigurierbaren Scopes genutzt werden – für Integrationen ohne Datenbank-Client.

Legacy Blog: BLOG_API_KEY (Bearer) erlaubt vollen Zugriff auf /api/blog/publish ohne Scope-Modell.

2. Scopes (Public Agent API)

Jeder Datenbank-Client erhält eine Liste erlaubter Scopes. Zuordnung zu Routen:

ScopeEndpunkte
chat:writePOST /api/public/agent/v1/chat
tasks:writePOST /api/public/agent/v1/tasks
tasks:readGET /api/public/agent/v1/tasks/{id}
blog:readGET /api/blog/publish
blog:writePOST, PUT /api/blog/publish
blog:deleteDELETE /api/blog/publish
blog:generatePOST /api/public/agent/v1/blog/generate

Weitere Scopes (z. B. Emoji-Plattform) können im Dashboard zugewiesen werden, sofern die zugehörigen Routen im Einsatz sind.

3. Agent API (API-Key)

POST /api/public/agent/v1/chat

Scope: chat:write. Streaming-Antwort des Agenten.

{
  "messages": [{ "role": "user", "content": "…" }],
  "contact": { "name": "…", "email": "…", "company": "…" }
}

POST /api/public/agent/v1/tasks

Scope: tasks:write. Legt eine interne Aufgabe an.

{
  "title": "…",
  "details": "…",
  "priority": "low" | "normal" | "high",
  "contactName": "…",
  "contactEmail": "…",
  "contactCompany": "…"
}

GET /api/public/agent/v1/tasks/{id}

Scope: tasks:read. Liest eine angelegte Aufgabe.

POST /api/public/agent/v1/blog/generate

Scope: blog:generate. Generiert einen Blogartikel aus einem Thema (KI + optional Bild).

{
  "topic": "…",
  "keywords": [],
  "generateImage": true,
  "imageStyle": "corporate",
  "published": false,
  "publishAt": "2026-03-20T10:00:00.000Z",
  "categories": ["KI"],
  "tags": []
}

4. Blog Publishing API (API-Key oder BLOG_API_KEY)

  • GET /api/blog/publish – Einzelpost per ?slug=… oder ?id=…; ohne diese Parameter: Liste mit optional published=true|false und limit (max. 200, Scope blog:read).
  • POST – Anlegen/Upsert (Scope blog:write oder Legacy-Key).
  • PUT – Teilaktualisierung (blog:write).
  • DELETE – Löschen per Query slug oder id (blog:delete).

Typische Felder im JSON-Body: title, slug, content (Markdown), excerpt, keywords, categories, tags, imageUrl, published, publishAt.

5. Rate-Limit und Antworten

Bei geschützten Public-API-Routen: Limit pro Client und Endpunkt (Fenster typisch 60 Sekunden). Header:

  • X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset
  • Retry-After bei HTTP 429
  • X-Request-Id bei mehreren Routen

Häufige Fehler: 401 (fehlender/ungültiger Key), 403 (missing_scope), 429 (Limit), 400 (invalid_payload).

6. Öffentliche Endpunkte ohne API-Key

Diese Routen sind für Website, Widgets und Crawler gedacht – bitte schonend nutzen (kein Scraping gegen Fair-Use).

Website-Chat

  • POST /api/chat – Streaming-Chat für das eingebettete Widget. Body: messages (Rollen user/assistant/system), optional contact.
  • GET /api/chatbot-config – Modus (internal / external / disabled) und optionaler externer Script-Code.

Kontaktformular (Kalkulator)

  • POST /api/contact – Sendet eine Anfrage inkl. calculatorData (Paket, Summen, Zusammenfassung). Schema ist an die Leistungsseiten gebunden; nur über offizielle Formulare verwenden.

Emoji-Referenz

  • GET /api/emojis – Liste. Query: q, category, subcategory, tag, sort (popular | alphabetical | recent), page, limit, lang.
  • GET /api/emojis/{slug} – Detail inkl. canonicalSlug und data.
  • GET /api/emojis/suggest – Vorschläge: q, limit, lang.
  • POST /api/emojis/{slug}/view – Zählt eine Ansicht (kein Body nötig).
  • POST /api/emojis/{slug}/copy – Zählt eine Kopie.

Redirects (Edge / Middleware)

  • GET /api/redirects/lookup – Aktive Redirects und öffentliche Blog-Slugs (gecacht). Für Infrastruktur, nicht für massenhafte Abfragen von außen ohne Absprache.
  • POST /api/redirects/hit – JSON-Body mit Feld source (Pfad der Quelle) – Hit-Zähler (wird von der Site genutzt).

7. Nicht öffentlich

Alle Routen unter /api/admin/*, /api/agent/* (Dashboard-Agenten), /api/auth/* (außer dokumentierten OAuth-Flows), WordPress-Import, Bildgenerierung für Admins usw. erfordern Anmeldung bzw. sind nicht für externe Integration ohne Vertrag gedacht.

8. MCP (lokal / Desktop)

Für Claude Desktop & Co. existiert ein stdio-MCP-Server im Repository (npm run mcp:server). Details und Umgebungsvariablen siehe docs/AGENT_API.md im Quellcode-Repository.


Public APIs (English)

Base URL: https://www.ostheimer.at. Machine-readable index: /llms.txt.

Authentication

Use Authorization: Bearer <API_KEY> or x-api-key. Create keys in the dashboard (Settings → Public API Clients). Optional env key: PUBLIC_AGENT_API_KEY. Blog legacy: BLOG_API_KEY for full /api/blog/publish access.

Scoped endpoints

chat:write → POST /api/public/agent/v1/chat · tasks:write → POST …/tasks · tasks:read → GET …/tasks/{id} · blog:read|write|delete → /api/blog/publish (GET/POST/PUT/DELETE) · blog:generate → POST /api/public/agent/v1/blog/generate

Rate limits

Per client and route; headers X-RateLimit-*, Retry-After on 429. Errors: 401 unauthorized, 403 missing_scope, 400 invalid_payload.

Endpoints without an API key

  • POST /api/chat – website chat stream
  • GET /api/chatbot-config – widget configuration
  • POST /api/contact – contact + calculator payload (official forms only)
  • GET /api/emojis, GET /api/emojis/{slug}, GET /api/emojis/suggest
  • POST /api/emojis/{slug}/view, POST /api/emojis/{slug}/copy
  • GET /api/redirects/lookup, POST /api/redirects/hit

Not public

/api/admin/*, dashboard /api/agent/*, and similar routes require authentication and are not documented here for external use.