You run Nextcloud because your calendar should belong to you. Then work hands you Outlook, and your two calendars stop speaking.
The result is a personal calendar nobody at work can see, and a work calendar that books straight over your Saturday. Keeper.sh copies events from one onto the other so the busy blocks line up.
What will this actually do?
Your Nextcloud events appear on your Outlook calendar. Move one in Nextcloud and the copy moves. Delete it and the copy goes.
That is a connection, and it runs in one direction only. Want both directions? Build a second connection the other way, which counts separately.
What do you need before you start?
- A Nextcloud instance reachable over HTTPS from wherever Keeper.sh runs
- Your Nextcloud username, which is often not your email address
- An app password if you have two-factor enabled, and ideally even if you do not
- An Outlook or Microsoft 365 account
- An account on keeper.sh
One thing worth settling early: hosted Keeper.sh has to reach your Nextcloud over the public internet. A Nextcloud on 192.168.1.50 or nextcloud.local is not reachable, and no setting on your account changes that. Self-hosting Keeper.sh is the answer for a LAN-only instance.
How do you connect Nextcloud?
Open Import Calendars from your dashboard and choose Connect CalDAV Server from the bottom group. Nextcloud has no button of its own and does not need one, because it speaks the same CalDAV standard Keeper.sh uses for iCloud.
Three fields:
- CalDAV Server URL — your Nextcloud base URL, for example
https://cloud.example.com - CalDAV Server Username — your Nextcloud username, not your email address unless they match
- CalDAV Server Password — your password, or an app password
Paste the base URL and Keeper.sh finds your calendars from there. You do not need to dig out the remote.php/dav/calendars/username/ path.
Get an app password
Use one even without two-factor, because it is revocable on its own.
In Nextcloud, open Settings → Security, find Devices & sessions, name the app and create the password. With two-factor turned on this stops being optional, because Nextcloud rejects your login password over CalDAV entirely.
Click Connect. Keeper.sh imports every calendar it discovers, then drops you into setup.
How do you connect Outlook?
Back on Import Calendars, Connect Outlook is for personal accounts and Connect Microsoft 365 is for work and school accounts. Either way, Keeper.sh lists what it will ask Microsoft for:
- See your email address
- View a list of your calendars
- View events, summaries and details
- Add or remove calendar events
Click Connect and complete Microsoft's consent screen. On a managed work tenant an administrator may need to approve the app first, and nothing in Keeper.sh can route around that.
Which calendar sends to which?
Setup is four screens.
- Which calendars would you like to configure? Tick what you want to set up now. Everything was already imported.
- Rename Your Calendars. Nextcloud defaults to names like "Personal". Renaming here is local to Keeper.sh and does not touch the calendar on your server.
- Where should 'Personal' send events? Pick the calendars that should receive copies.
- Where should 'Personal' pull events from? The same question in reverse.
For Nextcloud into Outlook you need screen three. Pick your Outlook calendar and the connection exists.
Everything is editable afterwards from a calendar's page, under Send Events to Calendars.
How much of the event crosses over?
Decide this deliberately, because one end of this pairing is your employer's system. Open the calendar in your dashboard and find Sync Settings, which holds Sync Event Name, Sync Event Description and Sync Event Location.
With Sync Event Name off, the copy is titled after the calendar it came from. A consultant's appointment reaches Outlook as a block called "Personal", not as its real name.
Turn it on and the true title goes through. The Event Name box accepts {{event_name}} and {{calendar_name}}, so you can word the placeholder however you like.
Exclusions below can drop all-day events. Both sections are Pro on Keeper.sh and included for everyone self-hosting.
What does not come across?
Time and text, and little else. None of this reaches the copy:
- Guests. The copy has no attendees, so nobody gets an invitation from it.
- Meeting links. Teams, Meet and Zoom joins are not carried over.
- Alerts. Reminders do not travel, so Outlook applies its own defaults.
- Colours, attachments and categories from your side. Not copied.
What does travel: the title, description, location, start and end, the time zone, whether it repeats, and whether it shows you as busy or free.
How quickly, and how far ahead?
Keeper.sh reads both calendars every minute, on every plan. Writing the change onto the other calendar is what differs: free does it every 30 minutes, Pro every minute.
If you are mirroring personal commitments so work sees you as busy, 30 minutes changes nothing you will notice. If people book you through a scheduling link, half an hour is enough to get double-booked.
Keeper.sh covers a week back to two years ahead. A one-off event further out is not copied until it drifts into range, though a repeating series that began before the window still has its upcoming occurrences copied.
Every event Keeper.sh creates in Outlook carries a category named keeper.sh. That tag is how Keeper.sh recognises its own work later, so leave it alone.
Why isn't it working?
Connecting fails with a short error mentioning 401. Nextcloud rejected the credentials. With two-factor enabled this is almost always the login password being used where an app password is required.
Keeper.sh says "No calendars found". It authenticated, but Keeper.sh keeps only collections advertising support for VEVENT, and some reverse proxies strip that property from PROPFIND responses.
Nextcloud is unreachable and you self-host Keeper.sh. The deployment Compose file sets BLOCK_PRIVATE_RESOLUTION=true, which refuses anything resolving to a private address. Add your host to PRIVATE_RESOLUTION_WHITELIST.
Microsoft consent fails outright on a work account. Managed tenants can block third-party calendar apps, and you need an administrator to approve it.
Events arrive on Outlook titled after the calendar. Sync Event Name is off. Turn it on in Sync Settings.
Changes in Outlook never reach Nextcloud. One connection, one direction. Add a second going back.
An entire calendar stops updating, not one event. Usually a repeating event with a runaway rule. Keeper.sh will not expand a series past ten thousand occurrences in the two-year window, and hitting that stops the calendar it belongs to.
Events vanish from Outlook that still exist in Nextcloud. Keeper.sh refetches Nextcloud in full each cycle, so a proxy that silently caps objects per response looks like a calendar that really lost them.
What does the free plan cover?
Two calendar accounts and three connections. Nextcloud is one account and Microsoft the second, so this pairing uses the whole account allowance.
Nothing caps calendars inside an account — twelve Nextcloud calendars still count as one. Three connections covers Nextcloud to Outlook, Outlook back to Nextcloud, and one spare.
Where are my Nextcloud credentials kept?
Encrypted at rest with a configurable key. CalDAV replays the password on every request, so Keeper.sh needs it in a reversible form and would rather say so than imply otherwise.
Revoking works from either end: delete the app password in Nextcloud, or open the account in Keeper.sh and use Delete Account.
Would you rather run Keeper.sh yourself too?
Running Nextcloud does not mean you want another service to babysit, so this is a real choice rather than the obvious one.
Self-hosting is not a downgrade. It is AGPL-3.0 with every Pro feature included, and it removes the public-reachability problem, since Keeper.sh can then sit on the same network as your Nextcloud.
The honest costs:
- Another server, domain and certificate to keep alive
- Docker and Docker Compose, plus Postgres and Redis
- Your own Microsoft OAuth app registered in Azure, with scopes
Calendars.ReadWrite,User.Readandoffline_access BETTER_AUTH_SECRETandENCRYPTION_KEYkept safe, because losing the second loses your stored credentials- Backups, updates, and being the person who gets paged when it stops
The README has a single-container setup and a full Compose file. If you would rather not own another thing, keeper.sh runs it and funds the project.