Reference
Hosting
17 routes, generated from Morse’s own OpenAPI document. Every path below hangs off the base URL, and every one needs the bearer header.
The examples are built from each route’s schema, so the shapes and types are exactly what the API declares. The values are illustrative, and no one has run them.
Say you have switched to a camera pointed at your desk, so your tile says so rather than looking like it has frozen.
/meetings/{meeting_id}/desk-viewThrough us for the reason
my_wide_camera is.
POST/meetings/{meeting_id}/desk-view
curl -X POST "$MORSE/meetings/3f9c1a24-5e6f-4b31-9a77-1b2c3d4e5f60/desk-view" \
-H "Authorization: Bearer $MORSE_TOKEN" \
-H "Content-Type: application/json" \
-d '{ "on": true }'Raise or lower your own hand.
/meetings/{meeting_id}/handThrough us rather than from the room: a
token that could write its own hand could also rename itself on every tile
(livekit.set_hand). Only someone in the room has a hand to raise.
POST/meetings/{meeting_id}/hand
curl -X POST "$MORSE/meetings/3f9c1a24-5e6f-4b31-9a77-1b2c3d4e5f60/hand" \
-H "Authorization: Bearer $MORSE_TOKEN" \
-H "Content-Type: application/json" \
-d '{ "raised": true }'Two topics, one connection.
/meetings/{meeting_id}/lobby-eventsWho is at the door, and how the room is configured — different questions, but a second EventSource to answer the second one would be a second connection to keep alive for no gain.
GET/meetings/{meeting_id}/lobby-events
curl "$MORSE/meetings/3f9c1a24-5e6f-4b31-9a77-1b2c3d4e5f60/lobby-events" \
-H "Authorization: Bearer $MORSE_TOKEN"Locked means even colleagues have to ask.
/meetings/{meeting_id}/lockGuests always knock regardless, so this only changes the internal path.
POST/meetings/{meeting_id}/lock
curl -X POST "$MORSE/meetings/3f9c1a24-5e6f-4b31-9a77-1b2c3d4e5f60/lock" \
-H "Authorization: Bearer $MORSE_TOKEN" \
-H "Content-Type: application/json" \
-d '{ "locked": true }'{
"locked": true
}Soft mute: everyone can unmute themselves again.
/meetings/{meeting_id}/mute-allA hard mute would need tokens reissued with can_publish=False, which is a Phase 3 concern.
POST/meetings/{meeting_id}/mute-all
curl -X POST "$MORSE/meetings/3f9c1a24-5e6f-4b31-9a77-1b2c3d4e5f60/mute-all" \
-H "Authorization: Bearer $MORSE_TOKEN"A member's own admission channel.
/meetings/{meeting_id}/my-lobby-eventsNo in-room requirement — the whole point is that they are not in the room yet — and it is scoped to their own user id, so it reveals nothing about anyone else.
GET/meetings/{meeting_id}/my-lobby-events
curl "$MORSE/meetings/3f9c1a24-5e6f-4b31-9a77-1b2c3d4e5f60/my-lobby-events" \
-H "Authorization: Bearer $MORSE_TOKEN"Who is in the room, and how they got there.
/meetings/{meeting_id}/participantsLiveKit knows identities and names; it does not know who is the host, who is
a guest, or who let them in. admitted_by is recorded precisely so admission
is never anonymous, and this is what surfaces it.
Every status the people panel sections by, and no more. left is absent
deliberately: someone who left is simply not here, and there is no section
for them. denied and removed are present because re-inviting is how a
misclick is undone, and that needs a row to act on.
GET/meetings/{meeting_id}/participants
curl "$MORSE/meetings/3f9c1a24-5e6f-4b31-9a77-1b2c3d4e5f60/participants" \
-H "Authorization: Bearer $MORSE_TOKEN"[
{
"admitted_by_name": "Priya Shah",
"display_name": "Priya Shah",
"email": "priya@neuralarc.ai",
"id": "3f9c1a24-5e6f-4b31-9a77-1b2c3d4e5f60",
"identity": "…",
"invited_by_name": "Priya Shah",
"kind": "…",
"meeting_role": "…",
"provenance": "…",
"status": "…"
}
]Let someone waiting in the lobby into the meeting.
/meetings/{meeting_id}/participants/{participant_id}/admitAnyone in the room may.
POST/meetings/{meeting_id}/participants/{participant_id}/admit
curl -X POST "$MORSE/meetings/3f9c1a24-5e6f-4b31-9a77-1b2c3d4e5f60/participants/3f9c1a24-5e6f-4b31-9a77-1b2c3d4e5f60/admit" \
-H "Authorization: Bearer $MORSE_TOKEN"Turn away someone waiting in the lobby; they may ask again.
/meetings/{meeting_id}/participants/{participant_id}/denyAnyone in the room may.
POST/meetings/{meeting_id}/participants/{participant_id}/deny
curl -X POST "$MORSE/meetings/3f9c1a24-5e6f-4b31-9a77-1b2c3d4e5f60/participants/3f9c1a24-5e6f-4b31-9a77-1b2c3d4e5f60/deny" \
-H "Authorization: Bearer $MORSE_TOKEN"Lower someone else's raised hand.
/meetings/{meeting_id}/participants/{participant_id}/lower-handHost only.
POST/meetings/{meeting_id}/participants/{participant_id}/lower-hand
curl -X POST "$MORSE/meetings/3f9c1a24-5e6f-4b31-9a77-1b2c3d4e5f60/participants/3f9c1a24-5e6f-4b31-9a77-1b2c3d4e5f60/lower-hand" \
-H "Authorization: Bearer $MORSE_TOKEN"Mute someone's microphone in the meeting.
/meetings/{meeting_id}/participants/{participant_id}/muteHost only.
POST/meetings/{meeting_id}/participants/{participant_id}/mute
curl -X POST "$MORSE/meetings/3f9c1a24-5e6f-4b31-9a77-1b2c3d4e5f60/participants/3f9c1a24-5e6f-4b31-9a77-1b2c3d4e5f60/mute" \
-H "Authorization: Bearer $MORSE_TOKEN"Remove someone from the meeting for good: they can't come back into it.
/meetings/{meeting_id}/participants/{participant_id}/removeHost only.
POST/meetings/{meeting_id}/participants/{participant_id}/remove
curl -X POST "$MORSE/meetings/3f9c1a24-5e6f-4b31-9a77-1b2c3d4e5f60/participants/3f9c1a24-5e6f-4b31-9a77-1b2c3d4e5f60/remove" \
-H "Authorization: Bearer $MORSE_TOKEN"The host's switch for whether anyone may present without asking.
/meetings/{meeting_id}/sharing-openHost-only, like the lock and unlike admitting: it decides how the room is configured rather than answering one person's request. The flag alone would only reach the next person to join — permission lives on the LiveKit participant, minted on arrival — so the room is walked too. Turning it off withdraws the share from everyone but the host, which will end a colleague's share in progress. That is the point of the switch; a host closing sharing while a screen is up means that screen.
POST/meetings/{meeting_id}/sharing-open
curl -X POST "$MORSE/meetings/3f9c1a24-5e6f-4b31-9a77-1b2c3d4e5f60/sharing-open" \
-H "Authorization: Bearer $MORSE_TOKEN" \
-H "Content-Type: application/json" \
-d '{ "anyone_can_share": true }'{
"anyone_can_share": true
}Who is waiting in the lobby to be let in.
/meetings/{meeting_id}/waitingAnyone in the room may ask.
GET/meetings/{meeting_id}/waiting
curl "$MORSE/meetings/3f9c1a24-5e6f-4b31-9a77-1b2c3d4e5f60/waiting" \
-H "Authorization: Bearer $MORSE_TOKEN"[
{
"display_name": "Priya Shah",
"email": "priya@neuralarc.ai",
"id": "3f9c1a24-5e6f-4b31-9a77-1b2c3d4e5f60",
"invited_by_name": "Priya Shah",
"kind": "…",
"provenance": "…"
}
]Say your camera is a wide or 360 one, so every tile shows its whole frame (2026-10-01).
/meetings/{meeting_id}/wide-cameraThrough us for the reason my_hand is.
POST/meetings/{meeting_id}/wide-camera
curl -X POST "$MORSE/meetings/3f9c1a24-5e6f-4b31-9a77-1b2c3d4e5f60/wide-camera" \
-H "Authorization: Bearer $MORSE_TOKEN" \
-H "Content-Type: application/json" \
-d '{ "on": true }'