API-Referenz

Weiterleitungen und 404-Protokoll

Weiterleitungen leiten tote URLs einer Website auf bestehende um. Sie greifen nur, wo sonst die 404-Seite käme – also bei Pfaden ohne Seite und bei unbekannten Unterpfaden einer Catch-All-Seite (not_found()). Vorhandene Seiten haben immer Vorrang.

  • Pfade werden normalisiert: dekodiert, klein geschrieben, ohne Query und ohne Schrägstrich am Ende. Eine eingefügte URL (https://alt.de/Seite/?x=1) wird zu /seite. Query-Parameter des Aufrufs hängen am Ziel, wenn das Ziel selbst keine hat.
  • Antwort: 301 (mit Cache-Control: max-age=3600, damit geänderte Weiterleitungen nicht ewig im Browser hängen) oder 302 (no-store).
  • Automatisch: Wird eine veröffentlichte Seite umbenannt (Slug) oder innerhalb ihrer Website verschoben, entstehen 301-Weiterleitungen für sie und ihre veröffentlichten Unterseiten (auto: true). Weiterleitungen, die auf den alten Pfad zeigten, zeigen danach direkt auf den neuen; eine Weiterleitung von einem wieder belegten Pfad wird entfernt.
  • 404-Protokoll: Aufrufe toter URLs ohne Weiterleitung (nur GET) werden je Website gezählt – mit erstem/letztem Aufruf und der zuletzt gesehenen Herkunft (Referer), höchstens 1.000 Einträge je Website. Das Anlegen einer Weiterleitung nimmt den Pfad aus dem Protokoll.
  • Bundles enthalten die Weiterleitungen, nicht das 404-Protokoll.

Weiterleitungs-Objekt

{
  "id": 4, "root_id": 1,
  "source": "/blog/123",
  "target": "/blog/mein-artikel",
  "status": 301, "auto": false,
  "hits": 12, "last_hit_at": 1791220210, "created_at": 1791220100,
  "target_missing": false
}
Feld Typ Beschreibung
root_id int Website (Root-Seite); beim Ändern nicht änderbar
source string Alte Adresse (Pfad oder URL, wird normalisiert). Nicht /, nicht unter /cms-admin, /api, /media, /_assets, /sitemap.xml, /healthz, /favicon.ico, /robots.txt und nicht der Pfad einer bestehenden Seite (400). Je Website eindeutig (409)
target string Pfad (/neu) oder http(s)-URL. Keine Schleifen über andere Weiterleitungen (400)
status int 301 (Standard) oder 302
auto bool Nur lesend: automatisch beim Umbenennen/Verschieben angelegt (wird beim Bearbeiten false)
hits, last_hit_at int Nur lesend: Nutzung
target_missing bool Nur in der Liste: das Ziel ist ein Pfad ohne Seite und ohne weitere Weiterleitung

GET /redirects?root_id={id} 🔑

Alle Weiterleitungen der Website, nach Pfad sortiert.

POST /redirects ✏️ · PUT /redirects/{id} ✏️ · DELETE /redirects/{id} ✏️

{ "root_id": 1, "source": "/blog/123", "target": "/blog/mein-artikel", "status": 301 }

POST → 201, PUT (Merge, source/target/status) → 200, DELETE → 204.

GET /notfound?root_id={id} 🔑 · DELETE /notfound?root_id={id}[&path=…] ✏️

404-Protokoll der Website, häufigste zuerst: [{ "path": "/angebote/2019", "hits": 7, "first_at": …, "last_at": …, "referer": "https://www.example.org/links" }]. Jeder Eintrag trägt ignored (true = ausgeblendet; zählt weiter, steht aber nicht im CSV-Export). PUT mit Body { "ignored": true|false } blendet einen Eintrag (path) aus bzw. wieder ein; ohne path alle offenen (true) bzw. alle ignorierten (false) – 204, der Eintrag bleibt samt Zähler erhalten. DELETE entfernt einen Eintrag (path) oder das ganze Protokoll endgültig. Das Protokoll hält höchstens 1000 offene und 5000 ignorierte Adressen je Website (die am längsten nicht mehr gesehenen fallen heraus).

GET /redirects/export?root_id={id} 🔑

CSV (UTF-8 mit BOM, Trennzeichen Semikolon) mit den Spalten Von;Nach;Status;Typ;Treffer;Zuletzt;Herkunft: zuerst die offenen Adressen aus dem 404-Protokoll (häufigste zuerst, Nach und Status leer, Typ = 404), danach alle Weiterleitungen (Typ = manuell oder auto). Zuletzt als JJJJ-MM-TT HH:MM (Serverzeit).

POST /redirects/import?root_id={id}[&dry_run=1][&delete=1] ✏️

Multipart-Feld file: CSV (UTF-8, optional mit BOM; Trennzeichen Komma, Semikolon oder Tab wird erkannt). Spalten werden über die Kopfzeile erkannt: Von (auch source, from, alt, pfad …) und Nach (auch target, to, ziel …) sind Pflicht, Status (301/302, leer = bisheriger Status bzw. 301) optional, alle weiteren werden ignoriert. Abgeglichen wird über den normalisierten Pfad in Von:

  • Zeile mit Ziel → neue Weiterleitung oder Änderung von Ziel/Status (gilt danach als manuell); unveränderte zählen als unchanged. Neue nehmen ihren Pfad aus dem 404-Protokoll.
  • Zeile ohne Ziel → bleibt offen (open); eine bestehende Weiterleitung bleibt unverändert.
  • delete=1: Weiterleitungen, die in der Datei fehlen oder dort kein Ziel haben, werden gelöscht.

Geprüft wird wie bei POST /redirects – Schleifen auch über mehrere Zeilen der Datei –, dazu doppelte Pfade. Alles oder nichts: bei Fehlern 422 (mit error, code csv.errors und params.count), nichts wird geschrieben. dry_run=1 liefert nur die Vorschau (200, auch bei Fehlern):

{ "delimiter": ";", "rows": 4, "created": 1, "updated": 1, "deleted": 0, "unchanged": 1, "open": 1,
  "changes": [{ "action": "create", "source": "/kaputt", "target": "/neu", "status": 301 },
              { "action": "update", "source": "/weg", "target": "https://example.com/", "status": 301, "old_target": "/neu", "old_status": 302 }],
  "errors": [{ "row": 3, "message": "this redirect would create a loop", "code": "redirect.loop" }], "error_count": 1, "imported": false }

row zählt die Kopfzeile als Zeile 1; errors enthält höchstens 50 Einträge.