Linear ging am 22.05.2026 im Elido-Integrationskatalog live. Das erste Ereignis, das wir ausgeliefert haben, war broken_link_hook - wenn unser Scanner einen toten Kurzlink findet, erstellt er ein Linear-Issue im Team, das du beim Verbinden ausgewählt hast, mit Click-Metriken im Body und Labels, die per Tag geroutet werden. Dieser Beitrag ist der technische Walkthrough: Wie die Authentifizierung funktioniert, wie der JSON-Payload aussieht und wie wir dieselbe Pipeline auf Click-Threshold-Spitzen ausgedehnt haben - damit der On-Call-Dienst ein Ticket bekommt statt einer 3-Uhr-Benachrichtigung.
Wer Hunderte oder Tausende von Kurzlinks in der Produktion pflegt, kennt das Szenario. Marketing wechselt ein Kampagnenziel, die neue URL gibt 404 zurück, und niemand bemerkt es, bis ein Kunde auf Bluesky einen Screenshot eines toten Links postet. Linear ist, wo dein Team Bugs bereits triagiert - also genau dorthin gehört das Ticket.
Linear über Personal API Key verbinden
Die Linear-Integration verwendet einen Personal API Key, kein OAuth. Diese Entscheidung haben wir aus drei Gründen getroffen: API Keys sind auf den Workspace beschränkt, sie überstehen Admin-Wechsel besser als OAuth-Tokens, die an einen einzelnen Nutzer gebunden sind, und Linears API: Authentication-Dokumentation empfiehlt sie explizit für Server-zu-Server-Jobs.
Erstelle den Key in Linear: Einstellungen, API, Personal API keys, Schlüssel erstellen. Nenn ihn elido-integration, damit du ihn später ohne Rätselraten widerrufen kannst. Kopiere den Key (er beginnt mit lin_api_) und füge ihn in die Linear-Integrationskarte im Elido-Dashboard ein.
Was dann passiert: Wir senden eine viewer-Query zur Validierung des Keys, dann eine teams-Query, um den Team-Picker zu befüllen. Du wählst ein Standardteam. Diese Auswahl schreibt eine Zeile in integration_configs in Postgres, einschließlich der von Linear zugewiesenen Team-ID. Wenn du mehrere Teams hast, kannst du tagbasiertes Routing auf demselben Bildschirm hinzufügen - dazu weiter unten mehr.
POST /v1/workspaces/:id/integrations/linear/connect
{
"api_key": "lin_api_<redacted>",
"default_team_id": "TEAM_a1b2c3",
"default_priority": 2,
"labels": ["short-link", "auto-filed"]
}
Im Hintergrund speichert der api-core-Dienst den Key verschlüsselt at rest über das Envelope-Encryption-Schema aus ADR-0036. Der entschlüsselte Key lebt nur während des tatsächlichen GraphQL-Aufrufs im Speicher. Wir loggen den Rohwert nie, und die Integrations-Logs-UI zeigt nur die letzten 4 Zeichen.
Ein wichtiger Hinweis: Linears Personal API Keys sind an den Nutzer gebunden, der sie erstellt hat. Wenn dieser Nutzer dein Unternehmen verlässt und sein Linear-Seat aufgelöst wird, wird der Key ungültig. Best Practice ist, in Linear einen Service-ähnlichen Nutzer anzulegen (wir verwenden [email protected]) und den Key über dieses Konto zu generieren.
Das broken_link_hook-Ereignis - was es auslöst und was im Body steht
Unser url-scanner-Dienst führt wöchentlich einen Crawl aller aktiven Kurzlinks in deinem Workspace durch. Für jeden Link macht er einen HTTP HEAD auf das Ziel, dann ein GET, wenn HEAD nicht unterstützt wird, und validiert anschließend die TLS-Kette. Vier Bedingungen lösen den Broken-Link-Status aus:
- HTTP 4xx oder 5xx bei zwei aufeinanderfolgenden Probes (zur Absicherung gegen transiente 500er)
- TLS abgelaufen oder selbstsigniert, obwohl es die Woche davor gültig war
- DNS NXDOMAIN - der Ziel-Host lässt sich nicht mehr auflösen
- Parked-Domain-Fingerprint-Treffer - das Ziel löst auf, aber der Response-Body entspricht einer bekannten Squatter-Vorlage (wir pflegen einen kleinen Fingerprint-Satz)
Wenn eine dieser vier Bedingungen eintritt, veröffentlicht der Scanner ein link.broken-Ereignis in Redpanda. Der Webhook-Dispatcher konsumiert es, schlägt deine aktiven Integrationen nach und materialisiert für Linear den folgenden Payload.
Hier ist ein echter broken_link_hook-Payload aus unserer Staging-Umgebung (einige Felder gekürzt):
{
"event": "link.broken",
"link_id": "01J9V7QXMZ8K2Y3N4P5R6T7W8Z",
"short_url": "https://s.elido.me/spring-launch",
"destination_url": "https://oldcampaign.example.com/landing",
"failure_type": "http_5xx",
"failure_detail": "502 Bad Gateway, 2 consecutive probes",
"last_working_at": "2026-05-28T14:22:00Z",
"detected_at": "2026-06-04T03:11:42Z",
"clicks_last_7d": 2841,
"clicks_last_24h": 412,
"top_referrers": [
{ "host": "linkedin.com", "clicks": 1203 },
{ "host": "twitter.com", "clicks": 488 },
{ "host": "direct", "clicks": 612 }
],
"tags": ["campaign-spring-2026", "paid"],
"owner_email": "[email protected]"
}
Der Linear-Adapter in services/api-core/internal/integrations/linear/broken_link_hook.go nimmt diesen Payload und erstellt eine GraphQL-Mutation gegen Linears Issues API. Der Issue-Titel folgt einem festen Muster, damit On-Call ihn per grep finden kann:
[Elido] Broken link: /spring-launch (502 Bad Gateway)
Der Body ist strukturiertes Markdown mit fünf Abschnitten: Link-Details, letzter funktionierender Zeitstempel, Click-Delta gegenüber dem 7-Tage-Baseline, die drei häufigsten Referrer und ein vorgeschlagener Fix-Block. Der Fix-Block prüft failure_type und wählt einen vorformulierten Vorschlag - für http_5xx: "Prüfen, ob das Ziel rate-limitet oder sich im Deploy befindet"; für parked_domain: "Domain könnte abgelaufen oder gesquattet sein, diesen Link archivieren"; und so weiter.
Labels werden aus zwei Quellen zugewiesen: deinem Standard-Label-Set (beim Connect konfiguriert) und dynamischen Labels aus der Tag-Liste. Wenn ein Tag paid oder organic enthält, fügen wir ihn als Label hinzu, damit PMs ihre Linear-Views filtern können.
Deduplizierung, Rate Limits und die Dead-Letter-Queue
Wir deduplizieren broken_link_hook-Ereignisse nach Ziel-Host für 24 Stunden. Wenn oldcampaign.example.com ausgefallen ist und 800 Kurzlinks darauf zeigen, erhältst du ein Linear-Ticket mit allen 800 Kurzlinks im Body - nicht 800 einzelne Tickets. Das war eine harte Lektion aus der frühen Beta: Der erste Kunde, der eine tote Domain traf, wurde damit begraben.
Linears GraphQL-Endpoint hat ein globales Rate-Limit pro Workspace. Unser Webhook-Dispatcher wertet den Retry-After-Header aus und verwendet exponentiellen Backoff mit Full Jitter, bis zu fünf Versuchen. Nach fünf Versuchen landet das Ereignis in einer Dead-Letter-Queue. DLQ-Einträge findest du unter Einstellungen, Integrationen, Linear, Fehlgeschlagene Ereignisse, und du kannst jeden davon mit einem Klick wiederholen. Die DLQ ist auch über die Webhooks-Funktion für programmatisches Replay zugänglich.
Click-Threshold und benutzerdefinierte Trigger
Derselbe Linear-Adapter verarbeitet click_threshold_hook-Ereignisse. Du definierst Schwellenwerte pro Link oder pro Kampagne im Elido-Dashboard, und wir erstellen ein Linear-Issue, wenn ein Link eine Bandgrenze überschreitet. Heute werden zwei Band-Typen unterstützt:
- Spike: Clicks in der letzten Stunde übersteigen N-mal die gleitende 7-Tage-Stunden-Baseline (Standard-N ist 3). Nützlich, um Viralität zu erkennen oder - weniger erfreulich - Bot-Traffic.
- Cliff: Clicks in der letzten Stunde fallen unter 10% der gleitenden Baseline. Nützlich, um tote Kampagnen zu erkennen - wenn eine bezahlte Anzeige upstream pausiert wurde, siehst du das Linear-Ticket noch vor dem Marketing-Standup.
Hier ist ein click_threshold_hook-Payload:
{
"event": "link.click_threshold",
"link_id": "01J9V7QXMZ8K2Y3N4P5R6T7W8Z",
"short_url": "https://s.elido.me/spring-launch",
"band": "spike",
"current_hour_clicks": 8421,
"baseline_hourly_clicks": 612,
"multiplier": 13.76,
"top_referrers": [
{ "host": "news.ycombinator.com", "clicks": 6203 },
{ "host": "direct", "clicks": 1488 }
],
"tags": ["campaign-spring-2026"],
"triggered_at": "2026-06-04T11:14:00Z"
}
Für einen Spike lautet der Fix-Block: "Überprüfen, ob es sich um organischen Traffic handelt und nicht um eine Referrer-Spoofing-Kampagne. Referrer-Aufschlüsselung oben prüfen." Bei einem Cliff: "Bestätigen, dass die Kampagne upstream noch läuft. Wenn sie pausiert wurde, diesen Link archivieren."
Tagbasiertes Routing über mehrere Teams
Der Standard-Team-Picker reicht für einen 20-Personen-Workspace. Bei größeren Organisationen soll ein Linear-Ticket für einen Marketing-Link ans Marketing-Team gehen und ein Ticket für einen Docs-Link ans Documentation-Team. Tagbasiertes Routing löst das.
Routing-Regeln leben in integration_configs.routing_json und werden von oben nach unten ausgewertet. Eine Regel sieht so aus:
[
{
"tag_glob": "campaign-*",
"team_id": "TEAM_growth",
"labels": ["growth", "urgent"]
},
{ "tag_glob": "docs-*", "team_id": "TEAM_docs", "labels": ["docs"] },
{
"tag_glob": "internal-*",
"team_id": "TEAM_internal",
"labels": ["internal"]
},
{ "default": true, "team_id": "TEAM_a1b2c3" }
]
Die erste Regel, deren Glob mindestens einen Tag des Links trifft, gewinnt. Wenn nichts passt, greift die Default-Regel. Die Glob-Syntax ist dieselbe wie bei Linears Saved-View-Filtern, die PMs also bereits kennen.
Du kannst auch nach failure_type routen. Manche Teams wollen alle TLS-Fehler ans Plattform-Team schicken, da sie meist auf Zertifikats-Fehlkonfigurationen bei Custom Domains hinweisen. Füge eine Regel mit failure_type: tls_expired hinzu, und du bist fertig.
Benutzerdefinierte Trigger über Webhooks
Nicht jedes Team möchte für jeden Ereignistyp, den wir veröffentlichen, Linear-Tickets erstellen. Den vollständigen Ereigniskatalog findest du auf der Webhooks-Seite, aber die gängigen Kombinationen, die Teams neben Linear einrichten, sind:
link.createdan ein Linear-Team für Audits neuer Links (selten, meist für Compliance-Teams)domain.takeover_detectedfür TLS-Überraschungen bei Custom Domainslink.scan_completefür wöchentliche Summary-Tickets (ein Issue pro Scan-Lauf mit allen markierten Links)
Wenn das Ereignis, das du brauchst, nicht im Katalog ist, kannst du deinen eigenen mit dem generischen Webhook-Ziel und unserem Observability-Leitfaden bauen. Oder du stellst einfach eine Feature-Request auf unserem öffentlichen Linear-Board - meta, aber konsequent.
Preise und was du in welchem Plan bekommst
Die Linear-Integration ist ab dem Pro-Tier enthalten. Im Free-Tarif kannst du Linear verbinden, erhältst aber nur broken_link_hook (keine Click-Threshold- oder benutzerdefinierten Trigger). Die vollständige Matrix findest du unter Preise. Wenn du ein größeres Team bist und das aus Compliance-Gründen einsetzt - etwa weil DSGVO Artikel 32 die Erkennung von Datenlecks durch defekte Weiterleitungen auf Squatter-Domains erfordert - erklärt die Enterprise-Lösungsseite, was wir im großen Maßstab anbieten.
Weiterführende Lektüre
- Webhooks für Link-Ereignisse: ein Entwickler-Leitfaden - der zugrundeliegende Event-Bus, der alle Integrationen einschließlich Linear antreibt.
- Sentry in 12 Go-Diensten verdrahten - wie wir den Dispatcher überwachen, der Linear-Ereignisse auslöst, damit wir merken, wenn der Dispatcher selbst krank ist.
- Link-Rotting-Prävention: Strategie - die umfassendere operative Geschichte hinter dem Grund, warum wir die Broken-Link-Erkennung gebaut haben.
Der vollständige Integrationskatalog listet Stand Juni 2026 43 Anbieter auf, darunter Linear als einer der 20 Live-Einträge. Wenn dein Team stattdessen Jira verwendet, ist dieser Adapter in der Beta - schreib uns, und wir schalten dich frei.
Häufig gestellte Fragen
Wie authentifiziert sich Elido bei Linear?
Wir verwenden einen Personal API Key, der auf den Workspace beschränkt ist - kein OAuth. Du generierst den Key in Linear unter Einstellungen, API, und fügst ihn dann in die Elido-Integrationskarte ein. Der Key verlässt unseren Vault nie, und wir schwärzen ihn aus den Logs. Wenn du ihn rotierst, löst das nächste Ereignis statt eines stillen Fehlers eine sanfte Re-Auth-Aufforderung aus.
Was gilt genau als Broken Link beim broken_link_hook-Ereignis?
Unser url-scanner crawlt jeden aktiven Kurzlink wöchentlich und kennzeichnet vier Bedingungen: HTTP 4xx oder 5xx bei zwei aufeinanderfolgenden Probes, abgelaufenes oder nicht verifizierbares TLS-Zertifikat, DNS NXDOMAIN sowie bekannte Parked-Domain-Fingerprints. Jede dieser vier Bedingungen erzeugt ein einzelnes Linear-Issue, dedupliziert nach Ziel-Host für 24 Stunden - damit eine tote Domain keine 800 Tickets erzeugt.
Kann ich Issues je nach Link-Tags an verschiedene Linear-Teams senden?
Ja. Auf dem Connect-Bildschirm wählst du ein Standardteam und kannst dann Routing-Regeln hinzufügen - zum Beispiel leiten Tags, die campaign-* entsprechen, an das Growth-Team weiter, während Tags wie docs-* ans Engineering-Team gehen. Regeln werden von oben nach unten ausgewertet, mit einem Standard-Fallback. Der Regelsatz liegt in Postgres, sodass du Änderungen über den Admin-Trail nachverfolgen kannst.
Funktioniert das auch für Click-Threshold-Warnungen, nicht nur für Broken Links?
Ja, seit Phase 12. Derselbe Linear-Adapter verarbeitet click_threshold_hook-Ereignisse neben broken_link_hook. Du definierst Schwellenwerte pro Link oder pro Kampagne im Elido-Dashboard, und wir erstellen ein Linear-Issue, wenn ein Link eine Bandgrenze überschreitet - entweder ein Spike (3x Baseline in einer Stunde) oder ein Cliff (Einbruch auf unter 10% der Baseline).
Was passiert, wenn Linear die Integration rate-limitet?
Linears GraphQL-Endpoint gibt eine 429 mit Retry-After-Header zurück. Unser Webhook-Dispatcher berücksichtigt das mit exponentiellem Backoff bis zu fünf Versuchen, dann landet das Ereignis in einer Dead-Letter-Queue. DLQ-Einträge kannst du in der Integrations-Logs-UI anzeigen und mit einem Klick wiederholen oder über die GraphQL-API unter /v1/integrations/linear/dlq. In der Produktion haben wir von Linear noch kein anhaltendes 429 gesehen.
Elido testen
URL einfügen, kurzer Link in Sekunden
Kein Konto nötig. Link bleibt 30 Tage aktiv. Konto erstellen, um ihn dauerhaft zu behalten.
Kostenlos, keine Anmeldung erforderlich · 2 pro Tag