Diil Docs
  1. Doku
  2. Erste Schritte

Authentifizierung mit Site-Keys

Aktualisiert:

Jeder Request an die Content API trägt einen Site-Key. Er sagt uns, von welcher Website du liest — und das ist so ziemlich alles, was er tut. Kein OAuth-Tanz, kein Token-Refresh, kein Signieren von Requests um Mitternacht. Ein String in einem Header, und du bist drin.

Was ein Site-Key ist

Ein Site-Key sieht so aus:

pk_3f9c2a7e1b4d4c0e8a6f5b2d9c1e7a40
  • Das Präfix pk_, gefolgt von genau 32 Hex-Zeichen in Kleinbuchstaben: ^pk_[a-f0-9]{32}$.
  • Er gehört zu einer Website. Allein der Key entscheidet, wessen Inhalte du bekommst — einen Parameter „site id“ gibt es nirgends in der API.
  • Er ist read-only und sieht nur veröffentlichte Inhalte.
  • Eine Website kann mehrere Keys gleichzeitig haben — so wird schmerzfreies Rotieren möglich (mehr dazu unten).

Das pk_ ist eine Anspielung auf die „Publishable Keys“, die du vielleicht von Payment-Anbietern kennst: ein Key, der dafür gemacht ist, in öffentlichem Code zu leben. Warum das völlig in Ordnung ist, klären wir gleich.

Wo du einen Key bekommst

  1. Öffne deine Website im CRM

    Melde dich bei Diil an und wähl die Website, deren Inhalte du lesen willst.
  2. Geh zu Einstellungen → Content-API-Keys

    Hier wohnen alle Keys der Website.
  3. Erstelle einen Key

    Du bekommst einen frischen pk_…-String. Kopier ihn.
  4. Leg ihn in eine Umgebungsvariable

    Nicht direkt in den Code — dein zukünftiges Ich wird dir beim Rotieren dankbar sein. Muster für beliebte Frameworks findest du unten.

So schickst du den Key mit

Pack den Key in den Request-Header x-crm-key. Das ist der Standardweg, und er funktioniert vom Server genauso wie aus dem Browser — CORS erlaubt den Header von jeder Origin.

curl "https://back.sitecog.com/content/v1/pages/home?lang=en" \
  -H "x-crm-key: pk_3f9c2a7e1b4d4c0e8a6f5b2d9c1e7a40"

Der Fallback ?key=

Wenn du wirklich keinen Header setzen kannst, übergib den Key stattdessen als Query-Parameter:

curl "https://back.sitecog.com/content/v1/pages/home?lang=en&key=pk_3f9c2a7e1b4d4c0e8a6f5b2d9c1e7a40"

Wann ist das okay?

  • Schnelle Checks — eine URL in die Adresszeile des Browsers kopieren, um zu sehen, was ein Endpoint liefert.
  • Tools, die nur eine URL nehmen — eine No-Code-Integration, ein Feed-Importer, ein Plugin für einen Static Site Generator ohne Header-Option.

Überall sonst nimm lieber den Header. URLs landen gern in Server-Logs, im Browserverlauf und in Analytics, und auch wenn der Key kein Geheimnis ist, gibt es keinen Grund, ihn überall zu verstreuen. Außerdem bleiben so deine URLs kurz und dein Code aufgeräumt.

Warum der Key im Browser sicher ist

Kurze Antwort: weil er nichts kann, was deine Besucher nicht sowieso können, indem sie deine Website öffnen. Ein Site-Key ist von vornherein öffentlich. Das kann er und das kann er nicht:

Ein Site-Key…
liest veröffentlichte Seiten, Sections, Blöcke und Blogposts seiner Websiteja
ändert, erstellt oder löscht irgendetwasnein — die API ist read-only
sieht Entwürfe oder unveröffentlichte Blogpostsnein — nur veröffentlichte Inhalte
liest Inhalte deiner anderen Websitesnein — ein Key, eine Website

Es ist dieselbe Idee wie beim Publishable Key eines Payment-Anbieters: Er bestimmt, wessen Daten gezeigt werden, gibt aber keine Macht über sie. Alles, was er lesen kann, landet sowieso auf deiner öffentlichen Website.

Das Einzige, was ein kopierter Key kann, ist dein Request-Kontingent verbrauchen: Jeder Key hat sein eigenes Limit von 600 Requests pro Minute (siehe Rate Limits). Fängt jemand damit an, rotier den Key — das dauert ein paar Minuten.

Den Key in Umgebungsvariablen halten

Der Key ist öffentlich — wozu also Env-Variablen? Weil Keys sich ändern: Ein rotierter Key sollte eine Konfigurationsänderung sein, keine Codeänderung. Außerdem verlangen die meisten Frameworks ein Präfix, bevor sie eine Variable in Browser-Code lassen:

.envbash
# Next.js — Server Components, Route Handlers (landet nie im Browser)
CRM_KEY=pk_3f9c2a7e1b4d4c0e8a6f5b2d9c1e7a40

# Next.js — Client Components (wird beim Build ins Bundle eingesetzt)
NEXT_PUBLIC_CRM_KEY=pk_3f9c2a7e1b4d4c0e8a6f5b2d9c1e7a40

# Vite (React, Vue, Svelte…) — wird beim Build eingesetzt
VITE_CRM_KEY=pk_3f9c2a7e1b4d4c0e8a6f5b2d9c1e7a40

# Nuxt — überschreibt runtimeConfig.public.crmKey
NUXT_PUBLIC_CRM_KEY=pk_3f9c2a7e1b4d4c0e8a6f5b2d9c1e7a40
// app/page.tsx — eine Server Component
export default async function Home() {
  const res = await fetch('https://back.sitecog.com/content/v1/pages/home?lang=en', {
    headers: { 'x-crm-key': process.env.CRM_KEY! },
    next: { revalidate: 60 },
  });
  const page = await res.json();

  return <h1>{page.content.hero.content.hero_title.content.en}</h1>;
}

Keys widerrufen und rotieren

Jeder Key lässt sich im CRM in derselben Liste unter Einstellungen → Content-API-Keys widerrufen. Ein widerrufener Key funktioniert nicht mehr: Jeder Request damit bekommt 401 invalid_key. Um Keys ohne einen einzigen fehlgeschlagenen Request zu tauschen, lass sie sich überlappen:

  1. Erstelle einen neuen Key

    Lass den alten erst mal in Ruhe — beide funktionieren parallel.
  2. Deploye mit dem neuen Key

    Aktualisier die Umgebungsvariable überall, wo der alte Key genutzt wurde, bau neu, falls dein Framework ihn einsetzt, und deploye.
  3. Prüf, ob die Website weiterhin Inhalte lädt

    Öffne ein paar Seiten, schau in die Logs. Keine 401er? Gut.
  4. Widerrufe den alten Key

    Jetzt kannst du gefahrlos den Stecker ziehen.

Key-Fehler

StatusBodyWas passiert ist
401{"message":"invalid_key"}Der Key fehlt, ist falsch formatiert (nicht pk_ + 32 Hex) oder widerrufen.
429{"message":"rate_limit_exceeded"}Zu viele Requests — oder zu viele falsche Keys von deiner IP in dieser Minute (siehe unten).

Die Sperre bei falschen Keys

Damit sich Key-Raten nicht lohnt, zählen wir Requests mit ungültigen Keys pro IP. Mehr als 20 Requests mit falschem Key pro Minute von einer IP, und diese IP bekommt für den Rest der Minute 429 — auch mit gültigem Key. Retry-After-Header gibt es nicht; das Fenster wird zu Beginn der nächsten Minute zurückgesetzt.

Der Klassiker, um da versehentlich reinzulaufen: Du widerrufst einen alten Key, aber ein Server oder ein vergessener Cronjob nutzt ihn noch. Das Server-Side-Rendering feuert fleißig 401er, und eine Minute später ist der ganze Server gesperrt — samt neuem Key. Also:

Einen 401 nicht wiederholenjs
const res = await fetch(url, { headers: { 'x-crm-key': process.env.CRM_KEY } });

if (res.status === 401) {
  // Ein falscher oder widerrufener Key repariert sich nicht von selbst. Retries verbrennen
  // nur das Budget für falsche Keys und sorgen dafür, dass diese IP gesperrt wird.
  throw new Error('Content API: invalid site key, check CRM_KEY');
}

if (res.status === 429) {
  // Bis zur nächsten Minute zurückhalten (etwa 60 s plus ein bisschen Jitter).
}

Alle anderen Codes findest du auf der Seite Fehler.

Sicherheits-FAQ