Unofficial Python client for the Plaud AI API.
Plaud is a wearable meeting recorder that captures audio and provides cloud-based transcription and AI summaries. There is no official public API — this library is reverse-engineered from browser traffic to api.plaud.ai and allows programmatic access to your recordings, transcriptions, speakers, and tags.
Disclaimer: This is an unofficial, reverse-engineered client. It is not affiliated with, endorsed by, or connected to Plaud Inc. in any way. Use at your own risk. The API may change without notice.
- List, upload, and download recordings
- Start transcription/analysis and retrieve results
- Get AI-generated meeting summaries
- Manage speakers (list, rename, per-recording stats)
- Organize recordings with tags
- Typed Pydantic models for all API responses
- CLI tool for quick operations from the terminal
Requires Python 3.10+
pip install plaud-apiFrom source (local development):
git clone https://github.com/arbuzmell/plaud-api.git
cd plaud-api
pip install -e ".[dev]"Token is resolved in this order:
- Explicit
token=parameter PLAUD_TOKENenvironment variable.envfile in current directory (PLAUD_TOKEN=...)~/.config/plaud/tokenfile
- Open web.plaud.ai and sign in
- Open DevTools → Network tab → find any request to
api.plaud.ai - Copy the
Authorizationheader value (without the "bearer " prefix) - Run
plaud auth setupand paste it
Step-by-step guides with screenshots:
| Browser | Guide |
|---|---|
| Google Chrome | Token guide for Chrome |
| Safari | Token guide for Safari |
| Firefox | Token guide for Firefox |
Safari users: DevTools are disabled by default — see the Safari guide for how to enable them.
from plaud import PlaudClient
client = PlaudClient() # auto-detects token from env / config file
# List recent recordings
recordings = client.recordings.list(limit=5)
for rec in recordings:
print(f"{rec.filename} {rec.duration_display} id={rec.id}")
# Get transcription for the first recording
transcript = client.transcriptions.get(recordings[0].id)
for seg in transcript.segments:
print(f"[{seg.speaker}] {seg.text}")
# Get AI summary
summary = client.transcriptions.get_summary(recordings[0].id)
print(summary.content)Some Plaud accounts are served from regional API hosts. Pass base_url when
creating the client:
from plaud import PlaudClient
client = PlaudClient(base_url="https://api-apse1.plaud.ai")
recordings = client.recordings.list()The default endpoint remains https://api.plaud.ai.
| Method | Returns | Description |
|---|---|---|
client.recordings.list(limit=50) |
list[Recording] |
List recent recordings, most recent first |
client.recordings.get(file_id) |
Recording |
Get a single recording by ID |
client.recordings.get_audio_url(file_id) |
str |
Get a temporary S3 presigned URL to download the audio |
client.recordings.upload(path, name=...) |
Recording |
Upload an MP3/OPUS file to Plaud |
client.recordings.get_raw(file_id) |
dict |
Raw API response (includes trans_result, ai_content, etc.) |
Recording fields: id, filename, duration_ms, filesize, created_at, has_transcription, has_summary, tag_ids, duration_display, duration_seconds.
Analysis is a 3-step flow: start -> wait -> save_results.
# 1. Start analysis on the Plaud server
client.transcriptions.start(file_id, language="en")
# 2. Block until the analysis completes (polls every 10s)
result = client.transcriptions.wait(file_id, language="en", timeout=600)
# 3. Save the results back to Plaud cloud (required to persist them)
client.transcriptions.save_results(file_id, result)After analysis is saved, you can retrieve the structured data:
| Method | Returns | Description |
|---|---|---|
client.transcriptions.get(file_id) |
Transcription |
Segments with speaker, text, start_time_ms, end_time_ms |
client.transcriptions.get_summary(file_id) |
Summary |
AI-generated summary as markdown |
client.transcriptions.get_status(file_id) |
AnalysisStatus |
Check if analysis is complete |
client.transcriptions.update_transcript(file_id, segments) |
dict |
Update transcript segments (e.g. fix speaker names) |
Supported languages: en, ru, zh, ja, ko, de, fr, es, and others.
Speaker names live in each recording's transcription. Use rename() to change them.
| Method | Returns | Description |
|---|---|---|
client.speakers.list() |
list[Speaker] |
All known speakers (global list, read-only) |
client.speakers.get_for_recording(file_id) |
list[dict] |
Speakers in a recording with name and segments_count |
client.speakers.rename(file_id, old, new) |
dict |
Rename a speaker in a recording's transcript |
# See who spoke in a recording
speakers = client.speakers.get_for_recording("file_id")
# [{"name": "Speaker 1", "segments_count": 42}, {"name": "Speaker 2", ...}]
# Rename "Speaker 1" to "Alice" in this recording
client.speakers.rename("file_id", "Speaker 1", "Alice")| Method | Returns | Description |
|---|---|---|
client.tags.list() |
list[Tag] |
All tags (folders) |
client.tags.get_recordings(tag_id) |
list[str] |
Recording IDs belonging to a tag |
# Recordings
plaud recordings list # list recent recordings
plaud recordings list -n 50 # list more
plaud recordings get <file_id> # show recording details
plaud recordings upload meeting.mp3 --name "Standup" --analyze
plaud recordings download <file_id> # download audio file
plaud recordings download <file_id> --url-only # just print the URL
# Transcription
plaud transcription start <file_id> --language en # start analysis
plaud transcription status <file_id> # check progress
plaud transcription get <file_id> # print transcript
plaud transcription get <file_id> --json # print as JSON
plaud transcription summary <file_id> # print AI summary
# Speakers
plaud speakers list # list known speakers
plaud speakers recording <file_id> # who spoke in a recording
plaud speakers rename <file_id> "Speaker 1" "Alice" # rename in a recording
# Tags
plaud tags list # list all tags
plaud tags recordings <tag_id> # recording IDs in a tag
# Auth
plaud auth setup # paste token manually
plaud auth token # print current token
plaud auth logout # remove saved tokenShort aliases: rec, tr, sp for recordings, transcription, speakers.
| Problem | Solution |
|---|---|
Plaud token not found |
Run plaud auth setup or set PLAUD_TOKEN env var |
Authentication failed (401) |
Token expired. Run plaud auth setup to get a new one |
AnalysisTimeoutError |
Increase timeout: client.transcriptions.wait(id, timeout=900). Long recordings can take up to 10 min |
NotFoundError |
Check the file ID. Use plaud recordings list to find valid IDs |
APIError 500 |
Plaud server issue. The client retries 5xx automatically (3 attempts) |
A ready-to-use Claude Code skill is included in claude-skill/. See claude-skill/README.md for setup instructions.
- Clone the repo
pip install -e ".[dev]"pytestto run testsruff check src/to lint
This project is for educational and personal use. It interacts with an undocumented API that was reverse-engineered from browser traffic. The author is not responsible for any consequences of using this software. The API may break at any time. Do not use this for any purpose that violates Plaud's Terms of Service.