Automate Audio Transcription with n8n + Nagovori
Automate Audio Transcription with n8n + Nagovori
You record a meeting, drop the file somewhere, and the transcript appears in your notes — automatically. No scripts, no server management, no manual API calls. That's what we're building in this guide using n8n, an open-source workflow automation tool, and the Nagovori transcription API.
Why n8n?
n8n is a self-hostable automation platform with a visual editor. Think Zapier, but you own your data and there are no per-execution fees. It connects to hundreds of services out of the box and supports custom HTTP requests for anything else.
For transcription workflows, n8n is perfect because:
- Trigger on anything: new file in Google Drive, incoming Telegram message, email attachment, webhook from your CRM.
- No code required: drag-and-drop nodes for HTTP requests, conditionals, and data transformation.
- Self-hosted: your audio files and transcripts never leave your infrastructure.
- Retry logic: built-in error handling and retries for API calls.
What We're Building
A workflow that:
- Triggers when an audio file appears (Google Drive, Telegram, or webhook)
- Uploads the file to Nagovori via a presigned URL
- Creates a transcription job
- Polls until the transcription completes
- Sends the result somewhere useful (Slack, Notion, email, etc.)
Prerequisites
- n8n instance (self-hosted or n8n.cloud)
- Nagovori API key (create one in your Profile)
- A destination for transcripts (Slack, Notion, Google Docs, etc.)
Step 1: Set Up Credentials
In n8n, go to Credentials and create a new Header Auth credential:
- Name:
Nagovori API - Header Name:
Authorization - Header Value:
Bearer nag_YOUR_API_KEY
You'll reference this credential in all HTTP Request nodes.
Step 2: Create the Trigger
Choose your trigger based on where audio files arrive:
Option A: Google Drive Trigger
Add a Google Drive Trigger node:
- Event: File Created
- Folder: Choose your audio uploads folder
- Filters: Match audio MIME types (
audio/*)
Option B: Webhook Trigger
Add a Webhook node for custom integrations:
- Method: POST
- Path:
/transcribe - Your system sends a POST with
{"file_url": "https://..."}when new audio is ready.
Option C: Telegram Trigger
Add a Telegram Trigger node:
- Updates: Message
- Filter for voice messages and audio files in a subsequent IF node.
Step 3: Get a Presigned Upload URL
Add an HTTP Request node:
- Method: POST
- URL:
https://api.nagovori.ru/v1/uploads/presign - Authentication: Use your
Nagovori APIcredential - Body (JSON):
{
"filename": "{{ $json.fileName || 'recording.mp3' }}",
"content_type": "{{ $json.mimeType || 'audio/mpeg' }}",
"size_bytes": {{ $json.fileSize || 0 }}
}
The response gives you upload_url and object_key.
Step 4: Upload the File
Add another HTTP Request node:
- Method: PUT
- URL:
{{ $json.upload_url }}(from the presign response) - Body: Binary data (the audio file from your trigger)
- Headers:
Content-Type: audio/mpeg
If your trigger provides a URL instead of binary data, add a preceding HTTP Request node to download the file first.
Step 5: Create the Transcription
Add an HTTP Request node:
- Method: POST
- URL:
https://api.nagovori.ru/v1/transcriptions - Authentication: Use your
Nagovori APIcredential - Body (JSON):
{
"object_key": "{{ $node['Presign'].json.object_key }}",
"filename": "{{ $json.fileName || 'recording.mp3' }}",
"content_type": "audio/mpeg",
"size_bytes": {{ $json.fileSize || 0 }},
"language": "auto"
}
Step 6: Poll for Completion
Nagovori processes audio asynchronously. You need to poll until status changes to completed or failed.
Add a Loop with:
- Wait node: 5 seconds
- HTTP Request node:
- Method: GET
- URL:
https://api.nagovori.ru/v1/transcriptions/{{ $json.id }} - Authentication:
Nagovori API
- IF node: Check if
statusequalscompletedorfailed- If yes: exit loop
- If no: continue loop
Alternatively, use n8n's Wait node with a webhook callback if you prefer event-driven flows.
Step 7: Send the Result
Once the transcription is complete, route the transcript_text to your destination:
Slack
Add a Slack node:
- Channel:
#transcripts - Message:
New transcript from {{ $json.filename }}:\n\n{{ $json.transcript_text }}
Notion
Add a Notion node:
- Operation: Create Page
- Title:
Meeting — {{ $json.filename }} - Content: The
transcript_textfield
Add a Send Email node with the transcript in the body.
Complete Workflow JSON
Here's the complete n8n workflow you can import directly:
{
"nodes": [
{
"name": "Webhook Trigger",
"type": "n8n-nodes-base.webhook",
"parameters": {
"httpMethod": "POST",
"path": "transcribe"
},
"position": [250, 300]
},
{
"name": "Presign Upload",
"type": "n8n-nodes-base.httpRequest",
"parameters": {
"method": "POST",
"url": "https://api.nagovori.ru/v1/uploads/presign",
"authentication": "predefinedCredentialType",
"jsonBody": "={\"filename\": \"recording.mp3\", \"content_type\": \"audio/mpeg\", \"size_bytes\": 0}"
},
"position": [450, 300]
},
{
"name": "Create Transcription",
"type": "n8n-nodes-base.httpRequest",
"parameters": {
"method": "POST",
"url": "https://api.nagovori.ru/v1/transcriptions",
"authentication": "predefinedCredentialType",
"jsonBody": "={\"object_key\": \"{{ $json.object_key }}\", \"filename\": \"recording.mp3\", \"content_type\": \"audio/mpeg\", \"language\": \"auto\"}"
},
"position": [650, 300]
}
]
}
(Simplified — add the upload and polling nodes as described above.)
Tips
- Timeout: Set a maximum of 20 polling iterations (100 seconds) before marking as failed. Long audio files may take several minutes.
- Error handling: Add an Error Trigger workflow that notifies you if any step fails.
- Batch processing: Use n8n's Split in Batches node if you're processing multiple files at once (Nagovori allows 1 concurrent transcription per account).
- File size: The presigned URL is valid for 15 minutes. For large files, ensure your upload completes within this window.
Cost
Each transcription uses your Nagovori minute balance, same as the web interface. There's no extra charge for API access. A 60-minute recording uses 60 minutes from your balance.
Next Steps
- Read the full API documentation for all available parameters
- Check the Examples for Python, TypeScript, and Go code
- Explore n8n's community workflows for more inspiration