On this page

Local API

The desktop app listens on http://127.0.0.1:47321 while it is running. It binds to the loopback interface only, rejects any other Host header, and requires a bearer token on every request except /v1/health and /v1/pair. The MCP gateway and the Chrome extension are both clients of this API; you can be one too.

Authentication

Authorization: Bearer <contents of api_token>

The token is written to api_token in the data folder on first launch, readable by your user only. It is local and personal: never commit it, share it, or send it anywhere. Requests without a valid token receive 401, except /v1/health, which then returns only ok and the version, and /v1/pair, which exchanges a pairing code for the token.

Endpoints

All requests and responses are JSON. Errors return { "error": { "code": 401, "message": "…" } }, where code is the HTTP status.

Method Path Purpose
GET /v1/health { ok, version, recording: { active, meeting_id? } }
GET /v1/meetings?q=&limit=&offset=&from=&to= List meetings; q runs a full-text search
GET /v1/meetings/:id One meeting with notes, action items, markers and its record; from 0.3.13, record.hidden_lines lists the lines hidden as a probable echo, each with echo_of, the line it repeats; from 1.0, record.passport is the Consent Passport once one was built for the meeting (the setting is on when its transcript lands, or it was built from the meeting page): verdict is detected, not_detected, objection or no_other_side, with at_ms, quote, notice_line, reply_line and hint; null before that
GET /v1/meetings/:id/transcript?format=json|md|srt|vtt|txt Transcript in the format you choose (a format the plan does not export answers 403, with the reason)
POST /v1/meetings/:id/notes { template_id? } writes the notes again with that template (default general); on Free, after the trial, it counts toward the 3 AI notes a month
POST /v1/meetings/:id/retranscribe Rebuilds the transcript from the meeting’s audio
PATCH /v1/meetings/:id Update title, tags, starred, attendees
DELETE /v1/meetings/:id Delete the meeting: database rows and audio
GET /v1/action_items?meeting_id=&open_only= Action items across meetings, each with its meeting’s title
GET /v1/search?q= Full-text search across transcript segments and notes, with snippets
POST /v1/recording/prompt { source_app, title?, url?, attendees? } shows the confirm-to-record card; returns { prompt_id }
POST /v1/recording/start { source_app?, title?, attendees? } starts a recording (requires Allow agents to start recordings in Settings → Integrations)
POST /v1/recording/stop Stops the current recording
POST /v1/recording/marker { label? } bookmarks the current moment
POST /v1/import { path, title? } transcribes an existing audio file (WAV natively, other formats through ffmpeg, or afconvert on macOS; regular files up to 4 GB with a known audio extension). Requires Allow agents to start recordings
GET /v1/ledger The Privacy Ledger: a summary and the latest 200 requests the app has recorded, each with its scope (loopback, lan or internet)
POST /v1/pair { code } exchanges an 8-digit pairing code for a token (see Extension pairing)
GET /v1/events Server-Sent Events stream

Nothing here can make the app record without a person having chosen it: the prompt endpoint only asks, and the start endpoint is refused unless Allow agents to start recordings is on in Settings → Integrations.

Meeting JSON

{
  "id": "01J…", "title": "Weekly sync", "source_app": "meet",
  "started_at": 1725270000000, "ended_at": 1725273600000, "duration_ms": 3600000,
  "status": "ready", "language": "en", "attendees": [{ "name": "Ana" }], "tags": ["sales"],
  "starred": false,
  "notes": [{ "id": "…", "kind": "summary", "content_md": "…" }],
  "action_items": [{ "id": "…", "text": "Send deck", "owner": "You", "done": false }],
  "markers": [{ "id": "…", "at_ms": 120000, "label": "pricing" }]
}

status moves through recording, transcribing, summarising and ready, or ends as failed when a recording produced no transcript.

Transcript JSON

{ "meeting_id": "…", "segments": [{ "speaker": "You", "channel": "mic", "start_ms": 0, "end_ms": 2100, "text": "Hi all" }] }

channel is mic (you) or sys (everyone else). The remote channel is one speaker today.

Events

GET /v1/events streams Server-Sent Events. The event name is the type; the data is { type, data, at }.

Type Data
recording.started { meeting_id, source_app, title, started_at }
recording.stopped { meeting_id, status }
recording.paused { paused }
recording.autostopped { meeting_id, source_app, title, grace_s }
segment.new a transcript segment
meeting.updated, meeting.ready, meeting.deleted { meeting_id }
prompt.shown the pending prompt
prompt.answered { prompt_id, accepted, answer }
marker.added the marker
notes.progress { meeting_id, stage, provider?, model?, started_at?, local?, chunk?, chunks? }
notes.fallback { meeting_id?, reason }
models.loading, models.loaded { model }
pair.completed {}
pair.failed { reason }
permission.asking { kind }
notice { message }
error { message }

The port

The port is fixed at 47321. If another program already uses it, the app cannot start its local API, and Settings → Integrations says so. Quit the other program, which is most often a second copy of Recordist, then open Recordist again.

Importing a caption transcript

POST /v1/import/transcript turns a call's caption transcript into a meeting, with notes. The Chrome extension sends one when you press the Recordist button in its side panel, and your own scripts can send one too.

POST /v1/import/transcript
Authorization: Bearer <token>
Content-Type: application/json

{
  "ref": "6f1c0e9e-1b2c-4d5e-8f90-a1b2c3d4e5f6",
  "source_app": "meet",
  "title": "Weekly sync",
  "started_at": 1793095320000,
  "ended_at": 1793097660000,
  "origin": "captions",
  "segments": [
    { "speaker": "Ana Costa", "text": "Morning, everyone.", "at": 1793095320000, "until": 1793095324000 },
    { "speaker": null, "text": "Revenue is up eight percent.", "at": 1793095380000, "until": 1793095382000 }
  ],
  "participants": [{ "name": "Ana Costa" }]
}
  • ref is your id for the transcript: 1 to 100 letters, digits, - or _. The same ref sent again is answered with the first meeting.
  • source_app is meet, teams or zoom. origin is captions, or left out.
  • title is optional. Without one the meeting is called after the call app ("Google Meet call"), and the notes may give it a better name.
  • Times are unix milliseconds. speaker is the name the captions showed, or null. You, or the name under Your name on invites in Settings → Detection, is you. Teams captions show your name rather than You, so set it there and your lines stay yours.
  • participants is optional and takes names only. Without it, the people named in the captions are the meeting's attendees.
  • Fields Recordist does not know are ignored.

A new meeting answers 201:

{ "meeting_id": "01J…", "kept": "captions", "updated": false, "notes": "writing" }
StatusWhen
201A new meeting. notes is writing, off when automatic notes are off in Settings, or allowance_used when this month's AI notes on Free are used, and the meeting is there without notes.
200The same ref came before (notes is unchanged), or Recordist recorded the same call itself (kept and notes are recording): the recording stays the record, and nothing of the captions is stored.
400A transcript Recordist cannot take: no lines, too many, times that do not add up, another call app or origin, or no ref it can keep.
401No token, or one Recordist did not issue.
403Transcripts are switched off in Recordist's Settings; an organisation turned agent recording off; or a program other than the paired extension sent it while Allow agents to start recordings is off.
409The same ref again, with more lines than the meeting holds. Delete that meeting in Recordist, then send it again to keep the whole call.
413The request is larger than 4 MB.

Every refusal carries one plain sentence in error.message that you can show as it is. No answer carries a title, a name or a line of the transcript.

A transcript holds up to 5,000 lines, in a request of up to 4 MB, from a call of up to 24 hours within the last year. A line longer than 4,000 characters, such as one person's long turn, is kept as several lines.

The token the Chrome extension got at pairing may send a transcript, and it still cannot read meetings. A token from New token for another program, or the MCP gateway's, may send one once Allow agents to start recordings is on in Settings → Integrations. The person switches transcripts on or off in Recordist's Settings, and on macOS an organisation's DisableAgentRecording turns them off for every program.

The meeting has the tag captions and no audio, and its source_app is import, because Recordist did not record the call. Your lines are on the mic side and everyone else's on the sys side, under the names the captions showed. Notes are written as for any meeting; on Free they count toward the month's AI notes. With a token, GET /v1/health also answers transcript_import: true while a transcript would be taken.

Recordist

Recordist for Mac is downloading.

Thank you for trying Recordist. Three steps and it is ready before your next call. Open it now, so it is set up in time.

  1. 1Open the download and drag Recordist to Applications, then open it from there.
  2. 2Allow the microphone and system audio when your Mac asks, so both sides of the call are heard. Calendar is optional: it names your meetings and who is in them.
  3. 3Close the window when you like. Recordist waits in the menu bar and, when your next call starts, asks: Record this meeting? Nothing is recorded until you say yes.

The first time it opens, Recordist downloads its speech model: 142 MB in English, 466 MB for other languages. That usually takes a minute or two, and you can record once it finishes. The notes engine, 1 to 3 GB, follows in the background.

While it downloads, see a finished call in your browser

Every install includes 7 days of Pro, so your first calls are written up in full.

No call today? Import a recording you already have: in Recordist, Meetings, then Import audio. One of 10 minutes or more starts your 7 days of Pro, and the notes follow the transcript.

While it downloads, get your Free key. More AI notes each month, with no end date. Optional: your download has already started.

Two emails: a link to confirm, then a copy of your key. Nothing else unless you ask. We never sell or share your address, and Resend, our email service, sends them for us. Privacy

Didn’t start? Download again. All downloads