FlowHunt JS API: Integration Guide for Advanced Users

FlowHunt JavaScript API Chatbot Integration

The FlowHunt JS API gives you full control over how your chatbot integrates with your website. Using the v2 integration code, you can embed the chatbot, subscribe to lifecycle and interaction events, pass dynamic data via flow variables, track interactions with URL parameters, and programmatically control the chat window.

This guide covers every aspect of the JS API with code examples you can copy and adapt to your project.

Integration Code (v2)

When you create a chatbot in FlowHunt, you get an integration snippet. Copy and paste it into your HTML just before the closing </body> tag:

<script id="fh-chatbot-script-YOUR_CHATBOT_ID">
  var currentScript = document.currentScript
    || document.getElementById('fh-chatbot-script-YOUR_CHATBOT_ID');

  var script = document.createElement('script');
  script.async = true;
  script.src = 'https://app.flowhunt.io/api/chatbot/YOUR_CHATBOT_ID'
    + '?workspace_id=YOUR_WORKSPACE_ID&v=2';

  script.onload = function() {
    window.FHChatbot_YOUR_CHATBOT_ID.init(function(chatbotManager) {
      // The chatbot is ready — use chatbotManager here
    });
  };

  if (currentScript && currentScript.parentNode) {
    currentScript.parentNode.insertBefore(script, currentScript.nextSibling);
  } else {
    document.head.appendChild(script);
  }
</script>

Replace YOUR_CHATBOT_ID and YOUR_WORKSPACE_ID with the values from your FlowHunt dashboard. The chatbot ID in the global variable name (window.FHChatbot_YOUR_CHATBOT_ID) uses underscores instead of hyphens.

Overriding Configuration with setConfig()

Before calling init(), you can override the default chatbot settings using setConfig():

<script id="fh-chatbot-script-YOUR_CHATBOT_ID">
  var currentScript = document.currentScript
    || document.getElementById('fh-chatbot-script-YOUR_CHATBOT_ID');

  var script = document.createElement('script');
  script.async = true;
  script.src = 'https://app.flowhunt.io/api/chatbot/YOUR_CHATBOT_ID'
    + '?workspace_id=YOUR_WORKSPACE_ID&v=2';

  script.onload = function() {
    window.FHChatbot_YOUR_CHATBOT_ID.setConfig({
      headerTitle: 'Support Assistant',
      maxWindowWidth: '700px',
      showChatButton: false,
      flowVariables: {
        userId: '12345',
        plan: 'enterprise'
      },
      urlSuffix: '?utm_source=chatbot'
    });

    window.FHChatbot_YOUR_CHATBOT_ID.init(function(chatbotManager) {
      // Chatbot initialized with custom config
    });
  };

  if (currentScript && currentScript.parentNode) {
    currentScript.parentNode.insertBefore(script, currentScript.nextSibling);
  } else {
    document.head.appendChild(script);
  }
</script>

Available Configuration Options

OptionTypeDescription
headerTitlestringCustom header title text
maxWindowWidthstringMaximum chat window width (e.g., '700px')
maxWindowHeightstringMaximum chat window height
inputPlaceholderstringPlaceholder text for the message input
showChatButtonbooleanShow or hide the default floating chat button
openChatPanelbooleanAutomatically open the chat panel on page load
flowVariablesobjectKey-value pairs of custom data passed to the flow
urlSuffixstringQuery string appended to all chatbot-generated URLs
cookieConsentbooleanEnable session persistence via cookies
embeddedstringSet to enable embedded mode (no close button)
themestringTheme mode
Logo

Ready to grow your business?

Start your free trial today and see results within days.

Flow Variables: Pass Dynamic Data

Flow variables let you send custom data from your website into the chatbot flow. This enables personalized conversations based on user context.

window.FHChatbot_YOUR_CHATBOT_ID.setConfig({
  flowVariables: {
    userId: getCurrentUserId(),
    userEmail: getCurrentUserEmail(),
    currentPage: window.location.pathname,
    plan: 'enterprise'
  }
});

Once set, these variables are accessible within your chatbot flow logic, allowing you to personalize responses, route conversations, or pass context to AI agents.

URL Suffix: Track Chatbot Interactions

The urlSuffix parameter appends a query string to every URL generated by the chatbot. This is useful for tracking chatbot-originated traffic in analytics tools:

window.FHChatbot_YOUR_CHATBOT_ID.setConfig({
  urlSuffix: '?utm_source=chatbot&utm_medium=widget'
});

Use cases:

  • Track conversions from chatbot interactions in Google Analytics.
  • Analyze user behavior after engaging with the chatbot.
  • Attribute campaigns that drive chatbot engagement.

Event Reference

The FlowHunt JS API dispatches 10 custom events on the window object. All events use the CustomEvent API with bubbles: true and composed: true.

onFHChatbotReady

Fired when the chatbot widget has fully rendered and is ready to use.

  • Event data: None
  • When: After the widget DOM is mounted and the chat button is visible.

onFHChatbotSessionCreated

Fired when a new chat session is created on the server. Also fires when the session is restarted.

  • Event data: None
  • When: After a successful session creation API call.

onFHChatbotWindowOpened

Fired when the user opens the chat window.

  • Event data: None
  • When: Chat panel becomes visible.
  • Note: Not fired in embedded mode.

onFHChatbotWindowClosed

Fired when the user closes the chat window.

  • Event data: None
  • When: Chat panel is hidden.
  • Note: Not fired in embedded mode.

onFHMessageSent

Fired when the user sends a message.

  • Event data (event.detail.metadata):
{
  "content": "Hello, I need help with...",
  "createdAt": "2026-02-19T10:30:00.000Z"
}

onFHMessageReceived

Fired when the chatbot receives and displays a response.

  • Event data (event.detail.metadata):
{
  "flow_id": "abc123",
  "message_id": "msg_456",
  "message": "Sure, I can help you with that!",
  "sender": {
    "sender_name": "Support Agent",
    "sender_avatar": "https://example.com/avatar.png"
  }
}

The sender field is optional and only present when a human agent is involved.

onFHFormDataSent

Fired when the user submits form data through the chatbot.

  • Event data (event.detail.metadata):
{
  "objectData": { "name": "John", "email": "john@example.com" },
  "createdAt": "2026-02-19T10:31:00.000Z"
}

onFHFeedback

Fired when a user gives thumbs up or thumbs down feedback on a chatbot message.

  • Event data (event.detail.metadata):
{
  "message_id": "msg_456",
  "content": "Optional feedback text",
  "feedback": "P"
}

The feedback value is "P" for positive (thumbs up) or "N" for negative (thumbs down).

onFHToolCall

Fired when a tool or action is executed during flow processing.

  • Event data (event.detail.metadata):
{
  "metadata": {
    "flow_id": "abc123",
    "message_id": "msg_789",
    "message": "Calling search API..."
  },
  "createdAt": "2026-02-19T10:32:00.000Z"
}

Note: Only fired in flowAssistant and flowAssistantV3 modes, not in standard chatbot mode.

onFHError

Fired when an error occurs during chatbot operation.

  • Event data (event.detail.metadata):
{
  "metadata": {
    "flow_id": "abc123",
    "message_id": "msg_err",
    "message": "Flow execution failed"
  },
  "createdAt": "2026-02-19T10:33:00.000Z"
}

Subscribing to Events

There are two ways to subscribe to chatbot events.

Method 1: Window Event Listeners

Use window.addEventListener anywhere in your page. This works even before the chatbot has loaded:

<script>
document.addEventListener('DOMContentLoaded', function() {
  // Chatbot lifecycle events
  window.addEventListener('onFHChatbotReady', function(event) {
    console.log('Chatbot is ready');
  });

  window.addEventListener('onFHChatbotSessionCreated', function(event) {
    console.log('Session created');
  });

  window.addEventListener('onFHChatbotWindowOpened', function(event) {
    console.log('Chat window opened');
  });

  window.addEventListener('onFHChatbotWindowClosed', function(event) {
    console.log('Chat window closed');
  });

  // Message events
  window.addEventListener('onFHMessageSent', function(event) {
    console.log('User sent:', event.detail.metadata.content);
  });

  window.addEventListener('onFHMessageReceived', function(event) {
    console.log('Bot replied:', event.detail.metadata.message);
  });

  window.addEventListener('onFHFormDataSent', function(event) {
    console.log('Form submitted:', event.detail.metadata.objectData);
  });

  // Feedback
  window.addEventListener('onFHFeedback', function(event) {
    var feedback = event.detail.metadata;
    console.log('Feedback on message', feedback.message_id, ':',
      feedback.feedback);
  });

  // Tool calls (flowAssistant modes only)
  window.addEventListener('onFHToolCall', function(event) {
    console.log('Tool called:', event.detail.metadata);
  });

  // Errors
  window.addEventListener('onFHError', function(event) {
    console.error('Chatbot error:', event.detail.metadata);
  });
});
</script>

To stop listening to an event, use removeEventListener with the same function reference:

var handleMessage = function(event) {
  console.log(event.detail.metadata);
};
window.addEventListener('onFHMessageReceived', handleMessage);

// Later, when you want to stop listening:
window.removeEventListener('onFHMessageReceived', handleMessage);

Method 2: Manager Callback Methods

Inside the init() callback, use the chatbot manager’s built-in methods:

window.FHChatbot_YOUR_CHATBOT_ID.init(function(chatbotManager) {
  chatbotManager.onSessionCreated(function() {
    console.log('Session created');
  });

  chatbotManager.onWindowOpened(function() {
    console.log('Window opened');
  });

  chatbotManager.onWindowClosed(function() {
    console.log('Window closed');
  });

  chatbotManager.onMessageSent(function(event) {
    console.log('User sent:', event.metadata);
  });

  chatbotManager.onMessageReceived(function(event) {
    console.log('Bot replied:', event.metadata);
  });

  chatbotManager.onFormDataSent(function(event) {
    console.log('Form data:', event.metadata);
  });

  chatbotManager.onFeedback(function(event) {
    console.log('Feedback:', event.metadata);
  });

  chatbotManager.onToolCall(function(event) {
    console.log('Tool call:', event.metadata);
  });

  chatbotManager.onError(function(event) {
    console.error('Error:', event.metadata);
  });
});

Manager Methods Reference

MethodParametersDescription
onSessionCreated(fn)fn: () => voidListen for session creation
onWindowOpened(fn)fn: () => voidListen for window open
onWindowClosed(fn)fn: () => voidListen for window close
onMessageSent(fn)fn: (event) => voidListen for user messages
onMessageReceived(fn)fn: (event) => voidListen for bot responses
onFormDataSent(fn)fn: (event) => voidListen for form submissions
onFeedback(fn)fn: (event) => voidListen for user feedback
onToolCall(fn)fn: (event) => voidListen for tool executions
onError(fn)fn: (event) => voidListen for errors
openChat()Opens the chat panel
closeChat()Closes the chat panel

Custom Chat Activation: Hide Button and Open on Click

To fully control when the chatbot appears, hide the default floating button and open the chat programmatically — for example, from your own custom button.

Full Example

<!-- Your custom chat button -->
<button id="my-chat-button">Chat with us</button>

<!-- FlowHunt integration with hidden default button -->
<script id="fh-chatbot-script-YOUR_CHATBOT_ID">
  var currentScript = document.currentScript
    || document.getElementById('fh-chatbot-script-YOUR_CHATBOT_ID');

  var script = document.createElement('script');
  script.async = true;
  script.src = 'https://app.flowhunt.io/api/chatbot/YOUR_CHATBOT_ID'
    + '?workspace_id=YOUR_WORKSPACE_ID&v=2';

  script.onload = function() {
    window.FHChatbot_YOUR_CHATBOT_ID.setConfig({
      showChatButton: false
    });

    window.FHChatbot_YOUR_CHATBOT_ID.init(function(chatbotManager) {
      // Open chat when your custom button is clicked
      document.getElementById('my-chat-button')
        .addEventListener('click', function() {
          chatbotManager.openChat();
        });
    });
  };

  if (currentScript && currentScript.parentNode) {
    currentScript.parentNode.insertBefore(script, currentScript.nextSibling);
  } else {
    document.head.appendChild(script);
  }
</script>

Show a Custom Button Only When the Chatbot Is Ready

You can combine hidden activation with event listeners to create advanced interactions:

<button id="open-chat" style="display:none;">Need help?</button>

<script>
// Show a custom button only when the chatbot is ready
window.addEventListener('onFHChatbotReady', function() {
  document.getElementById('open-chat').style.display = 'block';
});
</script>

<!-- FlowHunt integration -->
<script id="fh-chatbot-script-YOUR_CHATBOT_ID">
  var currentScript = document.currentScript
    || document.getElementById('fh-chatbot-script-YOUR_CHATBOT_ID');

  var script = document.createElement('script');
  script.async = true;
  script.src = 'https://app.flowhunt.io/api/chatbot/YOUR_CHATBOT_ID'
    + '?workspace_id=YOUR_WORKSPACE_ID&v=2';

  script.onload = function() {
    window.FHChatbot_YOUR_CHATBOT_ID.setConfig({
      showChatButton: false
    });

    window.FHChatbot_YOUR_CHATBOT_ID.init(function(chatbotManager) {
      document.getElementById('open-chat')
        .addEventListener('click', function() {
          chatbotManager.openChat();
        });
    });
  };

  if (currentScript && currentScript.parentNode) {
    currentScript.parentNode.insertBefore(script, currentScript.nextSibling);
  } else {
    document.head.appendChild(script);
  }
</script>

Complete Integration Example

A full working example that demonstrates configuration overrides, event tracking, and custom chat activation together:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  <title>FlowHunt Chatbot Integration</title>
</head>
<body>
  <h1>My Website</h1>
  <button id="open-chat-btn">Talk to our AI assistant</button>
  <button id="close-chat-btn">Close chat</button>

  <!-- Subscribe to events before the chatbot loads -->
  <script>
  document.addEventListener('DOMContentLoaded', function() {
    window.addEventListener('onFHChatbotReady', function() {
      console.log('Chatbot widget is ready');
    });

    window.addEventListener('onFHChatbotSessionCreated', function() {
      console.log('New chat session started');
    });

    window.addEventListener('onFHMessageSent', function(event) {
      console.log('User message:', event.detail.metadata.content);
    });

    window.addEventListener('onFHMessageReceived', function(event) {
      console.log('Bot response:', event.detail.metadata.message);
    });

    window.addEventListener('onFHFeedback', function(event) {
      var fb = event.detail.metadata;
      if (fb.feedback === 'P') {
        console.log('Positive feedback on message', fb.message_id);
      } else {
        console.log('Negative feedback on message', fb.message_id);
      }
    });

    window.addEventListener('onFHError', function(event) {
      console.error('Chatbot error:', event.detail.metadata);
    });
  });
  </script>

  <!-- FlowHunt integration -->
  <script id="fh-chatbot-script-YOUR_CHATBOT_ID">
    var currentScript = document.currentScript
      || document.getElementById('fh-chatbot-script-YOUR_CHATBOT_ID');

    var script = document.createElement('script');
    script.async = true;
    script.src = 'https://app.flowhunt.io/api/chatbot/YOUR_CHATBOT_ID'
      + '?workspace_id=YOUR_WORKSPACE_ID&v=2';

    script.onload = function() {
      window.FHChatbot_YOUR_CHATBOT_ID.setConfig({
        showChatButton: false,
        headerTitle: 'AI Assistant',
        maxWindowWidth: '600px',
        flowVariables: {
          source: 'website',
          page: window.location.pathname
        },
        urlSuffix: '?utm_source=chatbot'
      });

      window.FHChatbot_YOUR_CHATBOT_ID.init(function(chatbotManager) {
        document.getElementById('open-chat-btn')
          .addEventListener('click', function() {
            chatbotManager.openChat();
          });

        document.getElementById('close-chat-btn')
          .addEventListener('click', function() {
            chatbotManager.closeChat();
          });
      });
    };

    if (currentScript && currentScript.parentNode) {
      currentScript.parentNode.insertBefore(script, currentScript.nextSibling);
    } else {
      document.head.appendChild(script);
    }
  </script>
</body>
</html>

Frequently asked questions

What events can I listen to with the FlowHunt JS API?

The FlowHunt JS API emits 10 events: onFHChatbotReady, onFHChatbotSessionCreated, onFHChatbotWindowOpened, onFHChatbotWindowClosed, onFHMessageSent, onFHMessageReceived, onFHFormDataSent, onFHFeedback, onFHToolCall, and onFHError. You can subscribe to these using window.addEventListener or via the chatbot manager callback methods.

How do I hide the default chat button and open the chatbot programmatically?

Use the showChatButton: false configuration option to hide the default button, then call chatbotManager.openChat() to open the chatbot on your own terms — for example, on a custom button click.

What is the difference between the manager callback methods and window.addEventListener?

Both approaches work. The manager callback methods (e.g., chatbotManager.onMessageSent(fn)) are called inside the init callback and are tied to the manager instance. The window.addEventListener approach (e.g., window.addEventListener('onFHMessageSent', fn)) can be set up anywhere in your page, even before the chatbot loads.

How do I pass custom data to the chatbot using flow variables?

Use the flowVariables configuration option in setConfig() to pass key-value pairs such as user ID, email, or page URL. These variables become available inside your chatbot flow for personalized responses.

What data is available in event handlers?

Events that carry data include it in event.detail.metadata. For example, onFHMessageSent includes the message content and timestamp, onFHMessageReceived includes the flow_id, message_id, and message text, and onFHFeedback includes the message_id and whether the feedback was positive or negative.