Reference
Overview
Everything you can do in the Morse app, you can do from a script or an AI agent with a personal access token. This page assumes you have never seen Morse’s code.
Base URL
One host, one prefix. Every path on this page hangs off it, and there is no versioning in the URL, because the spec is the contract.
https://onmorse.com/apiThe whole surface, with every route’s parameters and schemas, is published as openapi.json, and there is a page you can send real requests from. Both need a sign-in or a token.
Authentication
A personal access token, sent as a bearer. Tokens are made in the app, at Settings → API tokens , never through the API. They start mp_, are 49 characters, and are shown once: Morse keeps only a fingerprint and the last four.
Authorization: Bearer mp_YOUR_MORSE_TOKENYour first request
GET /auth/me answers with the token’s owner, which makes it the cheapest way to find out whether the token works.
GET/auth/me
export MORSE=https://onmorse.com/api
export MORSE_TOKEN=mp_YOUR_MORSE_TOKEN
curl -H "Authorization: Bearer $MORSE_TOKEN" \
"$MORSE/auth/me"{
"id": "5e6f2b31-5c4a-4d0e-9a77-1b2c3d4e5f60",
"email": "priya@neuralarc.ai",
"name": "Priya Shah",
"title": "Head of Product",
"timezone": "Asia/Kolkata",
"accent": null
}Timezones
Anything that emails people (creating a meeting with emails, invites, reschedules, sharing notes) should also carry X-Timezone with an IANA name, so the times in those emails read in your zone rather than the server’s.
X-Timezone: Asia/KolkataWhen it’s refused
Errors answer with a detail, which is either a sentence meant to be shown to a person or a structure naming what was wrong.
| Status | detail | What it means |
|---|---|---|
| 401 | This token has expired. Create a new one in Settings. | Make a new token. |
| 401 | Not authenticated. | Missing, mistyped or revoked, or unused for a year, or the account was disabled. |
| 403 | Manage tokens in the Morse app. | Tokens can’t list, make or revoke tokens. |
| 403 | varies | You’re signed in, but that isn’t yours to see or do. |
| 404 | varies | Not found, or not something you’re allowed to know exists. |
| 409, 410 | a sentence, or {reason, message} | It clashes with the current state: a meeting that has ended, say. |
| 422 | a list | The body didn’t match the schema. Each item names the field. |
Voice-note routes are the exception: they answer {"error": "…", "detail": "…"}, where error is a short code such as not_found and detail is the sentence.
Streaming
Lobby, transcript, summary and voice-note changes stream as server-sent events. Keep the connection open and read it as it arrives.
curl -N -H "Authorization: Bearer $MORSE_TOKEN" \
"$MORSE/meetings/MEETING_ID/transcript-events"EventSource cannot send a header, so from a web page use the app’s own session. From a script or an agent, the token works.Uploads
Files never pass through Morse’s server. Ask for somewhere to put the file, send it straight to storage, then tell Morse it is there, which is when Morse checks it.
- Ask. The type and size must be exactly what you will send. You get back a URL and an upload key.
- Send the file to that URL with that content type.
- Complete with the upload key.
curl -X POST -H "Authorization: Bearer $MORSE_TOKEN" \
-H "Content-Type: application/json" \
-d '{"content_type": "image/jpeg", "size": 48213}' \
"$MORSE/users/me/avatar/upload"
curl -X PUT -H "Content-Type: image/jpeg" \
--data-binary @me.jpg "URL_FROM_STEP_1"
curl -X POST -H "Authorization: Bearer $MORSE_TOKEN" \
-H "Content-Type: application/json" \
-d '{"upload": "UPLOAD_KEY"}' \
"$MORSE/users/me/avatar/complete"Voice-note audio and knowledge files follow the same three steps; their schemas are in the spec.
What a token can’t do
Five refusals that are not bugs
- List, make or revoke tokens. Do that in Settings; a token can’t mint or kill tokens, including itself.
- Connect Google Calendar. Google needs a person to click Allow; once it’s connected, reading and writing events works with a token.
- Sign in or out. A token already is a sign-in, and signing out of a browser doesn’t touch it.
- Run from another website’s page. The API sends no CORS headers, so call it from a server, a script or an agent.
- Use the guest routes (/api/m/…). Those are for people without an account; your token acts as you, a member.