Skip to content

Provider Your Own API

github-actions[bot] edited this page Oct 6, 2026 · 1 revision

Provider: your own API

"backend": { "type": "http" }

Put HelpPuff's widget, dashboard, leads and webhooks in front of anything you have built: your own agent, a LangChain or LlamaIndex app, a local model, a gateway. Nothing about your stack goes into HelpPuff, and you need no fork.

Two shapes, chosen with mode.

mode: "openai": any Chat Completions endpoint

vLLM, Ollama, LiteLLM, OpenRouter, DeepSeek, Together, or your own OpenAI-compatible server. HelpPuff keeps the conversation history (from its record of the conversation in D1, or KV without a database) and sends prompt.md as the system message.

"backend": {
  "type": "http",
  "mode": "openai",
  "url": "https://llm.acme.com/v1",
  "model": "llama-3.3-70b",
  "token": { "env": "HELPPUFF_BACKEND_TOKEN" }
}

mode: "helppuff": your service owns everything

Your service decides what to say; HelpPuff carries the messages. It POSTs:

POST {url}/start    { siteId, sessionId, lead?, context, firstMessage? }
POST {url}/message  { siteId, sessionId, state, input }
  • context is the page the visitor is on: { pageUrl, pageTitle?, referrer?, utm?, locale? }.
  • lead is the pre-chat form's answers, when there is one.
  • input is what the visitor did: { kind: "text", text }, or { kind: "action", actionId, value, label } for a button or form.
  • state is whatever you returned last time (below).

Answer with JSON:

{ "text": "Yes, we service Lilydale. Want a quote?" }

or, for rich messages and state:

{
  "messages": [
    { "type": "text", "text": "Yes, we service Lilydale." },
    { "type": "options", "options": [{ "id": "q", "label": "Get a quote", "value": "I'd like a quote" }] }
  ],
  "state": { "conversation": "c-9" }
}

Messages use the protocol's message shapes (id, ts and role may be left out). Or stream the reply as server-sent events:

event: delta   data: {"text":"Yes, we "}
event: delta   data: {"text":"service Lilydale."}
event: done    data: {"text":"Yes, we service Lilydale.","state":{"conversation":"c-9"}}

state comes back to you with the next message. It rides inside the signed session token, so keep it small (under 1 KB): an id into your own storage, not the conversation.

Authentication

  • token: sent as Authorization: Bearer …. Store it with helppuff secret set HELPPUFF_BACKEND_TOKEN.
  • signingSecret: every request also carries X-HelpPuff-Timestamp and X-HelpPuff-Signature: sha256=<hex HMAC-SHA256 of "<timestamp>.<body>">, so your service can check the call came from your Worker.
"backend": {
  "type": "http",
  "mode": "helppuff",
  "url": "https://agent.acme.com/helppuff",
  "token": { "env": "HELPPUFF_BACKEND_TOKEN" },
  "signingSecret": { "env": "HELPPUFF_BACKEND_SECRET" }
}

Set up

npx @knowtific/helppuff init --url acme.com --backend http --http-url https://agent.acme.com/helppuff --http-mode helppuff --http-token "$TOKEN"

Your API must answer within 25 seconds. Errors and timeouts become a polite "something went wrong" for the visitor; the details are only in the Worker's logs.

For more ways to build on HelpPuff, see Extending.

Clone this wiki locally