Open Morse

Reference

Invites

12 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.

A guest's answer so far, by the token in their invitation.

GET/m/{code}/reply

GET/m/{code}/reply

curl "$MORSE/m/4KJ9P2/reply?i=%E2%80%A6" \
  -H "Authorization: Bearer $MORSE_TOKEN"
200
{
  "duration_minutes": 30,
  "host_name": "Priya Shah",
  "note": "Annual plans are billed up front.",
  "proposed_start": "2026-10-02T10:30:00+05:30",
  "response": "…",
  "scheduled_at": "2026-10-02T10:30:00+05:30",
  "status": "…"
}

A guest answers, as POST /meetings/{id}/reply does for a colleague.

POST/m/{code}/reply

POST/m/{code}/reply

curl -X POST "$MORSE/m/4KJ9P2/reply" \
  -H "Authorization: Bearer $MORSE_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{ "invite_token": "mp_YOUR_MORSE_TOKEN" }'
200
{
  "duration_minutes": 30,
  "host_name": "Priya Shah",
  "note": "Annual plans are billed up front.",
  "proposed_start": "2026-10-02T10:30:00+05:30",
  "response": "…",
  "scheduled_at": "2026-10-02T10:30:00+05:30",
  "status": "…"
}

Times the host is free for instead, for a guest, by their token.

GET/m/{code}/reply/slots

GET/m/{code}/reply/slots

curl "$MORSE/m/4KJ9P2/reply/slots?i=%E2%80%A6" \
  -H "Authorization: Bearer $MORSE_TOKEN"
200
{
  "slots": [
    "2026-10-02T10:30:00+05:30"
  ],
  "zone": "…"
}

Who the host has asked — the same people the calendar event and the move and cancel emails go to — each with how far they have got.

GET/meetings/{meeting_id}/invites

Someone who walked in through the link belongs in the room's people list, not here.

GET/meetings/{meeting_id}/invites

curl "$MORSE/meetings/3f9c1a24-5e6f-4b31-9a77-1b2c3d4e5f60/invites" \
  -H "Authorization: Bearer $MORSE_TOKEN"
200
[
  {
    "display_name": "Priya Shah",
    "email": "priya@neuralarc.ai",
    "key": true,
    "kind": "…",
    "note": "Annual plans are billed up front.",
    "proposed_start": "2026-10-02T10:30:00+05:30",
    "response": "…",
    "status": "…"
  }
]

Email up to 25 people an invitation to a meeting.

POST/meetings/{meeting_id}/invites

Anyone in the room may invite. Send X-Timezone so the email shows your times.

POST/meetings/{meeting_id}/invites

curl -X POST "$MORSE/meetings/3f9c1a24-5e6f-4b31-9a77-1b2c3d4e5f60/invites" \
  -H "Authorization: Bearer $MORSE_TOKEN" \
  -H "x-timezone: Asia/Kolkata" \
  -H "Content-Type: application/json" \
  -d '{ "emails": [ "priya@neuralarc.ai" ] }'
200
[
  {
    "delivery": "…",
    "detail": "…",
    "email": "priya@neuralarc.ai",
    "kind": "…"
  }
]

Each colleague's answer on the Google event, by address — 'accepted', 'declined', 'tentative' or 'needsAction'. Guests are never Google attendees, so they are never in it.

GET/meetings/{meeting_id}/invites/responses

Its own request, so the invite list never waits on Google: the list is Morse's and answers at once, and the replies fill in when Google answers — within a few seconds, or not at all. Read through each time, never kept (ADR-012): the answer is Google's, and a stored copy would only be stale.

GET/meetings/{meeting_id}/invites/responses

curl "$MORSE/meetings/3f9c1a24-5e6f-4b31-9a77-1b2c3d4e5f60/invites/responses" \
  -H "Authorization: Bearer $MORSE_TOKEN"

Withdraw an invitation to someone who has not arrived.

DELETE/meetings/{meeting_id}/invites/{email}

Host-only, like remove. Without it, a mistyped address, or a colleague who has no account and so no participant row to remove, stays on the calendar event and on every email for good. Someone who has already knocked or joined is removed from the people list instead. That is a different act, with a re-entry guard, and this must not become a quiet way around it.

DELETE/meetings/{meeting_id}/invites/{email}

curl -X DELETE "$MORSE/meetings/3f9c1a24-5e6f-4b31-9a77-1b2c3d4e5f60/invites/priya@neuralarc.ai" \
  -H "Authorization: Bearer $MORSE_TOKEN" \
  -H "x-timezone: Asia/Kolkata"

Star someone invited as key to the meeting, or unstar them.

PUT/meetings/{meeting_id}/invites/{email}/key

Host only. If a key person says no or suggests another time, the meeting shows as at risk.

PUT/meetings/{meeting_id}/invites/{email}/key

curl -X PUT "$MORSE/meetings/3f9c1a24-5e6f-4b31-9a77-1b2c3d4e5f60/invites/priya@neuralarc.ai/key" \
  -H "Authorization: Bearer $MORSE_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{ "key": true }'

Keep the booked time over the one this invitee suggested.

DELETE/meetings/{meeting_id}/invites/{email}/suggestion

Host only. They are emailed that it stands, with a way to answer again, and are back to no answer until they do: they said no to the old suggestion, not to this time. To use their time instead, move the meeting to it.

DELETE/meetings/{meeting_id}/invites/{email}/suggestion

curl -X DELETE "$MORSE/meetings/3f9c1a24-5e6f-4b31-9a77-1b2c3d4e5f60/invites/priya@neuralarc.ai/suggestion" \
  -H "Authorization: Bearer $MORSE_TOKEN" \
  -H "x-timezone: Asia/Kolkata"

Undoing a removal — the only thing that can. removed is the one status the re-entry guards refuse, so without this a misclicked Remove is permanent and the host has to build a new meeting around one mistake.

POST/meetings/{meeting_id}/participants/{participant_id}/reinvite

**Host-only**, matching remove rather than invite: undoing a removal is closer to removing than to inviting. And a named act on one person, never a side effect of re-sending a list — a host re-pasting eight addresses must not silently readmit someone they deliberately ejected. Google Meet resolves this the same way: a removed participant is readmitted only by being manually re-invited from inside the meeting. This goes *through* the guard rather than around it. The row returns to invited, so they still have to knock and still have to be admitted — three human decisions, where the removal took one.

POST/meetings/{meeting_id}/participants/{participant_id}/reinvite

curl -X POST "$MORSE/meetings/3f9c1a24-5e6f-4b31-9a77-1b2c3d4e5f60/participants/3f9c1a24-5e6f-4b31-9a77-1b2c3d4e5f60/reinvite" \
  -H "Authorization: Bearer $MORSE_TOKEN" \
  -H "x-timezone: Asia/Kolkata"
200
{
  "delivery": "…",
  "detail": "…",
  "email": "priya@neuralarc.ai",
  "kind": "…"
}

Answer an invitation: accepted, declined, or a proposed_start from /reply/slots.

POST/meetings/{meeting_id}/reply

The host is emailed a no, a suggested time, or a change of mind.

POST/meetings/{meeting_id}/reply

curl -X POST "$MORSE/meetings/3f9c1a24-5e6f-4b31-9a77-1b2c3d4e5f60/reply" \
  -H "Authorization: Bearer $MORSE_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{ "note": "Annual plans are billed up front.", "proposed_start": "2026-10-02T10:30:00+05:30", "response": "accepted" }'
200
{
  "duration_minutes": 30,
  "host_name": "Priya Shah",
  "note": "Annual plans are billed up front.",
  "proposed_start": "2026-10-02T10:30:00+05:30",
  "response": "…",
  "scheduled_at": "2026-10-02T10:30:00+05:30",
  "status": "…"
}

Times the host is free for instead, over the next two weeks.

GET/meetings/{meeting_id}/reply/slots

GET/meetings/{meeting_id}/reply/slots

curl "$MORSE/meetings/3f9c1a24-5e6f-4b31-9a77-1b2c3d4e5f60/reply/slots" \
  -H "Authorization: Bearer $MORSE_TOKEN"
200
{
  "slots": [
    "2026-10-02T10:30:00+05:30"
  ],
  "zone": "…"
}