Skip to main content
deepgram-webhooks-events 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".
Ir a la instalación Skills Marketplace Descubre y explora habilidades de IA creadas por la comunidad.
Instalar con Codex o Claude Copia este prompt, pégalo en Codex, Claude u otro asistente, y deja que revise la página de la skill y la instale por ti.
Copiar promptMostrar detalles del prompt Un comando directo omite el prompt de revisión. Revisa el origen antes de ejecutarlo.
npx skills add https://github.com/jeremylongshore/claude-code-plugins-plus-skills --skill deepgram-webhooks-eventsEl comando permanece en una sola línea. Desplázate horizontalmente para revisarlo antes de copiarlo.
¿Prefieres una copia local? Descarga los archivos que SkillsMP tiene disponibles ahora.
Descargar Zip Descargando... Más de este repositorio Implement user sign-up and sign-in flows with Clerk.
Use when building authentication UI, customizing sign-in experience,
or implementing OAuth social login.
Trigger with phrases like "clerk sign-in", "clerk sign-up",
"clerk login flow", "clerk OAuth", "clerk social login".
Implement session management and middleware with Clerk.
Use when managing user sessions, configuring route protection,
or implementing token refresh and custom JWT templates.
Trigger with phrases like "clerk session", "clerk middleware",
"clerk route protection", "clerk token", "clerk JWT".
Configure enterprise SSO, role-based access control, and organization management.
Use when implementing SSO integration, configuring role-based permissions,
or setting up organization-level controls.
Trigger with phrases like "clerk SSO", "clerk RBAC",
"clerk enterprise", "clerk roles", "clerk permissions", "clerk organizations".
Explorador de archivos
2 archivos Ocupaciones relacionadas SOC
Basado en la clasificación ocupacional SOC
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 <jeremy@intentsolutions.io> tags ["saas","deepgram","webhooks","transcription","async"] compatibility Designed for Claude Code, also compatible with Codex and OpenClaw
Deepgram Webhooks & Callbacks
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
import { createClient } from '@deepgram/sdk' ;
const deepgram = createClient (process.env .DEEPGRAM_API_KEY !);
async function submitAsync (audioUrl : string , callbackUrl : string ) {
const { result, error } = await deepgram.listen .prerecorded .transcribeUrl (
{ url : audioUrl },
{
model : 'nova-3' ,
smart_format : true ,
diarize : true ,
utterances : true ,
callback : callbackUrl,
}
);
(error) ( );
requestId = result. . ;
. ( );
. ( );
requestId;
}
if
throw
new
Error
`Submit failed: ${error.message} `
const
metadata
request_id
console
log
`Submitted. Request ID: ${requestId} `
console
log
`Results will be POSTed to: ${callbackUrl} `
return
Step 2: Callback Server import express from 'express' ;
import crypto from 'crypto' ;
const app = express ();
app.use ('/webhooks/deepgram' , express.raw ({ type : 'application/json' , limit : '50mb' }));
app.post ('/webhooks/deepgram' , async (req, res) => {
try {
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' );
if (!crypto.timingSafeEqual (Buffer .from (signature), Buffer .from (expected))) {
console .error ('Invalid webhook signature' );
return res.status (401 ).json ({ error : 'Invalid signature' });
}
}
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 )} ...` );
await processTranscriptionResult (requestId, result);
res.status (200 ).json ({ received : true , request_id : requestId });
} catch (err : any ) {
console .error ('Callback processing error:' , err.message );
res.status (500 ).json ({ error : 'Processing failed' });
}
});
async function processTranscriptionResult (requestId : string , result : any ) {
const transcript = result.results .channels [0 ].alternatives [0 ];
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 (),
};
console .log ('Processed:' , JSON .stringify (record, null , 2 ));
return record;
}
Step 3: Job Tracking with Redis 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 ().toISOString (),
...metadata,
});
await redis.expire (`job:${requestId} ` , 86400 );
}
async complete (requestId : string , result : any ) {
await redis.hset (`job:${requestId} ` , {
status : 'completed' ,
completedAt : new Date ().toISOString (),
transcript : result.results .channels [0 ].alternatives [0 ].transcript ,
duration : result.metadata .duration ,
});
await redis.publish ('transcription:complete' , JSON .stringify ({
requestId,
duration : result.metadata .duration ,
}));
}
async getStatus (requestId : string ) {
return redis.hgetall (`job:${requestId} ` );
}
}
app.get ('/api/transcription/:requestId' , async (req, res) => {
const tracker = new TranscriptionJobTracker ();
const status = await tracker.getStatus (req.params .requestId );
if (!status || Object .keys (status).length === 0 ) {
return res.status (404 ).json ({ error : 'Job not found' });
}
res.json (status);
});
Step 4: Client SDK with Submit/Poll/Wait class AsyncTranscriptionClient {
private deepgram : ReturnType <typeof createClient>;
private baseUrl : string ;
constructor (apiKey : string , serverBaseUrl : string ) {
this .deepgram = createClient (apiKey);
this .baseUrl = serverBaseUrl;
}
async submit (audioUrl : string ): Promise <string > {
const callbackUrl = `${this .baseUrl} /webhooks/deepgram` ;
const { result, error } = await this .deepgram .listen .prerecorded .transcribeUrl (
{ url : audioUrl },
{ model : 'nova-3' , smart_format : true , diarize : true , callback : callbackUrl }
);
if (error) throw error;
return result.metadata .request_id ;
}
async poll (requestId : string ): Promise <any > {
const res = await fetch (`${this .baseUrl} /api/transcription/${requestId} ` );
if (res.status === 404 ) return null ;
return res.json ();
}
async waitForResult (requestId : string , timeoutMs = 300000 ): Promise <any > {
const start = Date .now ();
while (Date .now () - start < timeoutMs) {
const status = await this .poll (requestId);
if (status?.status === 'completed' ) return status;
if (status?.status === 'failed' ) throw new Error ('Transcription failed' );
await new Promise (r => setTimeout (r, 2000 ));
}
throw new Error ('Timeout waiting for transcription' );
}
}
const client = new AsyncTranscriptionClient (
process.env .DEEPGRAM_API_KEY !,
'https://your-server.com'
);
const requestId = await client.submit ('https://example.com/long-recording.wav' );
const result = await client.waitForResult (requestId);
Step 5: Local Testing with ngrok
ngrok http 3000
curl -X POST 'https://api.deepgram.com/v1/listen?model=nova-3&callback=https://abc123.ngrok.io/webhooks/deepgram' \
-H "Authorization: Token $DEEPGRAM_API_KEY " \
-H "Content-Type: application/json" \
-d '{"url":"https://static.deepgram.com/examples/nasa-podcast.wav"}'
Step 6: Idempotent Processing
const processedRequests = new Set <string >();
app.post ('/webhooks/deepgram' , async (req, res) => {
const result = JSON .parse (req.body .toString ());
const requestId = result.metadata ?.request_id ;
if (processedRequests.has (requestId)) {
console .log (`Duplicate callback for ${requestId} — skipping` );
return res.status (200 ).json ({ received : true , duplicate : true });
}
processedRequests.add (requestId);
await processTranscriptionResult (requestId, result);
res.status (200 ).json ({ received : true });
});
Output
Async transcription submission with callback URL
Callback server with signature verification
Redis-backed job tracking with pub/sub notifications
Client SDK with submit/poll/wait pattern
Idempotent callback processing
Local testing setup with ngrok
Error Handling Issue Cause Solution Callback not received Endpoint unreachable Check HTTPS, firewall, use ngrok for local Duplicate callbacks Deepgram retry after slow response Implement idempotency with request_id Invalid signature Wrong webhook secret Verify DEEPGRAM_WEBHOOK_SECRET matches Console Processing timeout Slow downstream Return 200 immediately, process async Large payload Long audio transcript Increase express.raw limit
Resources