Skip to main content

Webhook Request Payload

Layercode sends different webhook event types to your backend. Each request body is JSON. All requests include:
  • type (string): One of message, data, session.start, session.end, session.update.
  • session_id (string): Connection identifier for this session. Changes each reconnect.
  • conversation_id (string): Stable conversation identifier.
  • custom_metadata (object, optional): Custom metadata supplied during session authorization. See custom metadata and headers how-to.
In addition, when you pass custom_headers during session authorization, Layercode appends those headers to every webhook request. See custom metadata and headers how-to. Additional fields vary by event type, as described below.

message

  • text (string): Transcribed user text.
  • session_id (string): A unique identifier for the current session.
  • conversation_id (string): A unique identifier for the conversation.
  • turn_id (string): Unique ID for this turn.
  • from_phone_number (string, optional): Caller phone number if Twilio is used.
  • to_phone_number (string, optional): Agent phone number if Twilio is used.
Example:
{
  "type": "message",
  "session_id": "sess_abc123",
  "conversation_id": "conv_xyz789",
  "turn_id": "turn_xyz123",
  "text": "Hello, how are you?",
  "from_phone_number": "+14155550123",
  "to_phone_number": "+14155559876"
}

data

Sent when your client emits client.response.data to pass structured JSON without interrupting speech.
  • data (object): The arbitrary JSON payload sent by the client.
  • session_id (string): A unique identifier for the current session.
  • conversation_id (string): A unique identifier for the conversation.
  • turn_id (string): Unique ID for the current turn.
  • from_phone_number (string, optional): Caller phone number if Twilio is used.
  • to_phone_number (string, optional): Agent phone number if Twilio is used.
The response to this event type should be a regular JSON HTTP response (not an SSE stream). See also: Send JSON data from the client. Example:
{
  "type": "data",
  "session_id": "sess_abc123",
  "conversation_id": "conv_xyz789",
  "turn_id": "turn_xyz123",
  "data": {
    "action": "confirm_order",
    "orderId": "ORD-12345",
    "timestamp": 1724848800000
  }
}

session.start

Sent when a new session begins and your agent should optionally speak first.
  • session_id (string): A unique identifier for the current session.
  • conversation_id (string): A unique identifier for the conversation.
  • turn_id (string): Unique ID for the assistant welcome turn.
  • from_phone_number (string, optional): Caller phone number if Twilio is used.
  • to_phone_number (string, optional): Agent phone number if Twilio is used.
Example:
{
  "type": "session.start",
  "session_id": "sess_abc123",
  "conversation_id": "conv_xyz789",
  "turn_id": "turn_welcome_123",
  "from_phone_number": "+14155550123",
  "to_phone_number": "+14155559876"
}

session.update

Sent when asynchronous session data becomes available (e.g., after a recording completes).
  • session_id (string): A unique identifier for the current session.
  • conversation_id (string): A unique identifier for the conversation.
  • recording_status (string): completed or failed.
  • recording_url (string, optional): API URL to download WAV when completed.
  • recording_duration (number, optional): Duration in seconds.
  • error_message (string, optional): Error details when failed.
  • metadata (object): Session metadata originally provided during authorization (if any).
  • from_phone_number (string, optional): Caller phone number if Twilio is used.
  • to_phone_number (string, optional): Agent phone number if Twilio is used.
Example:
{
  "type": "session.update",
  "session_id": "sess_abc123",
  "conversation_id": "conv_xyz789",
  "from_phone_number": "+14155550123",
  "to_phone_number": "+14155559876",
  "recording_status": "completed",
  "recording_url": "https://api.layercode.com/v1/agents/ag_123/sessions/sess_abc123/recording",
  "recording_duration": 42.3,
  "metadata": { "userId": "u_123" }
}

session.end

Sent when the session finishes. Includes transcript and usage metrics.
  • session_id (string): A unique identifier for the current session.
  • conversation_id (string): A unique identifier for the conversation.
  • agent_id (string): Agent ID.
  • started_at / ended_at (string): ISO timestamps.
  • duration (number|null): Total milliseconds (if available).
  • transcription_duration_seconds (number|null)
  • tts_duration_seconds (number|null)
  • latency (number|null)
  • ip_address (string|null)
  • country_code (string|null)
  • recording_status (string): enabled or disabled (org setting for session recording).
  • transcript (array): Items of { role: 'user' | 'assistant', text: string, timestamp: number }.
  • from_phone_number (string, optional): Caller phone number if Twilio is used.
  • to_phone_number (string, optional): Agent phone number if Twilio is used.
Example:
{
  "type": "session.end",
  "session_id": "sess_abc123",
  "conversation_id": "conv_xyz789",
  "agent_id": "ag_123",
  "from_phone_number": "+14155550123",
  "to_phone_number": "+14155559876",
  "started_at": "2025-08-28T10:00:00.000Z",
  "ended_at": "2025-08-28T10:03:00.000Z",
  "duration": 180000,
  "transcription_duration_seconds": 20.1,
  "tts_duration_seconds": 19.8,
  "latency": 120,
  "ip_address": "203.0.113.10",
  "country_code": "US",
  "recording_status": "enabled",
  "transcript": [
    { "role": "user", "text": "Hello", "timestamp": 1724848800000 },
    { "role": "assistant", "text": "Hi there!", "timestamp": 1724848805000 }
  ]
}

Webhook Response Events

When Layercode calls your webhook, your handler typically streams back Server-Sent Events (SSE) so the assistant can speak or update the UI. The following event types are recognized. Note: For response.data, you may either include it in an SSE stream, or when responding to the incoming data webhook event type, return it as a regular JSON HTTP response (non‑SSE). All other webhook events should return SSE events.

response.tts

Send spoken content for the assistant turn. Layercode converts the provided text to speech and streams it to the user.
{ "type": "response.tts", "content": "Let me check that for you.", "turn_id": "turn_xyz123" }

response.data

Deliver JSON payloads to the frontend without speaking. Useful for updating dashboards or sending structured data.
{ "type": "response.data", "content": { "status": "looking-up-order" }, "turn_id": "turn_xyz123" }
JSON (non‑SSE) response example (when responding to the incoming data webhook event). See docs page: Send JSON data from the client.
{ "type": "response.data", "content": { "status": "received", "echo": { "orderId": "ORD-12345" } }, "turn_id": "turn_xyz123" }

response.end

Signal that the assistant has finished generating its reply for the current turn. Always emit this once the turn is complete unless you are issuing a response.hangup.
{ "type": "response.end", "turn_id": "turn_xyz123" }

response.hangup

Request that Layercode end the session after finishing playback of the current assistant audio. Provide a farewell in the required content field. You do not need to send a separate response.end; Layercode will flush remaining audio and end the session automatically.
{
  "type": "response.hangup",
  "content": "Thank you for calling. Goodbye!",
  "turn_id": "turn_xyz123"
}