moltn / developers

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.

Authentication

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:

ScopeAllows
readList 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.

REST API (v1)

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.

Quickstart

# 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?"}'

Endpoints

Method & pathScopeDescription
GET /v1/meetingsreadRecent meetings with idea counts.
GET /v1/meetings/:idreadOne meeting: transcript chunks, ideas (status, artifact URLs), assistant answers.
GET /v1/meetings/:id/transcript.mdreadTranscript as a portable markdown file.
GET /v1/library?q=readThe artifact library — everything ever built, searchable.
GET /v1/brain/search?q=&limit=readFull-text search over vault documents + meeting transcripts.
GET /v1/templatesreadAvailable dictation templates (your own, managed under Inställningar → Mallar).
GET /v1/statusreadInstall health: which integrations are configured and live.
POST /v1/capturewrite{text, title?} — capture an idea; returns the detection (type, suggested artifact, confidence).
POST /v1/meetings/importwrite{transcript, title?} — raw "Speaker: text" lines or an array of {speaker, text}; sweeps for ideas in the background.
POST /v1/dictatewriteText or audio (multipart) + optional template_id — returns a finished document.
POST /v1/askwrite{question} — synthesized answer from the second brain, with cited sources.
POST /v1/meetings/joinbuild{meeting_url} — send the notetaker bot to a live Zoom/Meet/Teams call.
POST /v1/meetings/schedulebuild{meeting_url, join_at} — schedule the bot for a future meeting.
POST /v1/meetings/:id/ideas/:ideaId/approvebuildBuild the artifact. ?wait=1 blocks until done; ?artifact= overrides the type; JSON body {instructions} steers this build.
POST /v1/meetings/:id/ideas/:ideaId/rejectbuildDismiss a detected idea.
GET /v1/meetings/:id/ideas/:ideaId/sharebuildMint a signed public link for a built artifact.
POST /v1/meetings/:id/endbuildEnd a meeting: final detection pass + summary delivery.
GET /v1/statsadminPipeline and cost stats: ideas by status, tokens, spend per meeting, queue depth.

Rate limits & errors

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"}.

MCP — drive Moltn from your AI assistant

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.

What that feels like

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

CLI

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.

Outgoing webhooks

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:

EventFires whenPayload data
meeting.completeda meeting is finalized and deliveredmeeting (id, title, platform, times) + ideas with share links for built artifacts
artifact.builtan artifact finishes buildingidea_id, meeting_id, artifact_type, quote, artifact_url (share link)
idea.detectedthe live detector saves an ideaidea_id, meeting_id, type, artifact_type, confidence, quote
pingyou 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.

Inbound hooks (Zapier, Make, n8n)

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"}'

Versioning & stability

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