> ## Documentation Index
> Fetch the complete documentation index at: https://www.voiceflow.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Connect your support platform

> Build a service that opens a support conversation, forwards customer messages, and sends human replies back to Voiceflow.

## What you will build

A service with three Voiceflow-facing endpoints and a verified provider-event receiver. It opens a support conversation, forwards customer messages, and sends human replies back to Voiceflow.

<WrittenBlock kind="diagram" data='{"caption":"Two-way conversation through your connection","dir":"v","items":[{"node":{"title":"Voiceflow","sub":"Customer conversation"}},{"arr":{"label":"Then"}},{"node":{"title":"Your connection service","sub":"Translate requests and authenticated events"}},{"arr":{"label":"Then"}},{"node":{"title":"Support platform","sub":"Human support inbox"}}]}' />

Messages travel in both directions through the same connection. Your service owns the mapping between the two conversation IDs.

## Before you begin

Use a developer test account, a teammate who can answer, Node.js 22 or later, and HTTPS hosting. You need API access and event delivery for your support platform. Confirm Custom Handoff is available in your Voiceflow workspace. Choose a [platform guide](/docs/documentation/handoff/platforms).

The downloadable learning server is runnable in mock mode and includes a text-only Chatwoot pilot. Other platform guides describe the provider implementation you must add. It is a single-process example with in-memory state, not a production deployment.

## Build and connect the service

<Steps>
<Step title="Download and test the starter">
Save [server.mjs](/docs/examples/live-agent-handoff/server.mjs), [protocol.mjs](/docs/examples/live-agent-handoff/protocol.mjs), [chatwoot.mjs](/docs/examples/live-agent-handoff/chatwoot.mjs), and [test.mjs](/docs/examples/live-agent-handoff/test.mjs) in one directory. Run:

```sh
node --test test.mjs
```

Tests run against local fixtures, without provider accounts.
</Step>
<Step title="Configure a local test">
Set `HANDOFF_TOKEN` for Voiceflow-to-service authentication, a different `EVENT_TOKEN` for your normalized event receiver, `WEBHOOK_SECRET` with at least 32 random characters, `VOICEFLOW_PROJECT_ID`, and `VOICEFLOW_WEBHOOK_URL`. Store them outside source control.

```sh
PROVIDER=mock node server.mjs
```

Mock mode exercises the connection contract but does not contact a support platform. The server binds to localhost; put it behind your HTTPS proxy for Voiceflow testing.
</Step>
<Step title="Implement the provider operations">
Implement `create(request, connectionId)`, `message(providerConversationId, message)`, and `end(providerConversationId)`. `create` must return the provider conversation ID. Use the provided connection ID as provider metadata when supported. Persist customer identity and queue mapping in your implementation. The [connection reference](/docs/developers/handoff/connection-api) defines all inputs. Set `files: true` only after implementing attachment handling; the starter rejects files otherwise.
</Step>
<Step title="Verify and translate provider events">
Build a provider receiver using the vendor’s documented authentication or signature check. Reject untrusted events before mapping IDs. Translate only human-facing events; exclude internal notes and customer echoes. Send normalized events to the starter’s `/events` route with `Authorization: Bearer EVENT_TOKEN`. This is a private service-to-service route, not the vendor webhook URL.

Store provider-event IDs for deduplication. Buffer events arriving before creation completes. [Event reference](/docs/developers/handoff/webhook-events) defines the normalized shape and Voiceflow signatures.
</Step>
<Step title="Connect Voiceflow">
In **Settings → Integrations → Custom Handoff**, set Base URL to your HTTPS service, Auth header name to `Authorization`, Auth header value to `Bearer` followed by your HANDOFF_TOKEN, and Webhook secret to WEBHOOK_SECRET. Complete [handoff setup](/docs/documentation/handoff/setup).
</Step>
<Step title="Harden before production">
Replace the example Maps with durable, tenant-scoped storage and atomic idempotency records. Use a persistent outbox with bounded retries and operational alerts. Reconcile ambiguous provider timeouts before creating duplicates. Apply retention to customer data, enforce file limits, and test credential rotation. Deploy a provider-authenticated webhook receiver; do not expose `/events` using a public shared token in client code.
</Step>
</Steps>

## Verify the whole conversation

Create a test escalation; inspect the receiving inbox; send a customer reply and a human reply; close the conversation; verify the configured return path. Repeat creation with the same idempotency key and replay a message/event ID: each should create one visible effect. Test invalid credentials, missing IDs, a provider timeout, and a callback delivered before create completes. These checks require your provider account; local fixture tests do not prove them.

## Next steps

[Choose a platform guide](/docs/documentation/handoff/platforms) · [Connection API](/docs/developers/handoff/connection-api) · [Events](/docs/developers/handoff/webhook-events)
