<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Enjyn Gruppe</title>
    <description>The latest articles on DEV Community by Enjyn Gruppe (@enjyn_3feb58e98fa3).</description>
    <link>https://dev.to/enjyn_3feb58e98fa3</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3944888%2F9d1aa3e5-7ebb-45ad-9720-776901433160.jpg</url>
      <title>DEV Community: Enjyn Gruppe</title>
      <link>https://dev.to/enjyn_3feb58e98fa3</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/enjyn_3feb58e98fa3"/>
    <language>en</language>
    <item>
      <title>Wir haben einen Website-Crawler gebaut, der 50+ Checks in einem Scan macht — kostenlos</title>
      <dc:creator>Enjyn Gruppe</dc:creator>
      <pubDate>Thu, 21 May 2026 22:44:04 +0000</pubDate>
      <link>https://dev.to/enjyn_3feb58e98fa3/wir-haben-einen-website-crawler-gebaut-der-50-checks-in-einem-scan-macht-kostenlos-5704</link>
      <guid>https://dev.to/enjyn_3feb58e98fa3/wir-haben-einen-website-crawler-gebaut-der-50-checks-in-einem-scan-macht-kostenlos-5704</guid>
      <description>&lt;h2&gt;
  
  
  Das Problem: Eine Website checken = 8 Tools öffnen
&lt;/h2&gt;

&lt;p&gt;Als Software-Agentur prüfen wir bei Enjyn ständig Websites. Bei Erstgesprächen mit potenziellen Kunden, bei bestehenden Projekten, vor Übergaben, nach Releases. Die Frage ist immer dieselbe: &lt;strong&gt;Ist diese Website technisch sauber, DSGVO-konform und sicher?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Die Antwort findet sich in keinem einzelnen Tool:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Aspekt&lt;/th&gt;
&lt;th&gt;Tool das wir bisher öffneten&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Performance&lt;/td&gt;
&lt;td&gt;Google PageSpeed Insights, GTmetrix&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Security Headers&lt;/td&gt;
&lt;td&gt;securityheaders.com&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;SSL-Zertifikat&lt;/td&gt;
&lt;td&gt;SSL Labs&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;SEO&lt;/td&gt;
&lt;td&gt;Ahrefs / Screaming Frog / Mangools&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;DSGVO-Check&lt;/td&gt;
&lt;td&gt;manuell&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Cookie-Banner&lt;/td&gt;
&lt;td&gt;manuell&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Schema.org&lt;/td&gt;
&lt;td&gt;Google Rich Results Test&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Mobile&lt;/td&gt;
&lt;td&gt;PageSpeed Mobile&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Acht Tools für einen Website-Check.&lt;/strong&gt; Jedes mit eigener UI, eigenen Bewertungslogiken, eigenen Reports. Bei zwanzig Websites am Tag ist das ein halber Arbeitstag nur fürs Hin- und Herklicken.&lt;/p&gt;

&lt;p&gt;Wir wollten ein Tool, das &lt;strong&gt;alles auf einmal&lt;/strong&gt; macht — speziell für den DACH-Markt mit DSGVO-Fokus.&lt;/p&gt;

&lt;h2&gt;
  
  
  Die Frage: Können wir das selbst bauen?
&lt;/h2&gt;

&lt;p&gt;Bestehende All-in-One-Tools gibt es. Aber:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Die meisten sind &lt;strong&gt;englischsprachig&lt;/strong&gt; und ignorieren deutsche Rechtsanforderungen (Impressumspflicht §5 TMG, DSGVO-Cookie-Regeln, Google Fonts Schrems II)&lt;/li&gt;
&lt;li&gt;Viele sind &lt;strong&gt;kostenpflichtige SaaS&lt;/strong&gt; ab 50€/Monat&lt;/li&gt;
&lt;li&gt;Die kostenlosen geben nur Teil-Reports und wollen dich in einen Funnel zwingen&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Was wir wollten:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Eine URL rein, vollständiger Report raus&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;DSGVO-zentrisch&lt;/strong&gt; (Impressum, Datenschutz, externe Fonts, Tracking-ohne-Consent)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Kostenlos, ohne Registrierung&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Objektive Bewertung&lt;/strong&gt; — keine subjektiven Faktoren&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Also haben wir uns hingesetzt und den &lt;strong&gt;Enjyn Crawler&lt;/strong&gt; gebaut. Heute prüft er &lt;strong&gt;über 50 Faktoren in einem einzigen Scan&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Was wir prüfen — die 50+ Checks
&lt;/h2&gt;

&lt;p&gt;Vier Kategorien, jede mit konkreten technischen Tests:&lt;/p&gt;

&lt;h3&gt;
  
  
  Sicherheit (14 Checks)
&lt;/h3&gt;

&lt;p&gt;HTTPS/SSL, HSTS Header, CSP Header, X-Frame-Options, X-Content-Type, Referrer-Policy, Permissions-Policy, security.txt, Mixed Content, CSRF-Schutz, Server-Info Leakage, PHP-Version exposed, sensible Dateien (.env, .git), WP User Enumeration.&lt;/p&gt;

&lt;h3&gt;
  
  
  SEO (15 Checks)
&lt;/h3&gt;

&lt;p&gt;robots.txt, sitemap.xml, llms.txt, Meta-Title (10-70 Zeichen), Meta-Description (50-160 Zeichen), Canonical URL, H1-H6 Struktur, Open Graph, Twitter Cards, Schema.org, Favicon, Alt-Texte, interne/externe Links, Wortanzahl.&lt;/p&gt;

&lt;h3&gt;
  
  
  Rechtliches/DSGVO (12 Checks)
&lt;/h3&gt;

&lt;p&gt;Impressum, Datenschutzerklärung, AGB, Widerruf, Cookie-Banner, Cookie-Richtlinie, &lt;strong&gt;Google Fonts&lt;/strong&gt; (Schrems II!), Google Analytics, Facebook Pixel, Tracking ohne Consent, TMG/DDG-Prüfung, Kontaktdaten.&lt;/p&gt;

&lt;h3&gt;
  
  
  Performance &amp;amp; Mobile (13 Checks)
&lt;/h3&gt;

&lt;p&gt;Ladezeit, Seitengröße, GZIP/Brotli, HTTP/2, DOM-Größe, Ressourcen-Anzahl, Bilder, Scripts, Stylesheets, Third-Party Requests, Viewport, Skip-Link, ARIA Landmarks.&lt;/p&gt;

&lt;h2&gt;
  
  
  Der Stack — komplett offen
&lt;/h2&gt;

&lt;p&gt;Im Gegensatz zum KYC-Artikel müssen wir hier nichts verstecken — der Crawler ist Open-Approach, es gibt keinen Anti-Fraud-Grund für Geheimhaltung:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Sprache:&lt;/strong&gt; Python 3.11+&lt;br&gt;
&lt;strong&gt;Web-Framework:&lt;/strong&gt; Flask&lt;br&gt;
&lt;strong&gt;HTTP-Client:&lt;/strong&gt; httpx (statt requests — async + HTTP/2)&lt;br&gt;
&lt;strong&gt;HTML-Parser:&lt;/strong&gt; BeautifulSoup4 + lxml&lt;br&gt;
&lt;strong&gt;Spracherkennung:&lt;/strong&gt; Lingua (AI-basiert, 95%+ Genauigkeit)&lt;br&gt;
&lt;strong&gt;Datenbank:&lt;/strong&gt; SQLite (Scans werden temporär gespeichert)&lt;br&gt;
&lt;strong&gt;WSGI:&lt;/strong&gt; Gunicorn&lt;/p&gt;

&lt;p&gt;Bewusst kein Headless Browser (Puppeteer/Playwright). Warum? Geschwindigkeit. Ein vollständiger Scan dauert bei uns &lt;strong&gt;2-8 Sekunden&lt;/strong&gt; statt 30-60 Sekunden bei Lighthouse-basierten Tools.&lt;/p&gt;

&lt;p&gt;Das geht, weil wir bewusst nicht jedes JavaScript ausführen. Wir analysieren das &lt;strong&gt;gelieferte HTML, Headers und statische Assets&lt;/strong&gt; — das deckt 95% der relevanten Probleme ab. Die fehlenden 5% (z.B. Runtime-Performance) sind genau die, für die du PageSpeed Insights eh weiter brauchst.&lt;/p&gt;
&lt;h2&gt;
  
  
  Beispiel: SSL-Check
&lt;/h2&gt;

&lt;p&gt;So sieht der SSL-Check unter der Haube aus:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;ssl&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;socket&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;check_ssl&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;domain&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;context&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ssl&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create_default_context&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="k"&gt;with&lt;/span&gt; &lt;span class="n"&gt;socket&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create_connection&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="n"&gt;domain&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;443&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;timeout&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;sock&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;with&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;wrap_socket&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;sock&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;server_hostname&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;domain&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;ssock&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="n"&gt;cert&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ssock&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getpeercert&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

    &lt;span class="c1"&gt;# Ablaufdatum extrahieren
&lt;/span&gt;    &lt;span class="n"&gt;not_after&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;cert&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;notAfter&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="n"&gt;expires&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;datetime&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;strptime&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;not_after&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;%b %d %H:%M:%S %Y %Z&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;days_left&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;expires&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;datetime&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;utcnow&lt;/span&gt;&lt;span class="p"&gt;()).&lt;/span&gt;&lt;span class="n"&gt;days&lt;/span&gt;

    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;days_left&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;14&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;status&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;critical&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;days&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;days_left&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;elif&lt;/span&gt; &lt;span class="n"&gt;days_left&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;30&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;status&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;warning&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;days&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;days_left&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;status&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;ok&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;days&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;days_left&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Kein Hexenwerk. Nur Python-Standardbibliothek. Die meisten unserer 50+ Checks sind ähnlich straightforward — der Aufwand lag nicht im Einzelcheck, sondern im &lt;strong&gt;Sammeln aller Edge-Cases&lt;/strong&gt;, die in deutschen Websites real auftreten.&lt;/p&gt;

&lt;h2&gt;
  
  
  Beispiel: Google Fonts Detection (Schrems II!)
&lt;/h2&gt;

&lt;p&gt;Ein Check, der erst seit Schrems II 2020 wirklich wichtig ist:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;check_google_fonts&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;html&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="c1"&gt;# Schrems II: Google Fonts ohne Consent = DSGVO-Verstoß
&lt;/span&gt;    &lt;span class="c1"&gt;# (LG München, Urteil vom 20.01.2022, Az. 3 O 17493/20)
&lt;/span&gt;
    &lt;span class="n"&gt;indicators&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
        &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;fonts.googleapis.com&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;fonts.gstatic.com&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;@import url&lt;/span&gt;&lt;span class="se"&gt;\\&lt;/span&gt;&lt;span class="s"&gt;(.*fonts&lt;/span&gt;&lt;span class="se"&gt;\\&lt;/span&gt;&lt;span class="s"&gt;.google&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;
    &lt;span class="p"&gt;]&lt;/span&gt;

    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;pattern&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;indicators&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;re&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;search&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pattern&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;html&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;re&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;IGNORECASE&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;status&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;critical&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;reason&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Google Fonts wird extern geladen&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;risk&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;IP-Übertragung in die USA ohne Consent&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;fix&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Self-Hosting der Fonts oder Consent vor Laden&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;status&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;ok&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Das ist ein typischer Crawler-Check, den &lt;strong&gt;kein internationales Tool macht&lt;/strong&gt;, weil das Rechtsproblem deutsch-spezifisch ist.&lt;/p&gt;

&lt;h2&gt;
  
  
  Das Scoring: eRate + eTrust
&lt;/h2&gt;

&lt;p&gt;Statt eine einzige "Note" zu geben, splitten wir das Ergebnis bewusst in zwei Bewertungen:&lt;/p&gt;

&lt;h3&gt;
  
  
  eRate — Technische Qualität (0-100%)
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Kategorie&lt;/th&gt;
&lt;th&gt;Max. Punkte&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Sicherheit&lt;/td&gt;
&lt;td&gt;30&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Datenschutz &amp;amp; Rechtliches&lt;/td&gt;
&lt;td&gt;25&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;SEO &amp;amp; Auffindbarkeit&lt;/td&gt;
&lt;td&gt;25&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Performance&lt;/td&gt;
&lt;td&gt;20&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  eTrust — Vertrauenswürdigkeit (0-100%)
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Faktor&lt;/th&gt;
&lt;th&gt;Punkte&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;SSL/HTTPS&lt;/td&gt;
&lt;td&gt;15&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Impressum&lt;/td&gt;
&lt;td&gt;15&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Datenschutzerklärung&lt;/td&gt;
&lt;td&gt;12&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Kontaktinformationen&lt;/td&gt;
&lt;td&gt;10&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Keine Malware-Indikatoren&lt;/td&gt;
&lt;td&gt;10&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Sichere Formulare&lt;/td&gt;
&lt;td&gt;8&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Professionelles Erscheinungsbild&lt;/td&gt;
&lt;td&gt;8&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Transparenz&lt;/td&gt;
&lt;td&gt;7&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Warum zwei Werte? Weil eine Website &lt;strong&gt;technisch perfekt&lt;/strong&gt; sein kann (eRate A+), aber &lt;strong&gt;unseriös&lt;/strong&gt; wirken (kein Impressum, kein Kontakt → eTrust D). Beide Aspekte sind für Besucher relevant — und werden mit nur einem Score vermischt.&lt;/p&gt;

&lt;h2&gt;
  
  
  Was wir bewusst NICHT machen
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Keine echte Performance-Messung im Browser.&lt;/strong&gt; Wir messen Server-Response-Time und Asset-Größen, nicht Time-to-Interactive oder Largest Contentful Paint. Dafür gibt es PageSpeed Insights — wir wollten nicht der zweite sein, sondern die anderen 95% abdecken.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Keine Penetration Tests.&lt;/strong&gt; Wir scannen passiv. Kein Brute-Force, kein Port-Scanning, kein SQL-Injection-Test. Das wäre ohne Erlaubnis des Website-Betreibers illegal.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Keine englischsprachigen Websites.&lt;/strong&gt; Wir erkennen die Sprache der Website automatisch (via Lingua + HTML lang-Attribut) und führen den vollständigen Scan nur für &lt;strong&gt;deutschsprachige Websites&lt;/strong&gt; durch. Internationale Seiten bekommen einen reduzierten Report.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Keine Hidden-Funnel-Logic.&lt;/strong&gt; Du bekommst den vollen Report ohne E-Mail-Adresse, ohne Signup, ohne "Premium-Features dahinter". Die Bewertung ist die Bewertung.&lt;/p&gt;

&lt;h2&gt;
  
  
  Das Widget — Trust nach außen tragen
&lt;/h2&gt;

&lt;p&gt;Nach jedem Scan kannst du das &lt;strong&gt;eRate/eTrust-Widget&lt;/strong&gt; kostenlos auf deine Website einbinden. Ähnlich wie Trustpilot, aber für objektive Technik-Kriterien statt subjektive Bewertungen:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;iframe&lt;/span&gt; 
  &lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"https://crawler.eg-core.de/widget/embed?domain=deinedomain.de"&lt;/span&gt;
  &lt;span class="na"&gt;width=&lt;/span&gt;&lt;span class="s"&gt;"300"&lt;/span&gt; 
  &lt;span class="na"&gt;height=&lt;/span&gt;&lt;span class="s"&gt;"150"&lt;/span&gt;
  &lt;span class="na"&gt;frameborder=&lt;/span&gt;&lt;span class="s"&gt;"0"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/iframe&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Wir verifizieren beim Einbetten, dass die anzeigende Domain mit der gescannten übereinstimmt — kein "Fake-A+-Badge", den jemand stehlen könnte.&lt;/p&gt;

&lt;p&gt;Warum das was bringt: Ein automatisch generiertes, &lt;strong&gt;unbestechliches&lt;/strong&gt; Vertrauenssiegel. Im Gegensatz zu kaufbaren Gütesiegeln bedeutet ein A+ hier real, dass dein technisches Setup sauber ist.&lt;/p&gt;

&lt;h2&gt;
  
  
  Wer das nutzt
&lt;/h2&gt;

&lt;p&gt;Aktuell scannen wir mit dem Crawler intern:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Vor jedem Erstgespräch&lt;/strong&gt; mit potenziellen Kunden — wir gehen vorbereitet ins Meeting&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Nach jedem Projekt-Release&lt;/strong&gt; als Quality Gate&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Quartalsweise&lt;/strong&gt; für alle Hosting-Kunden, die unser Audit-Paket gebucht haben&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Extern wird er von Webentwicklern, Agenturen und einigen Datenschutzbeauftragten genutzt, um schnell Sites zu screenen. Genaue Zahlen behalten wir für uns — aber er läuft stabil und schnell genug für unseren Bedarf.&lt;/p&gt;

&lt;h2&gt;
  
  
  Wenn du es probieren willst
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Scanner:&lt;/strong&gt; &lt;a href="https://crawler.eg-core.de/scan" rel="noopener noreferrer"&gt;crawler.eg-core.de/scan&lt;/a&gt; — keine Registrierung, direkt URL eingeben&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Rating-Erklärung:&lt;/strong&gt; &lt;a href="https://crawler.eg-core.de/widget/info" rel="noopener noreferrer"&gt;crawler.eg-core.de/widget/info&lt;/a&gt; — alle Bewertungskriterien im Detail&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Technische Doku:&lt;/strong&gt; &lt;a href="https://crawler.eg-core.de/widget/tech" rel="noopener noreferrer"&gt;crawler.eg-core.de/widget/tech&lt;/a&gt; — für Entwickler, die alle Checks im Detail nachlesen wollen&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Wenn du das Widget auf deiner Website einbinden willst: nach erfolgreichem Scan bekommst du den Embed-Code direkt im Report.&lt;/p&gt;

</description>
      <category>seo</category>
      <category>dsgvo</category>
      <category>sicherheit</category>
      <category>deutsch</category>
    </item>
    <item>
      <title>Warum wir eine eigene KYC-API gebaut haben — und es kostenlos rausgeben</title>
      <dc:creator>Enjyn Gruppe</dc:creator>
      <pubDate>Thu, 21 May 2026 22:29:31 +0000</pubDate>
      <link>https://dev.to/enjyn_3feb58e98fa3/warum-wir-eine-eigene-kyc-api-gebaut-haben-und-es-kostenlos-rausgeben-2e5a</link>
      <guid>https://dev.to/enjyn_3feb58e98fa3/warum-wir-eine-eigene-kyc-api-gebaut-haben-und-es-kostenlos-rausgeben-2e5a</guid>
      <description>&lt;h2&gt;
  
  
  Das Problem: KYC ist teuer. Sehr teuer.
&lt;/h2&gt;

&lt;p&gt;Vor knapp einem Jahr hatten wir bei &lt;a href="https://enjyn.de" rel="noopener noreferrer"&gt;Enjyn&lt;/a&gt; ein wiederkehrendes Muster: Für mehrere unserer Kundenprojekte brauchten wir eine zuverlässige Identitätsprüfung — mal für Altersverifikation, mal für eine Community-Plattform, mal für einen Marktplatz mit Verkäufer-KYC.&lt;/p&gt;

&lt;p&gt;Wir haben uns die üblichen Verdächtigen angeschaut:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Anbieter&lt;/th&gt;
&lt;th&gt;Preis pro Verifikation&lt;/th&gt;
&lt;th&gt;Setup&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Onfido&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;ab ~2 €&lt;/td&gt;
&lt;td&gt;Enterprise-Sales&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;IDnow&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;ab ~2–5 €&lt;/td&gt;
&lt;td&gt;Vertrieblicher Erstkontakt&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Veriff&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;ab ~1–3 €&lt;/td&gt;
&lt;td&gt;Self-Service, aber Mindestvolumen&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Bei einem unserer Projekte mit erwarteten 1.500 Verifikationen im Monat wären das &lt;strong&gt;2.250 – 7.500 € monatlich&lt;/strong&gt; gewesen. Für ein Tool, das vor allem im Hintergrund läuft und „nur" prüft, ob ein Personalausweis echt ist.&lt;/p&gt;

&lt;p&gt;Die ehrliche Erkenntnis: Wir wollten das nicht zahlen. Und unsere Kunden auch nicht.&lt;/p&gt;

&lt;h2&gt;
  
  
  Die Frage: Können wir das selbst bauen?
&lt;/h2&gt;

&lt;p&gt;Ein paar Wochenenden Recherche später war klar: Ja, können wir. Die Bestandteile sind technisch alle vorhanden:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Dokumenten-OCR&lt;/strong&gt; für Ausweisdaten (Name, Geburtsdatum, MRZ-Zone)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Dokumenten-Authentizitätsprüfung&lt;/strong&gt; (Hologramme, Sicherheitsmerkmale, MRZ-Checksums)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Datenabgleich&lt;/strong&gt; zwischen Nutzer-Eingabe und Ausweisdaten&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Auto-Datenextraktion&lt;/strong&gt; aus Vorder- und Rückseite&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Was wir nicht wollten:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Daten in die USA schicken (DSGVO-Albträume mit Schrems II)&lt;/li&gt;
&lt;li&gt;Cloud-Lösungen mit Per-Call-Pricing (genau das Problem, das wir lösen wollten)&lt;/li&gt;
&lt;li&gt;Black-Box-Modelle, deren Funktion wir nicht erklären können&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Also haben wir uns hingesetzt und unsere &lt;strong&gt;eigene KI/ML-Pipeline&lt;/strong&gt; gebaut. Komplett in-house, auf eigenen Servern in Deutschland.&lt;/p&gt;

&lt;h2&gt;
  
  
  Der Stack — grob umrissen
&lt;/h2&gt;

&lt;p&gt;Aus naheliegenden Gründen veröffentlichen wir nicht jedes Detail (Anti-Fraud-Schutz), aber das große Bild:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Bildverarbeitung:&lt;/strong&gt; Ausweis-Bilder werden zuerst normalisiert, entzerrt und auf Qualität geprüft. Zu unscharf, zu schräg oder Bildschirm-Fotografie → automatische Ablehnung.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;OCR &amp;amp; MRZ-Parsing:&lt;/strong&gt; Die Maschinenlesbare Zone (MRZ) deutscher Ausweise und Reisepässe wird ausgelesen, validiert (Prüfsummen) und mit den OCR-Daten aus dem visuellen Bereich abgeglichen.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Datenabgleich:&lt;/strong&gt; Die vom Anwender vorab angegebenen Daten (Vorname, Nachname, Geburtsdatum) werden mit den extrahierten Ausweisdaten verglichen. Diskrepanzen → Status &lt;code&gt;failed&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Auto-Löschung:&lt;/strong&gt; Hochgeladene Bilder werden nach &lt;strong&gt;10 Minuten gelöscht&lt;/strong&gt;, Satus-Daten nach &lt;strong&gt;30 Tagen&lt;/strong&gt;. Mehr nicht.&lt;/p&gt;

&lt;h2&gt;
  
  
  Wie die API aussieht
&lt;/h2&gt;

&lt;p&gt;Wir nutzen einen einfachen, dreistufigen Flow — bewusst minimalistisch gehalten:&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Verifikations-Session erstellen
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-X&lt;/span&gt; POST https://api.verify.enjyn.de/api/v1/verify &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Content-Type: application/json"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"X-API-Key: YOUR_API_KEY"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;'{
    "vorname": "Max",
    "nachname": "Mustermann",
    "geburtsdatum": "01.01.1990",
    "return_url": "https://ihre-website.de/callback.html"
  }'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Response:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"success"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"session_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"uuid"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"token"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"secure-token"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"verify_url"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://api.verify.enjyn.de/verify/token"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"qr_url"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://api.verify.enjyn.de/api/v1/qr-code/token"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Du leitest den Nutzer auf die &lt;code&gt;verify_url&lt;/code&gt; weiter — oder zeigst den QR-Code an, damit er die Verifikation auf dem Smartphone fortsetzt. Der Nutzer lädt dort Vorder- und Rückseite seines Ausweises hoch, der Rest passiert automatisch.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Status nach Callback abrufen
&lt;/h3&gt;

&lt;p&gt;Nach Abschluss leiten wir den Nutzer auf deine &lt;code&gt;return_url&lt;/code&gt; weiter. Wichtig: Der &lt;code&gt;status&lt;/code&gt;-Parameter in der URL ist &lt;strong&gt;nicht vertrauenswürdig&lt;/strong&gt; (kann manipuliert werden). Den echten Status holst du dir per API:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl https://api.verify.enjyn.de/api/v1/get-result/&lt;span class="o"&gt;{&lt;/span&gt;session_id&lt;span class="o"&gt;}&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"X-API-Key: YOUR_API_KEY"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Response bei Erfolg:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"success"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"status"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"verified"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"vorname"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Max"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"nachname"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Mustermann"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"geburtsdatum"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"01.01.1990"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"verified_at"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"2026-05-21T23:42:18Z"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  3. Vollständige JavaScript-Integration
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// 1. Session erstellen&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;https://api.verify.enjyn.de/api/v1/verify&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;method&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;POST&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;headers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Content-Type&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;application/json&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;X-API-Key&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;YOUR_API_KEY&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="na"&gt;body&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;stringify&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
        &lt;span class="na"&gt;vorname&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Max&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;nachname&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Mustermann&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;geburtsdatum&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;01.01.1990&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;return_url&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;https://ihre-website.de/callback.html&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
    &lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;verify_url&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;session_id&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="c1"&gt;// Session-ID lokal merken für späteren Abruf&lt;/span&gt;
&lt;span class="nx"&gt;sessionStorage&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setItem&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;kyc_session&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;session_id&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// 2. Nutzer zur Verifikation weiterleiten&lt;/span&gt;
&lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;location&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;href&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;verify_url&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// 3. Auf der Callback-Seite: Status SICHER validieren&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;sessionId&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;sessionStorage&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getItem&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;kyc_session&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="s2"&gt;`https://api.verify.enjyn.de/api/v1/get-result/&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;sessionId&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;headers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;X-API-Key&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;YOUR_API_KEY&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;verification&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;verification&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;status&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;verified&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;✓ Verifiziert:&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;verification&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;vorname&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Status-Werte
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Status&lt;/th&gt;
&lt;th&gt;Beschreibung&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;pending&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Wartet auf Nutzer-Upload&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;processing&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Bilder werden verarbeitet&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;verified&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;✅ Erfolgreich&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;failed&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;❌ Fehlgeschlagen&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  Was wir bewusst NICHT machen
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Keine internationalen Ausweise&lt;/strong&gt; (noch nicht). Wir prüfen aktuell deutsche Personalausweise und Reisepässe. Das deckt unseren Use Case ab. Internationale Dokumente erfordern Trainingsdaten und Validierung, die wir bisher nicht haben.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Kein BaFin-Level KYC.&lt;/strong&gt; Für Banken und Finanzdienstleister gibt es regulatorische Anforderungen (qualifizierte elektronische Signatur, Video-Ident mit Schulungsanforderungen), die wir nicht abdecken. Wenn du als Bank KYC brauchst: nimm IDnow oder PostIdent. Wir sind die richtige Wahl für E-Commerce, Communities, SaaS, Events und Marktplätze.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Kein Speichern der Originaldaten über Wochen.&lt;/strong&gt; Manche Anbieter behalten Dokumente monatelang für „Audit-Zwecke". Wir nicht. Bilder weg nach 10min, Session (anonymisiert) weg nach 30 Tagen.&lt;/p&gt;

&lt;h2&gt;
  
  
  Warum wir es kostenlos rausgeben
&lt;/h2&gt;

&lt;p&gt;Faire Frage. Antwort in drei Teilen:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Erstens — Eigeninteresse.&lt;/strong&gt; Wir nutzen es selbst in mehreren Projekten. Es kostenlos verfügbar zu machen, kostet uns kaum mehr als es nur intern zu nutzen. Die Infrastruktur läuft sowieso.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Zweitens — Marktposition.&lt;/strong&gt; Wir sind eine Software-Agentur. Kunden, die unser KYC-API ausprobieren und damit zufrieden sind, fragen uns irgendwann auch für andere Dinge an. Hosting, Custom-Entwicklung, SEO. Das funktioniert.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Drittens — wir können Volumen-Preise später noch differenzieren.&lt;/strong&gt; Aktuell ist es bis zu 150 Verifys (nur erfolgreich) Monatlich kostenlos.&lt;/p&gt;

&lt;h2&gt;
  
  
  Aktuelle Nutzung
&lt;/h2&gt;

&lt;p&gt;Wir haben aktuell &lt;strong&gt;8 aktive Partner&lt;/strong&gt;, die zusammen &lt;strong&gt;60–150 Verifikationen pro Monat&lt;/strong&gt; durchführen. Klein, aber stetig wachsend. Wir wollten erst sicher sein, dass die Pipeline robust läuft, bevor wir lauter werden.&lt;/p&gt;

&lt;p&gt;Das hier ist der Anfang davon, lauter zu werden.&lt;/p&gt;

&lt;h2&gt;
  
  
  Wenn du es probieren willst
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Demo:&lt;/strong&gt; &lt;a href="https://enjyn.de/kyc" rel="noopener noreferrer"&gt;enjyn.de/kyc&lt;/a&gt; — du kannst dich live durchprüfen lassen&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;API-Docs:&lt;/strong&gt; &lt;a href="https://enjyn.de/apis?kyc" rel="noopener noreferrer"&gt;enjyn.de/apis?kyc&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;API-Key anfordern:&lt;/strong&gt; Kurze Nachricht über &lt;a href="https://enjyn.de/kontakt" rel="noopener noreferrer"&gt;enjyn.de/kontakt&lt;/a&gt; mit deinem Use Case. Wir machen das aktuell noch manuell, um Missbrauch zu verhindern. Antwortzeit meist unter 6h.&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>kyc</category>
      <category>dsgvo</category>
      <category>api</category>
      <category>deutsch</category>
    </item>
  </channel>
</rss>
