how to get call session data sent to posthog?
# ask-ai
n
how to get call session data sent to posthog?
t
Thanks for reaching out, rohit. I'm an AI assistant and I'm here to help. Give me a moment while I research this topic.
Thanks — I can help with that. Are you asking how to send LiveKit call session data to PostHog using LiveKit’s built‑in telemetry, or would you prefer to forward events from your backend (webhooks), agent logs, or an OpenTelemetry pipeline? Each approach has different setup steps, so a quick clarification will help me give the exact instructions you need. If you’re not sure which to use, tell me: • Do you need real‑time session events (joins/leaves/track publishes)? → webhooks are usually best. • Do you need detailed media/quality metrics from the SFU and agents? → built‑in telemetry / PostHog integration or OpenTelemetry export is better. • Are you using LiveKit Agents and want their logs/observability exported? → agent log forwarding or Agent Observability exports will fit. Pick one of the options above (or say “recommend best”) and I’ll send the step‑by‑step setup for PostHog including example code and verification steps. Sources: Announcing LiveKit Cloud | Say hello to improved Cloud analytics | Best practices for managing webhook event streams | LiveKit | Where to find your Agent Logs | LiveKit | Streamline troubleshooting with Agent Observability
n
which is better? webhooks sounds good
t
Great — webhooks are a solid choice for sending real-time session and participant events to PostHog. Below are clear setup steps, an example webhook handler that forwards events to PostHog, and verification tips. What I’m responding to: you chose webhooks and want the steps and example code to forward LiveKit session events to PostHog. 1) Configure LiveKit webhooks • Enable webhooks in your LiveKit server or dashboard and set the webhook URL to an endpoint you control (e.g., https://your-backend.example.com/livekit-webhook). • Select the events you want to receive (common useful ones): ◦ room_started, room_finished ◦ participant_joined, participant_left ◦ track_published, track_unpublished ◦ egress_started, egress_ended • LiveKit sends webhook POST requests with a JSON
WebhookEvent
body and an
Authorization
header containing a signed JWT. Your endpoint should validate this signature. 2) Secure and validate incoming webhooks • Validate the JWT in the
Authorization
header to ensure requests are from LiveKit. • Ensure idempotency: each
WebhookEvent
has a unique
id
. Use this to dedupe events in case of retries. 3) Example: Forward LiveKit webhooks to PostHog (Node.js / Express) • This example: ◦ Validates the webhook (using your existing validation method). ◦ Maps LiveKit event fields to a PostHog event payload. ◦ Uses the PostHog HTTP API to capture events.
Copy code
// Example: express app that receives LiveKit webhooks and forwards to PostHog
const express = require('express');
const fetch = require('node-fetch'); // or global fetch in newer Node
const bodyParser = require('body-parser');

const POSTHOG_API_URL = '<https://app.posthog.com>'; // or your self-hosted URL
const POSTHOG_API_KEY = process.env.POSTHOG_API_KEY; // project API key
const PORT = process.env.PORT || 3000;

const app = express();

// LiveKit sends webhook with content-type application/webhook+json
app.use('/livekit-webhook', bodyParser.raw({ type: ['application/webhook+json', 'application/json'] }));

<http://app.post|app.post>('/livekit-webhook', async (req, res) => {
  try {
    const authHeader = req.get('Authorization') || '';
    // Validate signature/JWT here (replace with your validation function)
    const isValid = validateLiveKitWebhook(req.body, authHeader);
    if (!isValid) return res.status(401).json({ error: 'Invalid signature' });

    const event = JSON.parse(req.body.toString('utf8'));
    // Use event.id to ensure idempotency in your storage if needed

    // Construct a PostHog event
    const posthogEvent = {
      event: event.event, // e.g., "participant_joined"
      properties: {
        livekit_event_id: event.id,
        room_sid: event.room?.sid,
        room_name: event.room?.name,
        participant_sid: event.participant?.sid,
        participant_identity: event.participant?.identity,
        timestamp: event.ts,
        // include any other fields of interest
        payload: event
      },
      distinct_id: event.participant?.sid || event.room?.sid || 'unknown'
    };

    // Send to PostHog capture API
    await fetch(`${POSTHOG_API_URL}/capture/`, {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
        'Authorization': `Bearer ${POSTHOG_API_KEY}`
      },
      body: JSON.stringify(posthogEvent)
    });

    res.json({ success: true });
  } catch (err) {
    console.error('Webhook forward error', err);
    res.status(500).json({ error: 'internal_error' });
  }
});

// Placeholder: implement actual LiveKit webhook JWT validation
function validateLiveKitWebhook(rawBody, authHeader) {
  // Validate the JWT signature in authHeader and return true/false.
  // Use LiveKit SDK or your configured signing key to verify.
  return true;
}

app.listen(PORT, () => console.log(`Listening on ${PORT}`));
Notes about the example: • Replace
validateLiveKitWebhook
with real verification using your LiveKit signing key. The
Authorization
header contains a signed JWT. • Use the PostHog project API key (or ingestion key) for the capture endpoint. For self-hosted PostHog the base URL may differ. • Use
distinct_id
to identify users/sessions in PostHog. Choose
participant_sid
, user ID, or
room_sid
depending on your analytics needs. • Store processed webhook IDs to prevent duplicate events from retries. 4) Helpful mapping suggestions • Map event types to PostHog event names directly (e.g., LiveKit
participant_joined
→ PostHog event
participant_joined
). • Include common properties: ◦ room: { sid, name } ◦ participant: { sid, identity } ◦ track info: { kind, sid, name } ◦ timestamps and any quality metrics present in the webhook payload • If you need aggregated metrics (e.g., minutes per room), either: ◦ send additional summary events from your backend, or ◦ compute aggregates in PostHog using their cohorts/insights or via periodic batch events. 5) Verification and testing • Start with a staging webhook endpoint. Trigger events by creating/joining a test room. • Check your backend logs for receipt and validation of requests. • Confirm events appear in PostHog: ◦ Use the Events/Insights page and filter by
event
name or
livekit_event_id
. • Verify no duplicates by checking unique webhook IDs you stored. 6) Advanced considerations • If you need media-quality metrics from the SFU (bitrate, jitter, packet loss), webhooks may include some lifecycle info but not all per-second metrics. For higher-fidelity telemetry consider combining webhooks with LiveKit telemetry/OpenTelemetry exports. • If you run LiveKit Agents, you can also forward agent logs/transcripts via the same pattern (receive, transform, post to PostHog). • Respect PII: Avoid sending raw sensitive data to PostHog unless allowed by your privacy rules. If you’d like, I can: • Provide a complete sample for validating LiveKit webhook JWTs (tell me what language you prefer). • Customize the mapping between LiveKit fields and PostHog properties for the specific events you care about. • Add retry/deduplication example code using a simple Redis store. Which of those would you like next?
n
is there a config setting I can use on posthog?
t
Thanks — I’m responding to your question about whether there’s a PostHog configuration you can flip to automatically receive LiveKit call session data. Short answer: No — there isn’t a PostHog-side config that will automatically ingest LiveKit session data. LiveKit can forward events and logs to external systems (including PostHog), but PostHog does not have a built‑in toggle to accept LiveKit data without a custom integration. What you can do instead (options): • Use LiveKit webhooks to send session and participant events to your backend, then forward those events to PostHog via the PostHog capture API (this is the most common approach). • Forward logs from the LiveKit JavaScript SDK or Agents to PostHog by adding a small adapter in your app/agent code (for example, use the SDK’s log-extension or a logging pipeline that posts into PostHog). • Use OpenTelemetry/exporter pipelines (if you already have one) to push traces/metrics into PostHog, but this requires configuring an exporter/collector on your side. If you’d like, I can: • Provide the exact PostHog capture payload/headers you should use. • Share a code sample for validating LiveKit webhooks and forwarding to PostHog in the language you prefer. • Help map which LiveKit events/properties are most useful to send to PostHog for your analytics goals. Which would you like next? Sources: Sub-processors | LiveKit | How to Send Logs from the JavaScript SDK to External Providers | LiveKit