What you will build
Customers stay in their Voiceflow conversation while your team replies from HubSpot Service Hub. Your service translates the platform’s conversation operations and events into the live agent handoff system.
This is a developer implementation guide, not a native connector. The API approach has been reviewed against provider documentation; a live account test is required before rollout.
Before you begin
You need a HubSpot app with Custom Channels access and a test support inbox, an HTTPS service, and access to Custom Handoff in Voiceflow. Start with the shared connection starter. Choose one test customer and one support destination.
This uses the Custom Channels API, not the Voiceflow HubSpot CRM tool. A CRM ticket creation action does not provide two-way live support.
Implement the connection
Prepare the support workspace
Register a custom channel, configure its webhook URL, and connect a channel account to the intended inbox. Confirm account entitlement and app permissions before implementation.
Confirm a teammate can receive and answer a manually created test conversation before adding Voiceflow.
Implement conversation creation
Publish the first incoming message through /conversations/v3/custom-channels/{channelId}/messages. Choose a threading model and persist its thread identity.
Use the starter’s create(request, connectionId) hook. Persist the provider ID and connection ID together. Forward relevant context as an initial summary or supported private note; never inject internal metadata into customer-visible replies.
Forward customer messages
Publish subsequent incoming messages through the same channel and channel account, retaining the same thread identity.
Implement the starter’s message(providerConversationId, message) hook. Deduplicate the Voiceflow message id. For the first test, support text and explicitly reject unsupported files rather than acknowledging and dropping them.
Receive human replies
Handle OUTGOING_CHANNEL_MESSAGE_CREATED at the registered webhook URL. Verify the HubSpot request signature and use the integration thread ID to recover the Voiceflow mapping.
After provider authentication succeeds, look up the mapped connection ID and send a normalized message.received event to the starter’s authenticated /events route. Include a stable provider event ID, timestamp and human display name. Do not manufacture an agent.joined event merely because a conversation was created.
Implement closure
Implement explicit closure using the supported conversation/thread lifecycle for your selected inbox. Verify closure notifications; do not infer closure from the last human message.
Implement the end(providerConversationId) hook. Deliver conversation.ended for provider-initiated closure. Make both paths idempotent so a reflected closure cannot trigger an endless loop.
Connect and test in Voiceflow
Configure your service in Settings → Integrations → Custom Handoff, then follow Set up live agent handoff. Set Queue ID only when your service has a documented mapping. Publish to a test environment and use the actual customer channel.
Provider mapping
Persist the channel ID, channel-account ID and integration thread ID separately. Use one thread identity consistently for the first and subsequent messages. For HubSpot-managed threading, consume the returned thread identity instead of inventing a second one. Confirm OUTGOING_CHANNEL_MESSAGE_CREATED carries a thread you can map before testing Voiceflow delivery. A public comment or CRM note is not a substitute for a channel reply.
Verify a complete handoff
Run this acceptance sequence with a teammate in HubSpot Service Hub:
- Escalate and confirm exactly one conversation appears in the intended inbox.
- Check the customer identity and escalation context.
- Send “customer test 1” from Voiceflow and “human test 1” from the support inbox. Both must arrive once.
- Add a private note; it must not reach the customer.
- Replay the same customer-message ID and provider event ID; neither should duplicate a message.
- Close from the support inbox and verify the configured return-to-AI path.
- Repeat with invalid credentials and an unavailable provider; verify the fallback.
If messages disappear, inspect the provider delivery log, the ID mapping and Voiceflow callback response in that order. A successful create call alone does not establish that the connection works.
Reference and next steps
Provider setup/API documentation · Provider messages/events documentation
Connection API · Event contract · Troubleshooting
Before production, replace in-memory state with durable storage, implement the provider’s retry/refresh rules, and test attachment and routing support only if your deployment needs them.