Files
Skrift-Auto-Article/docs/feldnachweis.md

8.3 KiB

Feldnachweis: live ermittelte Feldnamen

Alle Angaben stammen aus echten API-Antworten vom 20.09.2026, nicht aus Dokumentation. Rohbelege liegen als docs/beleg-*.json daneben.


1. NeuronWriter

Basis-URL https://app.neuronwriter.com/neuron-api/0.5/writer, Header X-API-KEY.

1.1 POST /list-projects

Aufruf mit leerem Body {}.

[
  {"id":"3da4d745e0e223cb","project":"3da4d745e0e223cb","name":"skrift.de","language":"German","engine":"google.de"}
]

Verwendet: project = 3da4d745e0e223cb. Anmerkung: id und project sind wertgleich, die Doku nennt nur project.

1.2 POST /new-query

Request: {"project":"...","keyword":"...","engine":"google.de","language":"German"}

Antwort (Beleg: beleg-01-new-query.json):

{
  "query": "565abcca58f65e52",
  "query_url": "https://app.neuronwriter.com/analysis/view/565abcca58f65e52",
  "share_url": "https://app.neuronwriter.com/analysis/share/565abcca58f65e52/d8418...",
  "readonly_url": "https://app.neuronwriter.com/analysis/content-preview/565abcca58f65e52/060df..."
}

Abweichung vom Auftrag: Das Feld heisst query, nicht query_id. Es ist gleichzeitig Request-Parameter aller Folgeaufrufe.

1.3 POST /get-query

Request: {"query":"565abcca58f65e52"}

Statuswerte real beobachtet: in progress -> ready. Die Analyse war nach 7 Polls a 20 Sekunden fertig, also nach rund 2 Minuten. Das konfigurierte Limit von 30 Versuchen entspricht 10 Minuten und ist reichlich.

Top-Level-Schluessel der fertigen Antwort (42 KB):

ideas, competitors, metrics, terms, terms_txt, status, keyword,
language, engine, project, query, serp_summary, query_url, share_url, readonly_url

Mapping auf die im Auftrag geforderten Felder

Auftrag Tatsaechlicher Pfad Struktur
query_id query String
keyword keyword String
begriffe_pflicht terms.content_basic [{t, usage_pc, sugg_usage:[min,max]}]
begriffe_erweitert terms.content_extended [{t, usage_pc, sugg_usage:[min,max]}]
fragen ideas.topic_matrix (Objekt!) + ideas.people_also_ask + ideas.content_questions + ideas.suggest_questions siehe unten
wortzahl_ziel metrics.word_count.target Integer (hier 1178)

Details, die man nicht raten kann

terms enthaelt genau diese Schluessel: title, desc, h1, h2, content_basic, content_extended, entities. Es gibt kein terms.content. Die Doku suggeriert das.

Beispiel-Eintraege:

terms.content_basic[0]    = {"t":"handschriftlich","usage_pc":70,"sugg_usage":[1,17]}
terms.content_extended[0] = {"t":"handgeschriebene briefe","usage_pc":40,"sugg_usage":[1,5]}
terms.h2[0]               = {"t":"handschriftlich","usage_pc":50}     // kein sugg_usage
terms.entities[0]         = {"t":"Brief","importance":33.89,"relevance":0.53,
                             "confidence":1.70,"links":[["wikipedia","http://de.wikipedia.org/wiki/Brief"]]}

sugg_usage ist ein Array [min, max], keine Zahl. usage_pc ist der Anteil der Wettbewerber, die den Begriff nutzen, keine Empfehlung.

terms_txt spiegelt dasselbe als Fliesstext. Schluesselnamen sind hier nicht identisch: title, desc_title (nicht desc), h1, h2, content_basic, content_basic_w_ranges, content_extended, content_extended_w_ranges, entities. Die _w_ranges-Varianten enthalten die Nutzungsspanne direkt im Text (handschriftlich: 1-17x) und sind als Schreibvorlage am brauchbarsten.

ideas hat vier Schluessel, die sich strukturell unterscheiden:

ideas.suggest_questions = []                       // war im Test LEER
ideas.people_also_ask   = [{"q":"..."}]            // 4 Eintraege
ideas.content_questions = [{"q":"..."}]            // 28 Eintraege
ideas.topic_matrix      = {"Frage als Schluessel": {"importance": 10}}   // OBJEKT, 10 Eintraege

topic_matrix ist kein Array. Die Frage steht im Schluessel, die Gewichtung im Wert. In der Doku taucht topic_matrix gar nicht auf, obwohl es die wertvollste Quelle ist: die Fragen sind bereits nach Wichtigkeit 1 bis 10 gewichtet. Der Workflow sortiert danach und dedupliziert gegen die anderen drei Quellen.

metrics hat nur word_count und readability, beide mit median und target. Im Test waren median und target identisch (1178 bzw. 29).

competitors liefert 31 Eintraege mit rank, url, title, desc, headers, content_score, readability, word_count, content_len. headers ist ein Array von Zweier-Arrays: ["h2","Text der Ueberschrift"]. Der Workflow uebernimmt die Gliederungen der Top 5 in den Brief.

serp_summary ist in der Doku nicht erwaehnt und enthaelt top_intent (hier informational), intent_stats, top_content_type (hier video) und content_type_stats in Prozent.

1.4 POST /evaluate-content und /import-content

Request laut Doku: query plus html (nicht content_html), optional title, description. Antwort: {"status":"ok","content_score":<number>}. Wird in Workflow 2 live gegengeprueft.


2. n8n

  • Version 1.120.4, ermittelt ueber GET /rest/settings -> data.versionCli
  • Public API unter /api/v1 mit Header X-N8N-API-KEY funktioniert
  • /rest/node-types und /types/nodes.json sind nicht ohne Session-Login erreichbar

Verwendete Node-Versionen, verifiziert durch einen importierten und erfolgreich ausgefuehrten Testworkflow:

Node typeVersion
n8n-nodes-base.manualTrigger 1
n8n-nodes-base.scheduleTrigger 1.2
n8n-nodes-base.webhook 2.1
n8n-nodes-base.set 3.4
n8n-nodes-base.code 2
n8n-nodes-base.if 2.2
n8n-nodes-base.httpRequest 4.3
n8n-nodes-base.splitInBatches 3
n8n-nodes-base.wait 1.1
n8n-nodes-base.noOp 1
n8n-nodes-base.emailSend 2.1

Bei splitInBatches v3 ist Ausgang 0 = done und Ausgang 1 = loop. Vertauschen fuehrt zu einem Workflow, der genau einmal laeuft und dann still endet.

Gelernt beim Testlauf: Ein Webhook mit responseMode: "lastNode" haelt die HTTP-Verbindung bis zum Workflow-Ende offen. Bei Poll-Schleifen laeuft der Reverse Proxy (openresty) nach 60 Sekunden in ein 504, obwohl der Workflow weiterlaeuft. Beide Workflows nutzen deshalb responseMode: "onReceived".


3. WordPress (skrift.de)

Benutzer ai-agent, Rolle editor, Authentifizierung per Application Password. Geprueft ueber GET /wp-json/wp/v2/users/me?context=edit.

3.1 Registrierte Meta-Felder

Ermittelt ueber OPTIONS /wp-json/wp/v2/posts, Pfad endpoints[].args.meta.properties. 43 Schluessel registriert.

Vorhanden und direkt ueber meta beschreibbar:

_seopress_titles_title        (string)
_seopress_titles_desc         (string)
_seopress_analysis_target_kw  (string)
_seopress_robots_index        (string)
_seopress_social_fb_title     (string)
... sowie 38 weitere _seopress_* und _elementor_* Schluessel

Nicht vorhanden: kurzantwort, faq, cta_ziel, stand_datum.

3.2 JetEngine ist auf skrift.de nicht installiert

GET /wp-json/ liefert diese Namespaces:

oembed/1.0, skrift/v1, elementor-one/v1, maspik/v1, elementor/v1,
elementor-pro/v1, seopress/v1, llar/v1, elementor-hello-elementor/v1,
jet-form-builder/v1, elementor/v1/documents, elementor-ai/v1,
elementor/v1/feedback, wp/v2, wp-site-health/v1, wp-block-editor/v1, wp-abilities/v1

jet-form-builder/v1 ist JetFormBuilder, ein anderes Plugin. Es gibt keinen JetEngine-Namespace und GET /wp-json/wp/v2/types zeigt keine JetEngine-CPTs. Die im Auftrag genannten JetEngine-Felder existieren also nicht.

3.3 Cache-Endpunkt

Das Skrift-Plugin registriert nur GET /skrift/v1/preis, also keinen Cache-Purge. WP Rocket ist nicht als Namespace sichtbar.

Nutzbar ist stattdessen ein echter, vorhandener Endpunkt:

POST /wp-json/seopress/v1/commands/clear-cache

3.4 Ausgangslage Inhalte

GET /wp-json/wp/v2/posts?status=any liefert 0 Beitraege. GET /wp-json/wp/v2/categories liefert nur uncategorized (ID 1). Workflow 2 muss Kategorien also anlegen koennen, nicht nur zuordnen.


4. Gitea

Version 1.25.4, Repo lucas.orth/Skrift-Auto-Article, Default-Branch main, leer.

Der hinterlegte Token hat die Scopes read:issue, read:repository. Schreibende Aufrufe scheitern mit:

{"message":"token does not have at least one of required scope(s),
  required=[write:repository], token scope=read:issue,read:repository"}

Benoetigt wird write:repository.