Unofficial Otter.ai CLI — list, search, download, and manage meeting transcripts. Built for developers, scripts, and AI agents.
Project description
otterai-cli — Otter.ai CLI & AI Agent Tool
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.
Features
- 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.)
AI Agent & LLM Usage
This CLI is designed to be used by AI agents (Claude, GPT, Cursor, Windsurf, etc.) as a tool for accessing Otter.ai meeting data.
Quick Reference
| 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 --json
All commands support --json for structured, machine-readable output that agents can parse directly.
JSON Output Schema
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.
Agent Workflow Example
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'
Agent Skill
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.
Authentication for Automated Environments
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
Requirements
- Python 3.10+
Installation
uv tool install otterai-cli
This makes the otter command available globally.
To update to the latest version:
uv tool upgrade otterai-cli
Or run directly without installing:
uvx --from otterai-cli otter --help
Setup
otter login
Credentials 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.
Auth commands
otter user # check current user
otter logout # remove saved credentials
Command Reference
| 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 |
Usage
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 folders
Run otter --help or otter <command> --help for more options.
Important: Speech IDs (otid vs speech_id)
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.
Speeches
# 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" --create
Markdown frontmatter (--format md)
Markdown 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 none
Default 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.
Speakers
# 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
Folders and Groups
# 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
Configuration
# Show current config
otter config show
# Clear saved config
otter config clear
JSON Output
Most commands support --json flag for machine-readable output:
otter speeches list --json
otter speakers list --json
Error Handling
The 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 |
FAQ
How do I bulk export all my Otter.ai transcripts?
otter speeches list --json | jq -r '.speeches[].otid' | while read otid; do
otter speeches download "$otid" --format md
done
How do I download Otter.ai meeting notes as markdown?
otter speeches download SPEECH_ID --format md
This generates a markdown file with YAML frontmatter (title, summary, speakers, timestamps). See Markdown frontmatter for customization.
Can AI agents like Claude or ChatGPT use this tool?
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.
Is there an Agent Skill for this CLI?
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.
Use Cases
- 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
Alternatives
| 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 |
Development
uv sync --dev # install dependencies
uv run pytest # run tests
Acknowledgements
Based on gmchad/otterai-api by Chad Lohrli, with CLI functionality from PR #9 by @andrewfurman.
License
MIT
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file otterai_cli-0.1.3.tar.gz.
File metadata
- Download URL: otterai_cli-0.1.3.tar.gz
- Upload date:
- Size: 87.7 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
35c674361b1b5fb6667713e0e907c6f8b2f7af5b94ec25dcd120e1a6e5700c2f
|
|
| MD5 |
ea3e4ae49a6f3c9789bbd23602389b4c
|
|
| BLAKE2b-256 |
b0f12c3d59ef5b2d27a0f1b40c1b63c6449662c3cfb0d1da71c1f1284bf2ff28
|
Provenance
The following attestation bundles were made for otterai_cli-0.1.3.tar.gz:
Publisher:
publish.yml on erickhchan/otterai-cli
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
otterai_cli-0.1.3.tar.gz -
Subject digest:
35c674361b1b5fb6667713e0e907c6f8b2f7af5b94ec25dcd120e1a6e5700c2f - Sigstore transparency entry: 1058417038
- Sigstore integration time:
-
Permalink:
erickhchan/otterai-cli@91cd267572a58517a989719ae1f71eeda0675953 -
Branch / Tag:
refs/tags/v0.1.3 - Owner: https://github.com/erickhchan
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@91cd267572a58517a989719ae1f71eeda0675953 -
Trigger Event:
release
-
Statement type:
File details
Details for the file otterai_cli-0.1.3-py3-none-any.whl.
File metadata
- Download URL: otterai_cli-0.1.3-py3-none-any.whl
- Upload date:
- Size: 23.6 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
e919a99189b5e413351791cdd83adbf76183f2ea8cbc1d6c3eb1a27b0075b726
|
|
| MD5 |
e4c416b690f9abbbd185f9a92bdbda4f
|
|
| BLAKE2b-256 |
b2f839098ffe7d02b31de457840b206fc7765ca9d17cb5a1d0517e5eaf39b2bf
|
Provenance
The following attestation bundles were made for otterai_cli-0.1.3-py3-none-any.whl:
Publisher:
publish.yml on erickhchan/otterai-cli
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
otterai_cli-0.1.3-py3-none-any.whl -
Subject digest:
e919a99189b5e413351791cdd83adbf76183f2ea8cbc1d6c3eb1a27b0075b726 - Sigstore transparency entry: 1058417039
- Sigstore integration time:
-
Permalink:
erickhchan/otterai-cli@91cd267572a58517a989719ae1f71eeda0675953 -
Branch / Tag:
refs/tags/v0.1.3 - Owner: https://github.com/erickhchan
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@91cd267572a58517a989719ae1f71eeda0675953 -
Trigger Event:
release
-
Statement type: