# Batch Job + Webhook Pipeline Use batch mode when you need to process stored archives asynchronously. ## Flow ```text submit batch job -> receive job_id -> poll /jobs or wait for webhook -> inspect /jobs/{jobId}/files -> ingest transcript outputs ``` ## Submit Example ```bash curl -X POST https://api.zoom.us/v2/aiservices/scribe/jobs -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" -d '{ "input": { "mode": "PREFIX", "source": "S3", "uri": "s3://example-bucket/audio/", "auth": { "aws": { "access_key_id": "...", "secret_access_key": "...", "session_token": "..." } } }, "output": { "destination": "S3", "uri": "s3://example-bucket/transcripts/", "layout": "PREFIX", "auth": { "aws": { "access_key_id": "...", "secret_access_key": "...", "session_token": "..." } } }, "config": { "language": "en-US", "word_time_offsets": true, "channel_separation": true }, "notifications": { "webhook_url": "https://example.com/webhooks/scribe", "secret": "replace-me" } }' ``` ## Webhook Verification Pattern ```js import crypto from 'crypto'; function verifyZoomWebhook(rawBody, timestamp, signature, secret) { const message = `v0:${timestamp}:${rawBody}`; const expected = `sha256=${crypto.createHmac('sha256', secret).update(message).digest('hex')}`; return crypto.timingSafeEqual(Buffer.from(signature), Buffer.from(expected)); } ```