Backup and restore
Export your recordings, transcripts, and audio so you can leave at any time.
OpenPlaud has two separate export paths, deliberately. They serve different jobs:
/api/backup— a complete JSON archive of every recording row and transcript that belongs to you. Built for full disaster recovery and migration off the instance./api/export— every recording's transcript flattened into one human-readable file (txt,srt,vtt) or ajsondump. Built for handing transcripts to other tools, not for backup.
The audio files themselves live in your configured storage backend (local volume or S3 bucket) and are backed up the same way you'd back up any other binary blob.
Backup the database state
Settings → Export/Backup → Create Backup (or POST /api/backup)
produces a single JSON file:
{
"version": "1.0",
"createdAt": "2026-05-13T12:00:00.000Z",
"userId": "...",
"recordings": [
{
"id": "...",
"filename": "Team standup",
"duration": 1820,
"startTime": "...",
"endTime": "...",
"filesize": 1234567,
"deviceSn": "...",
"transcription": {
"text": "Plaintext transcript text...",
"provider": "...",
"model": "..."
}
}
]
}The archive is plaintext. OpenPlaud's at-rest encryption decrypts all fields before serialization because the backup is your export of your own data — you own it from this point. Treat the file the same way you'd treat an unencrypted database dump: store it encrypted, restrict access, don't email it.
The backup does not include audio files. Back those up separately.
Backup the audio files
- Local storage backend. The Docker volume that mounts at
/app/audioinside the container holds every audio file. Snapshot it the same way you snapshot any other volume —restic,rsync, ZFS snapshots, your choice. - S3 backend. Whichever bucket you configured already lives outside the instance. Enable versioning, cross-region replication, or a lifecycle copy job on the bucket itself.
The path layout inside the bucket / directory is
{userId}/{filename}.mp3, with (2), (3), … suffixes appended
on collisions.
Bulk transcript export
GET /api/export?format=<fmt> flattens every one of your recordings
into a single file:
| Format | Content |
|---|---|
json | One JSON document with every recording + transcript |
txt | Plaintext, one block per recording (filename, time, text) |
srt | SubRip subtitles, all recordings concatenated |
vtt | WebVTT subtitles, all recordings concatenated |
The default format is whatever you set as Settings → Export/Backup
→ Default export format, falling back to json. The Export All
button in that same panel calls this endpoint.
Restore
There is no POST /api/backup/restore endpoint today. The backup file
is the export half of the contract — it lets you leave the instance
with your data intact, which is what "export parity" guarantees. If
you need to import a backup into a fresh instance, the supported path
is a Postgres-level restore (the snapshot of the database volume), not
a JSON re-import.
If you need a programmatic re-import — for migrating between self-host instances, for instance — file an issue with the use case. It's a deliberate gap, not an oversight, and the right shape depends on the use case.
What's encrypted vs. what's plaintext
A reminder, because this trips people up:
- In the database, sensitive fields are encrypted at rest with AES-256-GCM (see Encryption at rest).
- In a backup file produced by
/api/backup, those fields are decrypted before serialization. Your responsibility from there. - Audio files in storage are not encrypted by OpenPlaud's app-layer encryption — use bucket-level SSE if you need that.
Last updated on