When using the Hosted Backend on every complete user conversation turn, the server sends a webhook to the webhook URL provided in the Pipeline configuration (set in the Layercode Dashboard).

Webhook Request Payload

The webhook request body contains a JSON object with the following fields:

FieldTypeDescription
textstringThe transcribed text from the user’s speech
connection_idstringA unique identifier for the current connection. This changes each time the user reconnects to the same session
session_idstringA unique identifier for the current session
typestringThe type of webhook event. Can be “MESSAGE” for regular turns or “SESSION_START” for session initialization
turn_idstringA unique identifier for the current conversation turn

Example webhook request JSON payload:

{
  "text": "Hello, how are you?",
  "connection_id": "conn_abc123",
  "session_id": "sess_xyz789",
  "type": "MESSAGE",
  "turn_id": "turn_xyz123"
}

Verifying the webhook request

To confirm that webhook requests are from Layercode you should always verify the webhook request.

Webhook SSE Response Format

Your response should be a stream of SSE events. The SSE stream format is JSON based. Each JSON message below must be sent as a separate SSE event in the format below. Each SSE event consists of a data: field, followed by a stringified JSON object and two newlines (\n\n).

Event Types

Text to speech

Send any number of response.tts type events to the client containing text, which the Layercode voice pipeline will convert to speech and send to the client as response.audio events. The text will be processed in sentence chunks for natural speech delivery.

{
  "type": "response.tts",
  "content": "Hello this is a complete text message to speak to the user",
  "turn_id": "turn_xyz123"
}

JSON data to forward to the client

Your webhook SSE can return response.data type events, which will be forwarded directly to the browser client. This is ideal for updating UI and state in the browser. If you want to pass text or json deltas instead of full objects, you can simply pass a json object like { "delta": "text delta..." } and accumulate and render the delta in the client browser.

{
  "type": "response.data",
  "content": { "json": "object" },
  "turn_id": "turn_xyz123"
}

Note: Multiple response.tts and response.data messages can be sent over a single SSE response (e.g. so the agent can say “I’m just getting your results”, do a tool call, return the results in response.data, and then speak a summary of the results).

Ending the SSE response

Once the webhook SSE response is ready to be closed, you must send the following final event:

{
  "type": "response.end",
  "turn_id": "turn_xyz123"
}