Skip to content
HelpBot
v1.0.0TypeScriptNode.js SDK

SDK Reference

A fully-typed Node.js client for the HelpBot API. Authenticate with your API key (starts with wk_) and use async/await for every call.

npm package
Install
bun add @saastemly/helpbot-sdk
Quick start
import { HelpBot } from "@saastemly/helpbot-sdk";

const helpbot = new HelpBot({
  apiKey: process.env.HELPBOT_API_KEY!,
});

const { answer, sources } = await helpbot.chat("How do I get started?");

Chat

Send questions, receive AI answers, submit feedback, and escalate to humans.

Ask a question

Send a visitor's question and receive an AI-generated answer with source references.

const response = await helpbot.chat("How do I get started?");

console.log(response.answer);
console.log(response.sources);       // URLs used to generate the answer
console.log(response.conversationId); // use for feedback / handoff

Response

{
  "answer": "To get started, add our widget snippet to your site...",
  "sources": ["https://docs.example.com/getting-started"],
  "conversationId": "conv_abc123"
}

Ask with session & language

Group conversations by session ID and request answers in a specific language.

const response = await helpbot.chat("¿Cómo empiezo?", {
  sessionId: "session_xyz",
  language: "es",
});

Submit feedback

Let visitors rate an answer as helpful or not helpful.

const result = await helpbot.feedback(conversationId, "yes");
// result.success === true

Escalate to human

Request human agent escalation for a conversation, optionally with an email.

const result = await helpbot.handoff(conversationId, {
  customerEmail: "visitor@example.com",
});

Sources

Manage FAQ sources programmatically (Scale plan required).

List FAQ sources

Retrieve all FAQ source URLs with their scraping status and document count.

const { sources } = await helpbot.sources.list();

for (const source of sources) {
  console.log(source.url, source.status, source.documentCount);
}

Response

{
  "sources": [
    {
      "id": "src_1",
      "url": "https://example.com/faq",
      "status": "indexed",
      "documentCount": 42,
      "lastScrapedAt": "2024-01-15T10:30:00.000Z",
      "createdAt": "2024-01-10T08:00:00.000Z"
    }
  ]
}

Add a source

Submit a new FAQ URL for scraping. Scraping begins automatically.

const { source, message } = await helpbot.sources.add(
  "https://example.com/help"
);
console.log(source.id, source.status); // "pending"

Remove a source

Delete a FAQ source and its indexed documents.

const { deleted } = await helpbot.sources.remove("src_1");

Re-scrape a source

Trigger a fresh scrape of an existing source to pick up content changes.

const result = await helpbot.sources.rescrape("src_1");
console.log(result.status); // "scraping"

Widget

Retrieve widget display configuration (colors, labels, position).

Get widget config

Retrieve the full widget configuration: colors, position, labels, and language.

const config = await helpbot.config.get();

console.log(config.botName);
console.log(config.primaryColor);
console.log(config.position); // "bottom-right" | "bottom-left"

Response

{
  "botName": "HelpBot",
  "primaryColor": "#6366f1",
  "primaryForeground": "#ffffff",
  "backgroundColor": "#ffffff",
  "foregroundColor": "#1f2937",
  "position": "bottom-right",
  "greeting": "Hi! How can I help?",
  "showBranding": true,
  ...
}

Update widget config

Partially update widget configuration fields. Only send the fields you want to change.

const { updated, config } = await helpbot.config.update({
  botName: "Support Bot",
  primaryColor: "#2563eb",
  greeting: "Hello! Ask me anything.",
});
console.log(updated); // ["botName", "primaryColor", "greeting"]

Analytics

Usage statistics, daily activity, and unanswered question insights (Growth or Scale plan required).

Get analytics overview

Retrieve aggregate metrics: total questions, satisfaction rate, handoffs, and credit usage.

const stats = await helpbot.analytics.overview({ range: "30d" });

console.log(stats.totalQuestions);
console.log(stats.satisfactionRate);
console.log(stats.credits.used, "/", stats.credits.limit);

Response

{
  "range": "30d",
  "totalQuestions": 1284,
  "satisfactionRate": 0.87,
  "helpfulCount": 892,
  "totalFeedback": 1025,
  "handoffCount": 34,
  "handoffRate": 0.026,
  "weekOverWeekChange": 0.12,
  "credits": { "used": 1284, "limit": 5000 }
}

Get daily activity

Retrieve per-day question counts for charting trends over time.

const { activity } = await helpbot.analytics.activity({ range: "7d" });

for (const day of activity) {
  console.log(day.date, day.count);
}

List conversations

Search and filter past conversations with pagination support.

const { conversations, totalPages } = await helpbot.analytics.conversations({
  limit: 20,
  filter: "unanswered",
  sort: "-createdAt",
});

for (const convo of conversations) {
  console.log(convo.question, convo.wasHelpful);
}

Webhooks

Register callback URLs to receive real-time event notifications (Growth or Scale plan required).

Create a webhook

Register a callback URL to receive real-time event notifications.

const { webhook } = await helpbot.webhooks.create({
  url: "https://example.com/webhooks/helpbot",
  events: ["conversation.created", "conversation.feedback"],
  description: "Production webhook",
});

// Save webhook.secret securely — shown only once
console.log(webhook.secret);

List webhooks

Retrieve all registered webhooks. Secrets are redacted.

const { webhooks } = await helpbot.webhooks.list();

for (const wh of webhooks) {
  console.log(wh.url, wh.events, wh.secretHint);
}

Delete a webhook

Remove a webhook subscription by ID.

const { deleted } = await helpbot.webhooks.delete("wh_abc123");

Verify webhook signature

Use the built-in verifyWebhook utility to validate incoming webhook deliveries.

import { verifyWebhook } from "@saastemly/helpbot-sdk";

const rawBody = await request.text();
const signature = request.headers.get("x-helpbot-signature")!;

const isValid = verifyWebhook(rawBody, signature, WEBHOOK_SECRET);

if (!isValid) {
  return new Response("Invalid signature", { status: 401 });
}

const payload = JSON.parse(rawBody);
console.log(payload.event, payload.data);

Delivery format

Every webhook delivery is an HTTP POST with a JSON body and the following headers:

Content-TypeAlways application/json.
X-HelpBot-SignatureHMAC-SHA256 hex digest prefixed with sha256=.
X-HelpBot-EventThe event type, e.g. conversation.created.
X-HelpBot-DeliveryUnique UUID for this delivery (for idempotency).

Envelope

The JSON body wraps every event in a consistent envelope:

payload.json
{
  "event": "conversation.created",
  "timestamp": "2024-01-15T10:30:00.000Z",
  "data": { ... }
}

Verifying signatures

verify.ts
import { verifyWebhook } from "@saastemly/helpbot-sdk";

const rawBody = await request.text();
const signature = request.headers.get("x-helpbot-signature")!;

const isValid = verifyWebhook(rawBody, signature, WEBHOOK_SECRET);

if (!isValid) {
  return new Response("Invalid signature", { status: 401 });
}

const payload = JSON.parse(rawBody);
console.log(payload.event, payload.data);

Event payloads

The data field contains event-specific fields described below.

conversation.created

Fired when a visitor asks a question and receives an AI answer.

conversationIdstring
sessionIdstring
questionstring
answerstring
sourcesstring[]
conversation.unanswered

Fired alongside conversation.created when the AI could not find a relevant answer.

conversationIdstring
sessionIdstring
questionstring
answerstring
sourcesstring[]
conversation.feedback

Fired when a visitor rates an answer as helpful or not helpful.

conversationIdstring
helpful"yes" | "no"
conversation.handoff

Fired when a conversation is escalated to a human agent.

conversationIdstring
questionstring
answerstring
customerEmailstring | null