Skip to main content
miniti fires a POST with the full meeting json when a meeting is saved or updated. see webhooks for the payload shape. this page collects concrete recipes you can drop in.
webhooks are not signed and not retried. treat incoming payloads as untrusted until you add your own auth (shared secret in a header, ip allowlist, etc.) on your endpoint.

zapier

  1. create a new zap with webhooks by zapier -> catch hook
  2. copy the zapier webhook url
  3. paste into miniti: settings -> integrations -> webhooks -> url
  4. save a meeting in miniti to send a test payload
  5. zapier will parse the json and expose all fields (including nested meeting.meddpicc, meeting.training, meeting.action_items[])
common follow-up actions:
  • gmail: send email - email yourself the summary + action items after every meeting
  • notion: create database item - one row per meeting with title, summary, action items as a checklist
  • google sheets: create row - log meetings for reporting
  • linear / jira: create issue - one issue per action item (loop over meeting.action_items)

make (integromat)

  1. new scenario -> webhooks -> custom webhook
  2. copy the webhook url into miniti settings
  3. run once, save a miniti meeting, let make learn the structure
  4. chain modules: iterator on meeting.action_items -> your task tracker, or router on event (saved vs updated)

n8n

  1. add a webhook node, method POST, path of your choice
  2. copy the production url (not the test url) into miniti
  3. downstream nodes can reference {{$json["meeting"]["summary"]}}, {{$json["meeting"]["meddpicc"]["champion"]}}, etc.
example: split action items into separate rows
webhook -> item lists (split out, field: meeting.action_items) -> your tool

slack (via incoming webhook)

slack’s native incoming webhooks don’t accept miniti’s payload directly - you need a small middleman. two easy options: option 1: zapier/make - catch hook -> format a slack message -> post to channel. option 2: a tiny relay (cloudflare worker, vercel function, fly, etc.):
export default {
  async fetch(request) {
    const body = await request.json()
    const m = body.meeting
    const slack = {
      text: `*${m.title ?? 'untitled meeting'}*\n${m.summary ?? ''}`,
      blocks: [
        { type: 'header', text: { type: 'plain_text', text: m.title ?? 'meeting' } },
        { type: 'section', text: { type: 'mrkdwn', text: m.summary ?? '' } },
        ...(m.action_items?.length
          ? [{ type: 'section', text: { type: 'mrkdwn', text: '*action items*\n' + m.action_items.map(a => `- ${a}`).join('\n') } }]
          : [])
      ],
    }
    await fetch(SLACK_WEBHOOK_URL, {
      method: 'POST',
      headers: { 'content-type': 'application/json' },
      body: JSON.stringify(slack),
    })
    return new Response('ok')
  }
}
point miniti at your worker url.

custom endpoint (node / bun / deno)

bare-bones receiver with a shared-secret header for auth:
import express from 'express'
const app = express()
app.use(express.json({ limit: '5mb' }))

app.post('/miniti', (req, res) => {
  if (req.header('x-webhook-secret') !== process.env.WEBHOOK_SECRET) {
    return res.status(401).end()
  }
  const { event, meeting } = req.body
  console.log(event, meeting.title, meeting.action_items?.length ?? 0)
  // save to your db, queue a job, etc.
  res.status(200).end()
})

app.listen(3000)
miniti doesn’t support custom headers today, so the shared secret has to travel another way (subdomain-as-token, signed path, etc.) or skip auth and rely on an obscured url + ip allowlist.

python (flask)

from flask import Flask, request, abort
app = Flask(__name__)

@app.post('/miniti')
def miniti():
    data = request.get_json()
    event = data.get('event')
    meeting = data.get('meeting', {})
    # do your thing
    return '', 200

filtering by mode

the payload includes meeting.training (local metrics), meeting.meddpicc (only in meddpicc mode), and meeting.questions (only when questions mode has run). if you only care about sales calls, check meeting.meddpicc is non-null before acting.

idempotency

each saved meeting has a stable meeting.id (uuid). use it as the idempotency key in your downstream system so that meeting.updated events replace rather than duplicate.

see also

  • webhooks - payload shape + delivery rules