Use casesRecipes

SaaS Helpdesk Agent

Answer tier-1 support questions from your help docs, create and track tickets in your ticketing system, and route complex cases to a human agent.

DifficultyIntermediate
TrackDeveloper Track
ChannelsWeb ChatWhatsApp
IntegrationsHelp docs/FAQ (knowledge base)Ticketing system (API)Escalation email

What you'll build

An agent that deflects tier-1 support tickets by answering questions from your help docs and FAQ knowledge base. For issues it cannot resolve, it creates a ticket in your ticketing system and confirms the ticket number to the user. P1 outages and billing emergencies route directly to a human via escalation email.

Customer journey

A user opens Web Chat in your product or messages WhatsApp support with a how-to question. The agent searches the docs KB, walks through troubleshooting steps, and creates a ticket in your helpdesk when it cannot resolve the issue.

Loading diagram…

See Deploying and testing channels for connect and test steps per channel.

Prerequisites

  • BimpeAI account with an API key (sk_…)
  • Read Anatomy of a workflow agent first — this recipe skips steps covered there
  • Ticketing system connected in the Console dashboard (see Step 4)
  • Web chat widget and WhatsApp Business number connected in the Console dashboard (see Step 4)
  • Escalation email configured under Settings → Agent for P1 issues (see Step 4)

Steps

1. Find or create the workflow

import { BimpeAI } from "@bimpeai/sdk";

const bimpe = new BimpeAI({ apiKey: process.env.BIMPEAI_API_KEY! });

const page = await bimpe.workflows.list({ scope: "public", search: "helpdesk" });
const workflow = page.data[0];
console.log(workflow.id, workflow.name);
import os
from bimpeai import BimpeAI

client = BimpeAI(api_key=os.environ["BIMPEAI_API_KEY"])

page = client.workflows.list(scope="public", search="helpdesk")
workflow = page.data[0]
print(workflow.id, workflow.name)

Or build a new workflow from scratch with workflows.create instead of finding one. name and system_prompt are required; it returns the new Workflow whose id you bind the agent to. See Anatomy of a workflow agent for the full set of optional fields like rules and flows.

const workflow = await bimpe.workflows.create({
  name: "SaaS helpdesk agent",
  system_prompt: "You answer tier-1 support questions from the help docs, raise tickets for issues you cannot resolve, and escalate P1 outages and billing emergencies to a human.",
});
console.log(workflow.id);
workflow = client.workflows.create(
    name="SaaS helpdesk agent",
    system_prompt="You answer tier-1 support questions from the help docs, raise tickets for issues you cannot resolve, and escalate P1 outages and billing emergencies to a human.",
)
print(workflow.id)

2. Create the agent

const agent = await bimpe.agents.create(
  {
    name: "SaaS helpdesk agent",
    description: "First-line SaaS support that answers from help docs, raises tickets, and escalates P1 issues.",
    workflow_id: workflow.id,
  },
  { idempotencyKey: "create-saas-helpdesk-agent-v1" },
);

console.log(agent.id);
agent = client.agents.create(
    name="SaaS helpdesk agent",
    description="First-line SaaS support that answers from help docs, raises tickets, and escalates P1 issues.",
    workflow_id=workflow.id,
    idempotency_key="create-saas-helpdesk-agent-v1",
)

print(agent.id)

3. Add knowledge bases (optional)

Knowledge bases are optional; an agent whose workflow and integrations already cover everything it needs to say can skip this step. This recipe uses one to ground the agent in the details it must quote accurately.

Point a URL knowledge base at your published help docs, then add a text entry for the FAQ and SLA so the agent can answer without fetching live pages on every query.

// Help docs from your published documentation site
await bimpe.agents.knowledgeBases.create(agent.id, {
  type: "url",
  name: "Help docs",
  url: "https://docs.yourproduct.com",
});

// Frequently asked questions
await bimpe.agents.knowledgeBases.create(agent.id, {
  type: "text",
  name: "FAQ",
  content:
    "Q: How do I reset my password?\n" +
    "A: Go to Settings → Security → Change Password. If locked out, use Forgot Password on the login screen.\n\n" +
    "Q: How do I add a team member?\n" +
    "A: Settings → Team → Invite Member. Admin role required.\n\n" +
    "Q: Where can I download my invoices?\n" +
    "A: Settings → Billing → Invoice History.\n\n" +
    "Q: What browsers are supported?\n" +
    "A: Chrome 110+, Firefox 110+, Edge 110+, Safari 16+.",
});

// SLA commitments
await bimpe.agents.knowledgeBases.create(agent.id, {
  type: "text",
  name: "SLA",
  content:
    "P1 (service unusable): first response within 1 hour, 24/7.\n" +
    "P2 (major feature broken): first response within 4 hours, business hours.\n" +
    "P3 (minor issue or question): first response within 1 business day.\n" +
    "P4 (feature request or feedback): acknowledged within 3 business days.",
});
# Help docs from your published documentation site
client.agents.knowledge_bases.create(agent.id, {
    "type": "url",
    "name": "Help docs",
    "url": "https://docs.yourproduct.com",
})

# Frequently asked questions
client.agents.knowledge_bases.create(agent.id, {
    "type": "text",
    "name": "FAQ",
    "content": (
        "Q: How do I reset my password?\n"
        "A: Go to Settings → Security → Change Password. If locked out, use Forgot Password on the login screen.\n\n"
        "Q: How do I add a team member?\n"
        "A: Settings → Team → Invite Member. Admin role required.\n\n"
        "Q: Where can I download my invoices?\n"
        "A: Settings → Billing → Invoice History.\n\n"
        "Q: What browsers are supported?\n"
        "A: Chrome 110+, Firefox 110+, Edge 110+, Safari 16+."
    ),
})

# SLA commitments
client.agents.knowledge_bases.create(agent.id, {
    "type": "text",
    "name": "SLA",
    "content": (
        "P1 (service unusable): first response within 1 hour, 24/7.\n"
        "P2 (major feature broken): first response within 4 hours, business hours.\n"
        "P3 (minor issue or question): first response within 1 business day.\n"
        "P4 (feature request or feedback): acknowledged within 3 business days."
    ),
})

4. Connect channels and integrations (dashboard)

Channels and the ticketing system are connected in the dashboard

The API cannot create channel connections, but integrations can now be configured through it; see Configuring integrations. Connect your messaging channels on the Deploy screen and your ticketing system on the Integrations screen of the Console dashboard. The SDK lists what is active but cannot modify channel connections.

  1. In the Console dashboard, pick your agent from the switcher at the top, then open Deploy.
  2. Under Messaging & Chat, click Connect on the Web Chat Widget card to add the widget to your app.
  3. Under Messaging & Chat, click Connect on the WhatsApp card and follow the prompts to link your WhatsApp Business number for users who contact support via WhatsApp.
  4. Open Integrations, find your ticketing system (e.g. Zendesk, Linear, or Jira Service Management), and click Connect so the agent can raise and track tickets. If it is not in the catalogue, add it under the Custom API tab.
  5. Under Settings → Agent, set the Escalation Email for P1 escalations so emergencies route to a human.

Connect WhatsApp

Customers message your WhatsApp Business number for support and transactions.

  1. Open the Deploy screen in the Console dashboard and select your agent.
  2. Under Messaging & Chat, click Connect on the WhatsApp card.
  3. Follow the prompts to link your WhatsApp Business number.
  4. Once connected, customers can message your business number and the agent replies within WhatsApp's 24-hour session window.

Full reference: Deploying and testing channels.

Connect Web Chat

Visitors use the chat widget embedded on your website or app.

  1. Open Deploy and select your agent.
  2. Under Messaging & Chat, click Connect on the Web Chat Widget card.
  3. Copy the embed snippet and paste it into your site's HTML before the closing body tag.
  4. Publish your site — the chat bubble appears in the corner and routes messages to this agent.

Full reference: Deploying and testing channels.

Also on Instagram and Messenger: the same Deploy → Connect flow applies. Testers use the Deploy panel links or getTestCode deep links for each network. Instagram · Messenger

5. Test your agent

Before going live, exercise the agent on a test channel. Fetch the test code (created on first request), then test on WhatsApp — share the deep link or start message with a human tester, or inject a message from your server.

Test WhatsApp

Human tester: fetch the test code with agents.getTestCode (or use the Deploy panel). Share the deep link or start <code> message with a tester.

SDK injection: call conversations.send with is_test_channel: true and the matching channel_type.

Full reference: Deploying and testing channels.

Test Web Chat

Playground: open Playground → Chat in the dashboard for a quick sanity check.

SDK injection: call conversations.send with channel_type: "webchat" and a stable channel_user_id, or set is_test_channel: true before go-live.

Full reference: Deploying and testing channels.

const { channels } = await bimpe.agents.getTestCode(agent.id);
// A tester opens channels.whatsapp.url, or sends channels.whatsapp.start_message
// to channels.whatsapp.phone_number, to open a 24-hour test window.
console.log(channels.whatsapp.start_message, channels.whatsapp.url);

// Or inject a test message yourself:
await bimpe.conversations.send(agent.id, {
  message: "How do I reset my password? I'm locked out of my account.",
  channel_type: "whatsapp",
  channel_user_id: "<tester-whatsapp-number>",
  is_test_channel: true,
});
test_code = client.agents.get_test_code(agent.id)
# A tester opens .url, or sends .start_message to .phone_number, to open a 24-hour window.
print(test_code.channels.whatsapp.start_message, test_code.channels.whatsapp.url)

# Or inject a test message yourself:
client.conversations.send(
    agent.id,
    message="How do I reset my password? I'm locked out of my account.",
    channel_type="whatsapp",
    channel_user_id="<tester-whatsapp-number>",
    is_test_channel=True,
)

See Test your agent for the other test channels and the pause-AI rule.

6. Go live

const integrations = await bimpe.agents.integrations.list(agent.id);
const channels = await bimpe.agents.channels.list(agent.id);
console.log("Integrations:", integrations.map((i) => i.name));
console.log("Channels:", channels.map((c) => c.type));
integrations = client.agents.integrations.list(agent.id)
channels = client.agents.channels.list(agent.id)
print("Integrations:", [i.name for i in integrations])
print("Channels:", [c.type for c in channels])

Full example

import { BimpeAI } from "@bimpeai/sdk";

const bimpe = new BimpeAI({ apiKey: process.env.BIMPEAI_API_KEY! });

// 1. Find workflow
const page = await bimpe.workflows.list({ scope: "public", search: "helpdesk" });
const workflow = page.data[0];

// 2. Create agent
const agent = await bimpe.agents.create(
  {
    name: "SaaS helpdesk agent",
    description: "First-line SaaS support that answers from help docs, raises tickets, and escalates P1 issues.",
    workflow_id: workflow.id,
  },
  { idempotencyKey: "create-saas-helpdesk-agent-v1" },
);

// 3. Add knowledge bases
await bimpe.agents.knowledgeBases.create(agent.id, {
  type: "url",
  name: "Help docs",
  url: "https://docs.yourproduct.com",
});

await bimpe.agents.knowledgeBases.create(agent.id, {
  type: "text",
  name: "FAQ",
  content:
    "Reset password: Settings → Security → Change Password.\n" +
    "Add team member: Settings → Team → Invite Member (admin required).\n" +
    "Download invoices: Settings → Billing → Invoice History.",
});

await bimpe.agents.knowledgeBases.create(agent.id, {
  type: "text",
  name: "SLA",
  content:
    "P1: 1 hour response, 24/7. P2: 4 hours, business hours. P3: 1 business day. P4: 3 business days.",
});

// 4. Verify channels and integrations (configured via dashboard)
const integrations = await bimpe.agents.integrations.list(agent.id);
const channels = await bimpe.agents.channels.list(agent.id);
console.log("Agent ID:", agent.id);
console.log("Integrations:", integrations.map((i) => i.name));
console.log("Channels:", channels.map((c) => c.type));

// 5. Stream web chat conversations
const controller = new AbortController();
const conversations = await bimpe.conversations.list(agent.id, { channel: "webchat" });
const conv = conversations.data[0];

if (conv) {
  for await (const event of bimpe.conversations.messages.stream(agent.id, conv.id, {
    signal: controller.signal,
  })) {
    console.log(event.role, event.message);
  }
}
import os
from bimpeai import BimpeAI

client = BimpeAI(api_key=os.environ["BIMPEAI_API_KEY"])

# 1. Find workflow
page = client.workflows.list(scope="public", search="helpdesk")
workflow = page.data[0]

# 2. Create agent
agent = client.agents.create(
    name="SaaS helpdesk agent",
    description="First-line SaaS support that answers from help docs, raises tickets, and escalates P1 issues.",
    workflow_id=workflow.id,
    idempotency_key="create-saas-helpdesk-agent-v1",
)

# 3. Add knowledge bases
client.agents.knowledge_bases.create(agent.id, {
    "type": "url",
    "name": "Help docs",
    "url": "https://docs.yourproduct.com",
})

client.agents.knowledge_bases.create(agent.id, {
    "type": "text",
    "name": "FAQ",
    "content": (
        "Reset password: Settings → Security → Change Password.\n"
        "Add team member: Settings → Team → Invite Member (admin required).\n"
        "Download invoices: Settings → Billing → Invoice History."
    ),
})

client.agents.knowledge_bases.create(agent.id, {
    "type": "text",
    "name": "SLA",
    "content": "P1: 1 hour response, 24/7. P2: 4 hours, business hours. P3: 1 business day. P4: 3 business days.",
})

# 4. Verify channels and integrations (configured via dashboard)
integrations = client.agents.integrations.list(agent.id)
channels = client.agents.channels.list(agent.id)
print("Agent ID:", agent.id)
print("Integrations:", [i.name for i in integrations])
print("Channels:", [c.type for c in channels])

# 5. Stream web chat conversations
conversations = client.conversations.list(agent.id, channel="webchat")
if conversations.data:
    conv = conversations.data[0]
    for msg in client.conversations.messages.stream(agent.id, conv.id):
        print(msg.role, msg.message)

Deploy and go live

Go-live checklist

  • Store your API key in BIMPEAI_API_KEY (server-side only).
  • Confirm Ticketing system appears in integrations.list or is connected in the dashboard.
  • Confirm Documentation/knowledge base appears in integrations.list or is connected in the dashboard.
  • Verify Web Chat is connected on the Deploy screen (agents.channels.list shows it enabled).
  • Verify WhatsApp is connected on the Deploy screen (agents.channels.list shows it enabled).
  • Set Escalation Email under Settings → Agent if humans must take over.
  • Switch the agent to live with updateLiveStatus / update_live_status.
  • Monitor the Conversations screen (or stream via SDK) after launch.
  • Set Escalation Email for P1 escalations under Settings → Agent.

After go-live

Refresh URL knowledge base via knowledgeBases.update when you publish major doc changes.

Variations

  • Configure rules on the workflow (CreateWorkflowBody.rules / RuleInput) that hard-route any message containing "data breach" or "gdpr" to escalation regardless of conversation context.
  • Extend the FAQ knowledge base with release notes so the agent can answer "what changed in the last update" without a ticket.
  • Use conversations.messages.list after each resolved conversation to calculate deflection rate by comparing conversations with and without a ticket created.

On this page