Skip to main content

Overview

Calendar data services built on iCalendar (RFC 5545) and CalDAV standards. Events support start/end times, all-day events, RRULE recurrence, attendees with RSVP, timezones, and cross-domain links to contacts, tasks, and notes. Calendars are named containers (like “Work”, “Personal”) that hold events. Each tenant can have multiple calendars.

Data Model

Entities

EntityDescription
CalendarA named container for events (e.g., “Work”, “Personal”)
EventA scheduled item with start/end time, location, description
Event AttendeeA person invited to an event with RSVP status
Event LinkA cross-domain link from an event to another entity (contact, task, note, deal)

Relationships

  • A Calendar has many Events
  • An Event has many Attendees and Links
  • Attendees reference contacts by contact_id or external email

Key Concepts

All-day events

Events have an is_all_day boolean. All-day events have a date but no specific time. They span the full day in the event’s timezone.

Event types

TypeDescription
eventStandard calendar event (default)
focus_timeBlocked time for focused work
out_of_officeAway/vacation time
working_locationWhere you are working from
reminderA time-based reminder

RRULE recurrence

Events support iCalendar RRULE strings for recurrence:
FREQ=DAILY
FREQ=WEEKLY;BYDAY=MO,WE,FR
FREQ=MONTHLY;BYMONTHDAY=15
FREQ=YEARLY;BYMONTH=3;BYMONTHDAY=1;COUNT=5
The application parses RRULE strings in Rust and computes next_occurrence for efficient querying. Postgres indexes this computed field.

Timezone handling

All times are stored as UTC in the database. Events carry a timezone field (IANA timezone name like America/New_York) for display purposes. Convert UTC times to the event’s timezone when displaying to users.

Attendees

Attendees are linked to an event and can reference a contact by contact_id or include an external email. Each attendee has an RSVP status:
StatusDescription
pendingNo response yet
acceptedAccepted the invitation
declinedDeclined the invitation
tentativeTentatively accepted
Events can be linked to entities in other domains (contacts, tasks, notes, deals) via Event Links. Each link has an entity_type and entity_id. This enables the MCP prepare_for_meeting composite tool to pull related context automatically. Search across event titles, descriptions, and locations using GET /api/v1/events/search?q=....

MCP Tools

ToolDescription
events_listList events in a date range, optionally filtered by calendar or type
events_getGet full event details with attendees and links
events_createCreate a new event with attendees and recurrence
events_updateModify event details
events_deleteRemove an event
events_check_availabilityCheck if a time slot is free
events_searchFree-text search across events
See the MCP guide for setup instructions.

API Endpoints

See the API Reference for the full endpoint list with request/response details.

Examples

Create a calendar and add an event

# Create a calendar
curl -X POST https://api.backside.app/api/v1/calendars \
  -H "Authorization: Bearer bsk_live_..." \
  -H "Content-Type: application/json" \
  -d '{"name": "Work", "color": "#4285F4"}'

# Create an event
curl -X POST https://api.backside.app/api/v1/events \
  -H "Authorization: Bearer bsk_live_..." \
  -H "Content-Type: application/json" \
  -d '{
    "calendar_id": "uuid-of-calendar",
    "title": "Team Standup",
    "start_time": "2026-04-08T09:00:00Z",
    "end_time": "2026-04-08T09:30:00Z",
    "timezone": "America/New_York",
    "rrule": "FREQ=WEEKLY;BYDAY=MO,TU,WE,TH,FR"
  }'

List events for a date range

curl "https://api.backside.app/api/v1/events?start=2026-04-07T00:00:00Z&end=2026-04-14T00:00:00Z" \
  -H "Authorization: Bearer bsk_live_..."

Add an attendee

curl -X POST https://api.backside.app/api/v1/events/{id}/attendees \
  -H "Authorization: Bearer bsk_live_..." \
  -H "Content-Type: application/json" \
  -d '{
    "contact_id": "uuid-of-contact",
    "rsvp_status": "pending"
  }'