An automation tool that connects to Kivra (a Swedish digital mailbox service) to download and organize your digital receipts and letters, helping you maintain a local backup of your important documents.
This tool is originaly based on a script created here https://github.com/stefangorling/fetch-kivra, thanks Stefan! It has since gone through major changes and feature additions.
This project is not affiliated with Kivra in any way. It is an independent, open-source tool created by the community to help users download their documents from Kivra - a feature that is otherwise only available through manual clicks in their user interface.
We believe individuals should have easy access to their own data. Digital mailboxes like Kivra hold important documents on behalf of users, and the lack of an efficient export option makes it unnecessarily cumbersome for users to retrieve and back up their documents. This tool aims to bridge that gap.
Use it responsibly and at your own discretion.
- Authentication: Fetches and displays a QR code for authentication via BankID.
- Flexible Storage: Store documents locally on your filesystem or integrate with Paperless-ngx for advanced document management
- Multiple Interaction Modes: Run interactively in your terminal or set up a "headless" mode that listens for triggers and sends QR codes via a web page or ntfy.sh
This will:
- Authenticate with Kivra using BankID
- Fetch receipts and letters
- Store them in the filesystem
# Edit docker-compose.example.yml to set your configuration
# especially "your-national-identification-number-here"
# Then run:
docker compose build && docker compose upNote: this will not work with the default local interaction provider since there is currently no way for the provider to show the QR code required for login. The above is configured to launch with the web interaction provider.
# Install system dependencies (Debian/Ubuntu)
apt-get install weasyprint
# Install Python dependencies
pip install -r requirements.txt
# Run the script
python kivra_sync.py YYYYMMDDXXXXIf you have Nix with flakes enabled:
# Run (uses the flake-provided environment)
nix run . -- --help
# Typical run, storing under ./data/<ssn>/
nix run . -- YYYYMMDDXXXX --base-dir ./data
# Run with the web interaction provider
nix run . -- YYYYMMDDXXXX --interaction-provider web --web-port 8080
# Build and run help on resulting executable
nix build && result/bin/kivra-sync --help
# Dev shell with Python + deps + system libs
nix develop
Documents are stored in the local filesystem.
python kivra_sync.py YYYYMMDDXXXX --storage-provider filesystem --base-dir /path/to/storeUpload documents directly to Paperless-ngx:
python kivra_sync.py YYYYMMDDXXXX --storage-provider paperless \
--paperless-url http://your-paperless-server:8000/api \
--paperless-token your_paperless_api_token \
--paperless-tags "kivra,receipts,automated"Interaction providers handle user interaction during authentication and report completion statistics.
Displays QR codes locally and reports to the console:
python kivra_sync.py YYYYMMDDXXXX --interaction-provider localProvides a web interface for triggering syncs and viewing results:
python kivra_sync.py YYYYMMDDXXXX --interaction-provider web --web-port 8080Then navigate to http://localhost:8080 in your browser to access the interface. Perfect for containerized deployments where GUI access is not available.
Sends QR codes and reports via ntfy.sh, with optional listening mode:
python kivra_sync.py YYYYMMDDXXXX --interaction-provider ntfy --ntfy-topic your-topicTo trigger the script in listening mode, send the trigger message to the ntfy topic:
curl -d "run now" ntfy.sh/your-topicCustomize which documents to fetch and how many:
# Fetch only letters
python kivra_sync.py YYYYMMDDXXXX --no-fetch-receipts
# Fetch only receipts
python kivra_sync.py YYYYMMDDXXXX --no-fetch-letters
# Fetch up to 10 letters and 5 receipts
python kivra_sync.py YYYYMMDDXXXX --max-letters 10 --max-receipts 5
# Fetch unlimited receipts
python kivra_sync.py YYYYMMDDXXXX --max-receipts 0| Option | Description |
|---|---|
YYYYMMDDXXXX (positional) |
Personal identity number |
--dry-run |
Do not actually store documents, just simulate |
| Option | Description |
|---|---|
--storage-provider {filesystem,paperless} |
Storage provider to use (default: filesystem) |
--base-dir DIR |
Base directory for storing documents (default: current working directory) |
| Option | Description |
|---|---|
--paperless-url URL |
Paperless API URL (required for paperless) |
--paperless-token TOKEN |
Paperless API token (required for paperless) |
--paperless-tags TAGS |
Comma-separated list of tags to apply to all documents |
| Option | Description |
|---|---|
--interaction-provider {local,ntfy,web} |
Interaction provider to use (default: local) |
--ntfy-topic TOPIC |
ntfy topic to send notifications to (required for ntfy) |
--ntfy-server URL |
ntfy server URL (default: https://ntfy.sh) |
--ntfy-user USER |
ntfy username for authentication |
--ntfy-pass PASS |
ntfy password for authentication |
--web-port PORT |
Port for web interface (default: 8080) |
--web-host HOST |
Host for web interface (default: 0.0.0.0) |
--trigger-message MSG |
Message that triggers the script (default: "run now") |
| Option | Description |
|---|---|
--fetch-receipts / --no-fetch-receipts |
Enable/disable receipt fetching (default: enabled) |
--fetch-letters / --no-fetch-letters |
Enable/disable letter fetching (default: enabled) |
--max-receipts N |
Maximum number of receipts to fetch (0 for unlimited) |
--max-letters N |
Maximum number of letters to fetch (0 for unlimited) |
The code is organized into logical modules:
kivra/: Kivra-specific functionality (auth, API, models)storage/: Document storage providersinteraction/: User interaction providersutils/: Utility functions