Webhooks & Zapier
Outgoing webhooks let you push Karnyx meeting events to any external service in real time. Whether you are feeding data into a custom dashboard, triggering a Slack bot, or syncing action items to your project tracker via Zapier, webhooks are the foundation.
Overview
Karnyx webhooks are outgoing HTTP POST requests sent from our servers to an endpoint URL you specify. Each webhook delivers a JSON payload describing an event that occurred in your workspace. Webhooks are organization-scoped and can be filtered to specific event types.
- All payloads are JSON with a consistent envelope structure
- Requests include an HMAC-SHA256 signature for verification
- Failed deliveries are retried automatically with exponential backoff
- Webhook logs are retained for 30 days in the admin dashboard
- Each organization can register up to 25 webhook endpoints
Setting Up a Webhook
Navigate to Settings > Integrations > Webhooks and click "Add Webhook". You will need to provide three things:
- Endpoint URL: The HTTPS URL where Karnyx will send POST requests. Must be publicly accessible and respond within 10 seconds. HTTP URLs are not accepted for security reasons.
- Event selection: Choose which event types should trigger this webhook. You can select individual events or use "All Events" to receive everything.
- Secret key: Karnyx generates a random 256-bit secret for HMAC signature verification. Copy this immediately as it will not be shown again. You can regenerate it at any time, but doing so invalidates the previous key.
// Webhook configuration payload (what Karnyx stores)
{
"id": "whk_a1b2c3d4e5",
"url": "https://your-app.com/webhooks/karnyx",
"events": ["meeting.completed", "summary.ready", "action_item.created"],
"secret": "whsec_••••••••••••••••••••••",
"active": true,
"created_at": "2025-02-10T14:30:00Z",
"last_triggered_at": "2025-02-10T16:45:12Z",
"failure_count": 0
}HTTPS required
Available Events
Karnyx supports 9 webhook event types. Each event is fired at most once per occurrence (at-least-once delivery with deduplication on the receiver side recommended).
| Event | Fired When | Key Payload Fields |
|---|---|---|
meeting.started | Audio capture begins for a meeting | meeting_id, title, start_time, capture_mode |
meeting.completed | Audio capture ends and processing begins | meeting_id, title, duration_seconds, participant_count |
transcript.ready | Transcription and speaker ID are complete | meeting_id, transcript_url, word_count, language |
summary.ready | AI summary generation is complete | meeting_id, summary_url, template_used, summary_text |
action_item.created | A new action item is extracted or manually created | action_item_id, meeting_id, title, assignee, due_date |
action_item.completed | An action item is marked as done | action_item_id, meeting_id, title, completed_by, completed_at |
note.created | A meeting note is saved (on meeting end) | note_id, meeting_id, content_preview, highlight_count |
participant.joined | A new speaker is detected during capture | meeting_id, speaker_id, display_name, confidence |
recording.ready | Audio recording is finalized and available for download | meeting_id, recording_url, duration_seconds, file_size_bytes |
Payload Envelope
Every webhook payload follows a consistent envelope structure:
{
"id": "evt_f7g8h9i0j1",
"type": "summary.ready",
"created_at": "2025-02-10T16:45:12Z",
"organization_id": "org_k2l3m4n5",
"data": {
"meeting_id": "mtg_a1b2c3d4",
"summary_url": "https://app.karnyx.ai/meetings/mtg_a1b2c3d4/summary",
"template_used": "executive_summary",
"summary_text": "## Weekly Product Sync\n\n### Key Decisions\n..."
}
}HMAC Signature Verification
Every webhook request includes an X-Karnyx-Signature header containing an HMAC-SHA256 hash of the request body, signed with your webhook secret. Always verify this signature on your server to confirm the request originated from Karnyx.
Verification Example (Node.js / Express)
import crypto from "crypto";
import express from "express";
import { Callout } from "@/components/callout";
const app = express();
const WEBHOOK_SECRET = process.env.KARNYX_WEBHOOK_SECRET;
// Use raw body for signature verification
app.post(
"/webhooks/karnyx",
express.raw({ type: "application/json" }),
(req, res) => {
const signature = req.headers["x-karnyx-signature"];
const timestamp = req.headers["x-karnyx-timestamp"];
// Reject requests older than 5 minutes to prevent replay attacks
const age = Date.now() - new Date(timestamp).getTime();
if (age > 5 * 60 * 1000) {
return res.status(401).json({ error: "Request too old" });
}
// Compute expected signature
const payload = timestamp + "." + req.body.toString();
const expected = crypto
.createHmac("sha256", WEBHOOK_SECRET)
.update(payload)
.digest("hex");
// Constant-time comparison to prevent timing attacks
const isValid = crypto.timingSafeEqual(
Buffer.from(signature),
Buffer.from(expected)
);
if (!isValid) {
return res.status(401).json({ error: "Invalid signature" });
}
// Signature verified — process the event
const event = JSON.parse(req.body.toString());
console.log("Received event:", event.type, event.id);
switch (event.type) {
case "summary.ready":
handleSummaryReady(event.data);
break;
case "action_item.created":
handleActionItemCreated(event.data);
break;
// ... handle other event types
}
// Respond with 200 to acknowledge receipt
res.status(200).json({ received: true });
}
);
app.listen(3000, () => console.log("Webhook server running on :3000"));Always verify signatures
Request Headers
| Header | Description |
|---|---|
X-Karnyx-Signature | HMAC-SHA256 hex digest of the timestamp + body |
X-Karnyx-Timestamp | ISO 8601 timestamp of when the webhook was sent |
X-Karnyx-Event | The event type (e.g., summary.ready) |
X-Karnyx-Delivery-ID | Unique ID for this delivery attempt (useful for deduplication) |
Content-Type | Always application/json |
Zapier Integration
The Karnyx Zapier integration lets you connect meeting events to 6,000+ apps without writing code. Use it to create Jira tickets from action items, post summaries to Notion, update CRM records after client calls, and more.
Step-by-Step Setup
- Go to zapier.com and search for "Karnyx" or "Karnyx" in the app directory.
- Click "Connect" and authorize with your Karnyx account credentials. Zapier will request permission to read your meeting data and manage webhooks.
- Create a new Zap. Select "Karnyx" as the trigger app.
- Choose a trigger event from the dropdown. Available triggers map directly to the 9 webhook event types listed above (e.g., "New Summary Ready", "Action Item Created").
- Test the trigger. Zapier will pull a sample event from your most recent meetings to verify the connection.
- Add an action step. Choose the destination app (Slack, Notion, Jira, Google Sheets, etc.) and map Karnyx data fields to the action fields.
- Turn on the Zap. All future Karnyx events matching your trigger will automatically flow to the destination.
Popular Zap recipes
- Karnyx summary.ready → Post to Slack channel
- Karnyx action_item.created → Create Jira ticket
- Karnyx meeting.completed → Add row to Google Sheet
- Karnyx action_item.completed → Update Asana task status
- Karnyx transcript.ready → Create Notion page
// Example: Zapier receives this when "summary.ready" fires
{
"id": "evt_f7g8h9i0j1",
"type": "summary.ready",
"created_at": "2025-02-10T16:45:12Z",
"data": {
"meeting_id": "mtg_a1b2c3d4",
"meeting_title": "Weekly Product Sync",
"summary_text": "## Key Decisions\n- Approved Q2 roadmap...",
"template_used": "executive_summary",
"duration_seconds": 2700,
"participant_count": 5,
"action_item_count": 3
}
}
// In Zapier, you can map these fields:
// data.meeting_title → Slack message title
// data.summary_text → Slack message body
// data.action_item_count → Slack message footerWebhook Delivery & Retries
Karnyx uses an at-least-once delivery model with automatic retries. Here is how the delivery pipeline works:
Delivery Flow
- An event occurs in Karnyx (e.g., a summary is generated).
- Karnyx enqueues a delivery job for each webhook endpoint subscribed to that event type.
- The delivery worker sends an HTTP POST to your endpoint URL.
- Your server must respond with a 2xx status code within 10 seconds.
- If the response is non-2xx or times out, the delivery is marked as failed and retries are scheduled.
Retry Schedule
| Attempt | Delay After Previous | Notes |
|---|---|---|
| 1st retry | 1 minute | Covers transient network errors and brief downtime |
| 2nd retry | 5 minutes | Covers short deployment windows and restarts |
| 3rd retry | 30 minutes | Final attempt; failure here marks the delivery as permanently failed |
After 3 failed retries, the delivery is marked as permanently failed. If a webhook endpoint accumulates 50 consecutive failures, Karnyx automatically disables it and sends an email notification to organization admins.
Idempotency
X-Karnyx-Delivery-ID header to deduplicate incoming requests on your end.Testing Webhooks
Karnyx provides several tools to help you test and debug webhooks before relying on them in production.
Send a Test Event
From the webhook detail page in Settings > Integrations > Webhooks, click "Send Test Event". Choose an event type and Karnyx will send a sample payload with realistic-looking data to your endpoint. The test event has a special flag you can check:
{
"id": "evt_test_x9y8z7",
"type": "meeting.completed",
"test": true,
"created_at": "2025-02-10T17:00:00Z",
"data": {
"meeting_id": "mtg_test_001",
"title": "Test Meeting — Webhook Verification",
"duration_seconds": 1800,
"participant_count": 3
}
}Delivery Logs
Every webhook delivery is logged with the full request and response details. Navigate to the webhook detail page to see:
- Timestamp of each delivery attempt
- HTTP status code returned by your server
- Response time in milliseconds
- Full request payload (click to expand)
- Full response body from your server (first 10 KB)
- Retry count and next retry time (if applicable)
Local development
Best Practices
- Respond quickly: Return a 200 status as soon as you receive the payload. Process the event asynchronously in a background job. The 10-second timeout is strict.
- Implement idempotency: Store processed delivery IDs and skip duplicates. At-least-once delivery means you may receive the same event more than once.
- Verify signatures: Always validate the HMAC signature in production to prevent forged payloads.
- Monitor failures: Set up alerts for webhook failures in your monitoring system. Karnyx will email admins after 50 consecutive failures, but earlier detection is better.
- Use event filtering: Subscribe only to the events you need. This reduces noise and lowers the risk of processing irrelevant data.
- Rotate secrets periodically: Regenerate your webhook secret every 90 days. Karnyx supports a grace period where both the old and new secrets are valid for 24 hours during rotation.