Skip to content
Back to skills

Fireflies Webhooks Events

ASecurity

'Implement Fireflies.ai webhook receiver with HMAC signature verification and event processing. Use when setting up webhook endpoints, handling transcript-ready notifications, or building real-time meeting intelligence pipelines. Trigger with phrases like \"fireflies webhook\", \"fireflies events\", \"fireflies webhook signature\", \"handle fireflies events\", \"fireflies notifications\". '

  • 3 stars
  • 0 votes
  • 0 copies
  • 5 views
  • Added September 12, 2026
ai-agentstypescriptgobashexpressgitapidatabasebackend

Works with

  • cli
  • api

Security analysis

A100/100

Scanned September 12, 2026

npx -y skills add thedixitjain/the-mega-skill-library --skill fireflies-webhooks-events --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Fireflies Webhooks Events?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Fireflies Webhooks Events
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/thedixitjain-fireflies-webhooks-events/badge)](https://www.skillsdirectory.com/skills/thedixitjain-fireflies-webhooks-events)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: fireflies-webhooks-events
description: "'Implement Fireflies.ai webhook receiver with HMAC signature verification and event processing. Use when setting up webhook endpoints, handling transcript-ready notifications, or building real-time meeting intelligence pipelines. Trigger with phrases like \"fireflies webhook\", \"fireflies events\", \"fireflies webhook signature\", \"handle fireflies events\", \"fireflies notifications\". '"
allowed-tools: "Read, Write, Edit, Bash(curl:*)"
category: backend-and-data
source_repo: jeremylongshore/claude-code-plugins-plus-skills
source_path: "skills/.curated/fireflies-webhooks-events/SKILL.md"
source_url: https://github.com/jeremylongshore/claude-code-plugins-plus-skills/blob/HEAD/skills/.curated/fireflies-webhooks-events/SKILL.md
---

# Fireflies.ai Webhooks & Events

## Overview

Handle Fireflies.ai webhook events for real-time transcript notifications. Fireflies fires a webhook when a transcript finishes processing. The payload is signed with HMAC-SHA256 for verification.

## Prerequisites

- Fireflies.ai Business or Enterprise plan
- `FIREFLIES_API_KEY` and `FIREFLIES_WEBHOOK_SECRET` in environment
- HTTPS endpoint accessible from the internet

## Webhook Event Reference

Fireflies currently fires one event type:

| Event | `eventType` Value | Trigger |
|-------|-------------------|---------|
| Transcription completed | `"Transcription completed"` | Transcript is fully processed and ready |

### Payload Format

```json
{
  "meetingId": "ASxwZxCstx",
  "eventType": "Transcription completed",
  "clientReferenceId": "be582c46-4ac9-4565-9ba6-6ab4264496a8"
}
```

| Field | Type | Description |
|-------|------|-------------|
| `meetingId` | String | Transcript ID -- use in `transcript(id:)` query |
| `eventType` | String | Always `"Transcription completed"` currently |
| `clientReferenceId` | ID | Your custom ID from `uploadAudio` (null if bot-recorded) |

## Important Constraints

- Webhooks fire **only for meetings you own** (organizer_email matches your account)
- Super Admin webhooks (Enterprise only) fire for all team-owned meetings

## Instructions

### Step 1: Register Webhook in Dashboard

1. Go to [app.fireflies.ai/settings](https://app.fireflies.ai/settings)
2. Select **Developer settings** tab
3. Enter your HTTPS webhook URL
4. Enter or generate a 16-32 character secret
5. Save

### Step 2: Build Webhook Receiver with Signature Verification

```typescript
import express from "express";
import crypto from "crypto";

const app = express();

// IMPORTANT: Use raw body for HMAC verification
app.post("/webhooks/fireflies",
  express.raw({ type: "application/json" }),
  async (req, res) => {
    const signature = req.headers["x-hub-signature"] as string;
    const rawBody = req.body.toString();

    // Verify HMAC-SHA256 signature
    if (!signature || !verifySignature(rawBody, signature)) {
      console.warn("Rejected webhook: invalid signature");
      return res.status(401).json({ error: "Invalid signature" });
    }

    // Acknowledge immediately -- process async
    res.status(200).json({ received: true });

    const event = JSON.parse(rawBody);
    console.log(`Webhook: ${event.eventType} for meeting ${event.meetingId}`);

    // Process in background
    processTranscriptReady(event.meetingId, event.clientReferenceId)
      .catch(err => console.error("Webhook processing failed:", err));
  }
);

function verifySignature(payload: string, signature: string): boolean {
  const secret = process.env.FIREFLIES_WEBHOOK_SECRET!;
  const expected = crypto
    .createHmac("sha256", secret)
    .update(payload)
    .digest("hex");
  return crypto.timingSafeEqual(
    Buffer.from(signature),
    Buffer.from(expected)
  );
}
```

### Step 3: Fetch and Process the Transcript

```typescript
const FIREFLIES_API = "https://api.fireflies.ai/graphql";

async function processTranscriptReady(meetingId: string, clientRefId?: string) {
  const res = await fetch(FIREFLIES_API, {
    method: "POST",
    headers: {
      "Content-Type": "application/json",
      Authorization: `Bearer ${process.env.FIREFLIES_API_KEY}`,
    },
    body: JSON.stringify({
      query: `
        query GetTranscript($id: String!) {
          transcript(id: $id) {
            id title date duration
            organizer_email
            speakers { name }
            sentences { speaker_name text start_time end_time }
            summary {
              overview
              action_items
              keywords
              short_summary
            }
            meeting_attendees { displayName email }
          }
        }
      `,
      variables: { id: meetingId },
    }),
  });

  const json = await res.json();
  if (json.errors) throw new Error(json.errors[0].message);

  const transcript = json.data.transcript;
  console.log(`Processing: "${transcript.title}" (${transcript.duration}min)`);
  console.log(`Speakers: ${transcript.speakers.map((s: any) => s.name).join(", ")}`);
  console.log(`Action items: ${transcript.summary?.action_items?.length || 0}`);

  // Route to downstream systems
  await Promise.all([
    storeTranscript(transcript),
    createTasksFromActionItems(transcript),
    notifyTeam(transcript),
  ]);
}

async function storeTranscript(transcript: any) {
  // Store in your database
  console.log(`Stored transcript: ${transcript.id}`);
}

async function createTasksFromActionItems(transcript: any) {
  const items = transcript.summary?.action_items || [];
  for (const item of items) {
    console.log(`Task created: ${item}`);
    // await taskManager.create({ title: item, source: transcript.title });
  }
}

async function notifyTeam(transcript: any) {
  // Send Slack/email notification
  const summary = transcript.summary?.short_summary || transcript.summary?.overview;
  console.log(`Notification: "${transcript.title}" -- ${summary}`);
}
```

### Step 4: Per-Upload Webhook (Alternative)

Instead of dashboard-level webhook, include a webhook URL in `uploadAudio`:

```typescript
await fetch(FIREFLIES_API, {
  method: "POST",
  headers: {
    "Content-Type": "application/json",
    Authorization: `Bearer ${process.env.FIREFLIES_API_KEY}`,
  },
  body: JSON.stringify({
    query: `
      mutation($input: AudioUploadInput) {
        uploadAudio(input: $input) { success title message }
      }
    `,
    variables: {
      input: {
        url: "https://storage.example.com/recording.mp3",
        title: "Client Call 2026-03-22",
        webhook: "https://api.yourapp.com/webhooks/fireflies",
        client_reference_id: "order-12345",
      },
    },
  }),
});
```

### Step 5: Test Webhook

```bash
set -euo pipefail
# Test by uploading a short audio file
curl -s -X POST https://api.fireflies.ai/graphql \
  -H "Authorization: Bearer $FIREFLIES_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "query": "mutation($input: AudioUploadInput) { uploadAudio(input: $input) { success message } }",
    "variables": { "input": { "url": "https://example.com/test-audio.mp3", "title": "Webhook Test" } }
  }' | jq .
# The webhook will fire when transcription completes (usually 2-5 minutes)
```

## Error Handling

| Issue | Cause | Solution |
|-------|-------|----------|
| Webhook not firing | URL not saved in dashboard | Re-register at app.fireflies.ai/settings |
| Invalid signature | Secret mismatch | Verify secret matches dashboard value |
| Missing `meetingId` | Malformed payload | Log raw body, check Fireflies status |
| Webhook only fires for some meetings | Owner-only constraint | Webhooks fire only for your meetings |
| `clientReferenceId` is null | Bot-recorded meeting | Only set on `uploadAudio` calls |

## Output

- HTTPS webhook endpoint with HMAC-SHA256 signature verification
- Automatic transcript fetch on completion events
- Action item extraction and downstream routing
- Per-upload webhook support for custom tracking

## Resources

- [Fireflies Webhooks](https://docs.fireflies.ai/graphql-api/webhooks)
- Webhook Verification Example

## Next Steps

For deployment setup, see `fireflies-deploy-integration`.

---

**Source:** [`jeremylongshore/claude-code-plugins-plus-skills`](https://github.com/jeremylongshore/claude-code-plugins-plus-skills) → `skills/.curated/fireflies-webhooks-events/SKILL.md`

**Also appears in:** `jeremylongshore/claude-code-plugins-plus-skills/plugins/saas-packs/fireflies-pack/skills/fireflies-webhooks-events/SKILL.md`

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.