Site-API-Referenz (seoasist-site-api/1)
Die vollständige SEOAsist Site-API-Spezifikation: Authentifizierung und HMAC-Signierung, die vier Endpunkte, Regeltypen und eine Übersicht der fertigen Next.js/PHP-Beispiele.
Diese Ansicht im Panel öffnenDiese Seite beschreibt den SEOAsist Site-API-Vertrag (Spezifikation seoasist-site-api/1), den Ihre Website implementiert. Der Tab Entwicklerhandbuch → Spezifikation im Panel und der Einrichtungs-Prompt enthalten denselben Vertrag. Die Schritte zur Verbindung finden Sie unter Verbinden einer selbstgebauten Website mit der SEOAsist Site-API.
Allgemeine Regeln
- Alle Endpunkte befinden sich unter einem gemeinsamen Basispfad, z. B.
https://example.com/api/seoasist. - Antworten Sie immer mit JSON. Eine Antwort, die kein JSON ist, gilt als Fehler.
- Leiten Sie niemals weiter (kein 30x). SEOAsist folgt keinen Weiterleitungen; speichern Sie daher die finale API-URL im Panel.
- Antworten Sie im Fehlerfall mit 4xx/5xx und
{"error":"<kurze Nachricht>"}. Diese Nachricht wird im Panel angezeigt. - Validieren Sie Eingaben, begrenzen Sie die Body-Größe (~2 MB) und protokollieren Sie Aufrufe.
- SEOAsist bricht jede Anfrage nach 25 Sekunden per Timeout ab. Anfragen verwenden den User-Agent
SEOAsist-SiteAPI/1.0 (+https://seoasist.com). - Die URL muss öffentlich erreichbar sein; SEOAsist ruft niemals Localhost oder private Netzwerkadressen auf.
Authentifizierung
Jede Anfrage enthält drei Header:
| Header | Wert |
|---|---|
Authorization | Bearer <SEOASIST_SITE_TOKEN> |
X-SEOAsist-Timestamp | Unix-Timestamp (Sekunden) |
X-SEOAsist-Signature | sha256=<hex>, wobei hex = HMAC-SHA256(Schlüssel = Token, Nachricht = <timestamp>.<raw body>) |
- Bewahren Sie das Token in der Umgebungsvariable
SEOASIST_SITE_TOKENauf; kodieren Sie es niemals fest im Quelltext. Es wird im Panel generiert, wenn Sie auf Verbinden klicken, und beginnt mitsa_. - Vergleichen Sie das Token und die Signatur in konstanter Zeit.
- Bei GET-Anfragen ist der Raw Body eine leere Zeichenkette, die signierte Nachricht lautet also
<timestamp>.. - Antworten Sie mit
401 {"error":"unauthorized"}, wenn die Signatur falsch ist oder der Timestamp älter als 300 Sekunden ist.
const expected = "sha256=" + createHmac("sha256", token).update(`${ts}.${body}`).digest("hex");
GET /manifest
Der Verbindungstest ruft diesen Endpunkt auf. Führen Sie nur die Funktionen auf, die Sie implementiert haben.
{"spec":"seoasist-site-api/1","platform":"nextjs","name":"My site","capabilities":["rules","content","files"]}
spec muss mit seoasist-site-api/ beginnen. Die erkannten Funktionen sind rules, content und files; alles andere wird ignoriert. Das Panel zeigt sie als SEO-Regeln, Content-Veröffentlichung und llms.txt / robots an.
Es gibt zwei weitere optionale Felder:
locales: die Sprachen, in denen Sie veröffentlichen können (ISO 639-1), z. B.["az","ru","en","tr"]. SEOAsist sendet einen Beitrag nur dann in einer anderen Sprache als der primären Sprache der Website, wenn diese Sprache hier aufgeführt ist. Bevor ein Beitrag wegen einer Sprachabweichung abgelehnt wird, wird das Manifest noch einmal ausgelesen.ruleKinds: deklariert die Unterstützung für optionale Regeltypen. Der einzige optionale Typ ist derzeitlink; mit"ruleKinds":["link"]sendet SEOAsist interne Links an Ihre Site-API anstelle des Pixels.
{"spec":"seoasist-site-api/1","platform":"nextjs","name":"My site","capabilities":["rules","content","files"],"locales":["tr","en"],"ruleKinds":["link"]}
PUT /rules (Funktion: rules)
Body: {"rules": Rule[]}. Dies ist der vollständige aktuelle Regelsatz; ersetzen Sie alles zuvor Gespeicherte. Ein leeres Array löscht alle Regeln. Speichern Sie die Regeln dauerhaft (eine DB-Tabelle oder eine JSON-Datei) und wenden Sie sie serverseitig beim Rendering an, damit Crawler das Ergebnis im HTML und nicht im clientseitigen JavaScript sehen.
type Rule = { id: string; kind: string; matchType: "exact" | "prefix" | "regex" | "all"; matchPath: string; payload: object };
Das Matching verwendet den Anfrage-Pfadnamen ohne abschließenden Schrägstrich (/ für die Startseite):
exact: der Pfad ist identischprefix: der Pfad beginnt mitmatchPathregex: JavaScript RegExp-Testall: jede Seite
Wenn mehrere Regeln desselben Typs übereinstimmen, gewinnt die spezifischste: exact > prefix > regex > all.
| kind | payload | Anwenden als |
|---|---|---|
title | {"value"} | <title> |
meta_description | {"value"} | <meta name="description"> |
canonical | {"href"} | <link rel="canonical"> (absolute URL) |
robots | {"content"} | <meta name="robots"> (z. B. index,follow, noindex,follow) |
h1 | {"value","selector"?} | Den Haupt-H1-Text der Seite ersetzen |
og | {"title"?,"description"?,"image"?,"type"?} | og:* Meta-Tags |
json_ld | {"json"} | <script type="application/ld+json"> (json ist ein Objekt oder Array) |
hreflang | {"items":[{"lang","href"}]} | <link rel="alternate" hreflang> |
redirect | {"to","status"?} | HTTP-Weiterleitung vor dem Rendering (Standard 301) |
img_alt | {"items":[{"match","alt"}]} | Alt-Attribut für <img>-Elemente setzen, deren src den Wert match enthält |
lang | {"value"} | <html lang> |
link | {"anchor","href"} | Interner Link: Umschließen Sie das erste Vorkommen von anchor im Body-Text der Seite (nicht innerhalb eines Links, einer Überschrift, von Code, nav/header/footer) mit <a href="href">; tun Sie nichts, wenn die Seite bereits auf href verlinkt. Jede passende link-Regel wird angewendet, nicht nur die spezifischste. Wird nur gesendet, wenn ruleKinds im Manifest link enthält |
meta | {"name","content"} | <meta name="{name}" content="{content}"> im <head>. name ist nur ein Verifizierungs-Tag für den Website-Besitz: msvalidate.01 (Bing), google-site-verification, yandex-verification (in der Regel matchPath /) |
Speichern Sie unbekannte Typen und ignorieren Sie diese. Antwort: {"ok":true,"count":<gespeicherte Anzahl>}.
SEOAsist sendet alle aktivierten Regeln der Website: diejenigen, die im Pixel-Tab hinzugefügt wurden, angewendete Meta-Vorschläge, Regeln, die durch Autopilot (Otopilot)-Planaufgaben erstellt wurden, genehmigte interne Links und solche, die durch Auto-Korrektur / Mit Regeln korrigieren generiert wurden. Eine verbundene Site-API mit der Funktion rules wird als Regelkanal der Website verwendet.
POST /content (Funktion: content)
Body:
{"externalId":null,"type":"post","title":"…","slug":"…","html":"<h2>…</h2>","excerpt":"…","metaTitle":"…","metaDescription":"…","status":"draft","featuredImageUrl":"https://…","tags":["…"],"updateUrl":null,"locale":"tr","translationOf":null}
externalIdangegeben: diesen Eintrag aktualisieren.updateUrlangegeben (type: "page"): die bestehende Seite unter dieser URL aktualisieren (deren Hauptinhalt, Titel und Meta).- Andernfalls: einen neuen Blogbeitrag über das bestehende Inhalts-System der Website (DB/CMS/MDX) und dessen normales URL-Muster erstellen.
status: "draft"darf öffentlich nicht sichtbar sein.htmlist vertrauenswürdiges, bereits formatiertes Artikel-HTML (Überschriften, Listen, Tabellen, FAQ). Behalten Sie das Design und Layout der Website bei.tagsenthält maximal 5 Tags.locale: die Sprache des Textes (ISO 639-1, z. B.az,tr). Veröffentlichen Sie den Beitrag auf einer mehrsprachigen Website unter der eigenen URL dieser Sprache (Sprach-Präfix / Route), niemals unter einer anderen Sprache.translationOf: wenn der Beitrag eine Übersetzung ist, dieid, die Sie zuvor für den Originalbeitrag zurückgegeben haben. Speichern Sie ihn als Sprachversion dieses Beitrags (der Sprachumschalter muss diesen öffnen, nicht einen 404-Fehler) und verlinken Sie die Versionen mit<link rel="alternate" hreflang>auf jeder davon. Das Original wird immer zuerst gesendet; wenn der Eigentümer erneut veröffentlicht, wird jede Version erneut mit ihrer eigenenexternalIdgesendet.featuredImageUrl: die absolute URL des Beitragsbildes, dieselbe für jede Sprachversion. Wenn sie sich beim Erstellen und bei jedem Update von der gespeicherten unterscheidet, laden Sie sie herunter und ersetzen Sie das Beitragsbild (die URL hat möglicherweise keine Dateiendung; verwenden Sie den Content-Type der Antwort).- Bei Blogbeiträgen kann
htmldie strukturierten Daten des Beitrags (z. B. BlogPosting und FAQPage) am Ende als<script type="application/ld+json">enthalten. Entfernen Sie diese nicht; veröffentlichen Sie sie so wie sie sind auf der Seite.
Antwort: {"id":"<stabile id>","url":"<absolute öffentliche URL>","status":"draft"|"publish"}. SEOAsist speichert die id und sendet sie als externalId zurück, wenn dasselbe Element erneut gesendet wird. Wenn ein Blogbeitrag ohne externalId mit einem zuvor auf derselben Website veröffentlichten Beitrag mit demselben Slug und derselben Sprache übereinstimmt, verwendet SEOAsist die id dieses Beitrags, sodass keine zweite Kopie auf der Website geöffnet wird.
PUT /files (Funktion: files)
Body: {"path":"llms.txt"|"robots-ai.txt","content":string}
llms.txt: unter/llms.txtalstext/plainbereitstellen (und das vorherige ersetzen).robots-ai.txt: ein Block von AI-Crawler-Regeln. Stellen Sie/robots.txtmit den eigenen Regeln der Website bereit, an die dieser Block angehängt ist (und ersetzen Sie den vorherigen Block).
Antwort: {"ok":true,"url":"<öffentliche url>"}.
Fertige Beispiele
Der Dialog Entwicklerhandbuch enthält Copy-Paste-Code:
| Tab | Inhalt |
|---|---|
| Next.js | lib/seoasist.ts (JSON-Dateispeicher und seoRules(pathname), das die spezifischste Regel pro Typ auswählt), app/api/seoasist/[...path]/route.ts (die vier Endpunkte mit HMAC-Verifizierung) und ein Verwendungsbeispiel, das Regeln in generateMetadata anwendet und /llms.txt bereitstellt. |
| PHP | seoasist-api.php: ein .htaccess-Rewrite für /api/seoasist/*, ein data/seoasist.json-Speicher und Signaturprüfungen mit hash_hmac. |
| Test | Ein signierter curl-Befehl für /manifest. |
Der Endpunkt /content in den Beispielen ist ein Platzhalter (TODO); Sie müssen den Beitrag in Ihrem eigenen Blog/CMS speichern und seine reale URL zurückgeben.
Test-Befehl:
TOKEN="<SEOASIST_SITE_TOKEN>"
TS=$(date +%s)
SIG=$(printf "%s." "$TS" | openssl dgst -sha256 -hmac "$TOKEN" | sed 's/^.* //')
curl -s "https://example.com/api/seoasist/manifest" \
-H "Authorization: Bearer $TOKEN" \
-H "X-SEOAsist-Timestamp: $TS" \
-H "X-SEOAsist-Signature: sha256=$SIG"
Apache übermittelt den Authorization-Header möglicherweise nicht an PHP. Fügen Sie in diesem Fall SetEnvIf Authorization "(.*)" HTTP_AUTHORIZATION=$1 zu Ihrer .htaccess hinzu.
Im Panel angezeigte Fehlermeldungen
| Nachricht | Bedeutung |
|---|---|
token rejected | Die Website hat mit 401/403 ohne ein error-Feld im Body geantwortet. |
endpoint not found (is the Site API installed at this URL?) | 404; falsche URL oder die API ist nicht installiert. |
redirect to … (use the final API URL) | Die Website hat eine Weiterleitung zurückgegeben. |
non-JSON response | Die Antwort war kein JSON. |
timeout / unreachable: … | Keine Antwort innerhalb von 25 Sekunden oder die Verbindung ist fehlgeschlagen. |
unexpected manifest (spec "…") | /manifest hat kein gültiges spec zurückgegeben. |
Wenn Ihre Website {"error":"…"} im Body zurückgibt, zeigt das Panel diese Nachricht so wie sie ist an. Lösungsmöglichkeiten finden Sie unter Site-API-Verbindungsprobleme.
Verwandte Artikel
- Verbinden Sie eine eigens erstelle Website mit der SEOAsist Site APIFür Websites, die nicht auf WordPress oder Shopify laufen: Installieren und verbinden Sie die Site API, damit SEO-Korrekturen, Blogbeiträge und llms.txt automatisch serverseitig auf Ihre Website angewendet werden.
- Website-API-Verbindungstest schlägt fehlFinden und beheben Sie die Ursache für „Test fehlgeschlagen“: Token, Signatur, falsche URL, Weiterleitungen, Timeouts oder Apache, das den Authorization-Header verwirft.
- REST API v1: API-Schlüssel, Authentifizierung und EndpunkteSo erstellen Sie einen API-Schlüssel, senden den Authorization-Header, beachten die Anfragen-Limits und nutzen jeden v1-Endpunkt samt Parametern, Response-Envelope und Fehlercodes.