Internal Linker — API Dashboard

17 posts in corpus · /health · corpus admin · review queue
needed for admin 🔒 endpoints; public endpoints ignore it

Liveness

GET /health public
Is the service alive? How big is the corpus?
Liveness probe. Returns status ok + current corpus size. The fastest way to confirm the service is up and the data file loaded. No auth.
curl
copied

Corpus

GET /corpus public
List all posts in the corpus (id, url, title, PK).
Read-only inventory of the linkable corpus. Each entry shows id, url, title, primaryKeyword, status, publishedAt. Use this to spot-check what targets are available for linking. No auth.
curl
copied
GET /corpus/admin public
Corpus health dashboard (HTML).
HTML table flagging data-quality issues: multi-keyword PKs (comma blobs), posts with no aliases, non-slug ids. The quickest way to find ingested garbage that will produce bad links. No auth.
POST /corpus/verify 🔒 admin
Probe every corpus URL; classify live / dead / ambiguous.
Concurrently HEAD-probes each corpus URL and classifies it. dead = 404/410/DNS-failure (confident broken); ambiguous = 403/5xx/timeout (could be a WAF false positive — human review). Use this monthly to catch drift after WP deletes. Admin-gated. No auto-prune — you decide what to DELETE.
curl
copied
POST /ingest 🔒 admin
Add a post to the corpus (so future articles can link to it).
Called by n8n after WordPress publish. id = stable slug, primaryKeyword = anchor phrase, aliases = extra anchor candidates, headings = H2/H3 text (relevance signal + alias source). Upsert semantics — same id replaces. Admin-gated.
curl
copied
PATCH /corpus/ai-virtual-assistants-transforming-business-operations-cx 🔒 admin
Edit a post's PK, aliases, title, etc. (fix bad data in place).
Partial update. Only the fields you provide are touched; the rest are preserved. Use this to evergreen a year-bearing PK, enrich aliases, or fix a typo without a delete+reingest. Re-indexes and re-persists. Admin-gated.
curl
copied
DELETE /corpus/ai-virtual-assistants-transforming-business-operations-cx 🔒 admin
Remove a post from the corpus (evicts dead-link targets).
Hard delete from corpus + inverted index + persisted file. Use after /corpus/verify flags a post as dead. Safe — the engine will no longer suggest links to it. Admin-gated.
curl
copied
GET /phrases public
All linkable phrases (the n8n writer-prompt feed).
Returns primaryKeywords[] (clean array — feed to the writing agent so it weaves them in) and phrases[] (every indexed phrase + its target, for debugging or richer prompt context). This is what the n8n Format Link Index node calls. No auth.
curl
copied
POST /embeddings/rebuild 🔒 admin
Re-embed the whole corpus (M004 — only if embeddings enabled).
Regenerates embeddings for every post. Call after batch-adding posts without embeddings, or after changing the embedding model. Errors if no embedding provider is configured (the service runs pure deterministic). Admin-gated.
curl
copied

Linking

POST /suggest public
Ranked link suggestions for an article (no insertion).
The core engine call. Given finished article markdown + sourceId, returns ranked suggestions with anchorText, targetUrl, position, score, scoreBreakdown, matchType. No mutation — safe to call as many times as you want. No auth (read-only).
curl
copied
POST /apply 🔒 admin
Insert internal links into article markdown (returns rewritten markdown).
Suggests + applies in one call. Returns rewritten markdown with links inserted (respecting all guardrails: skip first 100 words, no links in H1/code, max 5/article, one per target) and an audit entry per insert written to /data/audit.jsonl. This is what the n8n Apply Internal Links node calls after the Final Edit Agent. Admin-gated (it's a write).
curl
copied

Review

POST /review/queue 🔒 admin
Queue suggestions for human review (called by n8n).
Stores a batch of suggestions for the approval UI. The review dashboard at GET /review then surfaces them for one-click accept/reject. If a target was previously rejected for this source, it's filtered out automatically. Admin-gated.
curl
copied
GET /review 🔒 admin
Approval dashboard (HTML).
Lists pending review batches with accept/reject buttons. Open this in a new tab — it's a full page, not an API call. Admin-gated: requires the admin secret via a cookie/query-param handshake (also true of /review/stats, /review/:batchId, and /review/:batchId/result). The "Open" button above handles this automatically — it forwards the secret already saved in sessionStorage as ?secret= so you don't have to log in again.

Config

GET /config public
Current guardrail config (cap, intro-skip, anchor rules).
Returns the live config: maxLinksPerArticle, introSkipWords, minAnchorChars, maxAnchorWords, blocklist. Use this to verify what rules /suggest and /apply are enforcing right now. No auth.
curl
copied
POST /config 🔒 admin
Tune guardrails without redeploying.
Partial update (deep merge). Override any of maxLinksPerArticle, introSkipWords, minAnchorChars, maxAnchorWords, blocklist, and weights (matchType.primary_keyword/alias/title, position, length, recency, headingCoOccurrence, semantic) — only the fields you send change, everything else is left as-is. Persists to disk (atomic write) and survives a restart/redeploy. Admin-gated.
curl
copied