Open Morse

Reference

Summary

11 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 finished meeting's notes: summary, decisions and action items.

GET/meetings/{meeting_id}/summary

The host, or someone they were shared with; figures are hidden from a reader shared them without.

GET/meetings/{meeting_id}/summary

curl "$MORSE/meetings/3f9c1a24-5e6f-4b31-9a77-1b2c3d4e5f60/summary" \
  -H "Authorization: Bearer $MORSE_TOKEN"
200
{
  "admin_opens": [
    {
      "admin_name": "Priya Shah",
      "opened_at": "2026-10-02T10:30:00+05:30",
      "reason": "…"
    }
  ],
  "content": "Annual plans are billed up front.",
  "edited_at": "2026-10-02T10:30:00+05:30",
  "edited_by_name": "Priya Shah",
  "error": "…",
  "generated_at": "2026-10-02T10:30:00+05:30",
  "generated_content": {},
  "is_host": true,
  "job": "…",
  "model": "…",
  "reviewed": true,
  "silent": true,
  "status": "…",
  "timeline_origin": "2026-10-02T10:30:00+05:30",
  "view": "…"
}

The host's reviewed version.

PATCH/meetings/{meeting_id}/summary

Never overwrites the generated document, so reverting stays possible for the life of the meeting.

PATCH/meetings/{meeting_id}/summary

curl -X PATCH "$MORSE/meetings/3f9c1a24-5e6f-4b31-9a77-1b2c3d4e5f60/summary" \
  -H "Authorization: Bearer $MORSE_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{ "content": "Annual plans are billed up front." }'
200
{
  "admin_opens": [
    {
      "admin_name": "Priya Shah",
      "opened_at": "2026-10-02T10:30:00+05:30",
      "reason": "…"
    }
  ],
  "content": "Annual plans are billed up front.",
  "edited_at": "2026-10-02T10:30:00+05:30",
  "edited_by_name": "Priya Shah",
  "error": "…",
  "generated_at": "2026-10-02T10:30:00+05:30",
  "generated_content": {},
  "is_host": true,
  "job": "…",
  "model": "…",
  "reviewed": true,
  "silent": true,
  "status": "…",
  "timeline_origin": "2026-10-02T10:30:00+05:30",
  "view": "…"
}

A nudge that generation finished, not the document.

GET/meetings/{meeting_id}/summary-events

The page refetches, the same way the transcript panel does.

GET/meetings/{meeting_id}/summary-events

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

What send would email, for the host to read first.

POST/meetings/{meeting_id}/summary/preview

Every check and every mask the send applies, and nothing sent, granted or recorded. recipients may be empty; the preview is a colleague's copy.

POST/meetings/{meeting_id}/summary/preview

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

Who the host could send the notes to, what each can already see, and what each can read in Morse: one roster for the whole Sharing card (plan 021a).

GET/meetings/{meeting_id}/summary/recipients

Host only.

GET/meetings/{meeting_id}/summary/recipients

curl "$MORSE/meetings/3f9c1a24-5e6f-4b31-9a77-1b2c3d4e5f60/summary/recipients" \
  -H "Authorization: Bearer $MORSE_TOKEN"
200
[
  {
    "access": "…",
    "already_sent": [
      "…"
    ],
    "asked": "…",
    "asked_at": "2026-10-02T10:30:00+05:30",
    "default_selected": true,
    "email": "priya@neuralarc.ai",
    "internal": true,
    "kind": "…",
    "name": "Priya Shah",
    "provenance": "…",
    "recording": true,
    "sent_masked": [
      "…"
    ],
    "title": "Pricing review",
    "user_id": "3f9c1a24-5e6f-4b31-9a77-1b2c3d4e5f60"
  }
]

Write the notes again, optionally in another template.

POST/meetings/{meeting_id}/summary/regenerate

Host only, once the meeting has ended. Answers 202; the notes change when it's done.

POST/meetings/{meeting_id}/summary/regenerate

curl -X POST "$MORSE/meetings/3f9c1a24-5e6f-4b31-9a77-1b2c3d4e5f60/summary/regenerate" \
  -H "Authorization: Bearer $MORSE_TOKEN"

Email the minutes, and grant their readers the record. What preview showed, actually sent: the same checks and the same masking, and each recipient with an account also gets a meeting_access row, because being sent the notes and being able to open them in Morse are the same permission.

POST/meetings/{meeting_id}/summary/send

One result per address, a failed send included — an address that bounced is something the host has to know about, not an error for the whole call.

POST/meetings/{meeting_id}/summary/send

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

What would be hidden, for the host deciding what to send.

GET/meetings/{meeting_id}/summary/sensitive

Host only: it is a list of exactly the lines nobody else should be handed.

GET/meetings/{meeting_id}/summary/sensitive

curl "$MORSE/meetings/3f9c1a24-5e6f-4b31-9a77-1b2c3d4e5f60/summary/sensitive" \
  -H "Authorization: Bearer $MORSE_TOKEN"
200
{
  "checking": true,
  "groups": [
    {
      "count": 3,
      "items": [
        {
          "in_summary": true,
          "notes": "…",
          "quote": "…",
          "reason": "…",
          "t_ms": 1,
          "title": "Pricing review",
          "transcript": "…"
        }
      ],
      "reason": "…"
    }
  ],
  "incomplete": true,
  "mask": "…",
  "scan_only": true,
  "total": 3,
  "truncated": true
}

Every time the notes were sent: to whom, and with what.

GET/meetings/{meeting_id}/summary/shares

Host only.

GET/meetings/{meeting_id}/summary/shares

curl "$MORSE/meetings/3f9c1a24-5e6f-4b31-9a77-1b2c3d4e5f60/summary/shares" \
  -H "Authorization: Bearer $MORSE_TOKEN"
200
[
  {
    "error": "…",
    "hidden_count": 3,
    "includes": [
      "…"
    ],
    "recipient_email": "priya@neuralarc.ai",
    "redacted_includes": [
      "…"
    ],
    "sent_at": "2026-10-02T10:30:00+05:30",
    "sent_by_name": "Priya Shah",
    "status": "…"
  }
]

The minutes, read aloud. See speech.py for why this is served here.

GET/meetings/{meeting_id}/summary/speech

GET because <audio src> can only GET, and a GET plays progressively. The v parameter the client adds is a cache-busting version key and is not read: the document is always loaded fresh, so an edit is heard on the next play. Playing the same words again is free, and new readings are bounded per person (#29): see speech.py. Anything else in the query — a text someone hopes will be spoken — is ignored for the same reason.

GET/meetings/{meeting_id}/summary/speech

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

The notes templates a host can pick from (plan 012).

GET/summary-templates

GET/summary-templates

curl "$MORSE/summary-templates" \
  -H "Authorization: Bearer $MORSE_TOKEN"
200
[
  {}
]