Skip to content

Email: Invitation Flow (CalDAV Callback)

Event invitations require a multi-step flow across four components.

Full Flow

User creates event with attendee in Calendars UI
Calendars Frontend → Caddy → Calendars Backend → CalDAV Server
                                              (event saved with
                                               attendees in ICS)
                                          CalDAV HttpCallbackIMipPlugin
                                          sends scheduling callback:
                                          POST http://172.29.0.30:8000/
                                                api/v1.0/caldav-scheduling-callback/
                                          Headers: X-LS-Api-Key, X-LS-Sender,
                                                   X-LS-Recipient, X-LS-Method,
                                                   X-LS-Is-Mailbox
                                          Calendars Backend receives callback
                                          If X-LS-Is-Mailbox: true →
                                          sends via Messages API submit endpoint
                                          If no mailbox →
                                          sends via Django email backend (Brevo SMTP)
                                          Attendee receives email with:
                                          - ICS attachment
                                          - Accept/Maybe/Decline RSVP links

Key Headers

CalDAV sends these headers in the callback:

Header Value
X-LS-Api-Key CALDAV_INBOUND_API_KEY
X-LS-Sender Organizer email (mailto: format)
X-LS-Recipient Attendee email
X-LS-Method REQUEST, REPLY, or CANCEL
X-LS-Is-Mailbox true when calendar is linked to Messages mailbox

Requirements for Invitations to Work

  1. CALDAV_CALLBACK_BASE_URL points to Calendars backend static IP (172.29.0.30:8000)
  2. 172.29.0.30 in Calendars DJANGO_ALLOWED_HOSTS
  3. CALDAV_INBOUND_API_KEY matches between CalDAV server and Calendars .env
  4. translations.json mounted at /data/translations.json in Calendars backend
  5. Messages API channel configured with messages:send scope
  6. Brevo SMTP or Messages API accessible from Calendars backend

Translations File

The invitation service reads translations for email subject lines. Without this file, invitations fail with:

FileNotFoundError: [Errno 2] No such file or directory: '/data/translations.json'

Get the file from the Calendars source repo and mount it:

# From cloned repo
cp src/frontend/apps/calendars/src/features/i18n/translations.json ./calendars/

# Mount in compose.yml
volumes:
  - ./translations.json:/data/translations.json:ro