chub-dev 0.1.0 → 0.1.2-beta.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (139) hide show
  1. package/README.md +55 -0
  2. package/bin/chub-mcp +2 -0
  3. package/dist/airtable/docs/database/javascript/DOC.md +1437 -0
  4. package/dist/airtable/docs/database/python/DOC.md +1735 -0
  5. package/dist/amplitude/docs/analytics/javascript/DOC.md +1282 -0
  6. package/dist/amplitude/docs/analytics/python/DOC.md +1199 -0
  7. package/dist/anthropic/docs/claude-api/javascript/DOC.md +503 -0
  8. package/dist/anthropic/docs/claude-api/python/DOC.md +389 -0
  9. package/dist/asana/docs/tasks/DOC.md +1396 -0
  10. package/dist/assemblyai/docs/transcription/DOC.md +1043 -0
  11. package/dist/atlassian/docs/confluence/javascript/DOC.md +1347 -0
  12. package/dist/atlassian/docs/confluence/python/DOC.md +1604 -0
  13. package/dist/auth0/docs/identity/javascript/DOC.md +968 -0
  14. package/dist/auth0/docs/identity/python/DOC.md +1199 -0
  15. package/dist/aws/docs/s3/javascript/DOC.md +1773 -0
  16. package/dist/aws/docs/s3/python/DOC.md +1807 -0
  17. package/dist/binance/docs/trading/javascript/DOC.md +1315 -0
  18. package/dist/binance/docs/trading/python/DOC.md +1454 -0
  19. package/dist/braintree/docs/gateway/javascript/DOC.md +1278 -0
  20. package/dist/braintree/docs/gateway/python/DOC.md +1179 -0
  21. package/dist/chromadb/docs/embeddings-db/javascript/DOC.md +1263 -0
  22. package/dist/chromadb/docs/embeddings-db/python/DOC.md +1707 -0
  23. package/dist/clerk/docs/auth/javascript/DOC.md +1220 -0
  24. package/dist/clerk/docs/auth/python/DOC.md +274 -0
  25. package/dist/cloudflare/docs/workers/javascript/DOC.md +918 -0
  26. package/dist/cloudflare/docs/workers/python/DOC.md +994 -0
  27. package/dist/cockroachdb/docs/distributed-db/DOC.md +1500 -0
  28. package/dist/cohere/docs/llm/DOC.md +1335 -0
  29. package/dist/datadog/docs/monitoring/javascript/DOC.md +1740 -0
  30. package/dist/datadog/docs/monitoring/python/DOC.md +1815 -0
  31. package/dist/deepgram/docs/speech/javascript/DOC.md +885 -0
  32. package/dist/deepgram/docs/speech/python/DOC.md +685 -0
  33. package/dist/deepl/docs/translation/javascript/DOC.md +887 -0
  34. package/dist/deepl/docs/translation/python/DOC.md +944 -0
  35. package/dist/deepseek/docs/llm/DOC.md +1220 -0
  36. package/dist/directus/docs/headless-cms/javascript/DOC.md +1128 -0
  37. package/dist/directus/docs/headless-cms/python/DOC.md +1276 -0
  38. package/dist/discord/docs/bot/javascript/DOC.md +1090 -0
  39. package/dist/discord/docs/bot/python/DOC.md +1130 -0
  40. package/dist/elasticsearch/docs/search/DOC.md +1634 -0
  41. package/dist/elevenlabs/docs/text-to-speech/javascript/DOC.md +336 -0
  42. package/dist/elevenlabs/docs/text-to-speech/python/DOC.md +552 -0
  43. package/dist/firebase/docs/auth/DOC.md +1015 -0
  44. package/dist/gemini/docs/genai/javascript/DOC.md +691 -0
  45. package/dist/gemini/docs/genai/python/DOC.md +555 -0
  46. package/dist/github/docs/octokit/DOC.md +1560 -0
  47. package/dist/google/docs/bigquery/javascript/DOC.md +1688 -0
  48. package/dist/google/docs/bigquery/python/DOC.md +1503 -0
  49. package/dist/hubspot/docs/crm/javascript/DOC.md +1805 -0
  50. package/dist/hubspot/docs/crm/python/DOC.md +2033 -0
  51. package/dist/huggingface/docs/transformers/DOC.md +948 -0
  52. package/dist/intercom/docs/messaging/javascript/DOC.md +1844 -0
  53. package/dist/intercom/docs/messaging/python/DOC.md +1797 -0
  54. package/dist/jira/docs/issues/javascript/DOC.md +1420 -0
  55. package/dist/jira/docs/issues/python/DOC.md +1492 -0
  56. package/dist/kafka/docs/streaming/javascript/DOC.md +1671 -0
  57. package/dist/kafka/docs/streaming/python/DOC.md +1464 -0
  58. package/dist/landingai-ade/docs/api/DOC.md +620 -0
  59. package/dist/landingai-ade/docs/sdk/python/DOC.md +489 -0
  60. package/dist/landingai-ade/docs/sdk/typescript/DOC.md +542 -0
  61. package/dist/landingai-ade/skills/SKILL.md +489 -0
  62. package/dist/launchdarkly/docs/feature-flags/javascript/DOC.md +1191 -0
  63. package/dist/launchdarkly/docs/feature-flags/python/DOC.md +1671 -0
  64. package/dist/linear/docs/tracker/DOC.md +1554 -0
  65. package/dist/livekit/docs/realtime/javascript/DOC.md +303 -0
  66. package/dist/livekit/docs/realtime/python/DOC.md +163 -0
  67. package/dist/mailchimp/docs/marketing/DOC.md +1420 -0
  68. package/dist/meilisearch/docs/search/DOC.md +1241 -0
  69. package/dist/microsoft/docs/onedrive/javascript/DOC.md +1421 -0
  70. package/dist/microsoft/docs/onedrive/python/DOC.md +1549 -0
  71. package/dist/mongodb/docs/atlas/DOC.md +2041 -0
  72. package/dist/notion/docs/workspace-api/javascript/DOC.md +1435 -0
  73. package/dist/notion/docs/workspace-api/python/DOC.md +1400 -0
  74. package/dist/okta/docs/identity/javascript/DOC.md +1171 -0
  75. package/dist/okta/docs/identity/python/DOC.md +1401 -0
  76. package/dist/openai/docs/chat/javascript/DOC.md +407 -0
  77. package/dist/openai/docs/chat/python/DOC.md +568 -0
  78. package/dist/paypal/docs/checkout/DOC.md +278 -0
  79. package/dist/pinecone/docs/sdk/javascript/DOC.md +984 -0
  80. package/dist/pinecone/docs/sdk/python/DOC.md +1395 -0
  81. package/dist/plaid/docs/banking/javascript/DOC.md +1163 -0
  82. package/dist/plaid/docs/banking/python/DOC.md +1203 -0
  83. package/dist/playwright-community/skills/login-flows/SKILL.md +108 -0
  84. package/dist/postmark/docs/transactional-email/DOC.md +1168 -0
  85. package/dist/prisma/docs/orm/javascript/DOC.md +1419 -0
  86. package/dist/prisma/docs/orm/python/DOC.md +1317 -0
  87. package/dist/qdrant/docs/vector-search/javascript/DOC.md +1221 -0
  88. package/dist/qdrant/docs/vector-search/python/DOC.md +1653 -0
  89. package/dist/rabbitmq/docs/message-queue/javascript/DOC.md +1193 -0
  90. package/dist/rabbitmq/docs/message-queue/python/DOC.md +1243 -0
  91. package/dist/razorpay/docs/payments/javascript/DOC.md +1219 -0
  92. package/dist/razorpay/docs/payments/python/DOC.md +1330 -0
  93. package/dist/redis/docs/key-value/javascript/DOC.md +1851 -0
  94. package/dist/redis/docs/key-value/python/DOC.md +2054 -0
  95. package/dist/registry.json +2817 -0
  96. package/dist/replicate/docs/model-hosting/DOC.md +1318 -0
  97. package/dist/resend/docs/email/DOC.md +1271 -0
  98. package/dist/salesforce/docs/crm/javascript/DOC.md +1241 -0
  99. package/dist/salesforce/docs/crm/python/DOC.md +1183 -0
  100. package/dist/search-index.json +1 -0
  101. package/dist/sendgrid/docs/email-api/javascript/DOC.md +371 -0
  102. package/dist/sendgrid/docs/email-api/python/DOC.md +656 -0
  103. package/dist/sentry/docs/error-tracking/javascript/DOC.md +1073 -0
  104. package/dist/sentry/docs/error-tracking/python/DOC.md +1309 -0
  105. package/dist/shopify/docs/storefront/DOC.md +457 -0
  106. package/dist/slack/docs/workspace/javascript/DOC.md +933 -0
  107. package/dist/slack/docs/workspace/python/DOC.md +271 -0
  108. package/dist/square/docs/payments/javascript/DOC.md +1855 -0
  109. package/dist/square/docs/payments/python/DOC.md +1728 -0
  110. package/dist/stripe/docs/api/DOC.md +1727 -0
  111. package/dist/stripe/docs/payments/DOC.md +1726 -0
  112. package/dist/stytch/docs/auth/javascript/DOC.md +1813 -0
  113. package/dist/stytch/docs/auth/python/DOC.md +1962 -0
  114. package/dist/supabase/docs/client/DOC.md +1606 -0
  115. package/dist/twilio/docs/messaging/python/DOC.md +469 -0
  116. package/dist/twilio/docs/messaging/typescript/DOC.md +946 -0
  117. package/dist/vercel/docs/platform/DOC.md +1940 -0
  118. package/dist/weaviate/docs/vector-db/javascript/DOC.md +1268 -0
  119. package/dist/weaviate/docs/vector-db/python/DOC.md +1388 -0
  120. package/dist/zendesk/docs/support/javascript/DOC.md +2150 -0
  121. package/dist/zendesk/docs/support/python/DOC.md +2297 -0
  122. package/package.json +22 -6
  123. package/skills/get-api-docs/SKILL.md +84 -0
  124. package/src/commands/annotate.js +83 -0
  125. package/src/commands/build.js +12 -1
  126. package/src/commands/feedback.js +150 -0
  127. package/src/commands/get.js +83 -42
  128. package/src/commands/search.js +7 -0
  129. package/src/index.js +43 -17
  130. package/src/lib/analytics.js +90 -0
  131. package/src/lib/annotations.js +57 -0
  132. package/src/lib/bm25.js +170 -0
  133. package/src/lib/cache.js +69 -6
  134. package/src/lib/config.js +8 -3
  135. package/src/lib/identity.js +99 -0
  136. package/src/lib/registry.js +103 -20
  137. package/src/lib/telemetry.js +86 -0
  138. package/src/mcp/server.js +177 -0
  139. package/src/mcp/tools.js +251 -0
@@ -0,0 +1,1043 @@
1
+ ---
2
+ name: transcription
3
+ description: "AssemblyAI JavaScript SDK coding guide for speech-to-text transcription"
4
+ metadata:
5
+ languages: "javascript"
6
+ versions: "4.18.4"
7
+ updated-on: "2026-03-02"
8
+ source: maintainer
9
+ tags: "assemblyai,transcription,speech-to-text,audio,ai"
10
+ ---
11
+
12
+ # AssemblyAI JavaScript SDK Coding Guide
13
+
14
+ ## 1. Golden Rule
15
+
16
+ **Always use the official AssemblyAI JavaScript SDK:**
17
+
18
+ Package name: `assemblyai`
19
+
20
+ To check the latest version, run:
21
+ ```bash
22
+ npm view assemblyai version
23
+ ```
24
+
25
+ **Never use deprecated, unofficial, or direct HTTP clients.** The official `assemblyai` package is the only supported JavaScript/TypeScript SDK maintained by AssemblyAI. It provides type-safe interfaces, automatic polling, streaming support, and simplified error handling.
26
+
27
+ ## 2. Installation
28
+
29
+ ### npm
30
+ ```bash
31
+ npm install assemblyai
32
+ ```
33
+
34
+ ### yarn
35
+ ```bash
36
+ yarn add assemblyai
37
+ ```
38
+
39
+ ### pnpm
40
+ ```bash
41
+ pnpm add assemblyai
42
+ ```
43
+
44
+ **Environment Variables (Required):**
45
+ ```bash
46
+ ASSEMBLYAI_API_KEY=your_api_key_here
47
+ ```
48
+
49
+ **Get your API key:**
50
+
51
+ Sign up at https://www.assemblyai.com, navigate to the AssemblyAI Dashboard, and copy your API key from the "Your API Key" section.
52
+
53
+ ## 3. Initialization
54
+
55
+ ### Basic Client Initialization
56
+ ```javascript
57
+ import { AssemblyAI } from "assemblyai";
58
+
59
+ const client = new AssemblyAI({
60
+ apiKey: process.env.ASSEMBLYAI_API_KEY,
61
+ });
62
+ ```
63
+
64
+ ### With Custom Configuration
65
+ ```javascript
66
+ const client = new AssemblyAI({
67
+ apiKey: process.env.ASSEMBLYAI_API_KEY,
68
+ // Optional: Custom base URL (for testing or proxy)
69
+ baseUrl: "https://api.assemblyai.com",
70
+ });
71
+ ```
72
+
73
+ **Authentication Best Practice:**
74
+ The SDK reads from the `ASSEMBLYAI_API_KEY` environment variable by default. Always store API keys in environment variables, never hardcode them in source code.
75
+
76
+ ## 4. Core API Surfaces
77
+
78
+ ### 4.1 Async Transcription
79
+
80
+ Async transcription processes pre-recorded audio files. The SDK automatically polls the transcription status until completion.
81
+
82
+ **Minimal Example (Transcribe from URL):**
83
+ ```javascript
84
+ const transcript = await client.transcripts.transcribe({
85
+ audio: "https://example.com/audio.mp3",
86
+ });
87
+
88
+ console.log(transcript.text);
89
+ ```
90
+
91
+ **Minimal Example (Transcribe from Local File):**
92
+ ```javascript
93
+ const transcript = await client.transcripts.transcribe({
94
+ audio: "./path/to/local/audio.mp3",
95
+ });
96
+
97
+ console.log(transcript.text);
98
+ ```
99
+
100
+ **Advanced Example with Audio Intelligence:**
101
+ ```javascript
102
+ const transcript = await client.transcripts.transcribe({
103
+ audio: "https://example.com/meeting.mp3",
104
+ // Speaker identification
105
+ speaker_labels: true,
106
+ speakers_expected: 2,
107
+
108
+ // Audio intelligence features
109
+ sentiment_analysis: true,
110
+ entity_detection: true,
111
+ auto_highlights: true,
112
+ content_safety: true,
113
+ iab_categories: true,
114
+
115
+ // Language detection and translation
116
+ language_code: "en",
117
+ language_detection: false,
118
+
119
+ // Formatting options
120
+ format_text: true,
121
+ punctuate: true,
122
+ disfluencies: false,
123
+
124
+ // Custom vocabulary
125
+ word_boost: ["AssemblyAI", "JavaScript", "Node.js"],
126
+ boost_param: "high",
127
+ });
128
+
129
+ // Access results
130
+ console.log(transcript.text);
131
+ console.log(transcript.sentiment_analysis_results);
132
+ console.log(transcript.entities);
133
+ console.log(transcript.auto_highlights_result);
134
+ ```
135
+
136
+ **Transcribe Without Waiting (Webhook or Manual Polling):**
137
+ ```javascript
138
+ // Submit transcription without waiting
139
+ const transcript = await client.transcripts.submit({
140
+ audio: "https://example.com/audio.mp3",
141
+ webhook_url: "https://your-domain.com/webhook",
142
+ });
143
+
144
+ console.log(transcript.id); // Use this ID to check status later
145
+
146
+ // Later, retrieve the transcript
147
+ const result = await client.transcripts.get(transcript.id);
148
+ if (result.status === "completed") {
149
+ console.log(result.text);
150
+ } else if (result.status === "error") {
151
+ console.error(result.error);
152
+ }
153
+ ```
154
+
155
+ ### 4.2 Real-Time Streaming Transcription
156
+
157
+ Real-time transcription provides live speech-to-text with low latency (300ms P50 on final transcripts).
158
+
159
+ **Minimal Example:**
160
+ ```javascript
161
+ import { RealtimeTranscriber } from "assemblyai";
162
+
163
+ const transcriber = new RealtimeTranscriber({
164
+ apiKey: process.env.ASSEMBLYAI_API_KEY,
165
+ sampleRate: 16000,
166
+ });
167
+
168
+ transcriber.on("open", ({ sessionId }) => {
169
+ console.log("Session opened:", sessionId);
170
+ });
171
+
172
+ transcriber.on("transcript", (transcript) => {
173
+ if (!transcript.text) return;
174
+
175
+ if (transcript.message_type === "FinalTranscript") {
176
+ console.log("Final:", transcript.text);
177
+ } else {
178
+ console.log("Partial:", transcript.text);
179
+ }
180
+ });
181
+
182
+ transcriber.on("error", (error) => {
183
+ console.error("Error:", error);
184
+ });
185
+
186
+ transcriber.on("close", (code, reason) => {
187
+ console.log("Session closed:", code, reason);
188
+ });
189
+
190
+ // Connect to the streaming service
191
+ await transcriber.connect();
192
+
193
+ // Send audio data (16-bit PCM audio)
194
+ transcriber.sendAudio(audioChunk);
195
+
196
+ // Close when done
197
+ await transcriber.close();
198
+ ```
199
+
200
+ **Advanced Example with Audio Intelligence:**
201
+ ```javascript
202
+ const transcriber = new RealtimeTranscriber({
203
+ apiKey: process.env.ASSEMBLYAI_API_KEY,
204
+ sampleRate: 16000,
205
+ encoding: "pcm_s16le",
206
+
207
+ // Enable word-level timestamps
208
+ word_boost: ["AssemblyAI", "JavaScript"],
209
+
210
+ // Disable automatic punctuation
211
+ disable_partial_transcripts: false,
212
+
213
+ // End utterance silence threshold
214
+ end_utterance_silence_threshold: 500,
215
+ });
216
+
217
+ transcriber.on("transcript", (transcript) => {
218
+ if (transcript.message_type === "FinalTranscript") {
219
+ console.log("Final transcript:", transcript.text);
220
+ console.log("Confidence:", transcript.confidence);
221
+ console.log("Words:", transcript.words);
222
+ } else if (transcript.message_type === "PartialTranscript") {
223
+ console.log("Partial:", transcript.text);
224
+ }
225
+ });
226
+
227
+ await transcriber.connect();
228
+
229
+ // Stream from microphone or file
230
+ const stream = getMicrophoneStream(); // Your audio source
231
+ stream.on("data", (chunk) => {
232
+ transcriber.sendAudio(chunk);
233
+ });
234
+ ```
235
+
236
+ **Streaming with Temporary Token (Client-Side Security):**
237
+ ```javascript
238
+ // Server-side: Generate temporary token
239
+ const token = await client.realtime.createTemporaryToken({
240
+ expires_in: 3600, // 1 hour
241
+ });
242
+ // Send token to client
243
+
244
+ // Client-side: Use token instead of API key
245
+ import { RealtimeTranscriber } from "assemblyai";
246
+
247
+ const transcriber = new RealtimeTranscriber({
248
+ token: temporaryToken, // Use token instead of apiKey
249
+ sampleRate: 16000,
250
+ });
251
+ ```
252
+
253
+ ### 4.3 PII Redaction
254
+
255
+ Automatically detect and redact 23 categories of Personally Identifiable Information (PII).
256
+
257
+ **Minimal Example:**
258
+ ```javascript
259
+ const transcript = await client.transcripts.transcribe({
260
+ audio: "https://example.com/audio.mp3",
261
+ redact_pii: true,
262
+ redact_pii_policies: ["us_social_security_number", "credit_card_number"],
263
+ });
264
+
265
+ console.log(transcript.text); // PII replaced with [REDACTED]
266
+ ```
267
+
268
+ **Advanced Example with Audio Redaction:**
269
+ ```javascript
270
+ const transcript = await client.transcripts.transcribe({
271
+ audio: "https://example.com/sensitive-call.mp3",
272
+
273
+ // Text redaction
274
+ redact_pii: true,
275
+ redact_pii_policies: [
276
+ "us_social_security_number",
277
+ "credit_card_number",
278
+ "credit_card_cvv",
279
+ "date_of_birth",
280
+ "drivers_license",
281
+ "email_address",
282
+ "phone_number",
283
+ "medical_condition",
284
+ "medication",
285
+ "person_name",
286
+ ],
287
+ redact_pii_sub: "hash", // Options: "hash" or "entity_name"
288
+
289
+ // Audio redaction
290
+ redact_pii_audio: true,
291
+ redact_pii_audio_quality: "mp3", // Options: "mp3" or "wav"
292
+ });
293
+
294
+ console.log(transcript.text); // Text with PII redacted
295
+ console.log(transcript.redacted_audio_url); // URL to redacted audio file
296
+
297
+ // Download redacted audio
298
+ if (transcript.redacted_audio_url) {
299
+ const redactedAudio = await fetch(transcript.redacted_audio_url);
300
+ // Process redacted audio
301
+ }
302
+ ```
303
+
304
+ **Available PII Categories:**
305
+
306
+ To see the complete list of 23+ available PII categories, check the TypeScript types or run:
307
+ ```bash
308
+ npm info assemblyai | grep -A 50 "redact_pii_policies"
309
+ ```
310
+
311
+ Or view the official documentation at https://www.assemblyai.com/docs/audio-intelligence/pii-redaction for the most up-to-date list of supported PII categories including SSN, credit cards, medical information, and more.
312
+
313
+ ### 4.4 Speaker Diarization
314
+
315
+ Identify and label different speakers in audio (up to 10 speakers).
316
+
317
+ **Minimal Example:**
318
+ ```javascript
319
+ const transcript = await client.transcripts.transcribe({
320
+ audio: "https://example.com/meeting.mp3",
321
+ speaker_labels: true,
322
+ });
323
+
324
+ // Access speaker-labeled words
325
+ for (const utterance of transcript.utterances) {
326
+ console.log(`Speaker ${utterance.speaker}: ${utterance.text}`);
327
+ }
328
+ ```
329
+
330
+ **Advanced Example:**
331
+ ```javascript
332
+ const transcript = await client.transcripts.transcribe({
333
+ audio: "https://example.com/conference-call.mp3",
334
+ speaker_labels: true,
335
+ speakers_expected: 4, // Hint for better accuracy
336
+
337
+ // Combine with other features
338
+ sentiment_analysis: true,
339
+ entity_detection: true,
340
+ });
341
+
342
+ // Analyze per-speaker sentiment
343
+ const speakerSentiments = {};
344
+ for (const result of transcript.sentiment_analysis_results) {
345
+ const speaker = result.speaker;
346
+ if (!speakerSentiments[speaker]) {
347
+ speakerSentiments[speaker] = [];
348
+ }
349
+ speakerSentiments[speaker].push(result.sentiment);
350
+ }
351
+
352
+ console.log("Speaker sentiments:", speakerSentiments);
353
+
354
+ // Get full utterances with timestamps
355
+ for (const utterance of transcript.utterances) {
356
+ console.log({
357
+ speaker: utterance.speaker,
358
+ text: utterance.text,
359
+ start: utterance.start,
360
+ end: utterance.end,
361
+ confidence: utterance.confidence,
362
+ });
363
+ }
364
+ ```
365
+
366
+ ### 4.5 LeMUR - Apply LLMs to Audio
367
+
368
+ LeMUR (Leveraging Large Language Models to Understand Recordings) applies powerful LLMs to transcribed speech for summarization, Q&A, action items, and custom tasks.
369
+
370
+ **Question & Answer:**
371
+ ```javascript
372
+ const transcript = await client.transcripts.transcribe({
373
+ audio: "https://example.com/meeting.mp3",
374
+ });
375
+
376
+ const { response } = await client.lemur.question({
377
+ transcript_ids: [transcript.id],
378
+ questions: [
379
+ {
380
+ question: "What were the main action items discussed?",
381
+ answer_format: "bullet points",
382
+ },
383
+ {
384
+ question: "Who was assigned to work on the new feature?",
385
+ },
386
+ ],
387
+ });
388
+
389
+ console.log(response);
390
+ ```
391
+
392
+ **Summarization:**
393
+ ```javascript
394
+ const { response } = await client.lemur.summary({
395
+ transcript_ids: [transcript.id],
396
+ answer_format: "one sentence",
397
+ context: "This is a sales call between a sales rep and a potential customer",
398
+ });
399
+
400
+ console.log("Summary:", response);
401
+ ```
402
+
403
+ **Action Items:**
404
+ ```javascript
405
+ const { response } = await client.lemur.actionItems({
406
+ transcript_ids: [transcript.id],
407
+ });
408
+
409
+ console.log("Action items:", response);
410
+ ```
411
+
412
+ **Custom Task:**
413
+ ```javascript
414
+ const { response } = await client.lemur.task({
415
+ transcript_ids: [transcript.id],
416
+ prompt: "Identify the key risks discussed in this meeting and categorize them as technical, financial, or operational. Return as JSON with structure: {technical: [], financial: [], operational: []}",
417
+ final_model: "anthropic/claude-3-5-sonnet",
418
+ });
419
+
420
+ console.log(response);
421
+ ```
422
+
423
+ **Advanced LeMUR with Multiple Transcripts:**
424
+ ```javascript
425
+ // Transcribe multiple files
426
+ const transcript1 = await client.transcripts.transcribe({
427
+ audio: "https://example.com/day1.mp3",
428
+ });
429
+ const transcript2 = await client.transcripts.transcribe({
430
+ audio: "https://example.com/day2.mp3",
431
+ });
432
+
433
+ // Analyze all transcripts together
434
+ const { response } = await client.lemur.task({
435
+ transcript_ids: [transcript1.id, transcript2.id],
436
+ prompt: `Analyze these two conference sessions and:
437
+ 1. Identify common themes
438
+ 2. List key speakers and their main points
439
+ 3. Suggest follow-up topics for the next conference
440
+
441
+ Return as structured markdown.`,
442
+ final_model: "anthropic/claude-3-5-sonnet",
443
+ max_output_size: 4000,
444
+ temperature: 0.3,
445
+ });
446
+
447
+ console.log(response);
448
+ ```
449
+
450
+ **Available LeMUR Models:**
451
+
452
+ To see the current list of supported LLM models, check the official documentation at https://www.assemblyai.com/docs/api-reference/lemur or inspect the TypeScript types. As of 2025, Claude 3.5 Sonnet is recommended for most tasks.
453
+
454
+ ### 4.6 Content Moderation
455
+
456
+ Detect sensitive or inappropriate content across multiple categories.
457
+
458
+ **Minimal Example:**
459
+ ```javascript
460
+ const transcript = await client.transcripts.transcribe({
461
+ audio: "https://example.com/content.mp3",
462
+ content_safety: true,
463
+ });
464
+
465
+ for (const result of transcript.content_safety_labels.results) {
466
+ console.log(`${result.text}: ${result.labels.map(l => l.label).join(", ")}`);
467
+ }
468
+ ```
469
+
470
+ **Advanced Example:**
471
+ ```javascript
472
+ const transcript = await client.transcripts.transcribe({
473
+ audio: "https://example.com/user-generated-content.mp3",
474
+ content_safety: true,
475
+
476
+ // Set confidence threshold
477
+ content_safety_confidence: 75,
478
+ });
479
+
480
+ // Filter high-severity content
481
+ const severityThreshold = 0.8;
482
+ const flaggedContent = transcript.content_safety_labels.results.filter(
483
+ (result) => result.labels.some(label => label.confidence > severityThreshold)
484
+ );
485
+
486
+ if (flaggedContent.length > 0) {
487
+ console.log("Flagged content detected:");
488
+ for (const item of flaggedContent) {
489
+ console.log({
490
+ text: item.text,
491
+ timestamp: `${item.timestamp.start}ms - ${item.timestamp.end}ms`,
492
+ labels: item.labels.map(l => ({
493
+ category: l.label,
494
+ confidence: l.confidence,
495
+ severity: l.severity,
496
+ })),
497
+ });
498
+ }
499
+ }
500
+
501
+ // Summary of content safety
502
+ console.log("Summary:", transcript.content_safety_labels.summary);
503
+ ```
504
+
505
+ **Content Safety Categories:**
506
+
507
+ To see the complete list of content moderation categories, check the official documentation at https://www.assemblyai.com/docs/audio-intelligence/content-moderation or inspect the SDK TypeScript types for `ContentSafetyLabel`. Categories include violence, profanity, NSFW, hate speech, and more.
508
+
509
+ ### 4.7 Topic Detection (IAB Classification)
510
+
511
+ Automatically classify content using IAB (Interactive Advertising Bureau) taxonomy.
512
+
513
+ **Minimal Example:**
514
+ ```javascript
515
+ const transcript = await client.transcripts.transcribe({
516
+ audio: "https://example.com/podcast.mp3",
517
+ iab_categories: true,
518
+ });
519
+
520
+ console.log("Detected topics:", transcript.iab_categories_result.summary);
521
+ ```
522
+
523
+ **Advanced Example:**
524
+ ```javascript
525
+ const transcript = await client.transcripts.transcribe({
526
+ audio: "https://example.com/podcast.mp3",
527
+ iab_categories: true,
528
+ });
529
+
530
+ // Get overall summary
531
+ const topTopics = Object.entries(transcript.iab_categories_result.summary)
532
+ .sort((a, b) => b[1] - a[1])
533
+ .slice(0, 5);
534
+
535
+ console.log("Top 5 topics:");
536
+ for (const [topic, relevance] of topTopics) {
537
+ console.log(`${topic}: ${(relevance * 100).toFixed(1)}%`);
538
+ }
539
+
540
+ // Get segment-level topics
541
+ for (const result of transcript.iab_categories_result.results) {
542
+ console.log({
543
+ text: result.text,
544
+ timestamp: `${result.timestamp.start}ms - ${result.timestamp.end}ms`,
545
+ topics: result.labels.map(l => ({
546
+ category: l.label,
547
+ relevance: l.relevance,
548
+ })),
549
+ });
550
+ }
551
+ ```
552
+
553
+ ### 4.8 Sentiment Analysis
554
+
555
+ Analyze emotional tone throughout the audio.
556
+
557
+ **Minimal Example:**
558
+ ```javascript
559
+ const transcript = await client.transcripts.transcribe({
560
+ audio: "https://example.com/customer-call.mp3",
561
+ sentiment_analysis: true,
562
+ });
563
+
564
+ for (const result of transcript.sentiment_analysis_results) {
565
+ console.log(`"${result.text}": ${result.sentiment}`);
566
+ }
567
+ ```
568
+
569
+ **Advanced Example:**
570
+ ```javascript
571
+ const transcript = await client.transcripts.transcribe({
572
+ audio: "https://example.com/customer-call.mp3",
573
+ sentiment_analysis: true,
574
+ speaker_labels: true,
575
+ });
576
+
577
+ // Calculate sentiment distribution
578
+ const sentimentCounts = { POSITIVE: 0, NEUTRAL: 0, NEGATIVE: 0 };
579
+ for (const result of transcript.sentiment_analysis_results) {
580
+ sentimentCounts[result.sentiment]++;
581
+ }
582
+
583
+ const total = transcript.sentiment_analysis_results.length;
584
+ console.log("Sentiment distribution:");
585
+ console.log(`Positive: ${(sentimentCounts.POSITIVE / total * 100).toFixed(1)}%`);
586
+ console.log(`Neutral: ${(sentimentCounts.NEUTRAL / total * 100).toFixed(1)}%`);
587
+ console.log(`Negative: ${(sentimentCounts.NEGATIVE / total * 100).toFixed(1)}%`);
588
+
589
+ // Analyze sentiment by speaker
590
+ const speakerSentiments = {};
591
+ for (const result of transcript.sentiment_analysis_results) {
592
+ if (!result.speaker) continue;
593
+
594
+ if (!speakerSentiments[result.speaker]) {
595
+ speakerSentiments[result.speaker] = { POSITIVE: 0, NEUTRAL: 0, NEGATIVE: 0 };
596
+ }
597
+ speakerSentiments[result.speaker][result.sentiment]++;
598
+ }
599
+
600
+ console.log("\nSentiment by speaker:", speakerSentiments);
601
+ ```
602
+
603
+ ### 4.9 Entity Detection
604
+
605
+ Extract and classify named entities from transcripts.
606
+
607
+ **Minimal Example:**
608
+ ```javascript
609
+ const transcript = await client.transcripts.transcribe({
610
+ audio: "https://example.com/news.mp3",
611
+ entity_detection: true,
612
+ });
613
+
614
+ for (const entity of transcript.entities) {
615
+ console.log(`${entity.text} (${entity.entity_type})`);
616
+ }
617
+ ```
618
+
619
+ **Advanced Example:**
620
+ ```javascript
621
+ const transcript = await client.transcripts.transcribe({
622
+ audio: "https://example.com/business-meeting.mp3",
623
+ entity_detection: true,
624
+ });
625
+
626
+ // Group entities by type
627
+ const entitiesByType = {};
628
+ for (const entity of transcript.entities) {
629
+ if (!entitiesByType[entity.entity_type]) {
630
+ entitiesByType[entity.entity_type] = [];
631
+ }
632
+ entitiesByType[entity.entity_type].push({
633
+ text: entity.text,
634
+ start: entity.start,
635
+ end: entity.end,
636
+ });
637
+ }
638
+
639
+ console.log("Entities by type:");
640
+ for (const [type, entities] of Object.entries(entitiesByType)) {
641
+ console.log(`\n${type}:`);
642
+ const uniqueEntities = [...new Set(entities.map(e => e.text))];
643
+ console.log(uniqueEntities.join(", "));
644
+ }
645
+ ```
646
+
647
+ **Entity Types:**
648
+
649
+ To see the complete list of detectable entity types, check the official documentation at https://www.assemblyai.com/docs/audio-intelligence/entity-detection or inspect the SDK TypeScript types for `EntityType`. Supported types include person names, locations, organizations, dates, medical terms, and more.
650
+
651
+ ### 4.10 Auto Highlights
652
+
653
+ Automatically identify and extract key phrases and important moments.
654
+
655
+ **Minimal Example:**
656
+ ```javascript
657
+ const transcript = await client.transcripts.transcribe({
658
+ audio: "https://example.com/meeting.mp3",
659
+ auto_highlights: true,
660
+ });
661
+
662
+ for (const highlight of transcript.auto_highlights_result.results) {
663
+ console.log(`${highlight.text} (rank: ${highlight.rank})`);
664
+ }
665
+ ```
666
+
667
+ **Advanced Example:**
668
+ ```javascript
669
+ const transcript = await client.transcripts.transcribe({
670
+ audio: "https://example.com/podcast.mp3",
671
+ auto_highlights: true,
672
+ });
673
+
674
+ // Get top highlights
675
+ const topHighlights = transcript.auto_highlights_result.results
676
+ .sort((a, b) => b.rank - a.rank)
677
+ .slice(0, 10);
678
+
679
+ console.log("Top 10 highlights:");
680
+ for (const highlight of topHighlights) {
681
+ console.log({
682
+ text: highlight.text,
683
+ rank: highlight.rank,
684
+ count: highlight.count,
685
+ timestamps: highlight.timestamps.map(t => ({
686
+ start: t.start,
687
+ end: t.end,
688
+ })),
689
+ });
690
+ }
691
+ ```
692
+
693
+ ### 4.11 Export Subtitles (SRT/VTT)
694
+
695
+ Export completed transcripts as subtitle files for video.
696
+
697
+ **Export as SRT:**
698
+ ```javascript
699
+ const transcript = await client.transcripts.transcribe({
700
+ audio: "https://example.com/video-audio.mp3",
701
+ });
702
+
703
+ const srt = await client.transcripts.subtitles(transcript.id, "srt");
704
+ console.log(srt);
705
+
706
+ // Or with custom chars per caption
707
+ const srtCustom = await client.transcripts.subtitles(
708
+ transcript.id,
709
+ "srt",
710
+ 40 // chars_per_caption
711
+ );
712
+ ```
713
+
714
+ **Export as VTT:**
715
+ ```javascript
716
+ const vtt = await client.transcripts.subtitles(transcript.id, "vtt");
717
+ console.log(vtt);
718
+
719
+ // Save to file
720
+ import fs from "fs";
721
+ fs.writeFileSync("subtitles.vtt", vtt);
722
+ ```
723
+
724
+ ### 4.12 Paragraphs and Sentences
725
+
726
+ Retrieve transcripts automatically segmented into paragraphs or sentences.
727
+
728
+ **Get Paragraphs:**
729
+ ```javascript
730
+ const transcript = await client.transcripts.transcribe({
731
+ audio: "https://example.com/lecture.mp3",
732
+ });
733
+
734
+ const paragraphs = await client.transcripts.paragraphs(transcript.id);
735
+
736
+ for (const para of paragraphs.paragraphs) {
737
+ console.log(`[${para.start}ms - ${para.end}ms]`);
738
+ console.log(para.text);
739
+ console.log("---");
740
+ }
741
+ ```
742
+
743
+ **Get Sentences:**
744
+ ```javascript
745
+ const sentences = await client.transcripts.sentences(transcript.id);
746
+
747
+ for (const sentence of sentences.sentences) {
748
+ console.log({
749
+ text: sentence.text,
750
+ start: sentence.start,
751
+ end: sentence.end,
752
+ confidence: sentence.confidence,
753
+ speaker: sentence.speaker,
754
+ });
755
+ }
756
+ ```
757
+
758
+ ### 4.13 Word-Level Timestamps
759
+
760
+ Access precise word-level timing information.
761
+
762
+ **Example:**
763
+ ```javascript
764
+ const transcript = await client.transcripts.transcribe({
765
+ audio: "https://example.com/speech.mp3",
766
+ });
767
+
768
+ for (const word of transcript.words) {
769
+ console.log({
770
+ text: word.text,
771
+ start: word.start, // milliseconds
772
+ end: word.end,
773
+ confidence: word.confidence,
774
+ speaker: word.speaker, // if speaker_labels enabled
775
+ });
776
+ }
777
+
778
+ // Find specific words
779
+ const targetWord = "important";
780
+ const occurrences = transcript.words.filter(w =>
781
+ w.text.toLowerCase() === targetWord.toLowerCase()
782
+ );
783
+
784
+ console.log(`"${targetWord}" appears ${occurrences.length} times at:`);
785
+ for (const word of occurrences) {
786
+ console.log(` ${word.start}ms - ${word.end}ms`);
787
+ }
788
+ ```
789
+
790
+ ## 5. Advanced Features
791
+
792
+ ### 5.1 Language Detection and Multilingual Support
793
+
794
+ **Automatic Language Detection:**
795
+ ```javascript
796
+ const transcript = await client.transcripts.transcribe({
797
+ audio: "https://example.com/multilingual.mp3",
798
+ language_detection: true,
799
+ });
800
+
801
+ console.log("Detected language:", transcript.language_code);
802
+ ```
803
+
804
+ **Specify Language:**
805
+ ```javascript
806
+ const transcript = await client.transcripts.transcribe({
807
+ audio: "https://example.com/spanish-audio.mp3",
808
+ language_code: "es", // Spanish
809
+ });
810
+ ```
811
+
812
+ **Supported Languages:**
813
+
814
+ AssemblyAI supports 100+ languages. To see the complete list of supported language codes, check the official documentation at https://www.assemblyai.com/docs/concepts/supported-languages or run:
815
+ ```bash
816
+ npm info assemblyai | grep -A 20 "language_code"
817
+ ```
818
+
819
+ Common language codes include `en` (English), `es` (Spanish), `fr` (French), `de` (German), `zh` (Chinese), `ja` (Japanese), and many more.
820
+
821
+ **Multilingual Streaming (Beta):**
822
+ ```javascript
823
+ const transcriber = new RealtimeTranscriber({
824
+ apiKey: process.env.ASSEMBLYAI_API_KEY,
825
+ sampleRate: 16000,
826
+ // Auto-detect between supported languages
827
+ language_code: "multi",
828
+ });
829
+ ```
830
+
831
+ ### 5.2 Custom Vocabulary and Word Boost
832
+
833
+ Improve accuracy for domain-specific terms.
834
+
835
+ **Word Boost:**
836
+ ```javascript
837
+ const transcript = await client.transcripts.transcribe({
838
+ audio: "https://example.com/tech-talk.mp3",
839
+ word_boost: [
840
+ "AssemblyAI",
841
+ "Kubernetes",
842
+ "GraphQL",
843
+ "TypeScript",
844
+ "microservices",
845
+ ],
846
+ boost_param: "high", // Options: "low", "default", "high"
847
+ });
848
+ ```
849
+
850
+ ### 5.3 Audio Format Support
851
+
852
+ AssemblyAI automatically detects and processes various audio formats.
853
+
854
+ **Supported Formats:**
855
+
856
+ AssemblyAI automatically detects and supports most common audio/video formats including MP3, MP4, WAV, FLAC, AAC, and more. For the complete list of supported formats, see https://www.assemblyai.com/docs/concepts/audio-formats
857
+
858
+ **Optimal Settings:**
859
+ For best transcription quality, use audio with 16kHz+ sample rate, mono or stereo channels, and 16-bit+ depth.
860
+
861
+ ### 5.4 Webhook Configuration
862
+
863
+ Receive notifications when transcription completes.
864
+
865
+ **Setup Webhook:**
866
+ ```javascript
867
+ const transcript = await client.transcripts.submit({
868
+ audio: "https://example.com/audio.mp3",
869
+ webhook_url: "https://your-domain.com/webhook/assemblyai",
870
+ webhook_auth_header_name: "X-Webhook-Secret",
871
+ webhook_auth_header_value: process.env.WEBHOOK_SECRET,
872
+ });
873
+ ```
874
+
875
+ **Webhook Handler (Express Example):**
876
+ ```javascript
877
+ import express from "express";
878
+
879
+ const app = express();
880
+ app.use(express.json());
881
+
882
+ app.post("/webhook/assemblyai", (req, res) => {
883
+ // Verify webhook secret
884
+ if (req.headers["x-webhook-secret"] !== process.env.WEBHOOK_SECRET) {
885
+ return res.status(401).send("Unauthorized");
886
+ }
887
+
888
+ const { transcript_id, status } = req.body;
889
+
890
+ if (status === "completed") {
891
+ console.log("Transcription completed:", transcript_id);
892
+ // Retrieve full transcript
893
+ client.transcripts.get(transcript_id).then(transcript => {
894
+ console.log(transcript.text);
895
+ });
896
+ } else if (status === "error") {
897
+ console.error("Transcription failed:", req.body.error);
898
+ }
899
+
900
+ res.sendStatus(200);
901
+ });
902
+ ```
903
+
904
+ ### 5.5 Polling Status Manually
905
+
906
+ ```javascript
907
+ const transcript = await client.transcripts.submit({
908
+ audio: "https://example.com/audio.mp3",
909
+ });
910
+
911
+ // Poll every 3 seconds
912
+ const checkStatus = async () => {
913
+ const result = await client.transcripts.get(transcript.id);
914
+
915
+ if (result.status === "completed") {
916
+ console.log("Done:", result.text);
917
+ return result;
918
+ } else if (result.status === "error") {
919
+ throw new Error(result.error);
920
+ } else {
921
+ console.log("Status:", result.status);
922
+ await new Promise(resolve => setTimeout(resolve, 3000));
923
+ return checkStatus();
924
+ }
925
+ };
926
+
927
+ const finalTranscript = await checkStatus();
928
+ ```
929
+
930
+ ### 5.6 Delete Transcripts
931
+
932
+ Permanently delete transcripts from AssemblyAI servers.
933
+
934
+ ```javascript
935
+ // Delete a specific transcript
936
+ await client.transcripts.delete(transcript.id);
937
+ console.log("Transcript deleted");
938
+ ```
939
+
940
+ ### 5.7 List Transcripts
941
+
942
+ Retrieve a list of previously submitted transcripts.
943
+
944
+ ```javascript
945
+ const page = await client.transcripts.list({
946
+ limit: 10,
947
+ status: "completed",
948
+ });
949
+
950
+ for (const transcript of page.transcripts) {
951
+ console.log({
952
+ id: transcript.id,
953
+ status: transcript.status,
954
+ created: transcript.created,
955
+ audio_duration: transcript.audio_duration,
956
+ });
957
+ }
958
+
959
+ // Handle pagination
960
+ if (page.page_details.next_url) {
961
+ const nextPage = await client.transcripts.list({
962
+ limit: 10,
963
+ before_id: page.transcripts[page.transcripts.length - 1].id,
964
+ });
965
+ }
966
+ ```
967
+
968
+ ## 6. TypeScript Usage
969
+
970
+ The AssemblyAI SDK is written in TypeScript and provides comprehensive type definitions.
971
+
972
+ ### Import Types
973
+ ```typescript
974
+ import {
975
+ AssemblyAI,
976
+ TranscribeParams,
977
+ Transcript,
978
+ RealtimeTranscript,
979
+ TranscriptStatus,
980
+ SentimentAnalysisResult,
981
+ Entity,
982
+ ContentSafetyLabel,
983
+ LemurTaskParams,
984
+ LemurResponse,
985
+ } from "assemblyai";
986
+ ```
987
+
988
+ ### Type-Safe Transcription
989
+ ```typescript
990
+ const params: TranscribeParams = {
991
+ audio: "https://example.com/audio.mp3",
992
+ speaker_labels: true,
993
+ sentiment_analysis: true,
994
+ entity_detection: true,
995
+ };
996
+
997
+ const transcript: Transcript = await client.transcripts.transcribe(params);
998
+
999
+ // TypeScript knows the available properties
1000
+ if (transcript.status === "completed") {
1001
+ const text: string = transcript.text;
1002
+ const sentiments: SentimentAnalysisResult[] | undefined =
1003
+ transcript.sentiment_analysis_results;
1004
+ const entities: Entity[] | undefined = transcript.entities;
1005
+ }
1006
+ ```
1007
+
1008
+ ### Type-Safe LeMUR
1009
+ ```typescript
1010
+ import type { LemurQuestionAnswerParams } from "assemblyai";
1011
+
1012
+ const params: LemurQuestionAnswerParams = {
1013
+ transcript_ids: [transcript.id],
1014
+ questions: [
1015
+ {
1016
+ question: "What were the key takeaways?",
1017
+ answer_format: "bullet points",
1018
+ },
1019
+ ],
1020
+ final_model: "anthropic/claude-3-5-sonnet",
1021
+ };
1022
+
1023
+ const result = await client.lemur.question(params);
1024
+ ```
1025
+
1026
+ ### Type Guards for Real-Time Transcripts
1027
+ ```typescript
1028
+ import { RealtimeTranscript } from "assemblyai";
1029
+
1030
+ transcriber.on("transcript", (transcript: RealtimeTranscript) => {
1031
+ if (transcript.message_type === "FinalTranscript") {
1032
+ // TypeScript knows this is a final transcript
1033
+ const text: string = transcript.text;
1034
+ const confidence: number = transcript.confidence;
1035
+ const words: Array<{ text: string; start: number; end: number }> =
1036
+ transcript.words;
1037
+ } else if (transcript.message_type === "PartialTranscript") {
1038
+ // Partial transcript
1039
+ const partialText: string = transcript.text;
1040
+ }
1041
+ });
1042
+ ```
1043
+