Skip to content

Events & phases

An event is the thing you schedule and share — a fireside, meeting, breakout session or speed-networking rotation. Its agenda is a list of phases, each with a modality:

ModalityWhat happens
broadcastHosts & speakers on a stage, streamed to a watch-only audience (HLS)
meetingOne room, everyone joins with camera & mic
breakoutParallel small-group rooms, optional timer & extensions
rotationSpeed networking — attendees shuffle through timed rounds

Most events have a single phase; multi-phase agendas (e.g. broadcast → breakouts → broadcast) are fully supported.

Create an event

POST /v1/events

sh
curl -X POST https://api.gathercloud.dev/v1/events \
  -H "x-api-key: gck_..." \
  -H "content-type: application/json" \
  -d '{
    "type": "fireside",
    "title": "Quarterly AMA",
    "scheduledAt": "2026-07-01T17:00:00Z",
    "visibility": "public",
    "allowAnonymousVoting": true,
    "metadata": { "description": "Ask the founders anything." },
    "phases": [
      { "modality": "broadcast", "featureSet": ["qa", "transcript"] }
    ]
  }'
FieldTypeNotes
typestring, requiredFree-form label (fireside, meeting, …)
titlestring, required
scheduledAtISO timestampPlanned start
scheduledEndAtISO timestampPlanned end
visibilitypublic | unlisted | privateDefault unlisted
allowAnonymousVotingbooleanLet signed-out viewers vote on Q&A (public events)
allowAnonymousQuestionsbooleanLet signed-out viewers submit Q&A questions (public events)
metadataobjectYour own data; the dashboard uses description
phasesarrayEach: modality (required), config, featureSet

Phase featureSet values: qa, chat, polls, reactions, transcript, capture. Phase config (per modality): roomSize, durationSeconds, extendable (breakout); rounds, roundSeconds (rotation).

Returns 201 with the new event in draft status.

IMPORTANT

The 201 body is the bare event object — it does not echo back the phases you sent. Your phases are created (this is expected, not a silent failure); they're just not included in the create response. To read them back, follow up with GET /v1/events/:id, which includes the phases array. This matters most for multi-phase agendas, where you'll want to confirm the order and ids of every phase you submitted.

A freshly created event is in draft — not yet on any public surface. The natural next step is to publish it:

sh
curl -X POST https://api.gathercloud.dev/v1/events/{id}/publish \
  -H "x-api-key: gck_..."

This moves it draft → scheduled and fires the event.published webhook. See Lifecycle below for the full state machine.

Read & list

  • GET /v1/events — newest first (up to 100).
  • GET /v1/events/:id — includes the phases array.

Update

PATCH /v1/events/:id — any of title, scheduledAt (null clears it), visibility, allowAnonymousVoting, metadata (replaced wholesale).

Delete

DELETE /v1/events/:id — permanent; removes phases, Q&A and invites.

Lifecycle

Events move draft → scheduled → live → ended:

CallEffect
POST /v1/events/:id/publishdraft → scheduled; fires event.published
POST /v1/events/:id/startGoes live and activates the first phase
POST /v1/events/:id/advanceEnds the active phase, starts the next (ends the event after the last)
POST /v1/events/:id/endEnds the event immediately

The dashboard displays the scheduled state as "Published" — it's on the public surface, awaiting a manual go-live (there is no time-based auto-start at scheduledAt). The API value remains scheduled.

Phases

  • POST /v1/events/:id/phases — append a phase (modality, config, featureSet).
  • PATCH /v1/phases/:id — update config / featureSet.
  • POST /v1/phases/:id/extend — add { "seconds": 300 } (10–3600) to the active phase's timer.

Users & roles

Attendee roles are per event: host, speaker, participant, viewer (plus workspace_admin). When you pre-provision users from your own directory:

  • GET /v1/users / POST /v1/users — upsert by externalSub ({ externalSub, email, name, picture }).
  • POST /v1/events/:id/memberships{ "userId": "…", "role": "speaker" }.

Events created from the dashboard automatically make their creator a host.

Which roles an event has

Roles follow the event's phase modalities, because they describe positions in a room topology:

Phase modalityAssignable roles
broadcasthost, speaker, viewer
meeting, breakout, rotationhost, participant

A broadcast has a stage and a watch-only audience; a call has neither, so speaker there would name the same seat as participant and a viewer would have nothing to watch. An event made of several phases accepts the union of its phases' roles.

Both POST /v1/events/:id/memberships and POST /v1/workspaces/:id/invites reject a role the event has no place for with 400 role_not_on_event, listing the roles it does accept. workspace_admin is exempt — it mirrors workspace membership and is valid on any event.

Roles already stored are narrowed on read rather than rewritten, so an invite or membership that predates a change of modality still resolves to a sensible seat: a speaker in a call becomes a participant, and a participant in a broadcast phase becomes audience (viewer, no media seat). Narrowing never widens access — a viewer stays seatless.

Q&A

GET /v1/events/:id/questions — questions with vote tallies, sorted by votes.