Skip to main content
ListenLand can POST a signed JSON payload to your endpoint whenever a respondent finishes a conversation. Use webhooks to trigger data pipelines, send follow-up emails, import responses into your own tools, or fan out to any downstream system the moment new feedback arrives.

Setting up a webhook

1

Open your interview

Navigate to the interview you want to connect in your ListenLand dashboard.
2

Go to the Integrations section

Open the Integrations (or Webhooks) tab inside the interview editor.
3

Enter your endpoint URL

Paste the HTTPS URL that ListenLand should POST events to, e.g. https://your-app.com/webhooks/listenland.
4

Save and copy your secret

Click Save. ListenLand will display your webhook secret — a whsec_… string. Copy it now. It is shown only once and cannot be retrieved later. Store it in your secrets manager or environment variables immediately.
5

Send a test event

Use the Send Test Event button to fire a sample payload at your endpoint. The test event has the same shape as a real event, so you can build and validate your receiver without completing a real conversation.

Requirements

RequirementDetail
ProtocolHTTPS only (HTTP is rejected in production)
HostMust be a public DNS hostname — IP addresses and internal hostnames (e.g. .local, .internal) are rejected
ResponseYour endpoint must return a 2xx HTTP status within 10 seconds
RedirectsNot followed — use the exact destination URL

The conversation.completed event

This is the only event type sent for real conversations. A test event (with identical structure and placeholder data) is also available via the Send Test Event button in the dashboard. The full JSON payload looks like this:
{
  "event": "conversation.completed",
  "timestamp": "2024-11-15T14:32:00.000Z",
  "data": {
    "conversationId": "abc123def456ghi",
    "serialId": "xK9mP2qR7s",
    "interviewId": "def456uvw789xyz",
    "interviewTitle": "Onboarding experience feedback",
    "respondent": {
      "firstName": "Jane",
      "lastName": "Smith",
      "email": "jane@example.com"
    },
    "mode": "voice",
    "status": "complete",
    "title": "Frustrated by setup, loves the editor",
    "summary": "Jane found the onboarding clear but felt the email confirmation step was confusing. She praised the editor's simplicity and would recommend the product.",
    "url": "https://listen.land/c/xK9mP2qR7s",
    "startedAt": "2024-11-15T14:28:57.000Z",
    "durationMs": 183000,
    "messages": [
      {
        "role": "assistant",
        "content": "Hi! Thanks for joining. Can you tell me about your onboarding experience?",
        "createdAt": "2024-11-15T14:28:57.000Z"
      },
      {
        "role": "user",
        "content": "It was mostly smooth, but the email confirmation step confused me.",
        "createdAt": "2024-11-15T14:29:14.000Z"
      }
    ]
  }
}

Payload fields

FieldTypeDescription
eventstringAlways "conversation.completed" for real events; "test" for test events
timestampstringISO 8601 timestamp of when the event was dispatched
data.conversationIdstringUnique ID of the conversation
data.serialIdstringShort public ID — appears in the conversation URL
data.interviewIdstringID of the interview this conversation belongs to
data.interviewTitlestring | nullTitle of the interview
data.respondentobject | nullfirstName, lastName, and email if collected; null if the interview didn’t ask
data.mode"voice" | "text"Conversation mode chosen by the respondent
data.statusstring"complete" for completed conversations
data.titlestring | nullAI-generated title summarising the conversation
data.summarystring | nullAI-generated paragraph summary
data.urlstringPublic URL to view this conversation in ListenLand
data.startedAtstringISO 8601 timestamp of when the conversation began
data.durationMsnumberTime between the first and last message in milliseconds
data.messagesarrayTranscript — each item has role ("assistant" or "user"), content, and createdAt

Request headers

Every request ListenLand sends includes the following headers:
HeaderExample value
Content-Typeapplication/json
X-ListenLand-Eventconversation.completed
X-ListenLand-Signaturet=1731681120,v1=a3f9c2…
The X-ListenLand-Signature header contains a Unix timestamp and an HMAC-SHA256 signature. See Verify Webhook Signatures for full details on how to validate it.

Retry behavior

Events are delivered once — ListenLand makes a single POST attempt per event. Failures are logged but not retried. Ensure your endpoint is reliable, responds with 2xx promptly, and handles any queuing or retry logic on your side if needed.
Use the Send Test Event button in the dashboard to verify your endpoint before going live — it sends a realistic payload with the same shape as a real event, without needing a real conversation to complete.

Verify webhook signatures

Learn how to validate the X-ListenLand-Signature header and protect against replay attacks.