AI Agents & API
Strukturierte Daten für Recherche, Vergleiche und eigene Anwendungen.
Alle Zugänge sind öffentlich, kostenfrei und lesend. Es ist kein API-Key erforderlich. Verfügbar sind aktuelle Umfragezahlen für Deutschland und die Länder, vollständige Wahltermine, Gesamtwahlergebnisse, Abgeordnete und Mandatswechsel. Wahlkreisergebnisse und gebündelte Wahlkreis-Wahldaten sind über diese Schnittstelle nicht verfügbar.
Discovery
- AI Catalog 1.0 — auch unter /ai-catalog.json. Der HTML-Head verlinkt ihn mit
rel="ai-catalog". - Tool-Manifest mit JSON Schemas und HTTP Discovery.
- llms.txt beschreibt die Seitenstruktur.
WebMCP im Browser
Auf jeder Seite registriert wahl.de die unten aufgeführten Tools über document.modelContext.registerTool. Frühe Implementierungen mit navigator.modelContext werden ebenfalls erkannt. WebMCP ist ein experimenteller Browserstandard und benötigt HTTPS (lokal localhost) sowie einen kompatiblen Browser und Agent. Ohne WebMCP bleibt der HTTP-Zugang verfügbar.
const tools = await document.modelContext.getTools();
const tool = tools.find(t => t.name === "wahl_get_poll_trend");
const result = await document.modelContext.executeTool(tool, {
region: "Deutschland"
});Die Tools liefern JSON-Objekte direkt zurück. Abbruchsignale werden an den HTTP-Abruf weitergegeben. Dies ist eine WebMCP-Integration und eine HTTP JSON API; die HTTP-URL ist kein MCP-JSON-RPC-Server.
HTTP JSON
GET /api/ai liefert sämtliche Toolnamen und Eingabeschemas. Aufruf: GET /api/ai/{tool}?input={JSON} (URL-kodiert) oder POST /api/ai/{tool} mit Content-Type: application/json und den Parametern direkt als Body. CORS erlaubt lesende Abrufe von anderen Origins.
curl -G 'https://www.wahl.de/api/ai/wahl_get_poll_trend' --data-urlencode 'input={"region":"Deutschland"}'
curl 'https://www.wahl.de/api/ai/wahl_get_election_result' -H 'Content-Type: application/json' -d '{"electionId":"btw-25"}'Erfolgreiche Antworten enthalten tool, data, retrievedAt, documentationUrl und sourcesUrl. Der Abrufzeitpunkt ist kein Aktualisierungsdatum: Angaben wie updated, date, status und source im Datensatz bestimmen den Datenstand.
Listen mit offset/limit beginnen bei 0; Standard: 50, Maximum: 100. data.pagination enthält total, nextOffset und bei verschachtelten Listen collection. Bei einer einfachen Liste liegen die Einträge unter data.items, sonst unter dem angegebenen Feld. Der Wahlkalender und das Gesamtergebnis einer Wahl werden vollständig geliefert und verwenden keine Pagination.
Fehler liefern ein JSON-Objekt mit error: 400 für ungültige Parameter, 404 für unbekannte Tools oder fehlende Daten, 405 für nicht unterstützte Methoden, 413 für zu große Anfragen, 415 für falschen Content-Type und 502 für einen Datenladefehler. Unbekannte Parameter werden abgewiesen.
Live-Beispiel
Tools und Parameter
Elf Tools erschließen fünf Datenbereiche: aktuelle Umfragezahlen (mit Regionsliste), vollständige Termine, Gesamtwahlergebnisse (mit Wahlindex und Historie), Abgeordnete (Liste und Einzelprofil) sowie Mandatswechsel (Wahlperioden, einzelne Periode und Gesamtliste). HTTP und WebMCP verwenden dieselbe Freigabeliste. Andere Toolnamen werden mit 404 abgewiesen. Wahlkreis-Wahldaten sind ausgeschlossen. Abgeordnete und Mandatswechsel verlinken mit profileUrl auf die kanonischen Seiten unter /politiker/{partei}/{name}.
Beginne mit wahl_list_regions, wahl_list_elections und wahl_get_parliament, um gültige Regionnamen, Wahl- und Personen-IDs zu erhalten. Bei level="mdl" ist zusätzlich landSlug erforderlich. Für Mandatswechsel liefert wahl_list_mandate_periods die gültigen Parlamente und Wahlperioden.
wahl_list_regions
Verfügbare Regionen und ihre Slugs.
{}Vollständiges Eingabeschema
{
"type": "object",
"properties": {},
"required": [],
"additionalProperties": false
}wahl_get_poll_trend
So würde die Region aktuell wählen: ausschließlich aktuelle gewichtete Parteianteile, letzter Umfragestand und Quellen. Keine Einzelumfragen, Zeitreihen oder historischen Vergleichswerte.
region(string, erforderlich): Name der Region. Europa kann je nach Datenbestand keine Umfragen besitzen. Werte: Deutschland, Europa, Baden-Württemberg, Bayern, Berlin, Brandenburg, Bremen, Hamburg, Hessen, Mecklenburg-Vorpommern, Niedersachsen, Nordrhein-Westfalen, Rheinland-Pfalz, Saarland, Sachsen, Sachsen-Anhalt, Schleswig-Holstein, Thüringen.
{
"region": "Deutschland"
}Vollständiges Eingabeschema
{
"type": "object",
"properties": {
"region": {
"type": "string",
"description": "Name der Region. Europa kann je nach Datenbestand keine Umfragen besitzen.",
"enum": [
"Deutschland",
"Europa",
"Baden-Württemberg",
"Bayern",
"Berlin",
"Brandenburg",
"Bremen",
"Hamburg",
"Hessen",
"Mecklenburg-Vorpommern",
"Niedersachsen",
"Nordrhein-Westfalen",
"Rheinland-Pfalz",
"Saarland",
"Sachsen",
"Sachsen-Anhalt",
"Schleswig-Holstein",
"Thüringen"
]
}
},
"required": [
"region"
],
"additionalProperties": false
}wahl_get_calendar
Vollständiger Wahlkalender mit allen vergangenen und kommenden Terminen, Datum, Fristen und Quellenhinweisen; optional für ein Land. Keine Pagination.
landSlug(string, optional): Land-Slug; für Landesabfragen erforderlich. Werte: baden-wuerttemberg, bayern, berlin, brandenburg, bremen, hamburg, hessen, mecklenburg-vorpommern, niedersachsen, nordrhein-westfalen, rheinland-pfalz, saarland, sachsen, sachsen-anhalt, schleswig-holstein, thueringen.
{}Vollständiges Eingabeschema
{
"type": "object",
"properties": {
"landSlug": {
"type": "string",
"description": "Land-Slug; für Landesabfragen erforderlich.",
"enum": [
"baden-wuerttemberg",
"bayern",
"berlin",
"brandenburg",
"bremen",
"hamburg",
"hessen",
"mecklenburg-vorpommern",
"niedersachsen",
"nordrhein-westfalen",
"rheinland-pfalz",
"saarland",
"sachsen",
"sachsen-anhalt",
"schleswig-holstein",
"thueringen"
]
}
},
"required": [],
"additionalProperties": false
}wahl_get_parliament
Abgeordnete eines Parlaments mit Personen-ID und Profilangaben, paginiert. Keine Wahlkreis-Wahldaten oder Stimmenanteile.
level(string, erforderlich): Parlamentsebene. Werte: mdb, mdl.landSlug(string, optional): Land-Slug; für Landesabfragen erforderlich. Werte: baden-wuerttemberg, bayern, berlin, brandenburg, bremen, hamburg, hessen, mecklenburg-vorpommern, niedersachsen, nordrhein-westfalen, rheinland-pfalz, saarland, sachsen, sachsen-anhalt, schleswig-holstein, thueringen.offset(integer, optional): Startposition, Standard 0.limit(integer, optional): Seitengröße, Standard 50, maximal 100.
{
"level": "mdb"
}Vollständiges Eingabeschema
{
"type": "object",
"properties": {
"level": {
"type": "string",
"description": "Parlamentsebene.",
"enum": [
"mdb",
"mdl"
]
},
"landSlug": {
"type": "string",
"description": "Land-Slug; für Landesabfragen erforderlich.",
"enum": [
"baden-wuerttemberg",
"bayern",
"berlin",
"brandenburg",
"bremen",
"hamburg",
"hessen",
"mecklenburg-vorpommern",
"niedersachsen",
"nordrhein-westfalen",
"rheinland-pfalz",
"saarland",
"sachsen",
"sachsen-anhalt",
"schleswig-holstein",
"thueringen"
]
},
"offset": {
"type": "integer",
"description": "Startposition, Standard 0.",
"minimum": 0
},
"limit": {
"type": "integer",
"description": "Seitengröße, Standard 50, maximal 100.",
"minimum": 1,
"maximum": 100
}
},
"required": [
"level"
],
"additionalProperties": false,
"allOf": [
{
"if": {
"properties": {
"level": {
"const": "mdl"
}
},
"required": [
"level"
]
},
"then": {
"required": [
"landSlug"
]
}
}
]
}wahl_get_member
Profil eines Abgeordneten anhand der Personen-ID aus wahl_get_parliament. Keine Wahlkreis-Wahldaten oder Stimmenanteile.
id(string, erforderlich): Stabile Personen-ID.level(string, erforderlich): Parlamentsebene. Werte: mdb, mdl.landSlug(string, optional): Land-Slug; für Landesabfragen erforderlich. Werte: baden-wuerttemberg, bayern, berlin, brandenburg, bremen, hamburg, hessen, mecklenburg-vorpommern, niedersachsen, nordrhein-westfalen, rheinland-pfalz, saarland, sachsen, sachsen-anhalt, schleswig-holstein, thueringen.
{
"id": "p_abc",
"level": "mdb"
}Vollständiges Eingabeschema
{
"type": "object",
"properties": {
"id": {
"type": "string",
"description": "Stabile Personen-ID.",
"pattern": "^p_[a-z2-7]+$",
"maxLength": 100
},
"level": {
"type": "string",
"description": "Parlamentsebene.",
"enum": [
"mdb",
"mdl"
]
},
"landSlug": {
"type": "string",
"description": "Land-Slug; für Landesabfragen erforderlich.",
"enum": [
"baden-wuerttemberg",
"bayern",
"berlin",
"brandenburg",
"bremen",
"hamburg",
"hessen",
"mecklenburg-vorpommern",
"niedersachsen",
"nordrhein-westfalen",
"rheinland-pfalz",
"saarland",
"sachsen",
"sachsen-anhalt",
"schleswig-holstein",
"thueringen"
]
}
},
"required": [
"id",
"level"
],
"additionalProperties": false,
"allOf": [
{
"if": {
"properties": {
"level": {
"const": "mdl"
}
},
"required": [
"level"
]
},
"then": {
"required": [
"landSlug"
]
}
}
]
}wahl_list_elections
Index der verfügbaren Wahlergebnisse mit Wahl-IDs, Daten und Seitenpfaden.
offset(integer, optional): Startposition, Standard 0.limit(integer, optional): Seitengröße, Standard 50, maximal 100.
{}Vollständiges Eingabeschema
{
"type": "object",
"properties": {
"offset": {
"type": "integer",
"description": "Startposition, Standard 0.",
"minimum": 0
},
"limit": {
"type": "integer",
"description": "Seitengröße, Standard 50, maximal 100.",
"minimum": 1,
"maximum": 100
}
},
"required": [],
"additionalProperties": false
}wahl_get_election_result
Gesamtergebnis einer Wahl mit Quelle, Status, Beteiligung und Mandaten. Ausschließlich Bundes-/Landesaggregate; keine Wahlkreise, Bezirke, Geometrien oder Direktgewinnerlisten.
electionId(string, erforderlich): Wahl-ID aus wahl_list_elections, z. B. btw-25.
{
"electionId": "btw-25"
}Vollständiges Eingabeschema
{
"type": "object",
"properties": {
"electionId": {
"type": "string",
"description": "Wahl-ID aus wahl_list_elections, z. B. btw-25.",
"pattern": "^[a-z0-9]+(?:-[a-z0-9]+)*$",
"maxLength": 80
}
},
"required": [
"electionId"
],
"additionalProperties": false
}wahl_get_election_history
Landesweite historische Ergebniszeitreihe einschließlich Quellen.
landSlug(string, erforderlich): deutschland oder Land-Slug. Werte: deutschland, baden-wuerttemberg, bayern, berlin, brandenburg, bremen, hamburg, hessen, mecklenburg-vorpommern, niedersachsen, nordrhein-westfalen, rheinland-pfalz, saarland, sachsen, sachsen-anhalt, schleswig-holstein, thueringen.
{
"landSlug": "deutschland"
}Vollständiges Eingabeschema
{
"type": "object",
"properties": {
"landSlug": {
"type": "string",
"description": "deutschland oder Land-Slug.",
"enum": [
"deutschland",
"baden-wuerttemberg",
"bayern",
"berlin",
"brandenburg",
"bremen",
"hamburg",
"hessen",
"mecklenburg-vorpommern",
"niedersachsen",
"nordrhein-westfalen",
"rheinland-pfalz",
"saarland",
"sachsen",
"sachsen-anhalt",
"schleswig-holstein",
"thueringen"
]
}
},
"required": [
"landSlug"
],
"additionalProperties": false
}wahl_list_mandate_periods
Verfügbare Parlamente und Wahlperioden für Mandatswechsel, einschließlich Anzahl und letztem Wechsel.
{}Vollständiges Eingabeschema
{
"type": "object",
"properties": {},
"required": [],
"additionalProperties": false
}wahl_get_mandate_changes
Mandatswechsel einer Wahlperiode: ausgeschiedene Personen, Nachfolger, Gründe, Datum und Quellen. Keine Wahlkreis-Wahldaten.
parlament(string, erforderlich): Parlament aus wahl_list_mandate_periods. Werte: bundestag, baden-wuerttemberg, bayern, berlin, brandenburg, bremen, hamburg, hessen, mecklenburg-vorpommern, niedersachsen, nordrhein-westfalen, rheinland-pfalz, saarland, sachsen, sachsen-anhalt, schleswig-holstein, thueringen.periode(integer, erforderlich): Wahlperiode aus wahl_list_mandate_periods.
{
"parlament": "bundestag",
"periode": 21
}Vollständiges Eingabeschema
{
"type": "object",
"properties": {
"parlament": {
"type": "string",
"description": "Parlament aus wahl_list_mandate_periods.",
"enum": [
"bundestag",
"baden-wuerttemberg",
"bayern",
"berlin",
"brandenburg",
"bremen",
"hamburg",
"hessen",
"mecklenburg-vorpommern",
"niedersachsen",
"nordrhein-westfalen",
"rheinland-pfalz",
"saarland",
"sachsen",
"sachsen-anhalt",
"schleswig-holstein",
"thueringen"
]
},
"periode": {
"type": "integer",
"description": "Wahlperiode aus wahl_list_mandate_periods.",
"minimum": 1,
"maximum": 100
}
},
"required": [
"parlament",
"periode"
],
"additionalProperties": false
}wahl_list_mandate_changes
Mandatswechsel aller verfügbaren Parlamente, neueste zuerst, paginiert. Keine Wahlkreis-Wahldaten.
offset(integer, optional): Startposition, Standard 0.limit(integer, optional): Seitengröße, Standard 50, maximal 100.
{
"limit": 50
}Vollständiges Eingabeschema
{
"type": "object",
"properties": {
"offset": {
"type": "integer",
"description": "Startposition, Standard 0.",
"minimum": 0
},
"limit": {
"type": "integer",
"description": "Seitengröße, Standard 50, maximal 100.",
"minimum": 1,
"maximum": 100
}
},
"required": [],
"additionalProperties": false
}Daten richtig verwenden
Die Umfrageantwort enthält nur aktuelle gewichtete Prozentwerte unter data.values, den Stichtag und das Datum der jüngsten zugrunde liegenden Umfrage. Einzelumfragen, historische Umfrageverläufe und Vergleichsdeltas werden nicht ausgegeben. Umfragen sind keine Wahlergebnisse oder Vorhersagen. Der Trend verwendet dieselbe Alters- und Fallzahlgewichtung wie die Website; Streuungsbänder sind keine Konfidenzintervalle. Für Live-Ergebnisse müssen Auszählungsstand, Status und Ergebnisqualität mit angegeben werden. Historische Prozentreihen können synthetische Stimmen für die Darstellung enthalten; diese sind keine amtlichen absoluten Stimmenzahlen. Fehlende Datensätze bedeuten keine Nullwerte.
Quellen- und Lizenzhinweise im Ergebnis sowie auf /quellen beachten und bei Weiterverwendung angeben. Die Schnittstelle vergibt keine zusätzlichen Nutzungsrechte an Fremddaten.
Implementiert nach dem AI Catalog 1.0 Draft und dem WebMCP Draft, geprüft am 3. Oktober 2026. Beide Spezifikationen können sich noch ändern.