Introduction
Onboarding videos are awkward to produce at scale. You either hire a video agency (expensive), film yourself repeatedly (time-consuming), or record static screen captures (boring). Most SaaS companies end up with outdated documentation that doesn't match their current product, because updating video content is such a pain.
What if you could generate a professional onboarding video series directly from your feature documentation, without touching a camera or script? This workflow takes your written docs, converts them to natural speech using ElevenLabs, choreographs an AI avatar using Hour One, and produces polished videos ready to embed in your product.
The result: new users watch a friendly, professional guide to your features within minutes of signing up. Your documentation stays fresh because the videos rebuild automatically whenever you update your docs. No manual video production. No sync issues between docs and videos. Just automation doing the heavy lifting.
The Automated Workflow
This workflow chains three specialised tools together: Widify extracts and structures your feature documentation, ElevenLabs generates expressive voice narration, and Hour One creates the video with a human-like avatar. An orchestration platform ties everything together and handles the file routing.
Which Orchestration Tool to Use
For this workflow, I'd recommend n8n over Zapier or Make. Here's why: you need to handle file uploads, transform JSON structures, and make sequential API calls with data passing between steps. n8n handles file operations more predictably, and its built-in HTTP nodes let you work with multipart form data without additional configuration. Zapier would work, but you'd hit the 5MB file size limit quickly. Make is viable, but n8n's local file handling is cleaner.
You'll need: n8n (self-hosted or cloud), an ElevenLabs API key, an Hour One API key, and access to Widify's output or your own documentation source.
Step 1:
Extract Documentation with Widify
Widify isn't a traditional API; it's a web scraper that parses documentation sites and returns structured JSON. You'll use n8n's HTTP node to call it, or feed it your docs manually if you're using a static site generator.
If you're scraping your own docs site, use an HTTP GET request:
GET https://your-docs.example.com/api/features
If Widify processes your docs, export the JSON output and store it somewhere accessible via HTTP. The output should look like this:
{
"features": [
{
"title": "User Authentication",
"description": "Implement OAuth 2.0 login with Google and GitHub providers. Users can sign up with email or social accounts. Session tokens expire after 30 days.",
"section": "Core Setup",
"order": 1
},
{
"title": "Dashboard Analytics",
"description": "Real-time metrics including user count, active sessions, and feature adoption rates. Data updates every 60 seconds.",
"section": "Monitoring",
"order": 2
}
]
}
In n8n, add an HTTP Request node and configure it:
Method: GET
URL: https://docs.example.com/api/features.json
Authentication: Bearer token (if needed)
The output feeds directly into the next step.
Step 2:
Generate Narration with ElevenLabs
ElevenLabs' Text-to-Speech API converts your documentation text into natural-sounding speech. You'll call their API once per feature, then store the audio files for Hour One to use.
First, get your ElevenLabs API key from your account settings. Then, in n8n, add a Loop node to iterate through each feature:
Loop over: $.features
Inside the loop, add an HTTP Request node for ElevenLabs:
POST https://api.elevenlabs.io/v1/text-to-speech/{voice_id}/stream
Headers:
xi-api-key: your-api-key
Content-Type: application/json
Body:
{
"text": "feature-description-text",
"model_id": "eleven_monolingual_v1",
"voice_settings": {
"stability": 0.5,
"similarity_boost": 0.75
}
}
Replace {voice_id} with a voice ID from ElevenLabs' voice library. Popular choices for professional narration: Rachel (21m02s-EN), Adam (pNInz6obpgc4bq4dNXC0), or George (EXAVITQu4vr4xnSDxMaL).
The response is binary audio data (MP3). In n8n, you need to save it to a file. Add a Binary File Write node:
File path: /tmp/narration-{{$.item.json.title}}-{{$index}}.mp3
Binary data: The raw response from ElevenLabs
This creates files like /tmp/narration-User Authentication-0.mp3.
Step 3:
Generate Video Avatar with Hour One
Hour One creates videos with AI avatars that synchronise lip movements to audio. Their API accepts an audio file URL and returns a video file URL.
You'll need to host the MP3 files somewhere accessible. If you're using n8n cloud, use an AWS S3 bucket or any HTTP-accessible storage. If self-hosted n8n, you can use a local file server.
For this example, assume your MP3 files are at https://storage.example.com/narration-*.mp3.
In n8n, after the binary file write step, add an HTTP Request node to Hour One:
POST https://api.hourone.ai/v1/generate
Headers:
Authorization: Bearer YOUR_HOUR_ONE_TOKEN
Content-Type: application/json
Body:
{
"avatar_id": "avatar_007",
"audio_url": "https://storage.example.com/narration-{{$.item.json.title}}-{{$index}}.mp3",
"voice_id": "en_us_001",
"output_format": "mp4"
}
Hour One's API is asynchronous. The response includes a job_id:
{
"job_id": "job_12345abc",
"status": "processing",
"estimated_wait_seconds": 45
}
Store this job ID and poll the status endpoint every 10 seconds:
GET https://api.hourone.ai/v1/jobs/{job_id}
Once status is "completed", the response includes a video_url:
{
"job_id": "job_12345abc",
"status": "completed",
"video_url": "https://videos.hourone.ai/output-job_12345abc.mp4",
"duration_seconds": 45
}
In n8n, use a Loop node with a Wait node inside to handle polling:
Loop until: status === "completed"
Wait: 10 seconds
HTTP GET: Check job status
Extract: status field
Once the video URL exists, download it and store it in your video library.
Step 4:
Store and Deliver Videos
After Hour One generates the video, save its URL to a database or content management system. You could use a simple Google Sheet, a database, or a headless CMS.
Using a Google Sheets example:
POST https://sheets.googleapis.com/v4/spreadsheets/{spreadsheet_id}/values/Videos!A:F:append
Headers:
Authorization: Bearer GOOGLE_TOKEN
Content-Type: application/json
Body:
{
"values": [
[
"{{$.item.json.title}}",
"{{$.item.json.description}}",
"{{$.video_url}}",
"{{new Date().toISOString()}}",
"Published"
]
]
}
From here, embed the video URL in your onboarding flow. Use an iframe in your product, or link to it from your documentation.
Complete n8n Workflow Structure
Here's how the workflow nodes connect:
1. HTTP Request (fetch docs from Widify)
↓
2. Loop (iterate through features)
↓
3. HTTP Request (ElevenLabs text-to-speech)
↓
4. Binary File Write (save MP3)
↓
5. Upload to S3 (or file server)
↓
6. HTTP Request (Hour One generate video)
↓
7. Wait loop (poll for completion)
↓
8. HTTP Request (Google Sheets append)
↓
9. Done
Set this to run on a schedule (e.g., weekly), or trigger it manually when you update documentation.
The Manual Alternative
If you prefer more creative control, skip the automation and use each tool individually:
- Write your narration scripts in a document (Hour One accepts custom scripts, not just text-to-speech).
- Record or generate audio in ElevenLabs, download the MP3.
- Upload the audio to Hour One's web interface, select your avatar, configure settings, and generate the video.
- Download the video and upload it to your hosting platform.
This takes 10-15 minutes per video but gives you full control over pacing, tone, and avatar selection. Use this approach for hero videos or high-visibility features. Use automation for bulk feature documentation.
Pro Tips
1. Voice consistency matters. Choose one ElevenLabs voice for your entire series. Consistency builds familiarity. If you use "Rachel" for your first video, don't switch to "Adam" for the third. Users will notice.
2. Handle rate limits gracefully. ElevenLabs allows 10,000 characters per day on free plans. Hour One has a queue for video generation; jobs might take 2-5 minutes during peak hours. In n8n, add error handling to retry failed API calls with exponential backoff. Add a Delay node between loops to avoid hammering the APIs.
Wait: {{Math.pow(2, $nodeExecutionData[0].retryCount || 0)}} seconds
3. Monitor audio length. Longer narration uses more ElevenLabs quota and takes longer to generate video. Keep feature explanations to 30-90 seconds. Write scripts first; don't just dump your entire feature doc into the API.
4. Test avatar and voice together. Some ElevenLabs voices pair better with certain Hour One avatars. Avatar_007 works well with Rachel; Avatar_003 sounds better with Adam. Spend 15 minutes testing combinations before running the full workflow.
5. Cache audio files. If you regenerate the workflow, don't re-request audio from ElevenLabs for unchanged features. Store hashes of your documentation text and skip ElevenLabs if the hash matches a previous run. This saves quota and money.
Cost Breakdown
| Tool | Plan Needed | Monthly Cost | Notes |
|---|---|---|---|
| ElevenLabs | Starter | £11 | 50,000 characters. One feature description is roughly 200 characters. Covers 250 features per month. |
| Hour One | Growth | £500 | Includes 200 generated videos per month and unlimited avatar customisation. |
| n8n | Cloud Pro | £20 | Includes 100,000 executions and file storage. Self-hosted is free but requires your own infrastructure. |
| Storage (S3 or equivalent) | Standard | £5-10 | Storing 200 MP3 files (50MB total) and 200 MP4 files (2GB total). |
| Total | £536-541 | Per 200 feature videos generated. Cost per video: £2.68-£2.71. |
For comparison, outsourcing video production costs £300-£800 per video. Automation pays for itself after 200-250 videos.
If you're on a tighter budget, reduce volume: use ElevenLabs' free tier (50,000 characters per month) and Hour One's Basic plan (£200/month, 50 videos), bringing monthly cost to around £235. This covers about 50 features per month. Scale up as your onboarding needs grow.