Skip to main content

Overview

This guide covers calendar event management including creating events, managing attendees, handling RSVP status, and integrating with external calendars.

Event Structure

Events represent scheduled activities with start/end times, locations, and attendees.

Key Properties

{
  id: string;              // UUID
  title: string;           // Required
  description?: string;
  start_time: string;      // ISO 8601, required
  end_time: string;        // ISO 8601, required
  location?: string;
  all_day: boolean;
  user_id: string;         // Organizer
  context_id?: string;     // Optional project/context
  created_at: string;
  updated_at: string;
}

Creating Events

Basic Event

const event = await fetch('https://app.daycopilot.ai/api/v1/events', {
  method: 'POST',
  headers: {
    'Authorization': `Bearer ${token}`,
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({
    title: 'Team Standup',
    description: 'Daily sync meeting',
    start_time: '2025-11-03T10:00:00Z',
    end_time: '2025-11-03T10:30:00Z',
    location: 'Zoom: https://zoom.us/j/123456'
  })
}).then(r => r.json());

console.log('Event ID:', event.data.id);

All-Day Event

const event = await createEvent({
  title: 'Team Offsite',
  start_time: '2025-12-01T00:00:00Z',
  end_time: '2025-12-02T00:00:00Z',
  all_day: true,
  location: 'San Francisco Office'
});

Event in Context

const event = await createEvent({
  title: 'Sprint Planning',
  start_time: '2025-11-04T14:00:00Z',
  end_time: '2025-11-04T16:00:00Z',
  context_id: 'q4-launch-project-uuid',
  description: 'Plan upcoming sprint tasks'
});

Managing Attendees

Add Attendee

POST /api/v1/events/{eventId}/attendees
{
  "user_email": "colleague@example.com",
  "notify": true
}
Response:
{
  "data": {
    "event_id": "event-uuid",
    "user_id": "user-uuid",
    "email": "colleague@example.com",
    "rsvp_status": "pending",
    "added_at": "2025-11-02T12:00:00Z"
  }
}

Add Multiple Attendees

const attendees = [
  'alice@example.com',
  'bob@example.com',
  'charlie@example.com'
];

for (const email of attendees) {
  await fetch(
    `https://app.daycopilot.ai/api/v1/events/${eventId}/attendees`,
    {
      method: 'POST',
      headers: {
        'Authorization': `Bearer ${token}`,
        'Content-Type': 'application/json'
      },
      body: JSON.stringify({ user_email: email, notify: true })
    }
  );
}

List Attendees

GET /api/v1/events/{eventId}/attendees
Response:
{
  "data": [
    {
      "user_id": "user-1",
      "email": "alice@example.com",
      "name": "Alice Smith",
      "rsvp_status": "accepted"
    },
    {
      "user_id": "user-2",
      "email": "bob@example.com",
      "name": "Bob Jones",
      "rsvp_status": "tentative"
    }
  ]
}

Remove Attendee

DELETE /api/v1/events/{eventId}/attendees/{userId}

RSVP Management

RSVP Status Values

  • pending - Invitation sent, awaiting response
  • accepted - Confirmed attendance
  • declined - Will not attend
  • tentative - Maybe attending

Update RSVP Status

POST /api/v1/events/{eventId}/attendees/{userId}/response
{
  "rsvp_status": "accepted"
}

Attendee Responds to Invitation

// Attendee accepts invitation
await fetch(
  `https://app.daycopilot.ai/api/v1/events/${eventId}/attendees/${myUserId}/response`,
  {
    method: 'POST',
    headers: {
      'Authorization': `Bearer ${myToken}`,
      'Content-Type': 'application/json'
    },
    body: JSON.stringify({ rsvp_status: 'accepted' })
  }
);

Get RSVP Summary

async function getRSVPSummary(eventId, token) {
  const attendees = await fetch(
    `https://app.daycopilot.ai/api/v1/events/${eventId}/attendees`,
    { headers: { 'Authorization': `Bearer ${token}` } }
  ).then(r => r.json());

  const summary = {
    total: attendees.data.length,
    accepted: 0,
    declined: 0,
    tentative: 0,
    pending: 0
  };

  attendees.data.forEach(a => {
    summary[a.rsvp_status]++;
  });

  return summary;
}

Querying Events

By Date Range

# Events in next 7 days
GET /api/v1/events?start_date=2025-11-02&end_date=2025-11-09

Upcoming Events

GET /api/v1/events/upcoming?limit=10

By Context

GET /api/v1/events?context_id=project-uuid

Search Events

GET /api/v1/events/search?q=standup

Updating Events

Basic Update

await fetch(`https://app.daycopilot.ai/api/v1/events/${eventId}`, {
  method: 'PUT',
  headers: {
    'Authorization': `Bearer ${token}`,
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({
    location: 'Conference Room B (changed from A)',
    description: 'Updated location due to conflict'
  })
});

Reschedule Event

await fetch(`https://app.daycopilot.ai/api/v1/events/${eventId}`, {
  method: 'PUT',
  headers: {
    'Authorization': `Bearer ${token}`,
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({
    start_time: '2025-11-03T15:00:00Z',  // New time
    end_time: '2025-11-03T16:00:00Z',
    notify_attendees: true  // Send update notification
  })
});

Comments on Events

Add Comment

await fetch(`https://app.daycopilot.ai/api/v1/events/${eventId}/comments`, {
  method: 'POST',
  headers: {
    'Authorization': `Bearer ${token}`,
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({
    message: 'Please review the agenda before the meeting'
  })
});

List Comments

GET /api/v1/events/{eventId}/comments

Calendar Integration

CalDAV Support

Day Copilot supports CalDAV protocol for bidirectional calendar sync:
CalDAV URL: https://app.daycopilot.ai/caldav/
Setup in Calendar Apps:
  1. Apple Calendar:
    • Settings → Accounts → Add Account → Other
    • Add CalDAV Account
    • Server: app.daycopilot.ai/caldav/
    • Use Day Copilot credentials
  2. Google Calendar:
    • Settings → Import & Export
    • Add calendar using CalDAV URL
  3. Outlook:
    • File → Account Settings → Internet Calendars
    • Add CalDAV URL

Sync Behavior

  • Events created in Day Copilot appear in synced calendars
  • Events created in external calendars sync to Day Copilot
  • Updates sync bidirectionally
  • Deletions sync bidirectionally

Common Patterns

Meeting Scheduler

async function scheduleMeeting({
  title,
  duration_minutes,
  attendees,
  preferred_time,
  context_id
}) {
  // Create event
  const end_time = new Date(preferred_time);
  end_time.setMinutes(end_time.getMinutes() + duration_minutes);

  const event = await fetch('https://app.daycopilot.ai/api/v1/events', {
    method: 'POST',
    headers: {
      'Authorization': `Bearer ${token}`,
      'Content-Type': 'application/json'
    },
    body: JSON.stringify({
      title,
      start_time: preferred_time,
      end_time: end_time.toISOString(),
      context_id
    })
  }).then(r => r.json());

  // Add attendees
  for (const email of attendees) {
    await fetch(
      `https://app.daycopilot.ai/api/v1/events/${event.data.id}/attendees`,
      {
        method: 'POST',
        headers: {
          'Authorization': `Bearer ${token}`,
          'Content-Type': 'application/json'
        },
        body: JSON.stringify({ user_email: email, notify: true })
      }
    );
  }

  return event.data;
}

// Usage
const meeting = await scheduleMeeting({
  title: 'Sprint Retrospective',
  duration_minutes: 60,
  attendees: ['team@example.com'],
  preferred_time: '2025-11-04T14:00:00Z',
  context_id: 'sprint-uuid'
});

Daily Agenda

async function getDailyAgenda(date, token) {
  const start = new Date(date);
  start.setHours(0, 0, 0, 0);

  const end = new Date(date);
  end.setHours(23, 59, 59, 999);

  const events = await fetch(
    `https://app.daycopilot.ai/api/v1/events?` +
    `start_date=${start.toISOString()}&` +
    `end_date=${end.toISOString()}&` +
    `sort=start_time`,
    { headers: { 'Authorization': `Bearer ${token}` } }
  ).then(r => r.json());

  return events.data;
}

// Get today's agenda
const today = await getDailyAgenda(new Date(), token);
console.log(`You have ${today.length} events today`);

Attendance Tracking

async function getAttendanceReport(eventId, token) {
  const attendees = await fetch(
    `https://app.daycopilot.ai/api/v1/events/${eventId}/attendees`,
    { headers: { 'Authorization': `Bearer ${token}` } }
  ).then(r => r.json());

  const report = {
    attending: attendees.data.filter(a => a.rsvp_status === 'accepted'),
    not_attending: attendees.data.filter(a => a.rsvp_status === 'declined'),
    maybe: attendees.data.filter(a => a.rsvp_status === 'tentative'),
    no_response: attendees.data.filter(a => a.rsvp_status === 'pending')
  };

  return report;
}

Conflict Detection

async function checkScheduleConflicts(startTime, endTime, token) {
  const events = await fetch(
    `https://app.daycopilot.ai/api/v1/events?` +
    `start_date=${startTime}&` +
    `end_date=${endTime}`,
    { headers: { 'Authorization': `Bearer ${token}` } }
  ).then(r => r.json());

  return events.data.length > 0 ? events.data : null;
}

// Check before scheduling
const conflicts = await checkScheduleConflicts(
  '2025-11-03T10:00:00Z',
  '2025-11-03T11:00:00Z',
  token
);

if (conflicts) {
  console.log('Schedule conflict detected:', conflicts);
}

Best Practices

Always provide location information, especially for remote meetings:
await createEvent({
  title: 'Team Sync',
  location: 'Zoom: https://zoom.us/j/123456 (Password: abc123)',
  // ... other fields
});
End times should be realistic. Avoid back-to-back meetings without breaks:
// Good: 30 min meeting with 15 min buffer
start_time: '10:00:00Z',
end_time: '10:30:00Z',
// Next meeting at 10:45:00Z
When rescheduling or updating events, always notify attendees:
await updateEvent(eventId, {
  start_time: newTime,
  notify_attendees: true
});
Always use UTC timestamps in API calls. Convert to user’s local timezone in UI:
// Store as UTC
const utcTime = new Date(userLocalTime).toISOString();

// Display in user's timezone
const localTime = new Date(event.start_time).toLocaleString();
Group related events in contexts for better organization:
// All sprint events in sprint context
await createEvent({
  title: 'Sprint Planning',
  context_id: 'sprint-23-uuid'
});

Recurring Events (Roadmap)

Recurring events are coming soon. Current workaround is to create individual events for each occurrence.
Planned Features:
  • iCalendar RRULE support
  • Daily, weekly, monthly recurrence patterns
  • Exception dates
  • Series management (update all vs single occurrence)

Next Steps