Watching YouTube lectures and tutorials is common for learning, but the knowledge dissipates without notes. This tutorial builds a pipeline: search for relevant videos via API, extract structured metadata (title, channel, description), and create Obsidian notes with proper frontmatter and links.
Prerequisites
- Python 3.8+
- Obsidian vault with a notes folder
- A Scavio API key
Walkthrough
Step 1: Search for relevant videos
Find YouTube videos on a topic and return structured metadata.
import requests, os
from pathlib import Path
from datetime import date
H = {'x-api-key': os.environ['SCAVIO_API_KEY'], 'Content-Type': 'application/json'}
def find_videos(topic: str, max_results: int = 5) -> list:
resp = requests.post('https://api.scavio.dev/api/v1/search', headers=H,
json={'platform': 'youtube', 'query': topic}, timeout=10)
videos = resp.json().get('organic', [])[:max_results]
return [{
'title': v.get('title', ''),
'url': v.get('link', ''),
'channel': v.get('channel', ''),
'description': v.get('snippet', ''),
'views': v.get('views', ''),
'date': v.get('date', ''),
} for v in videos]Step 2: Generate Obsidian note content
Format video metadata as an Obsidian-compatible Markdown note with frontmatter.
def video_to_obsidian_note(video: dict, topic: str) -> str:
today = date.today().isoformat()
title = video['title'].replace(':', ' -').replace('/', '-')
note = f"""---
title: "{title}"
channel: "{video['channel']}"
url: "{video['url']}"
topic: "{topic}"
date_added: {today}
type: video-note
tags:
- youtube
- {topic.replace(' ', '-')}
---
# {title}
Channel: [[{video['channel']}]]
Views: {video['views']}
Published: {video['date']}
## Summary
{video['description']}
## Key Takeaways
-
-
-
## Notes
## Related
- [[{topic}]]
"""
return noteStep 3: Write notes to Obsidian vault
Save generated notes to your Obsidian vault directory.
def save_to_vault(videos: list, topic: str, vault_path: str = '~/Documents/Obsidian/Research') -> list:
vault = Path(vault_path).expanduser() / 'YouTube Notes'
vault.mkdir(parents=True, exist_ok=True)
saved = []
for video in videos:
note_content = video_to_obsidian_note(video, topic)
filename = video['title'][:60].replace(':', '-').replace('/', '-').replace('?', '') + '.md'
filepath = vault / filename
if not filepath.exists():
filepath.write_text(note_content)
saved.append(str(filepath))
return saved
# Usage:
videos = find_videos('FastAPI advanced patterns 2026')
saved = save_to_vault(videos, 'FastAPI')
print(f"Created {len(saved)} new notes")Step 4: Create a research session workflow
Combine search, note creation, and an index note for a research topic.
def research_session(topic: str, vault_path: str = '~/Documents/Obsidian/Research') -> dict:
videos = find_videos(topic, max_results=10)
saved = save_to_vault(videos, topic, vault_path)
# Create index note for this research session
vault = Path(vault_path).expanduser() / 'YouTube Notes'
index_content = f"""---
type: research-session
topic: "{topic}"
date: {date.today().isoformat()}
---
# Research: {topic}
## Videos Found\n\n"""
for v in videos:
title = v['title'][:60].replace(':', '-').replace('/', '-').replace('?', '')
index_content += f"- [[{title}]] by {v['channel']}\n"
index_file = vault / f"Research - {topic} - {date.today().isoformat()}.md"
index_file.write_text(index_content)
return {'topic': topic, 'videos_found': len(videos), 'notes_created': len(saved), 'index': str(index_file)}Python Example
import requests, os
from pathlib import Path
def yt_to_obsidian(topic, vault='~/Documents/Obsidian'):
r = requests.post('https://api.scavio.dev/api/v1/search',
headers={'x-api-key': os.environ['SCAVIO_API_KEY'], 'Content-Type': 'application/json'},
json={'platform': 'youtube', 'query': topic}).json()
for v in r.get('organic',[])[:5]:
note = f"# {v['title']}\nChannel: {v.get('channel','')}\nURL: {v.get('link','')}\n\n## Notes\n\n"
Path(vault).expanduser().joinpath(f"{v['title'][:50]}.md").write_text(note)JavaScript Example
async function ytToObsidian(topic) {
const r = await fetch('https://api.scavio.dev/api/v1/search', {
method: 'POST', headers: {'x-api-key': process.env.SCAVIO_API_KEY, 'Content-Type': 'application/json'},
body: JSON.stringify({platform: 'youtube', query: topic})
});
return (await r.json()).organic?.slice(0,5).map(v => ({
title: v.title, channel: v.channel, url: v.link,
obsidianNote: `# ${v.title}\nChannel: ${v.channel}\n\n## Notes\n\n`
}));
}Expected Output
An automated pipeline that searches YouTube, creates structured Obsidian notes with frontmatter, and generates research session index files.