This workflow corresponds to n8n.io template #16816 — we link there as the canonical source.
The workflow JSON
Copy or download the full n8n JSON below. Paste it into a new n8n workflow, add your credentials, activate. Full import guide →
{
"meta": {
"templateCredsSetupCompleted": true
},
"nodes": [
{
"id": "65662b3b-1ff9-409a-9ac0-1b46cd881137",
"name": "Webhook",
"type": "n8n-nodes-base.webhook",
"position": [
2800,
1520
],
"parameters": {
"path": "transcribe-audio",
"options": {},
"httpMethod": "POST",
"responseMode": "responseNode"
},
"typeVersion": 2.1
},
{
"id": "6daab792-1255-42b3-8dd6-ce39178afd67",
"name": "Transcribe audio",
"type": "n8n-nodes-smallestai.smallestai",
"onError": "continueErrorOutput",
"position": [
3328,
1392
],
"parameters": {
"resource": "stt",
"additionalOptions": {},
"binaryPropertyName": "audio"
},
"credentials": {},
"typeVersion": 1
},
{
"id": "7cbde30b-99c4-452b-aeba-1a8f2b3d0d75",
"name": "Shape Response",
"type": "n8n-nodes-base.set",
"position": [
3808,
1440
],
"parameters": {
"options": {},
"assignments": {
"assignments": [
{
"id": "0bfdc6a9-c857-4743-b3ce-695ddb257448",
"name": "transcript",
"type": "string",
"value": "={{ $json.transcription ?? JSON.stringify($json) }}"
}
]
}
},
"typeVersion": 3.4
},
{
"id": "15dad49c-1ca0-4282-bc37-21772ff2cc73",
"name": "Check if request has audio",
"type": "n8n-nodes-base.if",
"position": [
2992,
1520
],
"parameters": {
"options": {},
"conditions": {
"options": {
"version": 3,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "ae15fb5d-d3b9-48b9-9e8d-edfc4c5446df",
"operator": {
"type": "object",
"operation": "exists",
"singleValue": true
},
"leftValue": "={{ $binary.audio }}",
"rightValue": ""
}
]
}
},
"typeVersion": 2.3
},
{
"id": "feb67692-1900-4804-8d44-a03fc8206b07",
"name": "Respond Error if request has no audio",
"type": "n8n-nodes-base.respondToWebhook",
"position": [
3216,
1536
],
"parameters": {
"options": {
"responseCode": 400
},
"respondWith": "json",
"responseBody": "{ \"error\": \"No audio file found in the request\" }"
},
"typeVersion": 1.5
},
{
"id": "01a8d86f-3287-4bfc-bd37-7cacbc92096a",
"name": "Respond Error if STT failed",
"type": "n8n-nodes-base.respondToWebhook",
"position": [
3440,
1536
],
"parameters": {
"options": {
"responseCode": 502
},
"respondWith": "json",
"responseBody": "{ \"error\": \"{{ $json.error }}\" }"
},
"typeVersion": 1.5
},
{
"id": "aee4528d-25cb-471b-8383-7c814a7e0818",
"name": "Success",
"type": "n8n-nodes-base.respondToWebhook",
"position": [
4000,
1440
],
"parameters": {
"options": {}
},
"typeVersion": 1.4
},
{
"id": "0ed9728f-52ad-4a60-88f2-efe24e956222",
"name": "Log response in sheet",
"type": "n8n-nodes-base.googleSheets",
"onError": "continueErrorOutput",
"position": [
4208,
1440
],
"parameters": {
"columns": {
"value": {
"Duration": "={{ $('Transcribe audio').item.json.metadata.duration }}",
"Timestamp": "={{ $now }}",
"Transcription": "={{ $('Transcribe audio').item.json.transcription }}"
},
"schema": [
{
"id": "Transcription",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "Transcription",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Audio file name",
"type": "string",
"display": true,
"removed": true,
"required": false,
"displayName": "Audio file name",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Duration",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "Duration",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Timestamp",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "Timestamp",
"defaultMatch": false,
"canBeUsedToMatch": true
}
],
"mappingMode": "defineBelow",
"matchingColumns": [],
"attemptToConvertTypes": false,
"convertFieldsToString": false
},
"options": {},
"operation": "append",
"sheetName": {
"__rl": true,
"mode": "list",
"value": "gid=0",
"cachedResultUrl": "https://docs.google.com/spreadsheets/d/1juqiYRXU061yn7k31tQyJcq-1w_ivz_9uRIEGbanurI/edit#gid=0",
"cachedResultName": "Sheet1"
},
"documentId": {
"__rl": true,
"mode": "list",
"value": "1juqiYRXU061yn7k31tQyJcq-1w_ivz_9uRIEGbanurI",
"cachedResultUrl": "https://docs.google.com/spreadsheets/d/1juqiYRXU061yn7k31tQyJcq-1w_ivz_9uRIEGbanurI/edit?usp=drivesdk",
"cachedResultName": "STT Logs"
}
},
"typeVersion": 4.7
},
{
"id": "be7e44d9-9a63-4800-a069-f890d63df2ae",
"name": "Sticky Note",
"type": "n8n-nodes-base.stickyNote",
"position": [
2256,
1232
],
"parameters": {
"width": 464,
"height": 832,
"content": "# Instant Audio-to-Text API Service\n\n### How it works\nThis lightweight workflow exposes a secure webhook endpoint to act as a synchronous Audio-to-Text API. It receives an audio file, processes it instantly, and returns the text response in real time.\n\n### Setup steps\n* Deploy the workflow to generate your live webhook URL path (`/transcribe-audio`).\n* Connect your **Smallest.ai** API key credentials inside the transcription node.\n* Ensure your incoming API requests pass the raw file using the binary property name **`audio`**.\n\n---\n\n### How to customize\n\n* **Swap Providers:** Replace the Smallest.ai node with OpenAI Whisper, Deepgram, or AssemblyAI if you prefer a different engine. Just map the incoming `audio` binary data to the new node.\n* **Set Fixed Language:** Manually set the language parameter in the transcription node instead of using auto-detect. This reduces latency and improves accuracy for non-English audio.\n* **Handle Large Files:** Insert an FFmpeg node right after the webhook to compress or downscale heavy audio files before sending them to the API to save on bandwidth and costs.\n* **Add Post-Processing:** Chain an LLM node (like GPT-4o or Claude) after the transcription to automatically summarize, format, or extract action items before returning the API response."
},
"typeVersion": 1
},
{
"id": "550a7420-a9ce-4b6e-84c7-80ffaf27787b",
"name": "Sticky Note1",
"type": "n8n-nodes-base.stickyNote",
"position": [
2736,
1232
],
"parameters": {
"color": 7,
"width": 992,
"height": 528,
"content": "# API Ingestion\nExposes an HTTP POST endpoint to capture incoming binary audio streams and passes them directly to Smallest.ai for rapid speech-to-text conversion."
},
"typeVersion": 1
},
{
"id": "616e8253-02b9-45c3-8602-bb0200b59b8a",
"name": "Sticky Note2",
"type": "n8n-nodes-base.stickyNote",
"position": [
3744,
1232
],
"parameters": {
"color": 7,
"width": 688,
"height": 432,
"content": "# API Transcription"
},
"typeVersion": 1
}
],
"connections": {
"Success": {
"main": [
[
{
"node": "Log response in sheet",
"type": "main",
"index": 0
}
]
]
},
"Webhook": {
"main": [
[
{
"node": "Check if request has audio",
"type": "main",
"index": 0
}
]
]
},
"Shape Response": {
"main": [
[
{
"node": "Success",
"type": "main",
"index": 0
}
]
]
},
"Transcribe audio": {
"main": [
[
{
"node": "Shape Response",
"type": "main",
"index": 0
}
],
[
{
"node": "Respond Error if STT failed",
"type": "main",
"index": 0
}
]
]
},
"Check if request has audio": {
"main": [
[
{
"node": "Transcribe audio",
"type": "main",
"index": 0
}
],
[
{
"node": "Respond Error if request has no audio",
"type": "main",
"index": 0
}
]
]
}
}
}
For the full experience including quality scoring and batch install features for each workflow upgrade to Pro
About this workflow
This workflow exposes a POST webhook endpoint that accepts a binary audio file, transcribes it to text using Smallest.ai speech-to-text, and returns the transcript in the same synchronous HTTP response. Receives an HTTP POST request on the webhook endpoint containing an audio…
Source: https://n8n.io/workflows/16816/ — original creator credit. Request a take-down →
Related workflows
Workflows that share integrations, category, or trigger type with this one. All free to copy and import.
This workflow receives a webhook request with an audio sample URL, voice name, and script, clones a voice and generates a matching voiceover using Smallest AI, uploads the MP3 to Google Drive, logs th
Resume Screening & Behavioral Interviews with Gemini, Elevenlabs, & Notion ATS copy. Uses googleDrive, httpRequest, notion, formTrigger. Webhook trigger; 67 nodes.
[SANTOBET] FLUXO TODO - BACKUP. Uses googleSheets, httpRequest, googleSheetsTrigger. Webhook trigger; 57 nodes.
This workflow sends post-purchase review request emails for WooCommerce orders, stores expiring form links in Google Sheets, optionally shortens links with Dub.co and delays delivery, serves a hosted
FLUXO DISPARO DATA E HORA. Uses itemLists, googleSheets, httpRequest. Webhook trigger; 48 nodes.