AI Agent

Creating Actions

Step-by-step guide to building custom actions for your Chatsby AI agent — from trigger definition to webhook implementation, testing, and monitoring.

Creating Custom Actions

Custom actions let your AI agent interact with external systems during live conversations. This guide covers everything you need to build, test, and deploy a custom action — from defining triggers to writing webhook handlers and debugging in the Playground.

Prerequisites

Before you begin, make sure you have the following ready:

  • A Chatsby account on a paid plan (Pro, Business, or Enterprise). Custom actions are not available on the Free plan.
  • An HTTP endpoint that can receive POST requests and return JSON responses. This can be a serverless function (AWS Lambda, Vercel, Cloudflare Workers), a dedicated server, or any platform that exposes an HTTPS URL.
  • Basic understanding of webhooks. When your action triggers, Chatsby sends a POST request to your URL with the collected parameters. Your endpoint processes the request and returns a response that the agent delivers to the user.
  • Authentication credentials (if your endpoint is protected). Chatsby supports Bearer tokens and custom headers.

If you do not have a backend ready, you can use services like Pipedream or Make to create a webhook endpoint without writing code. For testing, webhook.site lets you inspect incoming requests.

Step-by-Step Creation Guide

Navigate to the Actions Panel

From your agent's dashboard, click the Actions tab in the left sidebar. You will see your existing actions (including built-in ones) listed here.

Click Create Action in the top-right corner to open the action builder.

Name Your Action

Give your action a clear, descriptive name. This name is internal only — users will never see it. It appears in your dashboard and analytics.

Good names:

  • Order Status Lookup
  • Appointment Booking — Dental
  • Refund Request Submission

Avoid vague names:

  • Action 1
  • New action
  • Test

Define the Trigger Condition

The trigger condition is a natural-language description that tells the agent when this action should activate. The AI uses this description to match user intent, so clarity and specificity matter.

Write your trigger as if you are instructing a human colleague: "Activate this action when..."

Good trigger examples:

Trigger DescriptionWhy It Works
"When the user asks about the status of an order, wants to track a package, or asks where their shipment is"Covers multiple phrasings of the same intent
"When the user wants to book, schedule, or reschedule an appointment with a doctor"Specific to the domain and includes related verbs
"When the user requests a refund or wants to return a product they purchased"Clear scope, two related intents grouped together

Bad trigger examples:

Trigger DescriptionProblem
"When the user asks a question"Far too broad — would trigger on nearly every message
"Order"Single keyword with no context — the agent cannot determine intent
"When the user is unhappy"Subjective and ambiguous — what counts as "unhappy"?
"When the user asks about anything related to their account"Too broad — could conflict with multiple actions

Define Parameters

Parameters are the pieces of information the agent must collect from the user before the action can execute. For each parameter, configure the following:

FieldDescriptionRequired
NameInternal identifier (e.g., order_id, email). Use snake_case, no spaces.Yes
TypeThe data type. See table below.Yes
DescriptionTells the agent what to ask for and how to describe it to the user.Yes
RequiredWhether the action can proceed without this parameter.Yes
ValidationAdditional rules (min/max for numbers, regex for text).No

Parameter Types

TypeDescriptionValidationExample Values
textFree-form text input. Use for names, addresses, descriptions, and any unstructured input.Optional regex pattern, min/max length"John Smith", "123 Main St"
emailEmail address. Chatsby validates format automatically.Built-in email format validation"[email protected]"
numberNumeric value. Integers or decimals.Optional min/max value42, 199.99
phonePhone number. Accepts international formats.Built-in phone format validation"+1 (555) 123-4567"
selectPredefined list of options. User must choose one.Options list (define in configuration)"standard", "express", "overnight"
dateCalendar date. Agent guides user to provide a parseable date.Optional min/max date"2026-04-15", "next Tuesday"

Tips for parameter design:

  • Only collect what your endpoint actually needs. Every additional parameter adds friction.
  • Mark parameters as optional when reasonable. For example, a phone number for a support ticket might be helpful but not mandatory.
  • Write descriptions from the user's perspective: "Your order confirmation number (starts with ORD-)" is better than "order_id field."

Configure the Webhook

Enter the details of the endpoint Chatsby should call when all parameters are collected.

SettingDescriptionNotes
Webhook URLThe HTTPS endpoint that receives the requestMust be HTTPS. HTTP is rejected.
MethodHTTP methodPOST (fixed)
HeadersCustom headers sent with every requestUse for authentication, API keys, content type overrides
AuthenticationBearer token authenticationToken is sent as Authorization: Bearer <token>
TimeoutMaximum time to wait for a response15s (Pro), 30s (Business), 60s (Enterprise)
Fallback messageMessage shown to the user if the webhook fails or times outDefault: "I'm sorry, I wasn't able to complete that request. Please try again."

Authentication example:

If your endpoint requires a Bearer token, enter the token in the Authentication field. Chatsby will include it in the request headers:

Authorization: Bearer sk_live_abc123def456
Content-Type: application/json
X-Chatsby-Signature: sha256=a1b2c3d4...

Test in the Playground

Before activating your action, test it thoroughly in the Playground.

  1. Open the Playground from your agent's dashboard.
  2. Start a conversation that should trigger your action.
  3. Verify that the agent recognizes the trigger and begins collecting parameters.
  4. Confirm that each parameter is requested with clear, natural language.
  5. Check that the webhook receives the correct payload (use your server logs or webhook.site).
  6. Verify that the agent delivers the response correctly.

Debugging tips:

  • If the action does not trigger, review your trigger description. It may be too narrow or conflicting with another action.
  • If parameters are collected in the wrong order, the agent is optimizing for conversational flow. This is expected and usually results in a better user experience.
  • If the webhook returns an error, the Playground will show the HTTP status code and response body in the debug panel.

Activate the Action

Once testing is complete, toggle the action status to Active in the action list. The action is immediately available in all deployed instances of your agent (widget, API, integrations).

You can deactivate an action at any time without deleting it. Deactivated actions are ignored by the agent.

Request Payload Format

When your action executes, Chatsby sends a POST request to your webhook URL with the following JSON payload:

{
  "event": "action.executed",
  "action_id": "act_8f3k2j1m",
  "action_name": "Order Status Lookup",
  "conversation_id": "conv_abc123",
  "agent_id": "agent_xyz789",
  "timestamp": "2026-04-02T14:30:00Z",
  "parameters": {
    "order_id": "ORD-78542",
    "email": "[email protected]"
  },
  "metadata": {
    "source": "website_widget",
    "page_url": "https://acme.com/support",
    "user_agent": "Mozilla/5.0 ...",
    "ip_country": "US"
  }
}

Payload Fields Reference

FieldTypeDescription
eventstringAlways "action.executed"
action_idstringUnique identifier for the action configuration
action_namestringThe name you gave the action
conversation_idstringUnique identifier for the current conversation
agent_idstringThe agent that triggered the action
timestampstringISO 8601 timestamp of when the action was triggered
parametersobjectKey-value pairs of collected parameters
metadataobjectContextual information about the conversation (source, page URL, user agent, inferred country)

Response Format

Your endpoint must return a JSON response. Chatsby uses the response to formulate the agent's reply to the user.

Success Response

{
  "status": "success",
  "message": "Order ORD-78542 shipped on March 28th via FedEx. Tracking number: 7891234567. Estimated delivery: April 4th.",
  "data": {
    "tracking_url": "https://fedex.com/track/7891234567",
    "carrier": "FedEx",
    "estimated_delivery": "2026-04-04"
  }
}
FieldTypeRequiredDescription
statusstringYes"success" or "error"
messagestringYesThe text the agent will use to respond to the user. Write this as you want the agent to say it.
dataobjectNoAdditional structured data. The agent may reference this in its response if relevant.

Error Response

{
  "status": "error",
  "message": "We couldn't find an order with that number. Please double-check your order confirmation email and try again.",
  "error_code": "ORDER_NOT_FOUND"
}

When your endpoint returns an error response, the agent delivers the message field to the user. Design error messages to be helpful and suggest next steps.

HTTP StatusBehavior
200Agent uses the message field from the response body
4xxAgent delivers the message from the response body if present, otherwise the fallback message
5xxAgent delivers the configured fallback message
TimeoutAgent delivers the configured fallback message

Error Handling and Retry Logic

Chatsby does not automatically retry failed webhook calls. If your endpoint returns a 5xx error or times out, the agent delivers the fallback message and the conversation continues normally.

To build resilience:

  • Implement retries in your backend if your action calls downstream services that may be temporarily unavailable.
  • Return meaningful error messages with a 200 status code and "status": "error" so the agent can communicate specific issues to the user (e.g., "order not found" vs. a generic failure).
  • Monitor your endpoint health. Use uptime monitoring (Pingdom, UptimeRobot, or your cloud provider's built-in tools) to catch outages early.
  • Set appropriate timeouts. If your backend operation takes longer than the allowed timeout, consider returning an acknowledgment immediately and following up via email or notification.

Complete Example: Order Status Lookup

Here is a full end-to-end example of building an order status lookup action, including the webhook handler in Node.js.

Action Configuration

SettingValue
NameOrder Status Lookup
Trigger"When the user asks about the status of an order, wants to track a package, asks where their shipment is, or wants to know when their order will arrive"
Parametersorder_id (text, required, description: "Your order number, usually starts with ORD-"), email (email, required, description: "The email address you used when placing the order")
Webhook URLhttps://api.yourstore.com/webhooks/chatsby/order-status
AuthBearer token: sk_live_yourtoken123

Webhook Handler (Node.js / Express)

const express = require("express");
const app = express();
 
app.use(express.json());
 
app.post("/webhooks/chatsby/order-status", async (req, res) => {
  // 1. Verify the request is from Chatsby
  const signature = req.headers["x-chatsby-signature"];
  if (!verifySignature(req.body, signature, process.env.CHATSBY_WEBHOOK_SECRET)) {
    return res.status(401).json({
      status: "error",
      message: "Unauthorized request.",
    });
  }
 
  // 2. Extract parameters
  const { order_id, email } = req.body.parameters;
 
  try {
    // 3. Look up the order in your database
    const order = await db.orders.findOne({
      orderId: order_id,
      customerEmail: email,
    });
 
    if (!order) {
      return res.json({
        status: "error",
        message: `We couldn't find order ${order_id} associated with ${email}. Please double-check your order number and the email you used at checkout.`,
      });
    }
 
    // 4. Format and return the response
    const statusMessages = {
      processing: `Order ${order_id} is being processed. It should ship within 1-2 business days.`,
      shipped: `Order ${order_id} shipped on ${order.shippedDate} via ${order.carrier}. Tracking number: ${order.trackingNumber}. Estimated delivery: ${order.estimatedDelivery}.`,
      delivered: `Order ${order_id} was delivered on ${order.deliveredDate}. It was left at: ${order.deliveryLocation}.`,
      cancelled: `Order ${order_id} was cancelled on ${order.cancelledDate}. If you were charged, the refund should appear within 5-10 business days.`,
    };
 
    return res.json({
      status: "success",
      message: statusMessages[order.status] || `Order ${order_id} status: ${order.status}.`,
      data: {
        order_status: order.status,
        tracking_url: order.trackingUrl || null,
        carrier: order.carrier || null,
      },
    });
  } catch (error) {
    console.error("Order lookup failed:", error);
    return res.status(500).json({
      status: "error",
      message: "Something went wrong while looking up your order. Please try again in a moment.",
    });
  }
});
 
app.listen(3000, () => console.log("Webhook server running on port 3000"));

Complete Example: Appointment Booking

Action Configuration

SettingValue
NameBook Appointment
Trigger"When the user wants to book, schedule, or make an appointment, or asks about available times"
Parametersfull_name (text, required), email (email, required), phone (phone, optional), preferred_date (date, required, description: "When would you like to come in?"), service_type (select, required, options: "General Checkup", "Consultation", "Follow-up")
Webhook URLhttps://api.yourclinic.com/webhooks/chatsby/book

Webhook Handler (Node.js / Express)

app.post("/webhooks/chatsby/book", async (req, res) => {
  const { full_name, email, phone, preferred_date, service_type } = req.body.parameters;
 
  try {
    // Check availability
    const slot = await calendar.findAvailableSlot({
      date: preferred_date,
      serviceType: service_type,
      duration: service_type === "General Checkup" ? 30 : 60,
    });
 
    if (!slot) {
      // No availability — suggest alternatives
      const alternatives = await calendar.getNextAvailable({
        serviceType: service_type,
        limit: 3,
      });
 
      const altText = alternatives
        .map((s) => `${s.date} at ${s.time}`)
        .join(", ");
 
      return res.json({
        status: "error",
        message: `Unfortunately, there are no openings on ${preferred_date} for a ${service_type}. The next available times are: ${altText}. Would you like to book one of those instead?`,
      });
    }
 
    // Book the appointment
    const appointment = await calendar.book({
      slot,
      patient: { full_name, email, phone },
      serviceType: service_type,
    });
 
    return res.json({
      status: "success",
      message: `Your ${service_type} appointment is confirmed for ${appointment.date} at ${appointment.time}. A confirmation email has been sent to ${email}. Please arrive 10 minutes early. To reschedule or cancel, reply to the confirmation email.`,
      data: {
        appointment_id: appointment.id,
        date: appointment.date,
        time: appointment.time,
      },
    });
  } catch (error) {
    console.error("Booking failed:", error);
    return res.json({
      status: "error",
      message: "We ran into an issue while booking your appointment. Please call us at (555) 123-4567 to complete the booking.",
    });
  }
});

Monitoring Action Performance

After deploying your actions, monitor their performance from the Actions tab in your agent dashboard. Chatsby tracks the following metrics for each action:

MetricDescription
Total triggersNumber of times the action was activated
Successful executionsWebhook returned a success response
Failed executionsWebhook returned an error or timed out
Average response timeHow long your webhook takes to respond
Parameter completion ratePercentage of triggered actions where all required parameters were collected

Use these metrics to identify:

  • High failure rates — Indicates your endpoint may be unreliable or returning unexpected responses.
  • Low completion rates — Suggests parameters are too complex, too numerous, or confusingly described. Consider simplifying.
  • Slow response times — Optimize your backend or consider caching frequent lookups.

Best Practices and Common Pitfalls

Do

  1. Write specific trigger descriptions. Include multiple phrasings and synonyms to catch variations of the same intent.
  2. Minimize required parameters. Every additional required field increases the chance a user abandons the flow.
  3. Return user-friendly messages. Write your webhook responses as if you are speaking to the customer directly.
  4. Handle all error cases. Always return a helpful message, even when things go wrong.
  5. Test with the Playground before activating. Simulate edge cases: missing info, invalid input, typos.
  6. Use HTTPS exclusively. Chatsby rejects HTTP webhook URLs for security.

Avoid

  1. Overlapping triggers. If two actions have similar triggers, the agent may activate the wrong one. Make each trigger description distinct.
  2. Exposing sensitive data in responses. Do not return full credit card numbers, passwords, or internal system details in the message field.
  3. Long-running operations in the webhook. If your process takes more than a few seconds, return an acknowledgment and follow up asynchronously.
  4. Ignoring the fallback message. Customize it for each action instead of relying on the generic default.
  5. Skipping request verification. Always validate the X-Chatsby-Signature header to ensure requests originate from Chatsby.