Deepgram Webhooks EventsSAFE
Model-agnostic agent-skills platform with a harness-free canonical layer, verified adapters, and the ccpi package manager. Explore at tonsofskills.com.
Overview
Model-agnostic agent-skills platform with a harness-free canonical layer, verified adapters, and the ccpi package manager. Explore at tonsofskills.com.
4f83675ca38aOBSERVED · 2026-10-08Host compatibility
What the documentation claims. We have not run a compatibility test.
| Host | Status | Notes |
|---|---|---|
| claude-code | mentioned |
What it tells the agent
The instruction file, verbatim from the audited commit — this is the text the model reads, and the surface the audit's instruction layer examines. Quoted here so you can judge it without cloning anything.
--- name: deepgram-webhooks-events description: 'Implement Deepgram callback and webhook handling for async transcription. Use when implementing callback URLs, processing async transcription results, or handling Deepgram event notifications. Trigger: "deepgram callback", "deepgram webhook", "async transcription", "deepgram events", "deepgram notifications", "deepgram async". ' allowed-tools: Read, Write, Edit, Bash(curl:*) version: 1.13.0 license: MIT author: Jeremy Longshore <[email protected]> tags: - saas - deepgram - webhooks - transcription - async compatibility: Designed for Claude Code --- # Deepgram Webhooks & Callbacks ## Prerequisites - A verified callback endpoint, signature/authentication requirements, idempotency store, and redacted observability. - A data-retention/consent decision and an owner for failed callback recovery. ## Examples Validate the callback signature before parsing its body, deduplicate by an opaque event ID, acknowledge promptly, and write only state/result metadata to logs. Test with a development event; retry transient failures with bounded backoff and quarantine terminal failures rather than replaying audio/transcripts blindly. ## Overview Implement async transcription with Deepgram's callback feature. When you pass a `callback` URL, Deepgram returns a `request_id` immediately, processes audio in the background, and POSTs results to your endpoint. Supports HTTP and WebSocket callbacks with automatic retry (10 attempts, 30s intervals). ## Deepgram Callback Flow ``` 1. Client -> POST /v1/listen?callback=https://you.com/webhook (with audio) 2. Deepgram -> 200 { request_id: "..." } (immediate) 3. Deepgram processes audio asynchronously 4. Deepgram -> POST https://you.com/webhook (results) Retries up to 10 times (30s delay) on non-2xx response ``` ## Instructions ### Step 1: Submit Async Transcription ```typescript import { createClient } from '@deepgram/sdk'; const deepgram = createClient(process.env.DEEPGRAM_API_KEY!); async function submitAsync(audioUrl: string, callbackUrl: string) { // Deepgram sends transcription via callback URL instead of // holding the connection open. const { result, error } = await deepgram.listen.prerecorded.transcribeUrl( { url: audioUrl }, { model: 'nova-3', smart_format: true, diarize: true, utterances: true, callback: callbackUrl, // Your HTTPS endpoint // callback_method: 'put', // Optional: use PUT instead of POST } ); if (error) throw new Error(`Submit failed: ${error.message}`); // Deepgram returns immediately with request_id const requestId = result.metadata.request_id; console.log(`Submitted. Request ID: ${requestId}`); console.log(`Results will be POSTed to: ${callbackUrl}`); return requestId; } // Also works with direct curl: // curl -X POST 'https://api.deepgram.com/v1/listen?model=nova-3&callback=https://you.com/webhook' \ // -H "Authorization: Token $DEEPGRAM_API_KEY" \ // -H "Content-Type: application/json" \ // -d '{"url":"https://example.com/audio.wav"}' ``` ### Step 2: Callback Server ```typescript import express from 'express'; import crypto from 'crypto'; const app = express(); // IMPORTANT: Use raw body for HMAC signature verification app.use('/webhooks/deepgram', express.raw({ type: 'application/json', limit: '50mb' })); app.post('/webhooks/deepgram', async (req, res) => { try { // 1. Verify signature (if webhook secret configured) const signature = req.headers['x-deepgram-signature'] as string; if (process.env.DEEPGRAM_WEBHOOK_SECRET && signature) { const expected = crypto .createHmac('sha256', process.env.DEEPGRAM_WEBHOOK_SECRET) .update(req.body) .digest('hex'); // Timing-safe comparison to prevent timing attacks if (!crypto.timingSafeEqual(Buffer.from(signature), Buffer.from(expected))) { console.error('Invalid webhook signature'); return res.status(401).json({ error: 'Invalid signature' }); } } // 2. Parse result const result = JSON.parse(req.body.toString()); const requestId = result.metadata?.request_id; const transcript = result.results?.channels?.[0]?.alternatives?.[0]?.transcript; const duration = result.metadata?.duration; console.log(`Callback received: ${requestId}`); console.log(`Duration: ${duration}s`); console.log(`Transcript: ${transcript?.substring(0, 200)}...`); // 3. Process and store await processTranscriptionResult(requestId, result); // 4. Return 200 — Deepgram retries on non-2xx res.status(200).json({ received: true, request_id: requestId }); } catch (err: any) { console.error('Callback processing error:', err.message); // Return 500 to trigger Deepgram retry res.status(500).json({ error: 'Processing failed' }); } }); async function processTranscriptionResult(requestId: string, result: any) { const transcript = result.results.channels[0].alternatives[0]; // Store transcript const record = { requestId, transcript: transcript.transcript, confidence: transcript.confidence, duration: result.metadata.duration, words: transcript.words?.length ?? 0, utterances: result.results.utterances?.map((u: any) => ({ speaker: u.speaker, text: u.transcript, start: u.start, end: u.end, })), processedAt: new Date().toISOString(), }; // Save to database / notify clients / trigger downstream console.log('Processed:', JSON.stringify(record, null, 2)); return record; } ``` ### Step 3: Job Tracking with Redis ```typescript import Redis from 'ioredis'; const redis = new Redis(process.env.REDIS_URL ?? 'redis://localhost:6379'); class TranscriptionJobTracker { async submit(requestId: string, metadata: Record<string, any>) { await redis.hset(`job:${requestId}`, { status: 'processing', submittedAt: new Date().
Trust audit
SAFEgrade B · trust 89/100 Nothing in the source contradicts what it says it does. Grade A is reserved for packages that have also passed the behavioural sandbox.
| Layer | What it checks | Result |
|---|---|---|
| L0 | Provenance & inventory | PASS |
| L1 | Static analysis of the code | PASS |
| L2 | Instruction surface (what it tells the agent) | PASS |
| L3 | Class-specific surface | PASS |
| L4 | Behavioural (sandbox) | SKIPPED |
What the source does
- Filesystem
- none-observed
- Network
- none-observed
- Shell
- none-observed
- Dependencies
- pinned
- Secrets in source
- none-found
Findings (0)
No findings outside the package's declared scope.
Gates applied: no_behavioural_pass.
4f83675ca38afull audit observations/trust-audit/skill/jeremylongshore__deepgram-webhooks-events.json · Report an issue / request a re-scanAudit history
Every audit this skill has had.
| Date | Source | Verdict | Grade | Score | Change |
|---|---|---|---|---|---|
| 2026-10-08 | 4f83675ca38a | SAFE | B | 89 | first audit |
Questions
What does the Deepgram Webhooks Events skill do?
Model-agnostic agent-skills platform with a harness-free canonical layer, verified adapters, and the ccpi package manager. Explore at tonsofskills.com.
Is Deepgram Webhooks Events safe to install?
The audit found nothing in the source that contradicts what it says it does, and graded it B (89/100). Grade A is held back for packages that have also passed a sandboxed behavioural run, which is why a clean skill reads B.
What can Deepgram Webhooks Events access on my machine?
The audit observed no filesystem, network or shell use at all in its source.
Which assistants does Deepgram Webhooks Events work with?
Its documentation mentions claude-code. That is what the text claims, not a compatibility test we ran.
How current is this page?
The grade is for one exact copy of the source (4f83675ca38a), read on 2026-10-08. The repository is watched, and a new audit runs when it changes — this is the first audit.