Say an idea in a meeting — when the meeting ends, you have the prototype. This page is the programmable version of that promise.
Everything the Moltn app does runs through the same HTTP API — the UI is just one client. Your install exposes that API three ways: versioned REST under /v1, a remote MCP endpoint so AI assistants can drive Moltn as tools, and a CLI for the terminal.
Create an API key under Konto & säkerhet → API keys in your install's UI. Keys look like moltn_sk_…, are shown once at creation, and are revocable individually. Send the key as a header — keys are never accepted in the URL:
Authorization: Bearer moltn_sk_...
Each key has one scope; higher scopes include the lower ones:
| Scope | Allows |
|---|---|
| read | List and read meetings, transcripts, the artifact library, brain search, status. |
| write | + create content: capture ideas, import transcripts, dictate, ask the second brain (spends LLM tokens). |
| build | + act: approve/reject ideas (builds artifacts), send the notetaker bot to meetings, mint share links. |
| admin | + operate the install: settings, users, stats, export, deletion. |
A request outside the key's scope answers 403 with the required scope named. Anything not documented here requires admin — new endpoints are never accidentally exposed to low-privilege keys.
Base URL: https://<your-install>/v1. JSON in, JSON out. The /v1 prefix is the stable contract for integrations; unprefixed paths are the app's internal API and may change without notice.
# Capture an idea — Moltn classifies it and suggests an artifact type
curl -X POST https://your-install/v1/capture \
-H "Authorization: Bearer $MOLTN_KEY" \
-H "Content-Type: application/json" \
-d '{"text": "We should build a churn dashboard for the sales team"}'
# Import a transcript from any other tool and sweep it for buildable ideas
curl -X POST https://your-install/v1/meetings/import \
-H "Authorization: Bearer $MOLTN_KEY" \
-H "Content-Type: application/json" \
-d '{"title": "Roadmap sync", "transcript": "Anna: we need a pricing mockup\nJohan: yes, for Friday"}'
# Approve an idea and wait for the finished artifact
curl -X POST "https://your-install/v1/meetings/$MEETING/ideas/$IDEA/approve?wait=1" \
-H "Authorization: Bearer $MOLTN_KEY"
# Ask the second brain (vault + all meeting history)
curl -X POST https://your-install/v1/ask \
-H "Authorization: Bearer $MOLTN_KEY" \
-H "Content-Type: application/json" \
-d '{"question": "What did we decide with Robin about pricing?"}'
| Method & path | Scope | Description |
|---|---|---|
GET /v1/meetings | read | Recent meetings with idea counts. |
GET /v1/meetings/:id | read | One meeting: transcript chunks, ideas (status, artifact URLs), assistant answers. |
GET /v1/meetings/:id/transcript.md | read | Transcript as a portable markdown file. |
GET /v1/library?q= | read | The artifact library — everything ever built, searchable. |
GET /v1/brain/search?q=&limit= | read | Full-text search over vault documents + meeting transcripts. |
GET /v1/templates | read | Available dictation templates (your own, managed under Inställningar → Mallar). |
GET /v1/status | read | Install health: which integrations are configured and live. |
POST /v1/capture | write | {text, title?} — capture an idea; returns the detection (type, suggested artifact, confidence). |
POST /v1/meetings/import | write | {transcript, title?} — raw "Speaker: text" lines or an array of {speaker, text}; sweeps for ideas in the background. |
POST /v1/dictate | write | Text or audio (multipart) + optional template_id — returns a finished document. |
POST /v1/ask | write | {question} — synthesized answer from the second brain, with cited sources. |
POST /v1/meetings/join | build | {meeting_url} — send the notetaker bot to a live Zoom/Meet/Teams call. |
POST /v1/meetings/schedule | build | {meeting_url, join_at} — schedule the bot for a future meeting. |
POST /v1/meetings/:id/ideas/:ideaId/approve | build | Build the artifact. ?wait=1 blocks until done; ?artifact= overrides the type; JSON body {instructions} steers this build. |
POST /v1/meetings/:id/ideas/:ideaId/reject | build | Dismiss a detected idea. |
GET /v1/meetings/:id/ideas/:ideaId/share | build | Mint a signed public link for a built artifact. |
POST /v1/meetings/:id/end | build | End a meeting: final detection pass + summary delivery. |
GET /v1/stats | admin | Pipeline and cost stats: ideas by status, tokens, spend per meeting, queue depth. |
LLM-backed endpoints (/capture, /ask, /dictate) are limited to 40 requests per minute per IP; webhooks to 600 per minute. Exceeding a limit answers 429 with a Retry-After header. Errors are always JSON: {"error": "human-readable message"}.
Every install is a remote Model Context Protocol server at /mcp (Streamable HTTP, stateless JSON). Add it to Claude Code with one command — no local install:
claude mcp add --transport http moltn https://your-install/mcp \
--header "Authorization: Bearer moltn_sk_..."
Your assistant then has these tools: capture_idea, import_transcript, approve_idea, share_artifact, list_meetings, get_meeting, list_library, join_meeting, ask_brain, search_brain, get_stats. Tool calls run with your API key's scope — a read key can browse but not build.
"Take the pricing idea from yesterday's meeting and build it as slides in English for the board" — the assistant finds the meeting, picks the idea, calls approve_idea with instructions, and hands you the artifact link. Or: "What did we promise Robin?" → ask_brain answers from your vault and meeting history, with sources.
Prefer local stdio (e.g. an offline setup)? Run the proxy from the repo instead: claude mcp add moltn -- bun run /path/to/moltn/src/tools/mcp.ts with MOLTN_URL and MOLTN_TOKEN set.
The moltn CLI drives the same API from the terminal. With Bun installed:
# From a clone of the repo:
bun run cli -- login https://your-install moltn_sk_... # saved to ~/.config/moltn/config.json
bun run cli -- capture "invoice reminder flow for overdue customers"
bun run cli -- ideas
bun run cli -- ask "what did we decide about EU hosting?"
# Or build a standalone binary (no Bun needed on the target machine):
bun run build:cli && ./dist/moltn --help
Commands: login, capture, import, ideas, meetings, approve, share, ask, search, library, join, status, stats.
Moltn POSTs signed JSON to URLs you register under Inställningar → Leverans → Webhooks — the fastest way to connect Zapier, Make, n8n or your own code. Events:
| Event | Fires when | Payload data |
|---|---|---|
meeting.completed | a meeting is finalized and delivered | meeting (id, title, platform, times) + ideas with share links for built artifacts |
artifact.built | an artifact finishes building | idea_id, meeting_id, artifact_type, quote, artifact_url (share link) |
idea.detected | the live detector saves an idea | idea_id, meeting_id, type, artifact_type, confidence, quote |
ping | you press "Skicka test" | a hello message |
Every delivery is signed with the endpoint's secret (shown in the UI). Verify before trusting:
# Header: X-Moltn-Signature: t=<unix seconds>,v1=<hex>
# v1 = HMAC-SHA256(secret, "<t>.<raw body>") — reject if |now - t| > 300 s
const [, t, v1] = sig.match(/^t=(\d+),v1=([0-9a-f]+)$/);
const expected = createHmac("sha256", secret).update(`${t}.${rawBody}`).digest("hex");
if (!timingSafeEqual(Buffer.from(v1), Buffer.from(expected))) reject();
Failed deliveries are retried twice (after 30 s and 5 min). Treat webhooks as notifications and fetch fresh state from the API using the ids in the payload.
Pipe text from any source — form submissions, CRM notes, email — into the capture pipeline with a single POST. Uses its own token (HOOK_TOKEN, set by the install owner) so automation platforms never hold an API key:
curl -X POST https://your-install/hooks/capture \
-H "X-Moltn-Token: $HOOK_TOKEN" \
-H "Content-Type: application/json" \
-d '{"text": "Customer asked for a white-label version", "source": "hubspot"}'
/v1 is additive-only: we add endpoints and response fields, we do not rename or remove them. Breaking changes would ship as /v2 with /v1 kept alive. The MCP tool names and input schemas follow the same rule.