Memos — User Guide

Personal voice journal with Markdown support, REST API, and Home Assistant voice integration.

Access: https://journal.haiven.site


Table of Contents

  1. Getting Started
  2. Creating Entries
  3. Searching and Browsing
  4. Hashtag Organization
  5. Access Tokens
  6. Home Assistant Voice Journaling
  7. Homepage Dashboard Widget
  8. API Reference
  9. Backup and Recovery
  10. Troubleshooting

Getting Started

Navigate to https://journal.haiven.site in any browser.

Login

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.


Creating Entries

Web UI

  1. Click the text area at the top of the timeline.
  2. Type your entry in Markdown.
  3. Add #hashtags anywhere in the body — Memos auto-parses them into tags.
  4. Click Send (or press Ctrl+Enter).

The entry appears instantly in the timeline with a timestamp.

Keyboard Shortcuts

Shortcut Action
Ctrl+Enter Save entry
Ctrl+B Bold
Ctrl+I Italic

Entry Visibility

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 SettingsSystem.


Searching and Browsing

Use the search bar at the top to search across all entry content.

Filter by Tag

Click any hashtag in the timeline to filter entries by that tag. The URL updates so you can bookmark filtered views.

Timeline Navigation

Entries appear in reverse-chronological order. The sidebar shows:
- All: All entries
- Tags: All hashtags used across entries
- Archive: Older entries by month


Hashtag Organization

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

Access tokens authorize API calls and the Home Assistant integration. They are distinct from your login password.

Generate a Token

  1. Log in to https://journal.haiven.site
  2. Go to Settings (gear icon) → Access Tokens
  3. Click Generate new token
  4. Set a name (e.g., home-assistant) and expiration
  5. Copy the token immediately — it is shown only once

Storing the Token for Home Assistant

Add 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.

Token Rotation

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)


Home Assistant Voice Journaling

The voice pipeline lets you dictate journal entries hands-free. An LLM formats the raw transcription before saving.

How It Works

Voice satellite → Wake word → HA Assist pipeline
  → haiven-transcribe (STT) → JournalEntry intent
  → llama-swap (format transcript) → Memos API (save)
  → smart_announce ("Journal entry saved.")

Voice Phrases

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.

Expected Timing

Test Without Voice

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.


Homepage Dashboard Widget

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

API Reference

All API calls require a Bearer token generated in Settings → Access Tokens.

Base URL

Create an Entry

curl -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.

List Entries

curl -s https://journal.haiven.site/api/v1/memos?limit=10 \
  -H "Authorization: Bearer YOUR_TOKEN"

Query parameters: limit (default 10), offset (for pagination).

Get a Single Entry

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).

Delete an Entry

curl -s -X DELETE "https://journal.haiven.site/api/v1/memos/memos%2F123" \
  -H "Authorization: Bearer YOUR_TOKEN"

Backup and Recovery

Automated Backups

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

Restore from Backup

# 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

Troubleshooting

Cannot Log In

Voice Entry Not Saving

  1. Check HA logs: docker logs homeassistant 2>&1 | grep -i "memos\|journal" | tail -20
  2. Verify the token is current: test it directly with curl -H "Authorization: Bearer TOKEN" http://10.0.0.42:5230/api/v1/memos
  3. A 401 means the token expired or was rotated — update memos_api_token_bearer in secrets.yaml

Entry Created But Not Appearing

The 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.

API Returns 422

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.