Personal voice journal with Markdown support, REST API, and Home Assistant voice integration.
Access: https://journal.haiven.site
Navigate to https://journal.haiven.site in any browser.
Log in with the admin credentials stored in Bitwarden (search "Memos journal.haiven.site"). The local admin password is not stored on disk — Memos keeps all credentials in its SQLite database.
If Authentik OIDC has been configured (see the setup guide at _server-setup/08/08k-memos-journal-v2.md), a "Sign in with Authentik" button will appear on the login page, allowing SSO with your Haiven credentials.
#hashtags anywhere in the body — Memos auto-parses them into tags.Ctrl+Enter).The entry appears instantly in the timeline with a timestamp.
| Shortcut | Action |
|---|---|
Ctrl+Enter |
Save entry |
Ctrl+B |
Bold |
Ctrl+I |
Italic |
Entries default to PRIVATE (visible only to you). You can override per-entry via the visibility selector in the editor, but it is recommended to keep the system default set to PRIVATE in Settings → System.
Use the search bar at the top to search across all entry content.
Click any hashtag in the timeline to filter entries by that tag. The URL updates so you can bookmark filtered views.
Entries appear in reverse-chronological order. The sidebar shows:
- All: All entries
- Tags: All hashtags used across entries
- Archive: Older entries by month
Memos auto-parses #word patterns anywhere in entry content. No special syntax required.
Voice pipeline entries use these auto-generated tags:
- #voice — All voice-dictated entries
- #journal — Default fallback tag
Add your own tags freely. Tags with spaces are not supported — use #morning-walk or #morningwalk.
Access tokens authorize API calls and the Home Assistant integration. They are distinct from your login password.
https://journal.haiven.sitehome-assistant) and expirationAdd the full Bearer string to homeassistant/config/secrets.yaml:
memos_api_token_bearer: "Bearer YOUR_TOKEN_HERE"
The !secret memos_api_token_bearer directive in the HA REST commands references this value.
When rotating a token:
1. Generate a new token in Memos UI
2. Update memos_api_token_bearer in secrets.yaml with the new Bearer <token> string
3. Reload Home Assistant configuration (Settings → System → Reload All YAML)
The voice pipeline lets you dictate journal entries hands-free. An LLM formats the raw transcription before saving.
Voice satellite → Wake word → HA Assist pipeline
→ haiven-transcribe (STT) → JournalEntry intent
→ llama-swap (format transcript) → Memos API (save)
→ smart_announce ("Journal entry saved.")
| Say | Result |
|---|---|
| "journal entry [anything]" | Creates journal entry |
| "journal [anything]" | Creates journal entry |
| "write in my journal [anything]" | Creates journal entry |
| "add to my journal [anything]" | Creates journal entry |
| "dear journal [anything]" | Creates journal entry |
Speak naturally after the trigger phrase. The LLM preserves your voice and word choices while adding a title, tags, and Markdown formatting.
In HA Developer Tools → Services, call intent.handle with:
name: JournalEntry
data:
text: "test entry from developer tools"
Check the Memos timeline for the entry.
If the Homepage configuration includes a Memos widget, it appears in the "Personal" group at home.haiven.site.
The widget shows recent entry count and links directly to https://journal.haiven.site.
To configure manually, add to Homepage's services.yaml:
- Personal:
- Memos Journal:
icon: memos.png
href: https://journal.haiven.site
description: Personal journaling
siteMonitor: https://journal.haiven.site/healthz
All API calls require a Bearer token generated in Settings → Access Tokens.
https://journal.haiven.sitehttp://10.0.0.42:5230curl -s -X POST https://journal.haiven.site/api/v1/memos \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"content": "# My Entry\n\nSome text #journal",
"visibility": "PRIVATE"
}'
Response includes name (e.g., memos/123), uid, content, and createTime.
curl -s https://journal.haiven.site/api/v1/memos?limit=10 \
-H "Authorization: Bearer YOUR_TOKEN"
Query parameters: limit (default 10), offset (for pagination).
curl -s "https://journal.haiven.site/api/v1/memos/memos%2F123" \
-H "Authorization: Bearer YOUR_TOKEN"
Use the name field from create/list responses (URL-encode the / as %2F).
curl -s -X DELETE "https://journal.haiven.site/api/v1/memos/memos%2F123" \
-H "Authorization: Bearer YOUR_TOKEN"
The backup.sh script creates timestamped SQLite backups with retention:
| Tier | Frequency | Retention | Location |
|---|---|---|---|
| Daily | Every run | 7 backups | /mnt/storage/memos/backups/daily/ |
| Weekly | Sundays | 4 backups | /mnt/storage/memos/backups/weekly/ |
| Monthly | 1st of month | Unlimited | /mnt/storage/memos/backups/monthly/ |
Run a manual backup:
/mnt/apps/docker/memos/backup.sh
# Stop the container
docker compose -f /mnt/apps/docker/memos/docker-compose.yml stop
# Restore the database
gunzip -c /mnt/storage/memos/backups/daily/memos_YYYYMMDD_HHMMSS.db.gz \
> /mnt/apps/docker/memos/data/memos.db
# Start the container
docker compose -f /mnt/apps/docker/memos/docker-compose.yml up -d
docker ps --filter name=memosdocker logs homeassistant 2>&1 | grep -i "memos\|journal" | tail -20curl -H "Authorization: Bearer TOKEN" http://10.0.0.42:5230/api/v1/memosmemos_api_token_bearer in secrets.yamlThe timeline auto-updates. Hard-refresh the page with Ctrl+Shift+R. If the entry was created with visibility other than PRIVATE, switch the filter from "All" to the appropriate visibility.
The JSON payload is malformed. Common causes: unescaped quotes in voice transcription, template rendering error. Check HA Developer Tools → Template to debug the Jinja rendering.