Skip to main content
This tool uses the Redbark REST API, which is in beta. Behaviour may change as the API evolves.
Actual Budget sync runs as a standalone Docker container that pulls transactions from the Redbark API and imports them directly into your Actual Budget server. It is not a dashboard destination.
This is a self-hosted Docker tool. You run it on your own infrastructure alongside your Actual Budget server.

Prerequisites

  • A running Actual Budget server
  • Docker installed on your machine or server
  • A Redbark account with connected bank accounts
  • A Redbark API key

Setup

1

Get a Redbark API key

Log into Redbark, go to Settings > API Keys, and create a new key. Copy it. It is only shown once.
2

Find your Redbark account IDs

Run the tool with --list-redbark-accounts to see your connected accounts and their IDs:
docker run --rm \
  -e REDBARK_API_KEY=rbk_live_... \
  ghcr.io/redbark-co/actual-sync:latest \
  --list-redbark-accounts
3

Find your Actual Budget account IDs

Run with --list-actual-accounts to see your Actual Budget accounts:
docker run --rm \
  -e ACTUAL_SERVER_URL=http://localhost:5006 \
  -e ACTUAL_PASSWORD=your-password \
  -e ACTUAL_BUDGET_ID=your-budget-sync-id \
  -v actual-sync-data:/app/data \
  ghcr.io/redbark-co/actual-sync:latest \
  --list-actual-accounts
You can also find account IDs in the Actual Budget web UI by copying the UUID from the account URL.
4

Create your account mapping

Map each Redbark account to an Actual Budget account using the format redbark_id:actual_id, comma-separated:
ACCOUNT_MAPPING=rbk-acc-1:actual-acc-1,rbk-acc-2:actual-acc-2
5

Configure environment variables

Create a .env file with your configuration:
REDBARK_API_KEY=rbk_live_a1b2c3d4e5f6...
ACTUAL_SERVER_URL=http://localhost:5006
ACTUAL_PASSWORD=your-password
ACTUAL_BUDGET_ID=1cfdbb80-6274-49bf-b0c2-737235a4c81f
ACCOUNT_MAPPING=rbk-acc-1:actual-acc-1,rbk-acc-2:actual-acc-2
6

Dry run

Preview what would be imported without writing any changes:
docker run --rm --env-file .env \
  -v actual-sync-data:/app/data \
  ghcr.io/redbark-co/actual-sync:latest --dry-run
7

Sync

Run the sync:
docker run --rm --env-file .env \
  -v actual-sync-data:/app/data \
  ghcr.io/redbark-co/actual-sync:latest

Configuration

Environment variables

VariableRequiredDefaultDescription
REDBARK_API_KEYYesYour Redbark API key (rbk_live_...)
ACTUAL_SERVER_URLYesURL of your Actual Budget server
ACTUAL_PASSWORDYesActual Budget server password
ACTUAL_BUDGET_IDYesBudget sync ID (Settings > Advanced in Actual)
ACCOUNT_MAPPINGYesAccount mapping (redbark_id:actual_id,...)
REDBARK_API_URLNohttps://api.redbark.coRedbark API base URL
ACTUAL_ENCRYPTION_PASSWORDNoE2E encryption password if enabled
ACTUAL_DATA_DIRNo/app/dataLocal cache directory for Actual’s SQLite DB
SYNC_DAYSNo30Number of days of history to sync
LOG_LEVELNoinfodebug, info, warn, or error
DRY_RUNNofalseSet to true to preview without importing

CLI flags

FlagDescription
--list-redbark-accountsList Redbark accounts and their IDs
--list-redbark-categoriesList Redbark transaction categories
--list-actual-accountsList Actual Budget accounts and their IDs
--dry-runPreview what would be imported without writing
--days <n>Override number of days to sync
--helpShow help message

Running with Docker

Docker run

docker run --rm \
  --env-file .env \
  -v actual-sync-data:/app/data \
  ghcr.io/redbark-co/actual-sync:latest
The /app/data volume caches the Actual Budget SQLite database locally. Mount a persistent volume so it doesn’t re-download the full budget every run.

Docker Compose

services:
  redbark-actual-sync:
    image: ghcr.io/redbark-co/actual-sync:latest
    restart: "no"
    environment:
      - REDBARK_API_KEY=rbk_live_your_key_here
      - ACTUAL_SERVER_URL=http://actual-server:5006
      - ACTUAL_PASSWORD=your-actual-password
      - ACTUAL_BUDGET_ID=your-budget-sync-id
      - ACCOUNT_MAPPING=redbark-acc-id:actual-acc-id
    volumes:
      - actual-sync-data:/app/data

  actual-server:
    image: actualbudget/actual-server:latest
    ports:
      - "5006:5006"
    volumes:
      - actual-data:/data

volumes:
  actual-sync-data:
  actual-data:

Kubernetes CronJob

apiVersion: batch/v1
kind: CronJob
metadata:
  name: redbark-actual-sync
spec:
  schedule: "0 */6 * * *"
  jobTemplate:
    spec:
      template:
        spec:
          restartPolicy: OnFailure
          containers:
            - name: sync
              image: ghcr.io/redbark-co/actual-sync:latest
              envFrom:
                - secretRef:
                    name: redbark-actual-sync-secrets
              volumeMounts:
                - name: data
                  mountPath: /app/data
          volumes:
            - name: data
              persistentVolumeClaim:
                claimName: redbark-actual-sync-data

Scheduling

Use cron or your orchestrator’s scheduling to run syncs automatically:
# Sync every 6 hours
0 */6 * * * docker run --rm --env-file /home/user/.redbark-sync.env -v actual-sync-data:/app/data ghcr.io/redbark-co/actual-sync:latest >> /var/log/redbark-sync.log 2>&1

How deduplication works

Each transaction is imported with an imported_id of redbark:<transaction_id>. Actual Budget’s importTransactions() uses this to detect duplicates:
  1. If a transaction with the same imported_id exists, it updates instead of creating a duplicate
  2. If no imported_id match, Actual falls back to fuzzy matching on amount + date + payee
You can run the sync as often as you want. Duplicates are never created.

Exit codes

CodeMeaning
0Sync completed successfully
1Sync completed with errors (some transactions failed)
2Configuration error (missing env vars, invalid mapping)
3Connection error (cannot reach Redbark or Actual)

Troubleshooting

Connection refused to Actual server Make sure your Actual Budget server is running and reachable from the Docker container. If both services are in the same Docker Compose stack, use the service name (e.g. http://actual-server:5006) rather than localhost. Budget not found Double-check your ACTUAL_BUDGET_ID. This is the sync ID found in Actual under Settings > Advanced, not the budget name. Encryption password required If you’ve enabled end-to-end encryption in Actual Budget, set the ACTUAL_ENCRYPTION_PASSWORD environment variable to your encryption passphrase. Self-signed certificates For Actual servers behind self-signed TLS certificates, set NODE_EXTRA_CA_CERTS=/path/to/cert.pem in the container environment. Version mismatch The tool automatically detects your Actual server version and downloads a matching client library. If you see version errors, make sure the /app/data volume is mounted so the cached client persists between runs.

Security

Your Redbark API key is only sent over HTTPS. Never bake secrets into Docker images. Use --env-file, Docker Secrets, or Kubernetes Secrets. The tool caches your Actual budget locally in ACTUAL_DATA_DIR, so encrypt the Docker volume on shared infrastructure.

Source code

The sync tool is open source: github.com/redbark-co/actual-sync