A command-line interface for Otter.ai to list, search, download, and manage your meeting transcripts and recordings. Built for developers, scripts, and AI agents like Claude, ChatGPT, and Cursor.
Note: This project is not affiliated with or endorsed by Otter.ai / Aisense Inc.
- List, search, and filter meeting transcripts by date, folder, or keyword
- Download transcripts as txt, pdf, md, docx, or srt
- Download meeting audio as mp3
- Export markdown with configurable YAML frontmatter
- Upload audio files for transcription
- Manage speakers, folders, and groups programmatically
- JSON output for scripting, piping, and AI agent consumption
- Secure credential storage via OS keychain (macOS Keychain, Windows Credential Locker, etc.)
This CLI is designed to be used by AI agents (Claude, GPT, Cursor, Windsurf, etc.) as a tool for accessing Otter.ai meeting data.
| Task | Command | Output |
|---|---|---|
| List recent meetings | otter speeches list --days 7 --json |
JSON array of speech objects |
| Get full transcript | otter speeches get OTID --json |
Speech + transcript segments |
| Download as markdown | otter speeches download OTID -f md |
.md file saved to disk |
| Download as text | otter speeches download OTID -f txt |
.txt file saved to disk |
| Download audio | otter speeches download OTID -f mp3 |
.mp3 file saved to disk |
| Search in meeting | otter speeches search "query" OTID |
Matching transcript segments |
| List folders | otter folders list --json |
JSON array of folder objects |
| List speakers | otter speakers list --json |
JSON array of speaker objects |
Agents can:
# List recent meetings (JSON for easy parsing)
otter speeches list --days 7 --json
# Search within a specific meeting transcript
otter speeches search "action items" SPEECH_ID
# Download a transcript as markdown
otter speeches download SPEECH_ID --format md
# Get full speech details and transcript
otter speeches get SPEECH_ID --json
# List all folders and speakers
otter folders list --json
otter speakers list --jsonAll commands support --json for structured, machine-readable output that agents can parse directly.
otter speeches list --json returns:
{
"speeches": [
{
"otid": "jqb7OHo6mrHtCuMkyLN0nUS8mxY",
"speech_id": "22WB27HAEBEJYFCA",
"title": "Weekly Standup",
"created_at": "2025-02-20T10:00:00Z",
"summary": "Discussed sprint progress and blockers...",
"folder": "Work",
"folder_id": "12345"
}
]
}otter speeches get SPEECH_ID --json returns the full speech object including transcript segments:
{
"speech": {
"otid": "jqb7OHo6mrHtCuMkyLN0nUS8mxY",
"title": "Weekly Standup",
"summary": "Discussed sprint progress and blockers...",
"transcripts": [
{
"speaker": "Alice",
"text": "Let's go over the sprint updates.",
"start_offset": 0,
"end_offset": 4500
}
]
}
}On error, the CLI exits with code 1 and prints a message to stderr:
Error: Authentication required. Run 'otter login' or set OTTERAI_USERNAME and OTTERAI_PASSWORD.
Find last week's standup, download its transcript as markdown:
# Step 1: List recent meetings as JSON, filter by title
OTID=$(otter speeches list --days 7 --json | jq -r '.speeches[] | select(.title | test("standup"; "i")) | .otid' | head -1)
# Step 2: Download the transcript
otter speeches download "$OTID" --format md --output standup.md
# Step 3: Or get full transcript data for further processing
otter speeches get "$OTID" --json | jq '.transcripts[] | .speaker + ": " + .text'This project includes an Agent Skill at skills/otterai-cli/ — a portable skill file that compatible agents (Claude Code, Cursor, Copilot, Gemini CLI, etc.) can use to learn this CLI's commands automatically. Copy the skills/otterai-cli/ directory into your agent's skills folder to give it full Otter.ai access.
For CI, scripts, or AI agents, use environment variables instead of interactive login:
export OTTERAI_USERNAME="you@example.com"
export OTTERAI_PASSWORD="your-password"
otter speeches list --json # no login prompt needed- Python 3.10+
uv tool install otterai-cliThis makes the otter command available globally.
To update to the latest version:
uv tool upgrade otterai-cliOr run directly without installing:
uvx --from otterai-cli otter --helpotter loginCredentials are stored in your OS keychain (macOS Keychain, Windows Credential Locker, etc.) via keyring, with ~/.otterai/config.json as fallback.
You can also use environment variables (OTTERAI_USERNAME, OTTERAI_PASSWORD), which take highest precedence.
otter user # check current user
otter logout # remove saved credentials| Command | Flags | Description |
|---|---|---|
otter login |
Interactive login, saves credentials to keychain | |
otter logout |
Remove saved credentials | |
otter user |
Show current authenticated user | |
otter speeches list |
--days N, --folder NAME, --page-size N, --source owned|shared, --json |
List speeches |
otter speeches get OTID |
--json |
Get speech details + full transcript |
otter speeches download OTID |
--format txt|pdf|md|docx|srt|mp3, --output NAME, --frontmatter-fields FIELDS |
Download transcript or audio |
otter speeches search QUERY OTID |
--json |
Search within a speech transcript |
otter speeches upload FILE |
Upload audio file for transcription | |
otter speeches trash OTID |
Move speech to trash | |
otter speeches rename OTID TITLE |
Rename a speech | |
otter speeches move OTID... |
--folder NAME, --create |
Move speeches to a folder |
otter speakers list |
--json |
List all speakers |
otter speakers create NAME |
Create a new speaker | |
otter speakers tag OTID SPEAKER_ID |
--all |
Tag speaker on transcript segments |
otter folders list |
--json |
List all folders |
otter folders create NAME |
Create a folder | |
otter folders rename ID NAME |
Rename a folder | |
otter groups list |
--json |
List all groups |
otter config show |
Show current config | |
otter config clear |
Clear saved config |
otter speeches list # list all speeches
otter speeches list --days 7 # last 7 days
otter speeches list --folder "Work" # by folder name
otter speeches get SPEECH_ID # get speech details + transcript
otter speeches download SPEECH_ID -f txt # download as txt, pdf, mp3, docx, srt, or md
otter speeches search "keyword" SPEECH_ID # search within a speech
otter speakers list # list all speakers
otter folders list # list all foldersRun otter --help or otter <command> --help for more options.
Otter.ai speeches have two identifiers:
speech_id(e.g.22WB27HAEBEJYFCA) -- internal ID, does NOT work with API endpointsotid(e.g.jqb7OHo6mrHtCuMkyLN0nUS8mxY) -- the ID used in all API calls
All CLI commands that accept a SPEECH_ID argument expect the otid value. Use otter speeches list to find otids, or otter speeches list --json | jq '.speeches[].otid' for just the IDs.
# List all speeches
otter speeches list
# List with options
otter speeches list --page-size 10 --source owned
# List speeches from the last N days
otter speeches list --days 2
# List speeches in a specific folder (by name or ID)
otter speeches list --folder "CoverNode"
# Get a specific speech
otter speeches get SPEECH_ID
# Search within a speech
otter speeches search "search query" SPEECH_ID
# Download a speech (formats: txt, pdf, mp3, docx, srt, md)
otter speeches download SPEECH_ID --format txt
# Download as markdown (generated locally from transcript data)
otter speeches download SPEECH_ID --format md
otter speeches download SPEECH_ID --format md --output meeting-notes
otter speeches download SPEECH_ID --format md --frontmatter-fields "title,summary,speakers,start_time,end_time,duration_seconds,source,speech_id,folder,folder_id"
# Upload an audio file
otter speeches upload recording.mp4
# Move to trash
otter speeches trash SPEECH_ID
# Rename a speech
otter speeches rename SPEECH_ID "New Title"
# Move speeches to a folder (by name or ID)
otter speeches move SPEECH_ID --folder "CoverNode"
otter speeches move ID1 ID2 ID3 --folder "CoverNode"
# Move to a new folder (auto-create if it doesn't exist)
otter speeches move SPEECH_ID --folder "New Folder" --createMarkdown export includes YAML frontmatter, configurable per download:
# Use defaults
otter speeches download SPEECH_ID --format md
# Pick exact fields (in your own order)
otter speeches download SPEECH_ID --format md --frontmatter-fields "title,speech_id,summary"
# Disable all frontmatter fields
otter speeches download SPEECH_ID --format md --frontmatter-fields noneDefault frontmatter fields (in order):
titlesummaryspeakersstart_timeend_timeduration_secondssourcespeech_idfolderfolder_id
Available frontmatter fields for --frontmatter-fields:
titlesummaryspeakersstart_timeend_timeduration_secondssourcespeech_idfolderfolder_idotidcreated_attranscript_updated_atlanguagetranscript_countprocess_status
Notes:
--frontmatter-fieldsis valid only with--format md.speech_idin frontmatter is the Otter internalspeech_id; command argumentSPEECH_IDstill expects theotid.
# List all speakers
otter speakers list
# Create a new speaker
otter speakers create "Speaker Name"
# Tag a speaker on transcript segments
otter speakers tag SPEECH_ID SPEAKER_ID
otter speakers tag SPEECH_ID SPEAKER_ID --all# List folders
otter folders list
# Create a folder
otter folders create "My Folder"
# Rename a folder
otter folders rename FOLDER_ID "New Name"
# List groups
otter groups list# Show current config
otter config show
# Clear saved config
otter config clearMost commands support --json flag for machine-readable output:
otter speeches list --json
otter speakers list --jsonThe CLI returns exit code 0 on success and 1 on any error. Common errors:
| Error | Cause | Fix |
|---|---|---|
Authentication required |
No credentials / expired session | Run otter login or set OTTERAI_USERNAME + OTTERAI_PASSWORD env vars |
Speech not found |
Invalid otid |
Use otter speeches list --json to get valid otids |
Rate limit exceeded |
Too many API requests | Wait a few seconds and retry |
otter speeches list --json | jq -r '.speeches[].otid' | while read otid; do
otter speeches download "$otid" --format md
doneotter speeches download SPEECH_ID --format mdThis generates a markdown file with YAML frontmatter (title, summary, speakers, timestamps). See Markdown frontmatter for customization.
Yes. Install the CLI, set OTTERAI_USERNAME and OTTERAI_PASSWORD environment variables, and agents can use all commands with --json for structured output. See AI Agent & LLM Usage.
Yes. The skills/otterai-cli/ directory contains an Agent Skill compatible with Claude Code, Cursor, Copilot, Gemini CLI, and other supporting agents. Copy it into your agent's skills directory and the agent will automatically know how to use all otter commands.
- Bulk export / backup — download all your Otter.ai transcripts programmatically
- Automate meeting workflows — pipe transcript data into scripts or cron jobs
- AI agent integration — let Claude, GPT, or other LLM agents access your meeting notes
- Search across meetings — find specific discussions without opening the Otter.ai UI
- Meeting note pipelines — download as markdown, process with other tools
- Transcript archival — export meetings before they expire or for compliance
| Tool | Type | Notes |
|---|---|---|
| Otter.ai web app | Web UI | Official interface, no CLI or API access |
| otterai-api | Python library | API wrapper only, no CLI — this project builds on it |
| Manual export | Web UI | One-at-a-time downloads from the Otter.ai dashboard |
uv sync --dev # install dependencies
uv run pytest # run testsBased on gmchad/otterai-api by Chad Lohrli, with CLI functionality from PR #9 by @andrewfurman.
MIT