← Writing

An AI support chatbot on WordPress for about $0

How I built a knowledge-base-grounded support assistant into a WordPress marketing site using OpenRouter's free models — including intent classification, prompt-extraction guardrails, cost tracking, and the feedback loop that makes the KB smarter over time.

On this page

The marketing site for a bootstrapped SaaS gets a steady trickle of pre-sales questions — the same twenty questions, mostly, with occasional genuinely new ones. A support chatbot is the obvious answer, and the SaaS chatbot market would like $50–200/month for one. This is how I built the same thing into the existing WordPress site for approximately $0/month, and — more interestingly — how the bot became a machine for improving its own knowledge base.

The architecture

Five pieces, all living inside WordPress and one external API:

  1. A knowledge base stored in the WordPress database — question/answer-style entries covering the product, pricing, and policies. Editable from wp-admin through a purpose-built KB editor with debounced search, because the KB only stays good if editing it is frictionless.
  2. A chat widget on the site that posts to a WordPress endpoint — no third-party JS, no external chat service.
  3. An OpenRouter integration using free-tier models. The server-side handler retrieves relevant KB entries, builds a grounded prompt, and streams the answer back.
  4. Conversation capture: every chat is stored — visitor name and email when offered, messages, and metadata — browsable in wp-admin. A support chatbot that doesn’t feed your lead list is leaving half its value on the table.
  5. Per-message cost tracking, read from OpenRouter’s usage data in each response and stored alongside the message. Even at $0 you want the meter running — the day you move to paid models, you already know your unit economics.

Grounding: the KB is the product

The single most important design decision: the model answers from retrieved KB entries, not from its own knowledge. The prompt instructs it to answer using the provided entries and to say when it doesn’t know, rather than improvising about pricing or features.

This matters doubly on free-tier models. You don’t control which model OpenRouter’s free pool serves you week to week, and smaller models hallucinate more confidently. Grounding shrinks the surface: the model’s job collapses from “know things” to “read these entries and compose a helpful answer,” which weak models do respectably.

Intent classification: not every visitor is a customer

Public AI endpoints attract three kinds of traffic: genuine prospects, the curious, and people actively probing — trying to extract the prompt, jailbreak the bot, or use your API budget as their free LLM.

So before answering, a lightweight classification step sorts the message: genuine product question, off-topic, or probing/abusive. Genuine questions get the full grounded pipeline. Off-topic and probing messages get a short canned redirect — no model round-trip spent engaging with them, no interesting output to reward the attempt.

Two honest notes on the guardrails:

  • Assume the prompt will leak eventually. The guardrail’s real job isn’t secrecy, it’s making extraction boring. Never put anything in a system prompt you’d mind seeing on a screenshot.
  • The logs are the real defense. Because every conversation is captured, probing attempts are visible in wp-admin. You learn what people try, and you tune the classifier against reality instead of imagination.

The feedback loop: unanswered questions become KB gaps

This is the feature I’d keep if I had to delete everything else.

When the bot can’t answer from the KB, that’s not a failure to hide — it’s a logged KB gap: the question gets recorded in a review queue. Working that queue is a ten-minute weekly ritual — write the missing entry, and the bot answers it correctly forever after.

The loop changes what the chatbot is. A static bot decays as the product changes. This one converts every stumped conversation into a work item, so the KB tracks what real visitors actually ask — which turned out to differ meaningfully from what I assumed they’d ask. After a few weeks, the gap queue is also a free market-research artifact: it’s a ranked list of what your marketing pages fail to explain.

Costs, honestly

  • Model calls: $0 on OpenRouter’s free tier at marketing-site volume. Per-message cost tracking confirmed the arithmetic rather than assuming it.
  • The real costs: the build time, and the weekly KB-gap review. The second one is a cost you should want — it’s the maintenance that keeps answer quality from rotting.
  • The risks: free-tier rate limits under a traffic spike, and model churn changing answer tone. Both acceptable for pre-sales chat on a marketing site. I would not run a paying-customer support surface this way without a paid-model fallback behind the same interface.

What I’d tell you to steal

If you build one of these, the transferable parts aren’t the WordPress specifics — they’re the four disciplines: ground every answer in a KB you control; classify intent before spending model calls; capture every conversation; and log every unanswerable question as a work item. The first three keep the bot safe and cheap. The fourth is what makes it get better every week — and it’s the part every off-the-shelf chatbot I evaluated treated as an afterthought.

← All writing Book a call →
Book a call → WhatsApp