Architektur

Zuletzt aktualisiert: Aug 31, 2026Abschnitt: Integrationen

IndexNOW-Benachrichtigung (Integrator-Endpunkt)

Wenn Blog- oder Market-Inhalte veröffentlicht, aktualisiert, depubliziert oder gelöscht werden, kann Mailoo IDs per POST an Ihre Website senden. Sie erstellen die öffentlichen Seiten-URLs und übermitteln sie an IndexNow. Mailoo ruft IndexNOW nicht direkt auf und sendet keine absoluten URLs.

Veröffentlichungen und Katalogschreibvorgänge in Mailoo sind immer erfolgreich, auch wenn Ihr Endpunkt fehlt oder einen Fehler zurückgibt (Fire-and-Forget). Mailoo zeichnet das Ergebnis auf dem Inhaltsdatensatz als indexNowStatus auf.

Verwandt: Blog-CMS --- blog-headless-cms{.interpreted-text role="doc"}; Marktkatalog --- market-catalog-external-api{.interpreted-text role="doc"}; Next.js-Blog-Beispiel --- blog-nextjs-example{.interpreted-text role="doc"}; Delivery-Webhook-HMAC (gleiche Signierformel) --- transactional-email{.interpreted-text role="doc"}.

Architektur

  • Auslöser: Nach einem erfolgreichen Blog-Artikel- oder Market-Produkt-Schreibvorgang (oder veröffentlichte Produktvariante).
  • Nutzlast: Projekt-/Integrations-/Inhalts-IDs, optionaler Blog-slug, locales und action --- keine Seiten-URLs.
  • Ihre Aufgabe: IDs → öffentliche URLs → IndexNOW-API mit Ihrem Schlüssel zuordnen.
  • Status am Inhalt: PENDINGNOTIFIED | FAILED oder SKIPPED wenn indexNow nicht konfiguriert ist. null bedeutet nie versucht (z. B. nur Entwurf).

Konfiguration

Pro BLOG- oder MARKET-Integration:

  • Dashboard → Connection & settings → IndexNOW notify
  • BLOG + MCP / Verwaltungs-API: GET/PATCH /api/v1/blog/{projectUid}/integrations/{integrationId}/settings (Feld indexNow; sanitisiertes GET zeigt notifyUrl + hasSecret). MCP-Tool manage_blog_integration_settings --- siehe mailoo-mcp{.interpreted-text role="doc"}.
  • Oder PATCH /api/v1/projects/{uid}/integrations/{id} mit Body:
{
  "indexNow": {
    "notifyUrl": "https://www.example.com/api/indexnow/notify",
    "secret": "your-signing-secret"
  }
}

Senden Sie "indexNow": null zum Zurücksetzen. Sanitisierte API-Antworten zeigen notifyUrl und hasSecret (niemals das rohe Secret).

Wenn notifyUrl / secret nicht gesetzt sind, setzt Mailoo indexNowStatus auf ``SKIPPED`` und führt keinen HTTP-Aufruf an Ihre Website durch.

Endpunktvertrag

Methode / URL: POST an die konfigurierte notifyUrl.

Header:

  • Content-Type: application/json
  • X-Mailoo-Event: indexnow.notify
  • X-Mailoo-Signature: t={unixSeconds},v1={hex} --- v1 ist HMAC-SHA256 von "{timestamp}.{rawBody}" mit indexNow.secret (gleiche Formel wie Transaktions-Delivery-Webhooks).

Body (JSON):

{
  "event": "indexnow.notify",
  "kind": "blog_post",
  "action": "published",
  "projectUid": "…",
  "integrationId": "…",
  "contentId": "…",
  "slug": "my-post",
  "locales": ["en", "de"],
  "timestamp": "2026-08-03T09:00:00.000Z"
}

Felder nach Kind

  • kind --- blog_post oder market_product
  • contentId --- Artikel-ID oder Produkt-ID
  • slug --- Artikel-Slug (nur Blog; bei Market weggelassen)
  • locales --- Blog: en plus Schlüssel aus dem Artikel-locales-JSON; Market: defaultCatalogLocale oder en
  • action --- published, updated, unpublished oder deleted

Wann Mailoo sendet

  • Erstellen mit PUBLISHEDpublished
  • Aktualisierung, die PUBLISHED wird oder bleibt → published / updated
  • Status verlässt PUBLISHEDunpublished
  • Löschen im veröffentlichten Zustand → deleted (danach keine Statuszeilen-Aktualisierung)
  • Nur-Entwurf-Schreibvorgänge → keine Benachrichtigung; indexNowStatus bleibt null

Erwartete Antworten

  • 2xx --- akzeptiert (Sie können IndexNOW asynchron in die Warteschlange stellen). Mailoo setzt NOTIFIED.
  • 404 / 5xx / Netzwerk / Timeout --- Mailoo setzt FAILED. Inhaltsveröffentlichung wurde bereits committed.
  • Fehlende Konfiguration --- SKIPPED ohne Anfrage.

indexNowStatus-Werte

  • PENDING --- Benachrichtigung unterwegs
  • NOTIFIED --- Integrator hat 2xx zurückgegeben
  • SKIPPED --- keine indexNow-Konfiguration auf der Integration
  • FAILED --- Anfrage fehlgeschlagen oder Nicht-2xx
  • null --- nicht anwendbar / nie versucht

Integrator-Verantwortlichkeiten

  1. X-Mailoo-Signature verifizieren (ungültige Signaturen ablehnen).
  2. Öffentliche URL(s) aus kind, contentId / slug und locales auflösen.
  3. IndexNOW mit Ihrem Schlüssel aufrufen (und Host-Schlüsseldatei wie von IndexNOW gefordert).
  4. 2xx schnell zurückgeben; rechenintensive Arbeit bei Bedarf asynchron erledigen.

Next.js-App-Router-Skizze

// app/api/indexnow/notify/route.ts
import { createHmac, timingSafeEqual } from 'node:crypto'
import { NextRequest, NextResponse } from 'next/server'

const SECRET = process.env.MAILOO_INDEXNOW_SECRET!

function verify(signatureHeader: string | null, body: string): boolean {
  if (!signatureHeader) return false
  const m = /^t=(\d+),v1=([a-f0-9]+)$/i.exec(signatureHeader.trim())
  if (!m) return false
  const [, t, v1] = m
  const expected = createHmac('sha256', SECRET)
    .update(`${t}.${body}`)
    .digest('hex')
  try {
    return timingSafeEqual(Buffer.from(v1, 'hex'), Buffer.from(expected, 'hex'))
  } catch {
    return false
  }
}

export async function POST(req: NextRequest) {
  const raw = await req.text()
  if (!verify(req.headers.get('x-mailoo-signature'), raw)) {
    return NextResponse.json({ error: 'invalid signature' }, { status: 401 })
  }
  const payload = JSON.parse(raw) as {
    kind: string
    action: string
    contentId: string
    slug?: string
    locales: string[]
  }
  // URLs aus Payload erstellen, dann POST an https://api.indexnow.org/indexnow
  void payload
  return NextResponse.json({ ok: true })
}

Voraussetzungen

  • BLOG- oder MARKET-Integration
  • indexNow.notifyUrl + secret konfiguriert (optional; ohne wird der Status SKIPPED)
  • Ihre Website implementiert den Notify-Endpunkt und das IndexNOW-Schlüssel-Hosting

Beispiel: mailoo.app als Integrator

Die Mailoo-Marketing-Website ist sowohl ein Blog-Konsument als auch ein IndexNOW-Integrator für diese Blog-Integration. Muster zum Nachahmen:

  1. Nur-Server-Umgebung auf der Website: gemeinsames Signier-Secret, IndexNOW-Schlüssel und öffentliche SITE_URL.
  2. IndexNOW-Schlüsseldatei unter https://{your-domain}/{key}.txt hosten.
  3. POST /api/indexnow/notify implementieren, der HMAC verifiziert, öffentliche URLs aus der Nutzlast erstellt und sie an https://api.indexnow.org/indexnow übermittelt.
  4. Auf der Blog-Integration notifyUrl auf diesen Endpunkt und secret auf dasselbe Signier-Secret setzen (Dashboard oder MCP manage_blog_integration_settings).