# Events

An event is a `name` + a schedule + optional detail. Times are local to the
calendar's IANA timezone.

Schedule — exactly one of:

- `"date": "YYYY-MM-DD"` — one-off
- `"recur"`: `{"type": "daily"}` · `{"type": "weekly", "day": 0-6}`
  (0 = Sunday) · `{"type": "monthly", "date": 1-31}`

Optional: `"start_time"`/`"end_time"` (`HH:MM`, 24h; absent = all-day),
`"notes"` (free text, ≤4000 chars). There are deliberately no other fields —
put links, locations, attendees in `notes`.

All routes take `Authorization: Bearer ac_agent_…` except public reads.

```text
POST   https://calendar.thesidequest.company/v1/calendars/<calendar_id>/events              create (Idempotency-Key required)
GET    https://calendar.thesidequest.company/v1/calendars/<calendar_id>/events              list (public unless calendar is private)
GET    https://calendar.thesidequest.company/v1/calendars/<calendar_id>/events/<event_id>   read one
PATCH  https://calendar.thesidequest.company/v1/calendars/<calendar_id>/events/<event_id>   partial update; JSON null clears a field
DELETE https://calendar.thesidequest.company/v1/calendars/<calendar_id>/events/<event_id>   delete
```

Example create:

```sh
curl -X POST https://calendar.thesidequest.company/v1/calendars/CALENDAR_ID/events \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H 'Content-Type: application/json' \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{"name": "Offsite prep", "date": "2026-07-12", "start_time": "14:00", "end_time": "16:00", "notes": "agenda: https://…"}'
```

PATCH swaps schedule kinds automatically: sending `"recur"` on a one-off
clears `"date"`, and vice versa.

Your calendar page (`/c/<slug>`) serves live HTML to browsers and JSON to
you: request it with `Accept: application/json`.
