Skip to content
proton-cli

Calendar

Events, recurrence, reminders and invitations in Proton Calendar, when other people are busy, booking pages, and .ics in and out. Everything is encrypted with your calendar key and signed with your address key.

This page is what people actually do. For every command and flag, see the reference: events, busy times, booking pages, reminders, invitations, settings.

Terminal window
proton calendar events list
proton calendar events list --calendar Work --after 2026-04-15 --before 2026-04-30
proton calendar events get "Team sync"

Every calendar is included unless --calendar narrows it.

--after and --before are the first and last whole days to include, read in your own zone, and both are included. Without them you get the next 30 days, starting today. Name one and you get the 30 days starting or ending there, so --after 2027-01-01 lists January 1 to 30.

An event is on a day when it touches any part of it, so a query for one day inside a three-day event returns it.

--keyword matches the title, the location, the description, the organizer and the people invited. Without a date range it covers every event there has been and the next three years of every repeating one, which is how to find one whose date you do not know:

Terminal window
proton calendar events list --keyword dentist

Reading every event takes a moment. To have it answered from a copy on this machine instead, see Local index.

Each occurrence of a recurring event is listed on its own day, with a reference naming that occurrence:

Terminal window
$ proton calendar events list --after 2026-04-20 --before 2026-04-27
ID DATE TIME DURATION TITLE LOCATION
───────────────────────── ────────── ─────── ──────── ────────────── ────────
4f2a1b9c@2026-04-20T09:00 2026-04-20 09:00 15m Standup Meet
7bd3e011 2026-04-21 all day 1d Public holiday
4f2a1b9c@2026-04-22T10:30 2026-04-22 10:30 30m Standup (long) Meet
4f2a1b9c@2026-04-27T09:00 2026-04-27 09:00 15m Standup Meet
Terminal window
proton calendar events create --title Dentist --start 2026-04-16T14:00 --duration 1h
proton calendar events create --title Conference --start 2026-04-20 --all-day --duration 3d
proton calendar events create --calendar Work --title "Quarterly sync" \
--start 2026-04-16T14:00 --duration 90m --location "Vienna HQ" --description "Numbers and roadmap"

Without --calendar, an event goes into your default calendar, and the result names it. settings calendars update --default sets which one that is.

Say how long an event lasts once, with either --end or --duration. Both together is refused, and so is either without --start. Say neither and a new event lasts as long as its calendar says a new event lasts - settings calendars get shows that, settings calendars update --default-duration sets it - while an all-day event lasts a day.

Flag Accepts
--start 2026-04-16T14:00, 2026-04-16 14:00, 2026-04-16, or full RFC 3339
--end the last day it runs through (2026-04-22), or a day and a time
--duration 15m, 90m, 1h, 2h30m, or 3d for an all-day event
--remind 15m, 1h, 1d, repeatable; add :email for an emailed one
--after / --before on list YYYY-MM-DD, both days included

--all-day makes an event with no time of day, measured in days. It ends at the midnight after its last day, which is how every other calendar client writes it.

Whether an event has a time of day is what a written time says it is. A bare day on create needs --all-day to agree; a day and a time on update gives an all-day event a time of day, and a bare day moves an event and leaves its time of day alone. --all-day takes one away, and --all-day=false gives one back - it needs a --start saying which time, since nothing else could.

Terminal window
proton calendar events update Offsite --all-day
proton calendar events update Offsite --all-day=false --start 2026-07-01T09:00 --end 2026-07-01T17:00

--status says whether the event is going ahead: confirmed, tentative or cancelled. Cancelling this way keeps the event and its history, which delete does not.

--color gives one event a colour of its own, on create and on update. An event without one is drawn in its calendar’s colour.

Terminal window
proton calendar events create --title Deadline --start 2026-04-30T17:00 --duration 1h --color strawberry
proton calendar events update Dentist --color pacific

Name one of the twenty accent colours or give its hex value. Anything else is refused, and the refusal prints the palette.

An edit that says nothing about the colour leaves it alone, and a colour reaches exactly what the reference names: one occurrence takes its own, --onwards colours that one and every later one, and the series’ own reference colours all of it.

A colour cannot be taken away once an event has one - it can only be changed.

A colour per event is a paid feature. On a free account the colour is stored and events get reports it, but Proton’s apps draw the calendar’s colour instead.

Proton users are added directly. External addresses get an emailed invitation.

A bare address invites somebody as required, and --attendee jane@example.com:optional as optional. A value that is not an address, or a role other than optional or required, is refused before anything is sent.

--rrule takes an iCal recurrence rule.

Terminal window
proton calendar events create --title Standup --start 2026-04-16T09:00 --duration 15m \
--rrule "FREQ=WEEKLY;COUNT=10" --remind 15m

The series is anchored to the zone you are working in, so a 09:00 standup stays at 09:00 when the clocks change.

Every event carries the zone it is anchored to, and the result says which:

Terminal window
$ proton calendar events create --title Dentist --start 2026-04-16T14:00
✓ Created event "Dentist" in Personal for 2026-04-16 14:00 Europe/Vienna, 30m long.

The zone comes from --zone, TZ, zone: in your config, your system, or your Proton calendar’s primary zone, in that order.

The four hours a year where a clock reading means two instants or none are refused rather than guessed. Add an offset to say which you meant:

Terminal window
$ proton calendar events create --title 'Night shift' --start 2026-10-25T02:30
Error: 02:30 happens twice on 2026-10-25 in Europe/Vienna, when the clocks go back; say which one, as 2026-10-25T02:30:00+02:00 or 2026-10-25T02:30:00+01:00

Before you invite people, see when they are busy:

Terminal window
$ proton calendar busy-times list jane.roe@example.com alex.roe@example.com max@example.org --after 2026-05-04 --before 2026-05-08
EMAIL DATE TIME DURATION
──────────────────── ────────── ─────── ────────
jane.roe@example.com 2026-05-04 09:00 1h
alex.roe@example.com 2026-05-04 14:00 1h30m
jane.roe@example.com 2026-05-05 all day 1d
alex.roe@example.com 2026-05-07 10:30 30m
4 busy times.
! Availability unknown for max@example.org: Proton will not say when they are busy.

It needs a Duo, Family, Visionary or business plan. On any other plan it is refused.

A busy time says when somebody is busy, never what with. Without --after and --before you get the next 7 days, starting today.

Anyone outside Proton, and anyone else Proton will not show, is listed as unknown rather than left out. With --output json they are under unknown.

Whether your own events make you look busy to others is set per calendar with --busy; see Your calendars.

Terminal window
proton calendar events update REF --title "New title" --start 2026-04-17T10:00 --duration 2h
proton calendar events respond "Team sync" --answer accept # emails the organizer
proton calendar events delete "Dentist"

Anything you do not mention is left alone, including the reminders, the recurrence and the occurrences you have cancelled.

--answer is accept, tentative or decline, and applies to the whole invitation rather than to one occurrence.

Recurring events, occurrence by occurrence

Section titled “Recurring events, occurrence by occurrence”

The reference decides how far a change reaches. Keep the @occurrence part to act on that occurrence. Drop it to act on the series. --onwards widens one occurrence to it and everything after.

Terminal window
# move one standup, leaving the series alone
proton calendar events update 4f2a1b9c@2026-04-22T09:00 --start 2026-04-22T10:30 --duration 30m
# cancel one standup
proton calendar events delete 4f2a1b9c@2026-04-22T09:00
# from May the 4th on, it moves half an hour later
proton calendar events update 4f2a1b9c@2026-05-04T09:00 --start 2026-05-04T09:30 --onwards
# end the series there
proton calendar events delete 4f2a1b9c@2026-05-04T09:00 --onwards
# the whole series
proton calendar events delete 4f2a1b9c

A bare reference reaches every occurrence a series holds, so both update and delete say how many and show the first of them:

Terminal window
$ proton calendar events update Standup --start 2026-04-16T10:00 --dry-run
Dry run - would update event "Standup" and all 500 occurrences of it, now 2026-04-16 10:00 Europe/Vienna:
ID DATE TIME DURATION TITLE LOCATION
──────────────────────────────── ────────── ───── ──────── ─────── ────────
Fh3jAe…/9xL4pQ…@2026-04-16T09:00 2026-04-16 09:00 15m Standup Room 2
…

A series with no end says so instead of giving a number.

--onwards on the first occurrence is refused. Delete the series instead.

events list shows which triggers an event carries. reminders list answers the other question, which is when they go off:

Terminal window
$ proton calendar reminders list --after 2026-08-27 --before 2026-08-28
ID FIRES REMIND TITLE STARTS LOCATION
───────────────────────── ──────────────── ────── ─────── ────────────────── ────────
7bd3e011 2026-08-27 06:00 6h Piano 2026-08-27 all day
4f2a1b9c@2026-08-27T09:00 2026-08-28 08:45 15m Standup 2026-08-28 09:00 Room 3

A reminder is listed on the day it fires, not the day its event is on. An event with two triggers is two rows, and a recurring one is a row per occurrence.

An all-day event’s reminder goes off at the calendar’s chosen morning hour, whatever trigger produced it.

Emailed reminders are sent by Proton and are left out.

The same rows, live:

Terminal window
proton calendar reminders watch --output json | jq -c .

watch lands a line on the second, and re-reads your calendars as it runs, so an event added while it is watching still reminds you.

The last column is the sentence a notification would say, which is says in JSON. See Desktop notifications.

Terminal window
proton calendar events export --after 2026-01-01 --before 2026-12-31 --dest year.ics
proton calendar events import holidays.ics
curl -s https://example.com/team.ics | proton calendar events import -

A recurring series is exported once with its rule rather than expanded, so another client reads it back as the same series. Reminders travel as VALARM components. An event that cannot be decrypted is left out rather than written as a stub.

An event’s own colour travels as a COLOR property, so a round trip keeps it. On the way in, a colour the file names in CSS - tomato, #FF6347 - becomes the nearest of the twenty accent colours.

An import is addressed by UID. An event carries the UID of the event it is, so reading a file back changes that event rather than making a second one. Export, edit, import, and the calendar says what the file says.

The replacement is a new event with a new ID, so a reference held from before no longer resolves. Use --dry-run to list what the file holds first.

Participants are left out. An imported event is a record, not an invitation being reissued. Writing the guests back would make your account the organizer of a meeting it did not call, which for external addresses means email going out.

Terminal window
proton calendar booking-pages create --title 'Intro call'
proton calendar booking-pages create --title 'Office hours' --calendar Work --duration 1h \
--available tue=14:00-18:00 --available thu=14:00-18:00 --notice 48h
proton calendar booking-pages list
proton calendar booking-pages get 'Intro call'
proton calendar booking-pages delete 'Intro call'

A booking page is a link anyone can open to see when you are free and book an appointment. Each appointment lands in the page’s calendar as an event. create and get print the link, and a listing never does.

--available says when appointments can be booked, as DAY=START-END, and can be given more than once:

Form Offers
mon=09:00-17:00 Every Monday
mon-fri=09:00-12:00 Every weekday morning
mon,wed=14:00-18:00 Every Monday and Wednesday afternoon
2026-10-05=09:00-12:00 That morning only

A page repeats every week or runs on set dates, never both. Without --available it offers Monday to Friday, 09:00-17:00, every week. Times are read in your zone, and 24:00 ends a window at midnight.

  • --duration is 15m, 30m, 1h, 1h30m or 2h. Without it, an appointment lasts what a new event lasts in the calendar.
  • --location sets a place. Without it, each appointment gets a Proton Meet link.
  • --notice is how soon before an appointment it can still be booked: none, 2h, 48h or next-day.
  • --blocked-by names another calendar whose events keep a time from being booked. The page’s own calendar always does.

A page offers at most 200 appointments.

Terminal window
proton calendar booking-pages update 'Intro call' --duration 1h --blocked-by Family
proton calendar booking-pages update 'Intro call' --location 'Café Central'
proton calendar booking-pages update 'Intro call' --meet --no-blocked-by

update leaves the link alone. --available replaces every window, and --duration alone re-cuts the windows the page offers now. The calendar a page books into cannot be changed.

Deleting a page stops the link working. Appointments already booked stay in your calendar.

How many pages you can have depends on your plan:

Plan Booking pages
Free None
Mail Plus, Mail Essentials, Proton Unlimited, Proton Duo, Proton Family 1
Mail Professional, Proton Business Suite, Workspace Standard, Workspace Premium, Visionary, Meet Professional, or any plan with Meet 25
Terminal window
proton calendar settings calendars create --name Work --color "#8080FF"
proton calendar settings calendars update Work --default-duration 30m --remind 15m
proton calendar settings calendars update Personal --busy off
proton calendar settings calendars update Work --default
proton calendar settings calendars delete Work

Each calendar carries its own defaults for the events made in it.

  • --busy says whether events there make you look busy to people checking your availability.
  • --no-remind gives new events none.
  • --default makes it the calendar new events go into when --calendar names none.

Colours have to be Proton accent colours.

KIND says which of four a calendar is, and that decides what you can do with it:

Kind What it is What you can do with it
personal Yours Everything: make events, share it, publish it, set a default duration, make it the default
shared Somebody else’s, shared with you Make events if you were given editor access; rename, recolour, set reminders and --busy; leave it
subscribed Filled from an address Rename, recolour, set reminders and --busy
holidays A country’s public holidays Recolour, set --remind-all-day and --busy

Deleting a calendar asks for your password even though you are signed in, except for a holidays calendar. With no terminal, pass --password-file, which takes - for standard input. The other commands that do this are listed in Account.

Deleting your default calendar makes your next calendar of your own the default, and the confirmation says which.

Terminal window
proton calendar settings calendars create --name Timetable --url https://example.com/team.ics

Proton fetches the .ics on a schedule and fills the calendar from it, so the events are read-only: they belong to whoever publishes them. A listing says which calendars are which under KIND.

Proton is asked whether it can read the address before the calendar is made, so a wrong one is refused rather than leaving you with a calendar that never fills.

Terminal window
proton calendar settings holidays list
proton calendar settings calendars create --holidays Austria
proton calendar settings calendars create --holidays Switzerland --language Français
proton calendar settings calendars update "Holidays in Austria" --remind-all-day 1d

--holidays takes a country by name or by its two-letter code. A country with holidays in more than one language needs --language, and holidays list shows which languages there are.

The calendar takes the name Proton gives it, and its events are read-only.

Terminal window
proton calendar settings calendars share add Work jane@proton.me --access editor
proton calendar settings calendars share get Work
proton calendar settings calendars share update Work jane@proton.me --access viewer
proton calendar settings calendars share remove Work jane@proton.me

It only works with another Proton account.

They see nothing until they accept, and until then share get shows them as pending. share update changes what they may do whether they have accepted or not, and share remove withdraws an unanswered invitation or ends a membership.

For a calendar somebody gave you:

Terminal window
proton calendar invitations list
proton calendar invitations accept Work
proton calendar settings calendars leave Work

Until you accept, you see the calendar’s name and who sent it, and nothing that is on it. Once accepted it lists as shared. leave gives it up, and only its owner can give it to you again.

Terminal window
proton calendar settings links create Work --name 'Team feed'
proton calendar settings links create Work --access full --name 'Team feed'
proton calendar settings links list
proton calendar settings links get 'Team feed'
proton calendar settings links revoke 'Team feed'

A link is an .ics feed that any calendar app can follow, and it stays up to date. Anyone holding the URL can open it, with no Proton account.

--access limited, the default, shows only whether you are busy. --access full shows every detail of every event, and Proton reads them to serve the feed.

The URL is shown when the link is made and by links get, never in a listing. --name is yours alone, and whoever follows the link never sees it.

A calendar carries at most five links. What a link shows cannot be changed afterwards: revoke it and publish another.

On another account, follow one the way you would any published calendar - see Subscribe to a published calendar.

Terminal window
proton calendar settings get # time zones, layout, invitations
proton calendar settings set view week
proton calendar settings set primary-timezone Europe/Vienna
Key Values
view day, week, month, year, planning
week-numbers · auto-detect-timezone · show-secondary-timezone · auto-import-invite off, on
primary-timezone · secondary-timezone An IANA zone
invite-locale A language, such as en_US