Calendar and calls
The calendar, calling, and meetings families cover time: scheduling on the workspace calendar, live-call lifecycle and in-call actions, and recording what a meeting decided. Scopes: calendar.read / calendar.write for the calendar, calling.write for call actions (call reads ride org.read).
Schedule an event
curl -X POST https://os.cohortapp.com/api/v1/calendar.create \
-H "Authorization: Bearer $COHORT_API_KEY" \
-H "Content-Type: application/json" \
-H "x-idempotency-key: kickoff-2026-08-10" \
-d '{"params": {
"title": "Q3 kickoff",
"kind": "MEETING",
"startsAt": "2026-08-10T14:00:00Z",
"endsAt": "2026-08-10T14:45:00Z",
"attendees": [{ "memberId": "mem_ada" }, { "email": "pat@client.com", "name": "Pat" }],
"channelId": "ch_growth"
}}'
Event kind is one of MEETING, REVIEW, FOCUS, AGENT_BLOCK, ALL_HANDS, HOLD. Attendees may be workspace members (memberId) or external people (email, name). An optional channelId links the event to a Space, and agendaFileId attaches an agenda doc from the drive. Creating, updating, rescheduling, and deleting queue real invite, update, and cancellation emails to attendees.
The rest of the family: update, reschedule, rsvp, delete, the reads get / list, and ask (a grounded question over the calendar, visibility-floored to what your seat can see).
Find a time
calendar.findATime is a deterministic free-slot scan across the named attendees — it proposes times and changes nothing, so it rides the read scope. Use it before calendar.create rather than guessing.
Run a call
The calling family drives live calls in the workspace app:
| Task | Methods |
| --- | --- |
| Lifecycle | start, join, end, invite |
| In-call actions | react, raiseHand, lowerHand, setMute, chat (the in-call chat panel) |
| Recording and transcript | recordingStart, recordingStop, addTranscriptLine (authorised agents write finalized transcript lines) |
| Reads | getDetails, getTranscript — participation-gated: you see a call's details only if you are in it |
| Host moderation | removeParticipant, setLock (block new joins; existing participants unaffected) |
Host moderation is gated in the domain layer: only the call's starter may remove or lock, and an agent host may act only on AI participants. A refused moderation act does not throw — the call succeeds and the result reports the refusal, with one audited *_refused event on the ledger. Check the result.
addTranscriptLine and calling.chat persist their content to the call
record, but the ledger event they append carries no line or message body —
the same redaction rule as messaging.
Record what a meeting decided
The meetings family is knowledge capture (it rides knowledge.write):
meetings.record— file a meeting's participants, outcome, and decisions into the org's meeting registry.meetings.recapFile— the notetaker's landing verb: files a held meeting's recap and transcript into the workspace drive as two documents plus a meeting record, all cross-linked.GET /meetings.listandGET /contacts.listread the registries back (ACL-filtered).