Developers

v1

Mesakem API

Everything Mesakem knows about your meetings — meetings, transcripts, summaries, decisions and tasks — is now available to your own systems: secure reads, Hebrew and English, with exactly the permissions your dashboard has. And with webhooks, Mesakem tells you the moment something changes.

Base URLhttps://mesakem.com/api/v1

Overview & use cases

The API is REST over HTTPS with UTF-8 JSON. Every request carries a personal API key that acts as you, in one work area, and sees exactly what your dashboard shows you — never more. A meeting deleted in Mesakem answers 404 immediately.

CRM sync

Summary, decisions and action items onto the HubSpot, Salesforce or Monday deal matched by participant domain.

Tasks to project tools

Meeting tasks into Asana, ClickUp or Jira, with assignee and due date.

Knowledge base

Summaries as Markdown or HTML straight into Notion or Confluence.

BI & analytics

Meeting hours per client, talk time and trends — incremental sync with updated_since.

AI agents & RAG

Transcripts and summaries as the knowledge source of an internal agent.

Archiving & compliance

Transcripts (VTT/SRT) and summaries into your own archive, including DOCX files.

Quick start

  1. In the dashboard open Settings → API & webhooks and press “Create key”. Name it, choose access and expiry. Open Settings

  2. Copy the key (msk_live_…) — it is shown once only. Keep it in a secret store, never in code.

  3. Make a first request: GET /me confirms the key works and shows its scopes.

  4. List your latest meetings, then fetch the summary of one.

export MESAKEM_API_KEY="msk_live_…"   # from Settings → API & webhooks

# 1. Check the key
curl https://mesakem.com/api/v1/me -H "Authorization: Bearer $MESAKEM_API_KEY"

# 2. Latest meetings
curl "https://mesakem.com/api/v1/meetings?limit=5" -H "Authorization: Bearer $MESAKEM_API_KEY"

# 3. A summary as Markdown
curl "https://mesakem.com/api/v1/meetings/run_…/summary?format=markdown" -H "Authorization: Bearer $MESAKEM_API_KEY"

Authentication & scopes

Send the key as Authorization: Bearer msk_live_…. No-code tools may send it as X-Api-Key instead. Cookies are never read. A wrong, revoked or expired key answers 401 without saying which.

HTTP
Authorization: Bearer msk_live_AbC1…wxYz
X-Api-Key: msk_live_AbC1…wxYz
  • A key belongs to one work area — your personal one, or your private organization area — fixed when you create it.
  • Revoking in Settings works immediately, even mid-request. Recording links minted with it stop working at the same moment.
  • Use keys on servers only. Never in a browser, a mobile app or a code repository.
  • What a key sees matches the dashboard: upcoming meetings from your own calendar, attendance and talk time for the meeting creator only, your own tasks only.
ScopeWhat it unlocks
meetings:readMeetings, one meeting, participants
transcripts:readTranscripts in every format
summaries:readSummaries and documents, including DOCX
recordings:read5-minute recording links
tasks:readYour tasks and their checklists
calendar:readUpcoming meetings from your calendar
team:readOrganization team members (owners and admins)
webhooks:readYour webhook endpoints, their delivery logs and the event catalog
webhooks:writeCreate, change, test, rotate, redeliver and delete endpoints (paid plans)
settings:readThe calendar auto-join mode
shares:readA meeting's public link
bot:writeSend, schedule and cancel the bot
tasks:writeCreate and update tasks and checklists
uploads:writeUpload recordings
settings:writeChange the auto-join mode
meetings:writeRename and delete meetings — only when ticked explicitly
shares:writeCreate and revoke public links — only when ticked explicitly
rooms:readYour rooms and shared rooms, their items, and their stored decisions and analyses
rooms:writeCreate, rename, archive, and add or remove meetings and calls
calls:readYour phone calls: transcript, summary and recording link
search:readKeyword search over meetings, tasks, rooms and people (with each type's own scope)
templates:readThe built-in summary templates and yours
templates:writeCreate, update, archive and set the default of your templates

Rate limits & best practices

Every response carries RateLimit-Limit, RateLimit-Remaining and RateLimit-Reset (and X-RateLimit-*). Going over answers 429 with Retry-After in seconds.

Per key60 requests / minute
Per work area20,000 requests / day (UTC)
Per IP before authentication120 requests / minute
Webhook changes per key20 / minute (create, update, delete, rotate, test, redeliver)
Bot send and schedule, per user10 / minute · 60 / hour · 200 / day
Bot send and schedule, per work area20 / minute · 120 / hour · 300 / day
Uploads, per user10 / minute, and at most 3 in progress
HTTP 429
HTTP/1.1 429 Too Many Requests
Retry-After: 21
RateLimit-Limit: 60
RateLimit-Remaining: 0
RateLimit-Reset: 21
X-Request-Id: apireq_mfa1b2c3XyZ0aBcDeFgHiJ

Working well with the API

Prefer webhooks over polling

Webhooks call you the moment a summary is ready — no wasted requests. See the Webhooks chapter.

Incremental sync with updated_since

If you must poll: GET /meetings?updated_since=… at most every 5 minutes, and keep the last updated_at you saw.

ETags and If-None-Match

Send the last ETag as If-None-Match. For transcripts and summaries only the version is checked and a body-less 304 comes back — almost free.

Back off

On 429 or 5xx wait for Retry-After and add jittered exponential backoff.

# Only what changed since your last sync, oldest change first
curl "https://mesakem.com/api/v1/meetings?updated_since=2026-10-17T08:00:00Z" \
  -H "Authorization: Bearer $MESAKEM_API_KEY" \
  -H 'If-None-Match: "c-…"'      # → 304 Not Modified when nothing changed

Pagination

Lists return { data, next_cursor, has_more }. Send limit (1–100, default 25) and the cursor from the previous page. Cursors are opaque and signed: they belong to the key, the work area and the request's filters, and changing any of them answers 400 invalid_cursor.

# First page
curl "https://mesakem.com/api/v1/meetings?limit=100" -H "Authorization: Bearer $MESAKEM_API_KEY"
# Next page: pass next_cursor back unchanged, with the SAME filters
curl "https://mesakem.com/api/v1/meetings?limit=100&cursor=<next_cursor>" -H "Authorization: Bearer $MESAKEM_API_KEY"

Errors

Every error has the same, stable shape. code is stable; message follows Accept-Language (Hebrew or English); request_id helps us find the request.

JSON
{
  "error": {
    "code": "insufficient_scope",
    "message": "The key is missing a required scope.",
    "details": [{ "field": "scope", "message": "Requires transcripts:read." }],
    "request_id": "apireq_mfa1b2c3XyZ0aBcDeFgHiJ"
  }
}
HTTPcodeMeaning
400bad_requestInvalid, unknown or repeated parameter
400invalid_cursorCursor from another key, route or filter set
401unauthorizedMissing, malformed, unknown, revoked or expired key
403insufficient_scopeThe key lacks the scope (details names it)
403plan_requiredThe plan does not include this part
404not_foundMissing or not accessible to you — never says which
413payload_too_largeResponse too large; lower limit or page
429rate_limitedOver a limit; see Retry-After
500internal_errorSomething failed on our side
403quota_exceededThe plan's meeting quota does not allow it (see reason)
409meeting_bot_already_activeA bot is already in the meeting; meeting_id is that meeting
409idempotency_key_reusedThe same Idempotency-Key with a different request
409idempotency_in_progressThe first request with that key is still running
409conflictConflicts with the current state (see reason, e.g. calendar_event_control_locked)
415unsupported_media_typeUnsupported content or file type
422unsupported_recipientSharing with a user or team — only a public link is supported
422unprocessableValid, but cannot be carried out (see reason)

Writes & idempotency

On paid plans a key can also act: send the bot to a meeting, schedule or cancel it, decide when it joins on its own, manage tasks, upload recordings and share a meeting by link. Every write runs the same code and checks as the dashboard, and is recorded in the audit log.

  • On the trial the API is read-only: every write answers 403 plan_required with an upgrade_url.
  • Send an Idempotency-Key (a UUID, say) on every POST, PUT and PATCH. A retry with the same key and body returns the first response instead of acting twice — for 24 hours. The same key with another body answers 409.
  • Every bot costs real money, so sending and scheduling have hard limits per user and per work area, and the plan's meeting quota applies as usual.
  • A meeting has at most one bot. Sending again to the same meeting answers 409 meeting_bot_already_active with the existing meeting_id.
  • Deleting or renaming a meeting (meetings:write) and creating public links (shares:write) are in no preset — tick them by hand. Deleting is final, as in the dashboard.
  • Sharing is by public link only: a user or team recipient answers 422 unsupported_recipient, because each member's meetings stay private.

Recipe: send the bot from your booking system

When a meeting is booked, send the bot with start_time and an Idempotency-Key from the booking id. When the summary is ready you get a webhook; then fetch the summary.

# A meeting was booked: send Mesakem to it, at its start time.
curl -X POST "https://mesakem.com/api/v1/meetings/bot" \
  -H "Authorization: Bearer $MESAKEM_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: booking-48213" \
  -d '{"meeting_url":"https://zoom.us/j/1234567890?pwd=abc123","title":"Discovery call — Acme","start_time":"2026-10-20T07:00:00Z"}'
# 202 → {"meeting_id":"run_…","status":"scheduling"}
# 409 meeting_bot_already_active → error.meeting_id is the meeting that already has the bot

What a write on the trial looks like

HTTP 403
{
  "error": {
    "code": "plan_required",
    "message": "Your plan does not include this part of the API.",
    "details": [
      { "field": "scope", "message": "bot:write is not included in this plan." },
      { "field": "plan", "message": "The trial includes read-only API access. Upgrade to Pro for writes: https://mesakem.com/dashboard/billing/pro?cycle=annual" }
    ],
    "request_id": "apireq_mfa1b2c3XyZ0aBcDeFgHiJ",
    "upgrade_url": "https://mesakem.com/dashboard/billing/pro?cycle=annual"
  }
}

Webhooks

Webhooks turn the direction around: instead of your system asking the API every few minutes whether anything changed, Mesakem sends it a signed POST the moment something happens — a summary is ready, a task was created, a meeting was deleted. You hear about it at once, with no wasted requests and nothing missed between two polls.

Right away

The event leaves moments after the change is saved — not at your next poll.

Signed and thin

Every delivery is signed with Standard Webhooks and carries only ids, status and counts. You fetch the details with the API, under your key's permissions.

Reliable

A failed delivery is retried — up to 9 attempts over about 45 hours — with a delivery log and redeliver.

Only what you need

Each endpoint gets only the events you picked, narrowed further by meeting source and by room.

How it works

  1. Something happens in MesakemA summary is ready, a task changed, a meeting was deleted
  2. Mesakem signs and POSTsto every endpoint subscribed to the event
  3. You verify and answer 2xxwithin 10 seconds; do the work afterwards
  4. You fetch details with the APIfrom data.links.api, when you need them

Webhooks: Webhooks quick start

  1. Create an endpoint: in Settings → API & webhooks, or with POST /webhooks and a key that has webhooks:write (paid plans). Open Settings

  2. Pick the events you want. Two events also have an alternate name, which you can subscribe with too.

  3. Copy the signing secret (whsec_…). It is shown once only; keep it in a secret store.

  4. Send a test event (webhook.test) from Settings or with POST /webhooks/{endpoint_id}/test. The answer shows your status code, the latency and the start of your response.

  5. Verify the signature on every request and answer 2xx within 10 seconds.

# 1. Create the endpoint (a key with webhooks:write — or use Settings → API & webhooks)
curl -X POST "https://mesakem.com/api/v1/webhooks" \
  -H "Authorization: Bearer $MESAKEM_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://hooks.example.com/mesakem",
    "events": ["summary.ready", "action_items.created", "meeting.deleted"],
    "description": "CRM sync"
  }'
# → 201 Created. Store "secret" (whsec_…) now: it is never shown again.

# 2. Send webhook.test and see what your endpoint answered
curl -X POST "https://mesakem.com/api/v1/webhooks/whk_…/test" \
  -H "Authorization: Bearer $MESAKEM_API_KEY"
# → { "delivered": true, "status": 200, "latency_ms": 162, … }

On the trial: one endpoint, managed in Settings. Managing endpoints with the API (webhooks:write) comes with paid plans.

Webhooks: Event catalog

24 event types, plus webhook.test, which is sent only when you ask for a test. Each endpoint subscribes to its own list, and filters (meeting sources and rooms) narrow it further. The same list is available from GET /webhook-event-types.

Alternate names: subscribe with an alternate name and the delivery's type is that name. Subscribe with both names and you get one delivery, labelled with the main name.

Event catalog
EventWhen it firesdata fields
Meetings
meeting.scheduledA meeting was scheduled for the notetaker (calendar, link or manual).object: "meeting"meeting_idsourcescheduled_start_timetitle
meeting.bot_status_changedThe notetaker is joining, waiting in the lobby, was not admitted or was removed.object: "meeting"meeting_idbot_statusprevious_status
meeting.startedRecording started.object: "meeting"meeting_idstart_time
meeting.endedThe meeting ended and processing began.object: "meeting"meeting_idend_timeduration_seconds
meeting.failedThe meeting ended without a recording (failed, cancelled or not admitted).object: "meeting"meeting_idstatusfailure_category
meeting.deletedA meeting was deleted. Delete your copy too.object: "meeting"meeting_id
Recordings, transcripts & summaries
recording.readyThe recording is stored and can be fetched.object: "recording"meeting_idrecording_idduration_seconds
transcript.readyalternate namemeeting.transcript_readyA transcript is ready.object: "transcript"meeting_idtranscript_idlanguagesegment_count
summary.readyalternate namemeeting.initial_summary_readyThe first summary of a meeting is ready.object: "summary"meeting_idsummary_iddocument_idslanguagecounts
summary.updatedA summary was regenerated or edited.object: "summary"meeting_idsummary_idedited
action_items.createdAction items from a meeting or call were added to tasks.object: "action_items"meeting_idtask_idscount
Phone calls
call.transcript_readyA phone call transcript is ready.object: "call"call_idmeeting_idtranscript_id
call.summarizedA phone call was summarized.object: "call"call_idmeeting_idsummary_id
Tasks
task.createdA task was created.object: "task"task_idstatus
task.updatedA task changed (title, status, due date or items).object: "task"task_idstatuschanged
task.deletedA task was deleted.object: "task"task_id
Public links
share.createdA public link to a meeting or room was created.object: "share"share_idresource
share.revokedA public link was turned off.object: "share"share_idresource
Rooms
room.createdA room was created.object: "room"room_id
room.updatedA room was renamed or its settings changed.object: "room"room_id
room.archivedA room was archived.object: "room"room_id
room.meeting_addedA meeting was added to a room.object: "room"room_idmeeting_id
room.meeting_removedA meeting was removed from a room.object: "room"room_idmeeting_id
Uploads
upload.failedAn uploaded recording could not be processed.object: "upload"upload_idreason
System
webhook.testtest onlyA test event, sent only from Settings or the test endpoint.object: "webhook"endpoint_id

Meeting and task events also carry data.links.api and data.links.app.

Webhooks: The payload

Every delivery is a POST with a UTF-8 JSON body. The envelope is the same for every event; only data changes. The payload is thin on purpose: ids, status and counts — no transcript or summary text, no e-mail addresses, no share links.

summary.ready, as your server receives it
POST /mesakem HTTP/1.1
Host: hooks.example.com
Content-Type: application/json
User-Agent: Mesakem-Webhooks/1.0
webhook-id: msg_1a2b3c4d5e6f708192a3b4c5d6e7f809
webhook-timestamp: 1792317141
webhook-signature: v1,hPEWJKsYRZkotC6qTrqona6rJhYw7hL1L0LA3CTlWD8=

{
  "id": "msg_1a2b3c4d5e6f708192a3b4c5d6e7f809",
  "type": "summary.ready",
  "api_version": "2026-10",
  "created_at": "2026-10-18T09:52:20.000Z",
  "workspace_id": "workspace_1a2b3c4d",
  "data": {
    "object": "summary",
    "meeting_id": "run_6f1c2a4e-0d3b-4e5f-9a7b-1c2d3e4f5a6b",
    "summary_id": "summary_2b7d0c1e-8f9a-4b3c-9d2e-5f6a7b8c9d0e",
    "document_ids": [
      "doc_sum_2b7d0c1e-8f9a-4b3c-9d2e-5f6a7b8c9d0e",
      "doc_act_2b7d0c1e-8f9a-4b3c-9d2e-5f6a7b8c9d0e",
      "doc_dec_2b7d0c1e-8f9a-4b3c-9d2e-5f6a7b8c9d0e"
    ],
    "language": "he",
    "counts": { "action_items": 5, "decisions": 2 },
    "links": {
      "api": "https://mesakem.com/api/v1/meetings/run_6f1c2a4e-0d3b-4e5f-9a7b-1c2d3e4f5a6b/summary",
      "app": "https://mesakem.com/dashboard/meeting/run_6f1c2a4e-0d3b-4e5f-9a7b-1c2d3e4f5a6b"
    }
  }
}

Envelope fields

Envelope fields
FieldMeaning
idThe message id, equal to the webhook-id header. The same across retries and redeliveries.
typeThe event name, or its alternate name if you subscribed with that.
api_versionThe payload version: 2026-10.
created_atWhen the event happened (ISO 8601, UTC). Order by it, not by arrival.
workspace_idThe event's work area.
data.objectThe resource kind: meeting, summary, task…
data.linksapi — the API URL for the full details; app — the page in the dashboard.

Headers

Headers
HeaderMeaning
webhook-idmsg_… — your dedupe key
webhook-timestampUnix seconds of this attempt
webhook-signaturev1,<base64> — two, space separated, during a secret rotation
Content-Typeapplication/json
User-AgentMesakem-Webhooks/1.0
X-Webhook-Signaturesha256=<hex> — only with the simple signature (simple_hmac)

Webhooks: Verifying signatures

Every delivery is signed with Standard Webhooks — the standard Svix and others use — so a ready-made library works. Without one, these are the steps:

  1. Take the raw body exactly as received — before any JSON parsing.

  2. Reject a request whose webhook-timestamp is more than 5 minutes away from your clock (replay protection).

  3. Compute HMAC-SHA256 over <webhook-id>.<webhook-timestamp>.<body> keyed with the base64-decoded secret (without whsec_), and base64 the result.

  4. Compare, in constant time, with each v1,… value in webhook-signature. One match is enough.

import express from "express";
import { Webhook } from "standardwebhooks";              // npm i standardwebhooks

const wh = new Webhook(process.env.MESAKEM_WEBHOOK_SECRET); // whsec_…
const app = express();

// express.raw: verify the body exactly as sent, BEFORE any JSON parsing
app.post("/mesakem/webhook", express.raw({ type: "application/json" }), async (req, res) => {
  let event;
  try {
    event = wh.verify(req.body, req.headers);           // signature + 5-minute window
  } catch {
    return res.status(400).end();
  }
  if (await seen(req.headers["webhook-id"])) return res.status(204).end(); // at least once: dedupe
  await queue.add(event);                               // answer fast, work later
  res.status(204).end();
});

Rotating the secret without downtime

Rotating (in Settings or with POST /webhooks/{endpoint_id}/rotate-secret) returns a new secret that signs at once. For 24 hours every delivery carries two signatures — the new one, then the old — so code that checks each signature keeps working until you deploy the new secret.

Simple signature (HMAC)

For a receiver that cannot verify Standard Webhooks: an endpoint set to signature_format: "simple_hmac" also gets X-Webhook-Signature: sha256=<hex> — HMAC-SHA256 of the body alone, keyed with the full secret string (whsec_ included). This header has no timestamp and no rotation overlap, so move to the standard check when you can.

import { createHmac, timingSafeEqual } from "node:crypto";

// Only for endpoints with signature_format "simple_hmac":
// X-Webhook-Signature: sha256=<hex HMAC-SHA256 of the raw body, keyed with the FULL secret string>
export function verifySimpleHmac(rawBody, headers, secret = process.env.MESAKEM_WEBHOOK_SECRET) {
  const expected = Buffer.from(`sha256=${createHmac("sha256", secret).update(rawBody).digest("hex")}`);
  const given = Buffer.from(String(headers["x-webhook-signature"] ?? ""));
  return given.length === expected.length && timingSafeEqual(given, expected);
}

Test vector

Check your code against these values (the body is the exact bytes, on one line). The timestamp is old, so switch off the 5-minute check for this run or pass your own clock.

Test vector
{
  "secret": "whsec_MfKQ9r8GKYqrTwjUPD8ILPZIo2LaLaSw",
  "webhook-id": "msg_0f1e2d3c4b5a69788796a5b4c3d2e1f0",
  "webhook-timestamp": "1792314000",
  "body": "{\"id\":\"msg_0f1e2d3c4b5a69788796a5b4c3d2e1f0\",\"type\":\"webhook.test\",\"api_version\":\"2026-10\",\"created_at\":\"2026-10-18T09:00:00.000Z\",\"workspace_id\":\"workspace_1a2b3c4d\",\"data\":{\"object\":\"webhook\",\"endpoint_id\":\"whk_3c2b1a0f9e8d7c6b5a493827161504f3\"}}",
  "webhook-signature": "v1,BTWmnJ208A8o6942h9e4GevByejb0CwCw/lva2zO6jM=",
  "X-Webhook-Signature": "sha256=42538b7323812ccd84b1dba444c3dfe2f769ecda320fa7d7e8fdbebf0e2cf1e2"
}

Webhooks: Retries, failures & auto-disable

A 2xx answer within 10 seconds is a success. Anything else is a failed attempt, and your answer decides whether we try again:

Retries, failures & auto-disable
Your answerWhat happens
2xxSuccess (when it arrives within 10 seconds).
5xx · 408 · timeout · networkRetried on the schedule.
429 · 503 + Retry-AfterRetried, waiting at least Retry-After (up to 1 hour).
410 GoneThe endpoint is disabled at once and its pending deliveries are cancelled.
3xxFailed, not retried — redirects are not followed. Use the final URL.
4xxAny other 4xx: failed, not retried. You can redeliver it from the log.

Retry schedule

Retry schedule
AttemptWhen
1Immediately
210 s after the previous one
31 min after the previous one
45 min after the previous one
530 min after the previous one
62 h after the previous one
76 h after the previous one
812 h after the previous one
924 h after the previous one

Each wait has ±10% random jitter. After attempt 9 (about 45 hours) the delivery stays failed in the log, and you can redeliver it from there.

Auto-disable

An endpoint that fails 50 times in a row, over at least 3 days, is disabled automatically and its owner gets an e-mail. Once fixed, re-enable it in Settings or with PATCH and enabled: true — the failure count resets.

At least once, in no guaranteed order

Every event arrives at least once, sometimes more (say you answered 2xx but the connection dropped). Order is not guaranteed: a retry of an older event can land after a newer one.

Webhooks: Delivery log & redeliver

Every delivery is kept for 30 days with its state, attempt count, last status code, latency and the first 512 bytes of your answer. See it in Settings or with GET /webhooks/{endpoint_id}/deliveries, newest first.

Redeliver (POST …/deliveries/{delivery_id}/redeliver, answers 202) starts a new attempt series for a finished delivery — with the same webhook-id, so your dedupe recognises it.

# The last 30 days, newest first
curl "https://mesakem.com/api/v1/webhooks/whk_…/deliveries?limit=25" \
  -H "Authorization: Bearer $MESAKEM_API_KEY"

# Send a finished delivery again — same webhook-id — answers 202 Accepted
curl -X POST "https://mesakem.com/api/v1/webhooks/whk_…/deliveries/whd_…/redeliver" \
  -H "Authorization: Bearer $MESAKEM_API_KEY"
State
StateMeaning
pendingWaiting for its first attempt
deliveringBeing sent now
retry_scheduledFailed; the next try is at next_attempt_at
succeededGot a 2xx answer
failedOut of attempts, or an answer we do not retry — you can redeliver
cancelledCancelled, for example because the endpoint was disabled or access to the meeting ended

Webhooks: Best practices

Answer fast, work later

Verify the signature, put the event on a queue and answer 2xx right away. Anything slower than 10 seconds counts as a failure and is sent again.

Dedupe on webhook-id

Delivery is at least once. Keep webhook-id for a few days and skip ids you have seen — retries and redeliveries reuse it.

Order by created_at

Events can arrive out of order. Compare created_at (or the resource's updated_at from the API) instead of trusting arrival order.

Details from data.links.api

Payloads are thin on purpose. Fetch the summary, transcript or task from the link with your API key — you always get the current version, under current permissions.

Delete your copies

On meeting.deleted and task.deleted, delete what you stored. A deleted meeting answers 404 in the API at once.

Answer 410 when you are done

A retired receiver can answer 410 — the endpoint is disabled at once and we stop trying.

Webhooks: Security

  • https only, on port 443 or 8443, to a public host. Private, loopback, link-local and cloud metadata addresses are refused when you save the URL — and again on every delivery, at connect time, so DNS rebinding cannot reach an internal network.
  • Redirects (3xx) are never followed. Register the final URL.
  • Thin payloads: ids, status and counts. No transcript or summary text, no e-mail addresses, no share links.
  • Before every delivery we check again that the endpoint's owner can still see the meeting. If that access has ended, nothing is sent.
  • The signing secret is stored encrypted and shown once. Rotate it whenever you like, with a 24-hour overlap.
  • Only an endpoint's owner can see or change it — through the API as well.

Webhooks: Webhooks by plan

TrialPro & organizations
Webhook endpoints1Up to 10 per person
Managing endpointsIn SettingsIn Settings and with the API (webhooks:write)
Reading endpoints and logs with the API (webhooks:read)IncludedIncluded
Every event, signing, retries and the delivery logIncludedIncluded

Webhooks: No-code: Zapier

The Mesakem integration for Zapier runs on these same webhooks: instant triggers such as “New Summary” and “New Action Item”, plus Find Meeting and Find Task, connected to the tools you already use without a line of code. It is private: anyone with the invite link can add it to their Zapier account.

  1. Open the invite link and add Mesakem to your Zapier account.

  2. Create an API key in Mesakem Settings. Triggers need the webhooks:write permission (Manage webhooks), on a paid plan.

  3. In Zapier, pick Mesakem, paste the key and build a Zap. Turning it on creates one webhook endpoint for it; turning it off deletes it.

Webhooks: No-code: n8n

A Mesakem community node for self-hosted n8n: an instant trigger on these same webhooks, plus actions on the API. The package is published on npm with provenance, and its source is on GitHub.

  1. In n8n, open Settings → Community Nodes → Install.

  2. Enter the package name n8n-nodes-mesakem and install.

  3. Create an API key in Mesakem Settings, then add a Mesakem API credential in n8n and paste the key.

Packagen8n-nodes-mesakem

What the node offers

What the node offers
PartWhat it does
Trigger · Mesakem TriggerStarts a workflow the moment something happens in Mesakem: a summary is ready, a meeting ended, a transcript is ready, a task was created or changed, and more, from all 24 event types. Details are fetched by id, in at most two API requests.
Meetings · MeetingGet, Get Many, Get Summary, Get Transcript, Get Upcoming
Tasks · TaskGet, Get Many, Create, Update, Delete
The bot · NotetakerSend, Schedule, Cancel: send it to a meeting link, schedule it for a calendar meeting, or cancel it
Documents · DocumentGet: the document as Markdown, HTML, text or JSON
Your account · AccountGet: the key, its user, plan, permissions and limits

You need a Mesakem API key. Triggers need a paid plan: the node registers its own webhook, which takes webhooks:write. To receive events, your n8n needs a public https address.

Rooms

A room gathers every meeting and call of one client or project. The API shows exactly the rooms your dashboard shows: your own and the work area's shared rooms. Another member's private room never appears, and a room never reveals a meeting or call you cannot read directly.

  • Rooms have no hard delete: DELETE /rooms/{id} archives, and PATCH with archived: false restores. The meetings themselves are untouched.
  • GET /rooms/{id}/insights returns only what already exists: the decisions on each meeting's summary, and analyses made in the dashboard. The call never creates a new one.
  • A room's public link is created in the dashboard, where you choose which meetings it shows. The API can read and revoke it.
curl -X POST "https://mesakem.com/api/v1/rooms" \
  -H "Authorization: Bearer $MESAKEM_API_KEY" \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "Content-Type: application/json" \
  -d '{"name": "Acme pilot", "client_name": "Acme"}'

curl -X PUT "https://mesakem.com/api/v1/rooms/$ROOM_ID/meetings/run_6f1c2a4e-0d3b-4e5f-9a7b-1c2d3e4f5a6b" \
  -H "Authorization: Bearer $MESAKEM_API_KEY"

Phone calls

Calls recorded from the phone system you connected, with their transcript, summary and a 5-minute recording link. You see only your own calls, and a deleted call (or one whose meeting was deleted) is never returned.

  • Call ids start with call_. A call that produced a meeting also appears in GET /meetings (source phone), and meeting_id links the two.
  • Calls are available on every plan.
curl "https://mesakem.com/api/v1/calls?limit=25" \
  -H "Authorization: Bearer $MESAKEM_API_KEY"

curl "https://mesakem.com/api/v1/calls/$CALL_ID/summary?format=markdown" \
  -H "Authorization: Bearer $MESAKEM_API_KEY"

Summary templates

A template decides how Mesakem writes a summary: structure, tone, emphasis and sections. The API returns the built-in templates and yours, and lets you create, update, archive and set the default, exactly like the Templates page in the dashboard.

  • A template is stored exactly as you send it: a name up to 120 characters, instructions of 20 to 12,000 characters, not the name of a built-in template. Up to 40 active templates per type (meetings and calls).
  • Built-in templates are read-only, but you can make one the default.

Draft with your own AI, then save it here

Ask any AI assistant you work with to draft a template, then send the result to POST /templates. Mesakem runs no AI on it: it is checked only against the rules above and stored as is. An example request to the assistant:

Draft with your own AI, then save it here
Draft a Mesakem summary template for discovery calls with new customers. Return JSON with two fields: name (up to 120 characters) and instructions (clear instructions, up to 12,000 characters). In the instructions: what to summarize, which sections (needs, objections, budget, next steps with owner and date), a businesslike tone and at most one page.
curl -X POST "https://mesakem.com/api/v1/templates" \
  -H "Authorization: Bearer $MESAKEM_API_KEY" \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "Content-Type: application/json" \
  -d '{"type": "meeting", "name": "Discovery call", "instructions": "Summarize as a discovery call: needs, objections, budget, next steps with owner and date."}'

Endpoint reference

Generated from the OpenAPI 3.1 document: reads (GET) and writes (POST, PUT, PATCH, DELETE). Every write names the scope it needs.

Your key

GET/meany key

The key, its owner, workspace, plan and limits

Costs one database statement. Use it to check a key.

curl "https://mesakem.com/api/v1/me" \
  -H "Authorization: Bearer $MESAKEM_API_KEY"
Example response
{
  "object": "api_key_context",
  "key": {
    "id": "key_3f2a9c0d4b5e6f708192a3b4c5d6e7f8",
    "name": "HubSpot sync",
    "display": "msk_live_AbC1…wxYz",
    "scopes": [
      "meetings:read",
      "summaries:read"
    ],
    "created_at": "2026-10-17T08:00:00.000Z",
    "expires_at": "2027-10-17T08:00:00.000Z"
  },
  "user": {
    "id": "user_9b8c7d6e",
    "name": "Dana Levi",
    "email": "dana@acme.co.il"
  },
  "workspace": {
    "id": "workspace_1a2b3c4d",
    "kind": "personal",
    "plan": "full",
    "organization": null
  },
  "limits": {
    "requests_per_minute": 60,
    "requests_per_day": 20000
  }
}

Meetings, transcripts & summaries

GET/meetingsmeetings:read

List meetings

Newest first by default. For incremental sync pass updated_since: results are then in ascending updated_at order; keep the last updated_at you saw and send If-None-Match. Prefer this (at most every 5 minutes) over re-reading everything.

Parameters
ParametersTypeNotes
limitinteger (1–100)default 25
cursorstringnext_cursor from the previous page of the SAME request (same key and filters).
statuscompleted | processing | scheduled | failed
fromdate-timeISO 8601 with offset, or YYYY-MM-DD (00:00 UTC).
todate-time
updated_sincedate-time
orderrecent | updated
expandstringComma-separated: participants, documents.
qstringKeyword search: every word must match (prefix match for meetings). Needs search:read.
curl "https://mesakem.com/api/v1/meetings?limit=25&updated_since=2026-10-01T00%3A00%3A00Z" \
  -H "Authorization: Bearer $MESAKEM_API_KEY"
Example response
{
  "object": "list",
  "data": [
    {
      "id": "run_6f1c2a4e-0d3b-4e5f-9a7b-1c2d3e4f5a6b",
      "object": "meeting",
      "title": "פגישת היכרות — אקמה",
      "status": "completed",
      "status_detail": "summarized",
      "source": "zoom",
      "kind": "live_meeting",
      "language": "he",
      "start_time": "2026-10-15T09:00:12.000Z",
      "end_time": "2026-10-15T09:47:40.000Z",
      "duration": 2848,
      "scheduled_start_time": "2026-10-15T09:00:00.000Z",
      "scheduled_end_time": "2026-10-15T10:00:00.000Z",
      "has_transcript": true,
      "has_recording": true,
      "has_summary": true,
      "summary_id": "summary_2b7d0c1e-8f9a-4b3c-9d2e-5f6a7b8c9d0e",
      "created_by_you": true,
      "app_url": "https://mesakem.com/dashboard/meeting/run_6f1c2a4e-0d3b-4e5f-9a7b-1c2d3e4f5a6b",
      "participants": [
        {
          "name": "Dana Levi",
          "email": "dana@acme.co.il",
          "company": "acme.co.il",
          "organizer": true
        }
      ],
      "created_at": "2026-10-15T08:58:01.000Z",
      "updated_at": "2026-10-15T09:52:18.000Z"
    }
  ],
  "next_cursor": "eyJ2IjoxLCJwIjp7InMiOiIyMDI2LTEwLTE1VDA5OjAwOjEyLjAwMDAwMFoifX0.Xn3k2l1PqR8sT6uV0wYz4aBcDeFgHiJk",
  "has_more": true
}
GET/meetings/upcomingcalendar:read

Upcoming calendar meetings (your own calendar)

Default window: the next 336 hours (14 days). within_hours up to 8760.

Parameters
ParametersTypeNotes
limitinteger (1–100)default 25
cursorstringnext_cursor from the previous page of the SAME request (same key and filters).
within_hoursinteger (1–8760)default 336
fromdate-timeISO 8601 with offset, or YYYY-MM-DD (00:00 UTC).
todate-time
curl "https://mesakem.com/api/v1/meetings/upcoming?within_hours=48" \
  -H "Authorization: Bearer $MESAKEM_API_KEY"
Example response
{
  "object": "list",
  "data": [
    {
      "id": "cal_evt_Qm9pZ2h0LXNlcmllcy0x",
      "object": "upcoming_meeting",
      "title": "סנכרון שבועי",
      "start_time": "2026-10-18T07:00:00.000Z",
      "end_time": "2026-10-18T07:30:00.000Z",
      "meeting_url": "https://zoom.us/j/1234567890",
      "source": "zoom",
      "organizer": {
        "email": "dana@acme.co.il"
      },
      "bot": {
        "decision": "will_join",
        "override": null,
        "reason": "calendar_auto_record"
      },
      "series_id": "8d7c6b5a",
      "created_at": "2026-10-10T12:00:00.000Z",
      "updated_at": "2026-10-16T12:00:00.000Z"
    }
  ],
  "next_cursor": null,
  "has_more": false
}
GET/meetings/{meeting_id}meetings:read

Get a meeting

Parameters
ParametersTypeNotes
meeting_id · requiredstringin path
expandstringComma-separated: participants, documents.
curl "https://mesakem.com/api/v1/meetings/run_6f1c2a4e-0d3b-4e5f-9a7b-1c2d3e4f5a6b" \
  -H "Authorization: Bearer $MESAKEM_API_KEY"
Example response
{
  "id": "run_6f1c2a4e-0d3b-4e5f-9a7b-1c2d3e4f5a6b",
  "object": "meeting",
  "title": "פגישת היכרות — אקמה",
  "status": "completed",
  "status_detail": "summarized",
  "source": "zoom",
  "kind": "live_meeting",
  "language": "he",
  "start_time": "2026-10-15T09:00:12.000Z",
  "end_time": "2026-10-15T09:47:40.000Z",
  "duration": 2848,
  "scheduled_start_time": "2026-10-15T09:00:00.000Z",
  "scheduled_end_time": "2026-10-15T10:00:00.000Z",
  "has_transcript": true,
  "has_recording": true,
  "has_summary": true,
  "summary_id": "summary_2b7d0c1e-8f9a-4b3c-9d2e-5f6a7b8c9d0e",
  "created_by_you": true,
  "app_url": "https://mesakem.com/dashboard/meeting/run_6f1c2a4e-0d3b-4e5f-9a7b-1c2d3e4f5a6b",
  "participants": [
    {
      "name": "Dana Levi",
      "email": "dana@acme.co.il",
      "company": "acme.co.il",
      "organizer": true
    }
  ],
  "created_at": "2026-10-15T08:58:01.000Z",
  "updated_at": "2026-10-15T09:52:18.000Z"
}
PATCH/meetings/{meeting_id}meetings:write

Rename a meeting

Needs meetings:write, which no preset includes: tick it explicitly. Only the meeting's owner.

Parameters
ParametersTypeNotes
meeting_id · requiredstringin path
Request body application/json
FieldTypeNotes
title · requiredstring | nullnull or "" restores the original title.up to 180 characters
curl -X PATCH "https://mesakem.com/api/v1/meetings/run_6f1c2a4e-0d3b-4e5f-9a7b-1c2d3e4f5a6b" \
  -H "Authorization: Bearer $MESAKEM_API_KEY" \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "Content-Type: application/json" \
  -d '{
    "title": "Discovery call — Acme (renamed)"
  }'
Example response
{
  "id": "run_6f1c2a4e-0d3b-4e5f-9a7b-1c2d3e4f5a6b",
  "object": "meeting",
  "title": "פגישת היכרות — אקמה (מעודכן)",
  "status": "completed"
}
DELETE/meetings/{meeting_id}→ 204 No Contentmeetings:write

Delete a meeting

Permanent for you, as in the dashboard (there is no restore). Needs meetings:write, which no preset includes. A meeting with a bot in it answers 409 meeting_in_progress: DELETE /meetings/{id}/bot first.

Parameters
ParametersTypeNotes
meeting_id · requiredstringin path
curl -X DELETE "https://mesakem.com/api/v1/meetings/run_6f1c2a4e-0d3b-4e5f-9a7b-1c2d3e4f5a6b" \
  -H "Authorization: Bearer $MESAKEM_API_KEY"
GET/meetings/{meeting_id}/participantsmeetings:read

Invitees, transcript speakers and (creator only) attendance

Parameters
ParametersTypeNotes
meeting_id · requiredstringin path
curl "https://mesakem.com/api/v1/meetings/run_6f1c2a4e-0d3b-4e5f-9a7b-1c2d3e4f5a6b/participants" \
  -H "Authorization: Bearer $MESAKEM_API_KEY"
Example response
{
  "object": "participants",
  "meeting_id": "run_6f1c2a4e-0d3b-4e5f-9a7b-1c2d3e4f5a6b",
  "invitees": [
    {
      "name": "Dana Levi",
      "email": "dana@acme.co.il",
      "organizer": true,
      "company": "acme.co.il"
    }
  ],
  "speakers": [
    {
      "id": "spk_1",
      "name": "Dana Levi"
    },
    {
      "id": "spk_2",
      "name": "דובר 1"
    }
  ],
  "attendance_available": false,
  "attendance": null
}
GET/meetings/{meeting_id}/transcripttranscripts:read

Transcript (json, text, vtt, srt)

format=json pages by segment (limit ≤ 2000, ≈512 KB per page). Text formats return the whole transcript. Supports If-None-Match → 304 with a version probe.

Parameters
ParametersTypeNotes
meeting_id · requiredstringin path
formatjson | text | vtt | srt
limitinteger (1–100)default 25
cursorstringnext_cursor from the previous page of the SAME request (same key and filters).
curl "https://mesakem.com/api/v1/meetings/run_6f1c2a4e-0d3b-4e5f-9a7b-1c2d3e4f5a6b/transcript?format=json&limit=500" \
  -H "Authorization: Bearer $MESAKEM_API_KEY"
Example response
{
  "object": "transcript",
  "meeting_id": "run_6f1c2a4e-0d3b-4e5f-9a7b-1c2d3e4f5a6b",
  "transcript_id": "transcript_7e6d5c4b-3a29-4180-9f8e-7d6c5b4a3928",
  "language": "he",
  "mode": "segments",
  "total_segments": 412,
  "speakers": [
    {
      "id": "spk_1",
      "name": "Dana Levi"
    },
    {
      "id": "spk_2",
      "name": "דובר 1"
    }
  ],
  "segments": [
    {
      "index": 0,
      "speaker_id": "spk_1",
      "start_time": 0.84,
      "end_time": 6.2,
      "text": "בוקר טוב, תודה שהצטרפתם."
    },
    {
      "index": 1,
      "speaker_id": "spk_2",
      "start_time": 6.4,
      "end_time": 11.03,
      "text": "שמחים להיות כאן."
    }
  ],
  "next_cursor": "eyJ2IjoxLCJwIjp7ImEiOjIsInQiOiJ0cmFuc2NyaXB0In19.Qz8xWv7uT6sR5qP4oN3mL2kJ1iH0gF9e",
  "has_more": true,
  "created_at": "2026-10-15T09:49:02.000Z"
}
GET/meetings/{meeting_id}/summarysummaries:read

Summary (json, markdown, html, text, docx)

Supports If-None-Match → 304 with a version probe.

Parameters
ParametersTypeNotes
meeting_id · requiredstringin path
formatjson | markdown | html | text | docx
curl "https://mesakem.com/api/v1/meetings/run_6f1c2a4e-0d3b-4e5f-9a7b-1c2d3e4f5a6b/summary?format=markdown" \
  -H "Authorization: Bearer $MESAKEM_API_KEY"
Example response
{
  "object": "summary",
  "id": "summary_2b7d0c1e-8f9a-4b3c-9d2e-5f6a7b8c9d0e",
  "meeting_id": "run_6f1c2a4e-0d3b-4e5f-9a7b-1c2d3e4f5a6b",
  "language": "he",
  "template": {
    "id": "system_detailed_mesakem",
    "name": "מפורט"
  },
  "title": "פגישת היכרות — אקמה",
  "overview": "סקרנו את הצרכים של אקמה ואת לוחות הזמנים.",
  "sections": [
    {
      "kind": "topic",
      "title": "תמחור",
      "body_markdown": "הוסכם לשלוח הצעה עד יום ראשון."
    }
  ],
  "action_items": [
    {
      "text": "לשלוח הצעת מחיר לאקמה"
    }
  ],
  "decisions": [
    {
      "text": "פיילוט של חודש"
    }
  ],
  "open_questions": [
    "מי מאשר את התקציב?"
  ],
  "citations": null,
  "body_markdown": "## תקציר\nסקרנו את הצרכים של אקמה…",
  "body_oversized": false,
  "meeting_description": null,
  "edited": false,
  "structured_stale": false,
  "structured_oversized": false,
  "documents": [
    {
      "id": "doc_sum_2b7d0c1e-8f9a-4b3c-9d2e-5f6a7b8c9d0e",
      "kind": "summary"
    }
  ],
  "created_at": "2026-10-15T09:52:18.000Z",
  "updated_at": "2026-10-15T09:52:18.000Z"
}
GET/meetings/{meeting_id}/recordingrecordings:read

A 5-minute recording link

The link re-checks the key when followed and then redirects to a short-lived storage URL.

Parameters
ParametersTypeNotes
meeting_id · requiredstringin path
curl "https://mesakem.com/api/v1/meetings/run_6f1c2a4e-0d3b-4e5f-9a7b-1c2d3e4f5a6b/recording" \
  -H "Authorization: Bearer $MESAKEM_API_KEY"
Example response
{
  "object": "recording_link",
  "meeting_id": "run_6f1c2a4e-0d3b-4e5f-9a7b-1c2d3e4f5a6b",
  "recording_id": "recording_0a1b2c3d-4e5f-4a6b-8c7d-9e0f1a2b3c4d",
  "status": "ready",
  "recording_url": "https://mesakem.com/api/v1/r/Zm9yLWV4YW1wbGUtb25seQ",
  "expires_at": "2026-10-17T08:05:00.000Z",
  "format": "mp4",
  "duration": 2848,
  "created_at": "2026-10-15T09:48:30.000Z"
}
PUT/meetings/upload→ 201 Createduploads:write

Upload a small recording in one request (≤ 4 MB)

The file is the request body; title and language go in the query.

Parameters
ParametersTypeNotes
titlestring
languagestringConversation language, e.g. he, en, auto.
summary_languagehe | en
categorymeeting | calldefault meeting
filenamestringNeeded for video/quicktime; otherwise derived from Content-Type.

Request body: the file itself. The audio or video file itself, at most 4 MB. Larger files: POST /uploads.

curl -X PUT "https://mesakem.com/api/v1/meetings/upload?title=Support+call&language=he" \
  -H "Authorization: Bearer $MESAKEM_API_KEY" \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "Content-Type: audio/mp4" \
  --data-binary @call.m4a
Example response · 201 Created
{
  "object": "upload",
  "id": "recjob_8a1b2c3d4e5f60718293a4b5c6d7e8f9",
  "meeting_id": "run_upload_8a1b2c3d4e5f60718293a4b5c6d7e8f9",
  "filename": "call.m4a",
  "content_type": "audio/mp4",
  "size_bytes": 3145728,
  "app_url": "https://mesakem.com/dashboard/meeting/run_upload_8a1b2c3d4e5f60718293a4b5c6d7e8f9",
  "created_at": "2026-10-18T09:00:00.000Z",
  "status": "processing",
  "upload_id": "recjob_8a1b2c3d4e5f60718293a4b5c6d7e8f9"
}
GET/meetings/{meeting_id}/permissionsshares:read

Who a meeting is shared with

Mesakem shares by public link only: the list holds perm_anyone or nothing.

Parameters
ParametersTypeNotes
meeting_id · requiredstringin path
curl "https://mesakem.com/api/v1/meetings/run_6f1c2a4e-0d3b-4e5f-9a7b-1c2d3e4f5a6b/permissions" \
  -H "Authorization: Bearer $MESAKEM_API_KEY"
Example response
{
  "object": "list",
  "data": [
    {
      "id": "perm_anyone",
      "object": "permission",
      "recipient": {
        "type": "anyone"
      },
      "role": "read",
      "status": "ready",
      "share_url": "https://mesakem.com/s#Zm9yLWV4YW1wbGU",
      "created_at": "2026-10-18T09:00:00.000Z"
    }
  ],
  "share_url": "https://mesakem.com/s#Zm9yLWV4YW1wbGU",
  "next_cursor": null,
  "has_more": false
}
POST/meetings/{meeting_id}/permissions→ 201 Createdshares:write

Create the meeting's public link

recipient {"type":"anyone"}, role read. user and team recipients answer 422 unsupported_recipient: members' meetings stay private.

Parameters
ParametersTypeNotes
meeting_id · requiredstringin path
Request body application/json
FieldTypeNotes
recipient · requiredobjectOnly anyone (a public, read-only link). user and team recipients answer 422 unsupported_recipient.
role"read"
curl -X POST "https://mesakem.com/api/v1/meetings/run_6f1c2a4e-0d3b-4e5f-9a7b-1c2d3e4f5a6b/permissions" \
  -H "Authorization: Bearer $MESAKEM_API_KEY" \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "Content-Type: application/json" \
  -d '{
    "recipient": {
      "type": "anyone"
    },
    "role": "read"
  }'
Example response · 201 Created
{
  "id": "perm_anyone",
  "object": "permission",
  "recipient": {
    "type": "anyone"
  },
  "role": "read",
  "status": "ready",
  "share_url": "https://mesakem.com/s#Zm9yLWV4YW1wbGU",
  "created_at": "2026-10-18T09:00:00.000Z"
}
DELETE/meetings/{meeting_id}/permissions/{permission_id}→ 204 No Contentshares:write

Revoke the public link

permission_id is perm_anyone. Idempotent.

Parameters
ParametersTypeNotes
meeting_id · requiredstringin path
permission_id · requiredstringin path
curl -X DELETE "https://mesakem.com/api/v1/meetings/run_6f1c2a4e-0d3b-4e5f-9a7b-1c2d3e4f5a6b/permissions/perm_anyone" \
  -H "Authorization: Bearer $MESAKEM_API_KEY"

Documents

GET/documents/{document_id}summaries:read

Get a document (summary, action items or decisions)

Ids: doc_sum_… (summary), doc_act_… (action items), doc_dec_… (decisions). docx content is base64.

Parameters
ParametersTypeNotes
document_id · requiredstringin path
formatjson | markdown | html | text | raw | docx
curl "https://mesakem.com/api/v1/documents/doc_sum_2b7d0c1e-8f9a-4b3c-9d2e-5f6a7b8c9d0e?format=markdown" \
  -H "Authorization: Bearer $MESAKEM_API_KEY"
Example response
{
  "id": "doc_act_2b7d0c1e-8f9a-4b3c-9d2e-5f6a7b8c9d0e",
  "object": "document",
  "kind": "action_items",
  "meeting_id": "run_6f1c2a4e-0d3b-4e5f-9a7b-1c2d3e4f5a6b",
  "title": "משימות",
  "format": "markdown",
  "language": "he",
  "content": "# משימות\n\n- לשלוח הצעת מחיר לאקמה\n",
  "created_at": "2026-10-15T09:52:18.000Z",
  "updated_at": "2026-10-15T09:52:18.000Z"
}

Tasks

GET/taskstasks:read

List your tasks

Parameters
ParametersTypeNotes
limitinteger (1–100)default 25
cursorstringnext_cursor from the previous page of the SAME request (same key and filters).
statusactive | all | open | in_progress | done | snoozed | delegated | cancelleddefault active
sourcemeeting_summary | manual | agent_chat | call_summary
meeting_idstring
updated_sincedate-time
due_afterdate-time
due_beforedate-time
orderrecent | updated
idsstringGET /tasks: 1 to 50 comma-separated task ids (any status). Only the ones your key can read come back.
qstringKeyword search: every word must match (prefix match for meetings). Needs search:read.
curl "https://mesakem.com/api/v1/tasks?status=active&limit=25" \
  -H "Authorization: Bearer $MESAKEM_API_KEY"
Example response
{
  "object": "list",
  "data": [
    {
      "id": "agent_task_5c1f9a2b",
      "object": "task",
      "privacy": "visible",
      "title": "לשלוח הצעת מחיר לאקמה",
      "description": null,
      "status": "open",
      "source": {
        "type": "meeting_summary",
        "meeting_id": "run_6f1c2a4e-0d3b-4e5f-9a7b-1c2d3e4f5a6b",
        "summary_id": "summary_2b7d0c1e-8f9a-4b3c-9d2e-5f6a7b8c9d0e"
      },
      "assignee": {
        "name": "Dana Levi",
        "email": "dana@acme.co.il"
      },
      "due_at": "2026-10-20T09:00:00.000Z",
      "snoozed_until": null,
      "items_count": 2,
      "app_url": "https://mesakem.com/dashboard/tasks",
      "created_at": "2026-10-15T09:52:20.000Z",
      "updated_at": "2026-10-16T07:10:00.000Z"
    }
  ],
  "next_cursor": null,
  "has_more": false
}
POST/tasks→ 201 Createdtasks:write

Create a task

Request body application/json
FieldTypeNotes
title · requiredstringup to 180 characters
descriptionstring | nullup to 4000 characters
statusstringone of: openin_progressdonesnoozeddelegatedcancelleddefault "open"
due_atdate-time | null
assigneeobject | null
itemsarray<string>Checklist rows.≤ 24 items
curl -X POST "https://mesakem.com/api/v1/tasks" \
  -H "Authorization: Bearer $MESAKEM_API_KEY" \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "Content-Type: application/json" \
  -d '{
    "title": "Send Acme the proposal",
    "due_at": "2026-10-20T09:00:00Z",
    "items": [
      "Confirm pricing with finance"
    ]
  }'
Example response · 201 Created
{
  "id": "agent_task_5c1f9a2b",
  "object": "task",
  "privacy": "visible",
  "title": "לשלוח הצעת מחיר לאקמה",
  "description": null,
  "status": "open",
  "source": {
    "type": "manual"
  },
  "assignee": {
    "name": "Dana Levi",
    "email": "dana@acme.co.il"
  },
  "due_at": "2026-10-20T09:00:00.000Z",
  "snoozed_until": null,
  "items_count": 1,
  "app_url": "https://mesakem.com/dashboard/tasks",
  "created_at": "2026-10-18T09:00:00.000Z",
  "updated_at": "2026-10-18T09:00:00.000Z",
  "description_oversized": false,
  "items": [
    {
      "id": "agent_task_item_1",
      "title": "לאשר תמחור מול הכספים",
      "completed": false,
      "position": 1000
    }
  ],
  "items_offset": 0,
  "items_has_more": false
}
GET/tasks/{task_id}tasks:read

Get a task with its checklist

Parameters
ParametersTypeNotes
task_id · requiredstringin path
items_limitinteger (1–100)With expand=meetings / calls.
items_offsetinteger (0–)default 0
curl "https://mesakem.com/api/v1/tasks/agent_task_5c1f9a2b?items_limit=100" \
  -H "Authorization: Bearer $MESAKEM_API_KEY"
Example response
{
  "id": "agent_task_5c1f9a2b",
  "object": "task",
  "privacy": "visible",
  "title": "לשלוח הצעת מחיר לאקמה",
  "description": null,
  "status": "open",
  "source": {
    "type": "meeting_summary",
    "meeting_id": "run_6f1c2a4e-0d3b-4e5f-9a7b-1c2d3e4f5a6b",
    "summary_id": "summary_2b7d0c1e-8f9a-4b3c-9d2e-5f6a7b8c9d0e"
  },
  "assignee": {
    "name": "Dana Levi",
    "email": "dana@acme.co.il"
  },
  "due_at": "2026-10-20T09:00:00.000Z",
  "snoozed_until": null,
  "items_count": 2,
  "app_url": "https://mesakem.com/dashboard/tasks",
  "created_at": "2026-10-15T09:52:20.000Z",
  "updated_at": "2026-10-16T07:10:00.000Z",
  "description_oversized": false,
  "items": [
    {
      "id": "agent_task_item_1",
      "title": "לאשר תמחור מול הכספים",
      "completed": true,
      "position": 1000
    },
    {
      "id": "agent_task_item_2",
      "title": "לשלוח ב-PDF",
      "completed": false,
      "position": 2000
    }
  ],
  "items_offset": 0,
  "items_has_more": false
}
PATCH/tasks/{task_id}tasks:write

Update a task (title, notes, status, due date, assignee)

Parameters
ParametersTypeNotes
task_id · requiredstringin path
Request body application/json
FieldTypeNotes
titlestringup to 180 characters
descriptionstring | nullup to 4000 characters
statusstringone of: openin_progressdonesnoozeddelegatedcancelled
due_atdate-time | null
assigneeobject | nullReplaces the assignee; null clears it.
curl -X PATCH "https://mesakem.com/api/v1/tasks/agent_task_5c1f9a2b" \
  -H "Authorization: Bearer $MESAKEM_API_KEY" \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "Content-Type: application/json" \
  -d '{
    "status": "done"
  }'
Example response
{
  "id": "agent_task_5c1f9a2b",
  "object": "task",
  "privacy": "visible",
  "title": "לשלוח הצעת מחיר לאקמה",
  "description": null,
  "status": "in_progress",
  "source": {
    "type": "manual"
  },
  "assignee": {
    "name": "Dana Levi",
    "email": "dana@acme.co.il"
  },
  "due_at": "2026-10-20T09:00:00.000Z",
  "snoozed_until": null,
  "items_count": 1,
  "app_url": "https://mesakem.com/dashboard/tasks",
  "created_at": "2026-10-18T09:00:00.000Z",
  "updated_at": "2026-10-18T09:00:00.000Z",
  "description_oversized": false,
  "items": [
    {
      "id": "agent_task_item_1",
      "title": "לאשר תמחור מול הכספים",
      "completed": false,
      "position": 1000
    }
  ],
  "items_offset": 0,
  "items_has_more": false
}
DELETE/tasks/{task_id}tasks:write

Cancel a task

Mesakem has no hard delete for tasks: the task is kept with status cancelled.

Parameters
ParametersTypeNotes
task_id · requiredstringin path
curl -X DELETE "https://mesakem.com/api/v1/tasks/agent_task_5c1f9a2b" \
  -H "Authorization: Bearer $MESAKEM_API_KEY"
Example response
{
  "id": "agent_task_5c1f9a2b",
  "object": "task",
  "privacy": "visible",
  "title": "לשלוח הצעת מחיר לאקמה",
  "description": null,
  "status": "cancelled",
  "source": {
    "type": "manual"
  },
  "assignee": {
    "name": "Dana Levi",
    "email": "dana@acme.co.il"
  },
  "due_at": "2026-10-20T09:00:00.000Z",
  "snoozed_until": null,
  "items_count": 1,
  "app_url": "https://mesakem.com/dashboard/tasks",
  "created_at": "2026-10-18T09:00:00.000Z",
  "updated_at": "2026-10-18T09:00:00.000Z",
  "description_oversized": false,
  "items": [
    {
      "id": "agent_task_item_1",
      "title": "לאשר תמחור מול הכספים",
      "completed": false,
      "position": 1000
    }
  ],
  "items_offset": 0,
  "items_has_more": false
}
POST/tasks/{task_id}/items→ 201 Createdtasks:write

Add a checklist row

Parameters
ParametersTypeNotes
task_id · requiredstringin path
Request body application/json
FieldTypeNotes
title · requiredstringup to 180 characters
curl -X POST "https://mesakem.com/api/v1/tasks/agent_task_5c1f9a2b/items" \
  -H "Authorization: Bearer $MESAKEM_API_KEY" \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "Content-Type: application/json" \
  -d '{
    "title": "Attach the PDF"
  }'
Example response · 201 Created
{
  "id": "agent_task_5c1f9a2b",
  "object": "task",
  "privacy": "visible",
  "title": "לשלוח הצעת מחיר לאקמה",
  "description": null,
  "status": "open",
  "source": {
    "type": "manual"
  },
  "assignee": {
    "name": "Dana Levi",
    "email": "dana@acme.co.il"
  },
  "due_at": "2026-10-20T09:00:00.000Z",
  "snoozed_until": null,
  "items_count": 2,
  "app_url": "https://mesakem.com/dashboard/tasks",
  "created_at": "2026-10-18T09:00:00.000Z",
  "updated_at": "2026-10-18T09:00:00.000Z",
  "description_oversized": false,
  "items": [
    {
      "id": "agent_task_item_1",
      "title": "לאשר תמחור מול הכספים",
      "completed": false,
      "position": 1000
    },
    {
      "id": "agent_task_item_2",
      "title": "לשלוח ב-PDF",
      "completed": false,
      "position": 2000
    }
  ],
  "items_offset": 0,
  "items_has_more": false,
  "item": {
    "id": "agent_task_item_2",
    "title": "לשלוח ב-PDF",
    "completed": false,
    "position": 2000
  }
}
PATCH/tasks/{task_id}/items/{item_id}tasks:write

Tick or untick a checklist row

Parameters
ParametersTypeNotes
task_id · requiredstringin path
item_id · requiredstringin path
Request body application/json
FieldTypeNotes
completed · requiredboolean
curl -X PATCH "https://mesakem.com/api/v1/tasks/agent_task_5c1f9a2b/items/agent_task_item_2" \
  -H "Authorization: Bearer $MESAKEM_API_KEY" \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "Content-Type: application/json" \
  -d '{
    "completed": true
  }'
Example response
{
  "id": "agent_task_5c1f9a2b",
  "object": "task",
  "privacy": "visible",
  "title": "לשלוח הצעת מחיר לאקמה",
  "description": null,
  "status": "open",
  "source": {
    "type": "manual"
  },
  "assignee": {
    "name": "Dana Levi",
    "email": "dana@acme.co.il"
  },
  "due_at": "2026-10-20T09:00:00.000Z",
  "snoozed_until": null,
  "items_count": 1,
  "app_url": "https://mesakem.com/dashboard/tasks",
  "created_at": "2026-10-18T09:00:00.000Z",
  "updated_at": "2026-10-18T09:00:00.000Z",
  "description_oversized": false,
  "items": [
    {
      "id": "agent_task_item_1",
      "title": "לאשר תמחור מול הכספים",
      "completed": true,
      "position": 1000
    }
  ],
  "items_offset": 0,
  "items_has_more": false,
  "item": {
    "id": "agent_task_item_1",
    "title": "לאשר תמחור מול הכספים",
    "completed": true,
    "position": 1000
  }
}
DELETE/tasks/{task_id}/items/{item_id}→ 204 No Contenttasks:write

Remove a checklist row

Parameters
ParametersTypeNotes
task_id · requiredstringin path
item_id · requiredstringin path
curl -X DELETE "https://mesakem.com/api/v1/tasks/agent_task_5c1f9a2b/items/agent_task_item_2" \
  -H "Authorization: Bearer $MESAKEM_API_KEY"

Team

GET/team/membersteam:read

Organization team members (organization owners and admins)

Personal workspaces return an empty list and team_id null. An organization key (msk_org_…, created in the organization dashboard) lists every active member of its organization.

Parameters
ParametersTypeNotes
limitinteger (1–100)default 25
cursorstringnext_cursor from the previous page of the SAME request (same key and filters).
curl "https://mesakem.com/api/v1/team/members?limit=25" \
  -H "Authorization: Bearer $MESAKEM_API_KEY"
Example response
{
  "object": "list",
  "team_id": "org_5e4d3c2b",
  "data": [
    {
      "id": "user_1f2e3d4c",
      "name": "Noa Cohen",
      "email": "noa@acme.co.il",
      "role": "member"
    }
  ],
  "next_cursor": null,
  "has_more": false
}

Webhooks

GET/webhookswebhooks:read

List your webhook endpoints

curl "https://mesakem.com/api/v1/webhooks" \
  -H "Authorization: Bearer $MESAKEM_API_KEY"
Example response
{
  "object": "list",
  "data": [
    {
      "object": "webhook_endpoint",
      "id": "whk_3c2b1a0f9e8d7c6b5a493827161504f3",
      "url": "https://hooks.acme.co.il/mesakem",
      "description": "CRM sync",
      "events": [
        "summary.ready",
        "action_items.created",
        "meeting.deleted"
      ],
      "filters": {},
      "signature_format": "standard",
      "enabled": true,
      "status": "healthy",
      "disabled_reason": null,
      "disabled_at": null,
      "secret_hint": "Qx9k",
      "secret_rotation_ends_at": null,
      "failure_streak": 0,
      "last_attempt_at": "2026-10-18T09:52:21.000Z",
      "last_success_at": "2026-10-18T09:52:21.000Z",
      "last_status": 200,
      "created_at": "2026-10-18T08:00:00.000Z",
      "updated_at": "2026-10-18T08:00:00.000Z"
    }
  ],
  "limit": 10,
  "has_more": false,
  "next_cursor": null
}
POST/webhooks→ 201 Createdwebhooks:write

Create a webhook endpoint

Returns the signing secret (whsec_…) once. The URL must be https on a public host; private, loopback and metadata addresses are refused, now and on every delivery.

Request body application/json
FieldTypeNotes
url · requiredurihttps only, port 443 or 8443, a public host.up to 2048 characters
events · requiredarray<string>1–64 itemsevent names or alternate names — see the catalog
descriptionstringup to 200 characters
filters.sourcesarray<string>Only meetings from these sources (the meeting source field).one of: google_meetzoomteamsphoneuploaddesktopemailunknown
filters.room_idsarray<string>Only meetings in, and events of, these rooms.≤ 50 items
signature_formatstandard | simple_hmacsimple_hmac also sends the X-Webhook-Signature header, for receivers that cannot verify Standard Webhooks.default "standard"
enabledbooleandefault true
curl -X POST "https://mesakem.com/api/v1/webhooks" \
  -H "Authorization: Bearer $MESAKEM_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://hooks.example.com/mesakem",
    "events": [
      "summary.ready",
      "action_items.created",
      "meeting.deleted"
    ],
    "description": "CRM sync"
  }'
Example response · 201 Created
{
  "object": "webhook_endpoint",
  "id": "whk_3c2b1a0f9e8d7c6b5a493827161504f3",
  "url": "https://hooks.acme.co.il/mesakem",
  "description": "CRM sync",
  "events": [
    "summary.ready",
    "action_items.created",
    "meeting.deleted"
  ],
  "filters": {},
  "signature_format": "standard",
  "enabled": true,
  "status": "healthy",
  "disabled_reason": null,
  "disabled_at": null,
  "secret_hint": "Qx9k",
  "secret_rotation_ends_at": null,
  "failure_streak": 0,
  "last_attempt_at": "2026-10-18T09:52:21.000Z",
  "last_success_at": "2026-10-18T09:52:21.000Z",
  "last_status": 200,
  "created_at": "2026-10-18T08:00:00.000Z",
  "updated_at": "2026-10-18T08:00:00.000Z",
  "secret": "whsec_MfKQ9r8GKYqrTwjUPD8ILPZIo2LaLaSw"
}
GET/webhooks/{endpoint_id}webhooks:read

Get a webhook endpoint

Parameters
ParametersTypeNotes
endpoint_id · requiredstringin path
curl "https://mesakem.com/api/v1/webhooks/whk_3c2b1a0f9e8d7c6b5a493827161504f3" \
  -H "Authorization: Bearer $MESAKEM_API_KEY"
Example response
{
  "object": "webhook_endpoint",
  "id": "whk_3c2b1a0f9e8d7c6b5a493827161504f3",
  "url": "https://hooks.acme.co.il/mesakem",
  "description": "CRM sync",
  "events": [
    "summary.ready",
    "action_items.created",
    "meeting.deleted"
  ],
  "filters": {},
  "signature_format": "standard",
  "enabled": true,
  "status": "healthy",
  "disabled_reason": null,
  "disabled_at": null,
  "secret_hint": "Qx9k",
  "secret_rotation_ends_at": null,
  "failure_streak": 0,
  "last_attempt_at": "2026-10-18T09:52:21.000Z",
  "last_success_at": "2026-10-18T09:52:21.000Z",
  "last_status": 200,
  "created_at": "2026-10-18T08:00:00.000Z",
  "updated_at": "2026-10-18T08:00:00.000Z"
}
PATCH/webhooks/{endpoint_id}webhooks:write

Change a webhook endpoint

Send only the fields to change. enabled=true re-enables an endpoint disabled after failures.

Parameters
ParametersTypeNotes
endpoint_id · requiredstringin path
Request body application/json · send at least one field
FieldTypeNotes
urluriup to 2048 characters
eventsarray<string>1–64 itemsevent names or alternate names — see the catalog
descriptionstring | nullup to 200 characters
filters.sourcesarray<string>Only meetings from these sources (the meeting source field).one of: google_meetzoomteamsphoneuploaddesktopemailunknown
filters.room_idsarray<string>Only meetings in, and events of, these rooms.≤ 50 items
signature_formatstandard | simple_hmac
enabledbooleantrue re-enables an endpoint disabled after failures and resets its failure count.
curl -X PATCH "https://mesakem.com/api/v1/webhooks/whk_3c2b1a0f9e8d7c6b5a493827161504f3" \
  -H "Authorization: Bearer $MESAKEM_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "events": [
      "summary.ready",
      "summary.updated",
      "meeting.deleted"
    ],
    "enabled": true
  }'
Example response
{
  "object": "webhook_endpoint",
  "id": "whk_3c2b1a0f9e8d7c6b5a493827161504f3",
  "url": "https://hooks.acme.co.il/mesakem",
  "description": "CRM sync (v2)",
  "events": [
    "summary.ready",
    "action_items.created",
    "meeting.deleted"
  ],
  "filters": {},
  "signature_format": "standard",
  "enabled": true,
  "status": "healthy",
  "disabled_reason": null,
  "disabled_at": null,
  "secret_hint": "Qx9k",
  "secret_rotation_ends_at": null,
  "failure_streak": 0,
  "last_attempt_at": "2026-10-18T09:52:21.000Z",
  "last_success_at": "2026-10-18T09:52:21.000Z",
  "last_status": 200,
  "created_at": "2026-10-18T08:00:00.000Z",
  "updated_at": "2026-10-18T10:00:00.000Z"
}
DELETE/webhooks/{endpoint_id}webhooks:write

Delete a webhook endpoint

Its pending deliveries are dropped.

Parameters
ParametersTypeNotes
endpoint_id · requiredstringin path
curl -X DELETE "https://mesakem.com/api/v1/webhooks/whk_3c2b1a0f9e8d7c6b5a493827161504f3" \
  -H "Authorization: Bearer $MESAKEM_API_KEY"
Example response
{
  "object": "webhook_endpoint",
  "id": "whk_3c2b1a0f9e8d7c6b5a493827161504f3",
  "deleted": true
}
POST/webhooks/{endpoint_id}/rotate-secretwebhooks:write

Rotate the signing secret

The new secret signs at once; for 24 hours deliveries carry both signatures, so you can switch without downtime.

Parameters
ParametersTypeNotes
endpoint_id · requiredstringin path
curl -X POST "https://mesakem.com/api/v1/webhooks/whk_3c2b1a0f9e8d7c6b5a493827161504f3/rotate-secret" \
  -H "Authorization: Bearer $MESAKEM_API_KEY"
Example response
{
  "object": "webhook_endpoint",
  "id": "whk_3c2b1a0f9e8d7c6b5a493827161504f3",
  "url": "https://hooks.acme.co.il/mesakem",
  "description": "CRM sync",
  "events": [
    "summary.ready",
    "action_items.created",
    "meeting.deleted"
  ],
  "filters": {},
  "signature_format": "standard",
  "enabled": true,
  "status": "healthy",
  "disabled_reason": null,
  "disabled_at": null,
  "secret_hint": "Lm3p",
  "secret_rotation_ends_at": "2026-10-19T10:00:00.000Z",
  "failure_streak": 0,
  "last_attempt_at": "2026-10-18T09:52:21.000Z",
  "last_success_at": "2026-10-18T09:52:21.000Z",
  "last_status": 200,
  "created_at": "2026-10-18T08:00:00.000Z",
  "updated_at": "2026-10-18T08:00:00.000Z",
  "secret": "whsec_Lm3pZx8rW2vT6yQ1nB5kD9fH4jS7aC0eG2iK"
}
POST/webhooks/{endpoint_id}/testwebhooks:write

Send a test event now

Sends webhook.test synchronously and returns your endpoint's status, latency and the first 512 bytes of its answer. Nothing is stored.

Parameters
ParametersTypeNotes
endpoint_id · requiredstringin path
curl -X POST "https://mesakem.com/api/v1/webhooks/whk_3c2b1a0f9e8d7c6b5a493827161504f3/test" \
  -H "Authorization: Bearer $MESAKEM_API_KEY"
Example response
{
  "object": "webhook_test",
  "endpoint_id": "whk_3c2b1a0f9e8d7c6b5a493827161504f3",
  "message_id": "msg_0f1e2d3c4b5a69788796a5b4c3d2e1f0",
  "delivered": true,
  "status": 200,
  "latency_ms": 162,
  "error": null,
  "response_snippet": "ok"
}
GET/webhooks/{endpoint_id}/deliverieswebhooks:read

Delivery log (last 30 days)

Newest first. Each row is one delivery with its latest attempt.

Parameters
ParametersTypeNotes
endpoint_id · requiredstringin path
limitinteger (1–100)default 25
cursorstringnext_cursor from the previous page of the SAME request (same key and filters).
curl "https://mesakem.com/api/v1/webhooks/whk_3c2b1a0f9e8d7c6b5a493827161504f3/deliveries?limit=25" \
  -H "Authorization: Bearer $MESAKEM_API_KEY"
Example response
{
  "object": "list",
  "data": [
    {
      "object": "webhook_delivery",
      "id": "whd_9f8e7d6c5b4a39281706f5e4d3c2b1a0",
      "endpoint_id": "whk_3c2b1a0f9e8d7c6b5a493827161504f3",
      "event_id": "msg_1a2b3c4d5e6f708192a3b4c5d6e7f809",
      "type": "summary.ready",
      "state": "succeeded",
      "attempt": 1,
      "max_attempts": 9,
      "last_status": 200,
      "last_error": null,
      "latency_ms": 184,
      "next_attempt_at": null,
      "response_snippet": "{\"ok\":true}",
      "redelivery_of": null,
      "created_at": "2026-10-18T09:52:20.000Z",
      "completed_at": "2026-10-18T09:52:21.000Z"
    },
    {
      "object": "webhook_delivery",
      "id": "whd_0a1b2c3d4e5f60718293a4b5c6d7e8f9",
      "endpoint_id": "whk_3c2b1a0f9e8d7c6b5a493827161504f3",
      "event_id": "msg_1a2b3c4d5e6f708192a3b4c5d6e7f809",
      "type": "meeting.ended",
      "state": "retry_scheduled",
      "attempt": 3,
      "max_attempts": 9,
      "last_status": 503,
      "last_error": "http_503",
      "latency_ms": 10000,
      "next_attempt_at": "2026-10-18T09:58:00.000Z",
      "response_snippet": "Service Unavailable",
      "redelivery_of": null,
      "created_at": "2026-10-18T09:52:20.000Z",
      "completed_at": null
    }
  ],
  "has_more": false,
  "next_cursor": null
}
POST/webhooks/{endpoint_id}/deliveries/{delivery_id}/redeliver→ 202 Acceptedwebhooks:write

Redeliver

A new attempt series for a finished delivery, with the same webhook-id (dedupe on it).

Parameters
ParametersTypeNotes
endpoint_id · requiredstringin path
delivery_id · requiredstringin path
curl -X POST "https://mesakem.com/api/v1/webhooks/whk_3c2b1a0f9e8d7c6b5a493827161504f3/deliveries/whd_9f8e7d6c5b4a39281706f5e4d3c2b1a0/redeliver" \
  -H "Authorization: Bearer $MESAKEM_API_KEY"
Example response · 202 Accepted
{
  "object": "webhook_delivery",
  "id": "whd_5e4d3c2b1a0f9e8d7c6b5a4938271605",
  "endpoint_id": "whk_3c2b1a0f9e8d7c6b5a493827161504f3",
  "event_id": "msg_1a2b3c4d5e6f708192a3b4c5d6e7f809",
  "type": "summary.ready",
  "state": "pending",
  "attempt": 0,
  "max_attempts": 9,
  "last_status": null,
  "last_error": null,
  "latency_ms": null,
  "next_attempt_at": null,
  "response_snippet": null,
  "redelivery_of": "whd_9f8e7d6c5b4a39281706f5e4d3c2b1a0",
  "created_at": "2026-10-18T11:00:00.000Z",
  "completed_at": null
}
GET/webhook-event-typeswebhooks:read

The event catalog

Every event type, its alternate name (if any) and payload fields, with Hebrew and English descriptions.

curl "https://mesakem.com/api/v1/webhook-event-types" \
  -H "Authorization: Bearer $MESAKEM_API_KEY"
Example response
{
  "object": "list",
  "data": [
    {
      "object": "webhook_event_type",
      "type": "meeting.scheduled",
      "alias": null,
      "group": "meetings",
      "data_object": "meeting",
      "fields": [
        "meeting_id",
        "source",
        "scheduled_start_time",
        "title"
      ],
      "description": "A meeting was scheduled for the notetaker (calendar, link or manual).",
      "description_he": "פגישה נקבעה לבוט (מהיומן, מקישור או ידנית).",
      "description_en": "A meeting was scheduled for the notetaker (calendar, link or manual)."
    },
    {
      "object": "webhook_event_type",
      "type": "meeting.bot_status_changed",
      "alias": null,
      "group": "meetings",
      "data_object": "meeting",
      "fields": [
        "meeting_id",
        "bot_status",
        "previous_status"
      ],
      "description": "The notetaker is joining, waiting in the lobby, was not admitted or was removed.",
      "description_he": "הבוט מצטרף, ממתין בלובי, לא אושר או הוצא מהפגישה.",
      "description_en": "The notetaker is joining, waiting in the lobby, was not admitted or was removed."
    }
  ],
  "has_more": false,
  "next_cursor": null
}

The bot

POST/meetings/bot→ 202 Acceptedbot:write

Send the bot to a meeting link

Needs bot:write on a paid plan. Hard limits per user and per work area (minute, hour, day) protect against runaway costs; the plan's meeting quota applies. A meeting that already has a Mesakem bot answers 409 meeting_bot_already_active with that meeting's meeting_id. Send an Idempotency-Key so a retry never sends a second bot.

Request body application/json
FieldTypeNotes
meeting_url · requiredstringA Zoom, Google Meet or Microsoft Teams link (a pasted invitation works too).up to 1024 characters
titlestringup to 180 characters
languagestringConversation language, e.g. he, en, auto. Default: the key owner's saved bot language.
summary_languagehe | en
summary_recipient_emailemailA verified summary recipient of the work area. Default: the key owner, else the default recipient.
start_timedate-timeJoin at this time instead of now (at most 60 days ahead).
end_timedate-time
curl -X POST "https://mesakem.com/api/v1/meetings/bot" \
  -H "Authorization: Bearer $MESAKEM_API_KEY" \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "Content-Type: application/json" \
  -d '{
    "meeting_url": "https://zoom.us/j/1234567890?pwd=abc123",
    "title": "Discovery call — Acme"
  }'
Example response · 202 Accepted
{
  "object": "bot_dispatch",
  "meeting_id": "run_6f1c2a4e-0d3b-4e5f-9a7b-1c2d3e4f5a6b",
  "status": "scheduling",
  "status_detail": "queued",
  "scheduled_start_time": null,
  "app_url": "https://mesakem.com/dashboard/meeting/run_6f1c2a4e-0d3b-4e5f-9a7b-1c2d3e4f5a6b"
}
POST/meetings/{meeting_id}/bot→ 202 Acceptedbot:write

Schedule the bot for an upcoming calendar meeting

event_id is the cal_evt_… id from GET /meetings/upcoming. The same switch as "join" on the dashboard's calendar.

Parameters
ParametersTypeNotes
meeting_id · requiredstringin path
Request body application/json
FieldTypeNotes
apply_to_seriesbooleanAlso join every future meeting of this recurring series.default false
curl -X POST "https://mesakem.com/api/v1/meetings/cal_evt_Qm9pZ2h0LXNlcmllcy0x/bot" \
  -H "Authorization: Bearer $MESAKEM_API_KEY" \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "Content-Type: application/json" \
  -d '{
    "apply_to_series": false
  }'
Example response · 202 Accepted
{
  "object": "bot_schedule",
  "event_id": "cal_evt_Qm9pZ2h0LXNlcmllcy0x",
  "status": "scheduling",
  "meeting_id": "run_6f1c2a4e-0d3b-4e5f-9a7b-1c2d3e4f5a6b",
  "admission": {
    "accepted": true,
    "reason": null
  },
  "apply_to_series": false,
  "start_time": "2026-10-20T07:00:00.000Z"
}
DELETE/meetings/{meeting_id}/bot→ 202 Acceptedbot:write

Cancel the bot for a calendar meeting, or make it leave a call

cal_evt_…: the bot will not join (the dashboard's "skip"). run_…: the bot in the call leaves now; the recording so far is transcribed and summarized as usual. Only the meeting's owner.

Parameters
ParametersTypeNotes
meeting_id · requiredstringin path
apply_to_seriestrue | falsecal_evt_… only: also skip every future meeting of the series.
curl -X DELETE "https://mesakem.com/api/v1/meetings/cal_evt_Qm9pZ2h0LXNlcmllcy0x/bot" \
  -H "Authorization: Bearer $MESAKEM_API_KEY"
Example response · 202 Accepted
{
  "object": "bot_schedule",
  "event_id": "cal_evt_Qm9pZ2h0LXNlcmllcy0x",
  "status": "cancelling",
  "cancelled_meetings": 1,
  "apply_to_series": false
}

Auto-join settings

GET/settings/notetaker-automationsettings:read

Calendar auto-join mode

curl "https://mesakem.com/api/v1/settings/notetaker-automation" \
  -H "Authorization: Bearer $MESAKEM_API_KEY"
Example response
{
  "object": "notetaker_automation",
  "automation": "JOIN_AS_HOST",
  "allowed": true
}
PUT/settings/notetaker-automationsettings:write

Set the calendar auto-join mode

MANUAL: never automatically. JOIN_ALL_EVENTS: every meeting with a supported link. JOIN_EXTERNAL_ONLY: only meetings with people outside your domain. JOIN_AS_HOST: only meetings you organize.

Request body application/json
FieldTypeNotes
automation · requiredMANUAL | JOIN_ALL_EVENTS | JOIN_EXTERNAL_ONLY | JOIN_AS_HOST
curl -X PUT "https://mesakem.com/api/v1/settings/notetaker-automation" \
  -H "Authorization: Bearer $MESAKEM_API_KEY" \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "Content-Type: application/json" \
  -d '{
    "automation": "JOIN_AS_HOST"
  }'
Example response
{
  "object": "notetaker_automation",
  "automation": "JOIN_EXTERNAL_ONLY",
  "allowed": true
}

Uploads

POST/uploads→ 201 Createduploads:write

Start an upload (presigned PUT, up to 200 MB)

PUT the file to upload.url with the given headers, then call POST /uploads/{upload_id}/complete. At most 3 uploads in progress at a time.

Request body application/json
FieldTypeNotes
filename · requiredstringExtension mp3, wav, m4a, mp4 or webm.up to 180 characters
content_type · requiredstringone of: audio/mpegaudio/mp3audio/wavaudio/x-wavaudio/mp4audio/m4aaudio/x-m4aaudio/aacaudio/webmvideo/mp4video/webmvideo/quicktime
size_bytes · requiredintegerExact size; at most 200 MB unless configured otherwise.
titlestringup to 180 characters
languagestring
summary_languagehe | en
categorymeeting | calldefault "meeting"
curl -X POST "https://mesakem.com/api/v1/uploads" \
  -H "Authorization: Bearer $MESAKEM_API_KEY" \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "Content-Type: application/json" \
  -d '{
    "filename": "call.m4a",
    "content_type": "audio/mp4",
    "size_bytes": 3145728,
    "language": "he"
  }'
Example response · 201 Created
{
  "object": "upload",
  "id": "recjob_8a1b2c3d4e5f60718293a4b5c6d7e8f9",
  "meeting_id": "run_upload_8a1b2c3d4e5f60718293a4b5c6d7e8f9",
  "filename": "call.m4a",
  "content_type": "audio/mp4",
  "size_bytes": 3145728,
  "app_url": "https://mesakem.com/dashboard/meeting/run_upload_8a1b2c3d4e5f60718293a4b5c6d7e8f9",
  "created_at": "2026-10-18T09:00:00.000Z",
  "status": "awaiting_upload",
  "upload": {
    "url": "https://storage.example/uploaded-recordings/…?X-Amz-Signature=…",
    "method": "PUT",
    "headers": {
      "content-type": "audio/mp4",
      "content-length": "3145728"
    },
    "expires_at": "2026-10-18T09:15:00.000Z"
  }
}
POST/uploads/{upload_id}/complete→ 202 Accepteduploads:write

Finish an upload

Checks the stored file's size and type, then queues transcription and the summary.

Parameters
ParametersTypeNotes
upload_id · requiredstringin path
Request body application/json
FieldTypeNotes
size_bytesintegerDefault: the size declared at POST /uploads.
curl -X POST "https://mesakem.com/api/v1/uploads/recjob_8a1b2c3d4e5f60718293a4b5c6d7e8f9/complete" \
  -H "Authorization: Bearer $MESAKEM_API_KEY" \
  -H "Idempotency-Key: $(uuidgen)"
Example response · 202 Accepted
{
  "object": "upload",
  "id": "recjob_8a1b2c3d4e5f60718293a4b5c6d7e8f9",
  "meeting_id": "run_upload_8a1b2c3d4e5f60718293a4b5c6d7e8f9",
  "filename": "call.m4a",
  "content_type": "audio/mp4",
  "size_bytes": 3145728,
  "app_url": "https://mesakem.com/dashboard/meeting/run_upload_8a1b2c3d4e5f60718293a4b5c6d7e8f9",
  "created_at": "2026-10-18T09:00:00.000Z",
  "status": "processing"
}
GET/uploads/{upload_id}meetings:read

Get an upload

The object upload.failed names: status and error code. The uploader only.

Parameters
ParametersTypeNotes
upload_id · requiredstringin path
curl "https://mesakem.com/api/v1/uploads/recjob_8a1b2c3d4e5f60718293a4b5c6d7e8f9" \
  -H "Authorization: Bearer $MESAKEM_API_KEY"
Example response
{
  "object": "upload",
  "id": "recjob_8a1b2c3d4e5f60718293a4b5c6d7e8f9",
  "meeting_id": "run_6f1c2a4e-0d3b-4e5f-9a7b-1c2d3e4f5a6b",
  "status": "failed",
  "category": "meeting",
  "filename": "interview.m4a",
  "content_type": "audio/mp4",
  "size_bytes": 18234567,
  "duration": null,
  "error_code": "transcription_failed",
  "app_url": "https://mesakem.com/dashboard/meeting/run_6f1c2a4e-0d3b-4e5f-9a7b-1c2d3e4f5a6b",
  "created_at": "2026-10-16T09:00:00.000Z",
  "updated_at": "2026-10-16T09:04:00.000Z"
}

Rooms

GET/roomsrooms:read

List rooms

Your rooms and the work area's shared rooms; another member's private room is never listed. Counts include only items you can read.

Parameters
ParametersTypeNotes
limitinteger (1–100)default 25
cursorstringnext_cursor from the previous page of the SAME request (same key and filters).
archivedtrue | falsedefault false
searchstringRoom name, description or client name contains this (case-insensitive).
curl "https://mesakem.com/api/v1/rooms?limit=25" \
  -H "Authorization: Bearer $MESAKEM_API_KEY"
Example response
{
  "object": "list",
  "data": [
    {
      "id": "room_3c2b1a09-8f7e-4d6c-9b5a-4f3e2d1c0b9a",
      "object": "room",
      "name": "אקמה — פיילוט",
      "description": "כל הפגישות עם אקמה",
      "client_name": "Acme",
      "keywords": [
        "אקמה",
        "פיילוט"
      ],
      "visibility": "private",
      "archived": false,
      "created_by_you": true,
      "meeting_count": 4,
      "call_count": 1,
      "last_activity_at": "2026-10-16T10:00:00.000Z",
      "app_url": "https://mesakem.com/dashboard/rooms/room_3c2b1a09-8f7e-4d6c-9b5a-4f3e2d1c0b9a",
      "created_at": "2026-09-01T08:00:00.000Z",
      "updated_at": "2026-10-16T10:00:00.000Z"
    }
  ],
  "next_cursor": null,
  "has_more": false
}
POST/rooms→ 201 Createdrooms:write

Create a room

Request body application/json
FieldTypeNotes
name · requiredstringThe room's name (title is accepted as the same field).up to 120 characters
titlestringSame as name.up to 120 characters
descriptionstring | nullup to 4000 characters
client_namestring | nullup to 200 characters
keywordsarray<string>≤ 100 items
curl -X POST "https://mesakem.com/api/v1/rooms" \
  -H "Authorization: Bearer $MESAKEM_API_KEY" \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Acme pilot",
    "client_name": "Acme"
  }'
Example response · 201 Created
{
  "id": "room_3c2b1a09-8f7e-4d6c-9b5a-4f3e2d1c0b9a",
  "object": "room",
  "name": "אקמה — פיילוט",
  "description": "כל הפגישות עם אקמה",
  "client_name": "Acme",
  "keywords": [
    "אקמה",
    "פיילוט"
  ],
  "visibility": "private",
  "archived": false,
  "created_by_you": true,
  "meeting_count": 0,
  "call_count": 0,
  "last_activity_at": "2026-10-16T10:00:00.000Z",
  "app_url": "https://mesakem.com/dashboard/rooms/room_3c2b1a09-8f7e-4d6c-9b5a-4f3e2d1c0b9a",
  "created_at": "2026-09-01T08:00:00.000Z",
  "updated_at": "2026-10-16T10:00:00.000Z"
}
GET/rooms/{room_id}rooms:read

Get a room

expand=meetings,calls lists its items (newest added first).

Parameters
ParametersTypeNotes
room_id · requiredstringin path
expandstringComma-separated: participants, documents.
items_limitinteger (1–100)With expand=meetings / calls.
curl "https://mesakem.com/api/v1/rooms/room_3c2b1a09-8f7e-4d6c-9b5a-4f3e2d1c0b9a?expand=meetings" \
  -H "Authorization: Bearer $MESAKEM_API_KEY"
Example response
{
  "id": "room_3c2b1a09-8f7e-4d6c-9b5a-4f3e2d1c0b9a",
  "object": "room",
  "name": "אקמה — פיילוט",
  "description": "כל הפגישות עם אקמה",
  "client_name": "Acme",
  "keywords": [
    "אקמה",
    "פיילוט"
  ],
  "visibility": "private",
  "archived": false,
  "created_by_you": true,
  "meeting_count": 4,
  "call_count": 1,
  "last_activity_at": "2026-10-16T10:00:00.000Z",
  "app_url": "https://mesakem.com/dashboard/rooms/room_3c2b1a09-8f7e-4d6c-9b5a-4f3e2d1c0b9a",
  "created_at": "2026-09-01T08:00:00.000Z",
  "updated_at": "2026-10-16T10:00:00.000Z",
  "meetings": [
    {
      "id": "run_6f1c2a4e-0d3b-4e5f-9a7b-1c2d3e4f5a6b",
      "object": "meeting",
      "title": "פגישת היכרות — אקמה",
      "status": "completed",
      "source": "zoom",
      "start_time": "2026-10-15T09:00:12.000Z",
      "added_at": "2026-10-15T10:00:00.000Z"
    }
  ],
  "meetings_has_more": false
}
PATCH/rooms/{room_id}rooms:write

Update a room (name, description, client, keywords, archive)

Parameters
ParametersTypeNotes
room_id · requiredstringin path
Request body application/json
FieldTypeNotes
namestringThe room's name (title is accepted as the same field).up to 120 characters
titlestringSame as name.up to 120 characters
descriptionstring | nullup to 4000 characters
client_namestring | nullup to 200 characters
keywordsarray<string>≤ 100 items
archivedbooleantrue archives, false restores.
curl -X PATCH "https://mesakem.com/api/v1/rooms/room_3c2b1a09-8f7e-4d6c-9b5a-4f3e2d1c0b9a" \
  -H "Authorization: Bearer $MESAKEM_API_KEY" \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Acme — customer"
  }'
Example response
{
  "id": "room_3c2b1a09-8f7e-4d6c-9b5a-4f3e2d1c0b9a",
  "object": "room",
  "name": "אקמה — לקוח",
  "description": "כל הפגישות עם אקמה",
  "client_name": "Acme",
  "keywords": [
    "אקמה",
    "פיילוט"
  ],
  "visibility": "private",
  "archived": false,
  "created_by_you": true,
  "meeting_count": 4,
  "call_count": 1,
  "last_activity_at": "2026-10-16T10:00:00.000Z",
  "app_url": "https://mesakem.com/dashboard/rooms/room_3c2b1a09-8f7e-4d6c-9b5a-4f3e2d1c0b9a",
  "created_at": "2026-09-01T08:00:00.000Z",
  "updated_at": "2026-10-16T10:00:00.000Z"
}
DELETE/rooms/{room_id}→ 202 Acceptedrooms:write

Archive a room

Rooms have no hard delete: DELETE archives (PATCH archived=false restores). Its meetings are not touched.

Parameters
ParametersTypeNotes
room_id · requiredstringin path
curl -X DELETE "https://mesakem.com/api/v1/rooms/room_3c2b1a09-8f7e-4d6c-9b5a-4f3e2d1c0b9a" \
  -H "Authorization: Bearer $MESAKEM_API_KEY"
Example response · 202 Accepted
{
  "id": "room_3c2b1a09-8f7e-4d6c-9b5a-4f3e2d1c0b9a",
  "object": "room",
  "name": "אקמה — פיילוט",
  "description": "כל הפגישות עם אקמה",
  "client_name": "Acme",
  "keywords": [
    "אקמה",
    "פיילוט"
  ],
  "visibility": "private",
  "archived": true,
  "created_by_you": true,
  "meeting_count": 4,
  "call_count": 1,
  "last_activity_at": "2026-10-16T10:00:00.000Z",
  "app_url": "https://mesakem.com/dashboard/rooms/room_3c2b1a09-8f7e-4d6c-9b5a-4f3e2d1c0b9a",
  "created_at": "2026-09-01T08:00:00.000Z",
  "updated_at": "2026-10-16T10:00:00.000Z"
}
PUT/rooms/{room_id}/meetings/{meeting_id}→ 204 No Contentrooms:write

Add a meeting to a room

Parameters
ParametersTypeNotes
room_id · requiredstringin path
meeting_id · requiredstringin path
curl -X PUT "https://mesakem.com/api/v1/rooms/room_3c2b1a09-8f7e-4d6c-9b5a-4f3e2d1c0b9a/meetings/run_6f1c2a4e-0d3b-4e5f-9a7b-1c2d3e4f5a6b" \
  -H "Authorization: Bearer $MESAKEM_API_KEY" \
  -H "Idempotency-Key: $(uuidgen)"
DELETE/rooms/{room_id}/meetings/{meeting_id}→ 204 No Contentrooms:write

Remove a meeting from a room

Parameters
ParametersTypeNotes
room_id · requiredstringin path
meeting_id · requiredstringin path
curl -X DELETE "https://mesakem.com/api/v1/rooms/room_3c2b1a09-8f7e-4d6c-9b5a-4f3e2d1c0b9a/meetings/run_6f1c2a4e-0d3b-4e5f-9a7b-1c2d3e4f5a6b" \
  -H "Authorization: Bearer $MESAKEM_API_KEY"
PUT/rooms/{room_id}/calls/{call_id}→ 204 No Contentrooms:write

Add a call to a room

Parameters
ParametersTypeNotes
room_id · requiredstringin path
call_id · requiredstringin path
curl -X PUT "https://mesakem.com/api/v1/rooms/room_3c2b1a09-8f7e-4d6c-9b5a-4f3e2d1c0b9a/calls/call_Y3JjXzFhMmIzYwoxNzI5MDAwMDAwLjQy" \
  -H "Authorization: Bearer $MESAKEM_API_KEY" \
  -H "Idempotency-Key: $(uuidgen)"
DELETE/rooms/{room_id}/calls/{call_id}→ 204 No Contentrooms:write

Remove a call from a room

Parameters
ParametersTypeNotes
room_id · requiredstringin path
call_id · requiredstringin path
curl -X DELETE "https://mesakem.com/api/v1/rooms/room_3c2b1a09-8f7e-4d6c-9b5a-4f3e2d1c0b9a/calls/call_Y3JjXzFhMmIzYwoxNzI5MDAwMDAwLjQy" \
  -H "Authorization: Bearer $MESAKEM_API_KEY"
GET/rooms/{room_id}/insightsrooms:read

A room's decisions and stored analyses (read only)

Returns what already exists: the decisions on each meeting's summary, and analyses made in the dashboard. Nothing is generated by this call.

Parameters
ParametersTypeNotes
room_id · requiredstringin path
curl "https://mesakem.com/api/v1/rooms/room_3c2b1a09-8f7e-4d6c-9b5a-4f3e2d1c0b9a/insights" \
  -H "Authorization: Bearer $MESAKEM_API_KEY"
Example response
{
  "object": "room_insights",
  "room_id": "room_3c2b1a09-8f7e-4d6c-9b5a-4f3e2d1c0b9a",
  "source_count": 4,
  "decision_log": [
    {
      "source": {
        "type": "meeting",
        "id": "run_6f1c2a4e-0d3b-4e5f-9a7b-1c2d3e4f5a6b"
      },
      "title": "פגישת היכרות — אקמה",
      "occurred_at": "2026-10-15T09:00:12.000Z",
      "decisions": [
        "פיילוט של חודש"
      ]
    }
  ],
  "analyses": {
    "decisions": null,
    "trends": {
      "kind": "trend_analysis",
      "created_at": "2026-10-10T12:00:00.000Z",
      "stale": true,
      "content": {
        "momentum": "…",
        "open_threads": [],
        "risks": [],
        "sentiment_by_meeting": [],
        "next_step_suggestions": []
      }
    }
  },
  "generated_on_request": false
}
GET/rooms/{room_id}/permissionsshares:read

A room's public link (room creator only)

Parameters
ParametersTypeNotes
room_id · requiredstringin path
curl "https://mesakem.com/api/v1/rooms/room_3c2b1a09-8f7e-4d6c-9b5a-4f3e2d1c0b9a/permissions" \
  -H "Authorization: Bearer $MESAKEM_API_KEY"
Example response
{
  "object": "list",
  "data": [],
  "share_url": null,
  "next_cursor": null,
  "has_more": false
}
POST/rooms/{room_id}/permissionsshares:write

Create a room's public link (done in the dashboard)

Answers 422 public_link_in_dashboard: a room's public link is created in the dashboard, where you choose its meetings. Revoking works here.

Parameters
ParametersTypeNotes
room_id · requiredstringin path
Request body application/json
FieldTypeNotes
recipient · requiredobject
role"read"
curl -X POST "https://mesakem.com/api/v1/rooms/room_3c2b1a09-8f7e-4d6c-9b5a-4f3e2d1c0b9a/permissions" \
  -H "Authorization: Bearer $MESAKEM_API_KEY" \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "Content-Type: application/json" \
  -d '{
    "recipient": {
      "type": "anyone"
    },
    "role": "read"
  }'
Example response
{
  "id": "perm_anyone",
  "object": "permission",
  "recipient": {
    "type": "anyone"
  },
  "role": "read",
  "status": "ready",
  "share_url": "https://mesakem.com/r#…",
  "created_at": null
}
DELETE/rooms/{room_id}/permissions/{permission_id}→ 204 No Contentshares:write

Revoke a room's public link

Parameters
ParametersTypeNotes
room_id · requiredstringin path
permission_id · requiredstringin path
curl -X DELETE "https://mesakem.com/api/v1/rooms/room_3c2b1a09-8f7e-4d6c-9b5a-4f3e2d1c0b9a/permissions/perm_anyone" \
  -H "Authorization: Bearer $MESAKEM_API_KEY"

Phone calls

GET/callscalls:read

List phone calls

Calls recorded from your connected phone system. Calls that produced a meeting also appear in GET /meetings (source phone).

Parameters
ParametersTypeNotes
limitinteger (1–100)default 25
cursorstringnext_cursor from the previous page of the SAME request (same key and filters).
fromdate-timeISO 8601 with offset, or YYYY-MM-DD (00:00 UTC).
todate-time
curl "https://mesakem.com/api/v1/calls?limit=25" \
  -H "Authorization: Bearer $MESAKEM_API_KEY"
Example response
{
  "object": "list",
  "data": [
    {
      "id": "call_Y3JjXzFhMmIzYwoxNzI5MDAwMDAwLjQy",
      "object": "call",
      "title": "דנה לוי",
      "provider": "link",
      "direction": "outbound",
      "duration": 312,
      "status": "ready",
      "contact_name": "דנה לוי",
      "caller": "035551234",
      "callee": "0525551234",
      "recorded_date": "15/10/2026",
      "recorded_time": "11:42",
      "start_time": "2026-10-15T08:42:00.000Z",
      "language": "he",
      "has_transcript": true,
      "has_summary": true,
      "has_recording": true,
      "meeting_id": "run_9a8b7c6d-5e4f-4a3b-8c2d-1e0f9a8b7c6d",
      "app_url": "https://mesakem.com/dashboard/meeting/run_9a8b7c6d-5e4f-4a3b-8c2d-1e0f9a8b7c6d",
      "created_at": "2026-10-15T08:47:00.000Z",
      "updated_at": "2026-10-15T08:51:00.000Z"
    }
  ],
  "next_cursor": null,
  "has_more": false
}
GET/calls/{call_id}calls:read

Get a call

Parameters
ParametersTypeNotes
call_id · requiredstringin path
curl "https://mesakem.com/api/v1/calls/call_Y3JjXzFhMmIzYwoxNzI5MDAwMDAwLjQy" \
  -H "Authorization: Bearer $MESAKEM_API_KEY"
Example response
{
  "id": "call_Y3JjXzFhMmIzYwoxNzI5MDAwMDAwLjQy",
  "object": "call",
  "title": "דנה לוי",
  "provider": "link",
  "direction": "outbound",
  "duration": 312,
  "status": "ready",
  "contact_name": "דנה לוי",
  "caller": "035551234",
  "callee": "0525551234",
  "recorded_date": "15/10/2026",
  "recorded_time": "11:42",
  "start_time": "2026-10-15T08:42:00.000Z",
  "language": "he",
  "has_transcript": true,
  "has_summary": true,
  "has_recording": true,
  "meeting_id": "run_9a8b7c6d-5e4f-4a3b-8c2d-1e0f9a8b7c6d",
  "app_url": "https://mesakem.com/dashboard/meeting/run_9a8b7c6d-5e4f-4a3b-8c2d-1e0f9a8b7c6d",
  "created_at": "2026-10-15T08:47:00.000Z",
  "updated_at": "2026-10-15T08:51:00.000Z"
}
GET/calls/{call_id}/transcriptcalls:read

A call's transcript (json or text)

Parameters
ParametersTypeNotes
call_id · requiredstringin path
formatstring
curl "https://mesakem.com/api/v1/calls/call_Y3JjXzFhMmIzYwoxNzI5MDAwMDAwLjQy/transcript" \
  -H "Authorization: Bearer $MESAKEM_API_KEY"
Example response
{
  "object": "call_transcript",
  "call_id": "call_Y3JjXzFhMmIzYwoxNzI5MDAwMDAwLjQy",
  "meeting_id": "run_9a8b7c6d-5e4f-4a3b-8c2d-1e0f9a8b7c6d",
  "language": "he",
  "text": "דובר 1: שלום, מדברת דנה…",
  "text_oversized": false
}
GET/calls/{call_id}/summarycalls:read

A call's summary (json, markdown or text)

Parameters
ParametersTypeNotes
call_id · requiredstringin path
formatstring
curl "https://mesakem.com/api/v1/calls/call_Y3JjXzFhMmIzYwoxNzI5MDAwMDAwLjQy/summary?format=markdown" \
  -H "Authorization: Bearer $MESAKEM_API_KEY"
Example response
{
  "object": "call_summary",
  "call_id": "call_Y3JjXzFhMmIzYwoxNzI5MDAwMDAwLjQy",
  "meeting_id": "run_9a8b7c6d-5e4f-4a3b-8c2d-1e0f9a8b7c6d",
  "summary_id": "summary_1b2c3d4e-5f6a-4b7c-8d9e-0f1a2b3c4d5e",
  "language": "he",
  "body_markdown": "## סיכום\nהלקוחה ביקשה הצעת מחיר…",
  "action_items": [
    {
      "text": "לשלוח הצעת מחיר"
    }
  ],
  "decisions": [],
  "edited": false,
  "created_at": "2026-10-15T08:51:00.000Z"
}
GET/calls/{call_id}/recordingcalls:read

A 5-minute recording link for a call

Parameters
ParametersTypeNotes
call_id · requiredstringin path
curl "https://mesakem.com/api/v1/calls/call_Y3JjXzFhMmIzYwoxNzI5MDAwMDAwLjQy/recording" \
  -H "Authorization: Bearer $MESAKEM_API_KEY"
Example response
{
  "object": "recording_link",
  "call_id": "call_Y3JjXzFhMmIzYwoxNzI5MDAwMDAwLjQy",
  "meeting_id": "run_9a8b7c6d-5e4f-4a3b-8c2d-1e0f9a8b7c6d",
  "recording_id": "recording_5d6e7f8a-9b0c-4d1e-8f2a-3b4c5d6e7f8a",
  "status": "ready",
  "recording_url": "https://mesakem.com/api/v1/r/Zm9yLWV4YW1wbGUtb25seQ",
  "expires_at": "2026-10-18T08:05:00.000Z",
  "format": "mp3",
  "duration": 312,
  "created_at": "2026-10-15T08:47:00.000Z"
}

Search

GET/searchsearch:read

Search meetings, tasks, rooms and people

Keyword search over your own data: meeting titles and summaries, task titles and descriptions, room names, and meeting invitees. Every word must match. Results follow each resource's read rule.

Parameters
ParametersTypeNotes
qstringKeyword search: every word must match (prefix match for meetings). Needs search:read.
typesstringComma-separated: meeting, task, room, person. Default: every type your key can read.
limitinteger (1–100)default 25
fromdate-timeISO 8601 with offset, or YYYY-MM-DD (00:00 UTC).
todate-time
curl "https://mesakem.com/api/v1/search?q=proposal&types=meeting%2Ctask" \
  -H "Authorization: Bearer $MESAKEM_API_KEY"
Example response
{
  "object": "list",
  "query": "הצעת מחיר",
  "types": [
    "meeting",
    "task",
    "room",
    "person"
  ],
  "mode": "keyword",
  "data": [
    {
      "type": "meeting",
      "id": "run_6f1c2a4e-0d3b-4e5f-9a7b-1c2d3e4f5a6b",
      "title": "פגישת היכרות — אקמה",
      "snippet": "הוסכם לשלוח הצעת מחיר עד יום ראשון…",
      "status": "completed",
      "source": "zoom",
      "start_time": "2026-10-15T09:00:12.000Z",
      "match": {
        "title": false,
        "summary": true
      },
      "app_url": "https://mesakem.com/dashboard/meeting/run_6f1c2a4e-0d3b-4e5f-9a7b-1c2d3e4f5a6b"
    },
    {
      "type": "task",
      "id": "agent_task_5c1f9a2b",
      "title": "לשלוח הצעת מחיר לאקמה",
      "snippet": null,
      "status": "open",
      "updated_at": "2026-10-16T07:10:00.000Z",
      "app_url": "https://mesakem.com/dashboard/tasks"
    }
  ],
  "has_more": false
}

Summary templates

GET/templatestemplates:read

List summary templates (built-in and yours)

Parameters
ParametersTypeNotes
typemeeting | callSummary type. The focused built-in template exists for both.
curl "https://mesakem.com/api/v1/templates?type=meeting" \
  -H "Authorization: Bearer $MESAKEM_API_KEY"
Example response
{
  "object": "list",
  "data": [
    {
      "id": "system_detailed_mesakem",
      "object": "template",
      "type": "meeting",
      "name": "סיכום פגישה של Mesakem",
      "instructions": "…",
      "built_in": true,
      "is_default": true,
      "format": "classic",
      "source_citations": false,
      "editable": false,
      "created_at": "2026-10-18T09:00:00.000Z",
      "updated_at": "2026-10-18T09:00:00.000Z"
    },
    {
      "id": "summary_template_4a5b6c7d-8e9f-4a0b-9c1d-2e3f4a5b6c7d",
      "object": "template",
      "type": "meeting",
      "name": "שיחת מכירה",
      "instructions": "סכם כפגישת מכירה: צורכי הלקוח, התנגדויות, סיכוי סגירה, משימות המשך עם אחראי ותאריך, והודעת המשך קצרה ללקוח.",
      "built_in": false,
      "is_default": false,
      "format": "classic",
      "source_citations": false,
      "editable": true,
      "created_at": "2026-10-18T09:00:00.000Z",
      "updated_at": "2026-10-18T09:00:00.000Z"
    }
  ],
  "next_cursor": null,
  "has_more": false
}
POST/templates→ 201 Createdtemplates:write

Create a summary template

Stored exactly as sent: no AI rewrites or checks it. Draft it however you like, then send it here.

Request body application/json
FieldTypeNotes
name · requiredstringShown in the template picker. Not the name of a built-in template.up to 120 characters
instructions · requiredstringHow to write the summary: structure, tone, emphasis, sections. Stored exactly as sent.up to 12000 characters
typemeeting | calldefault "meeting"
make_defaultbooleandefault false
source_citationsbooleandefault false
curl -X POST "https://mesakem.com/api/v1/templates" \
  -H "Authorization: Bearer $MESAKEM_API_KEY" \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "Content-Type: application/json" \
  -d '{
    "type": "meeting",
    "name": "Discovery call",
    "instructions": "Summarize as a discovery call: needs, objections, budget, next steps with owner and date."
  }'
Example response · 201 Created
{
  "id": "summary_template_4a5b6c7d-8e9f-4a0b-9c1d-2e3f4a5b6c7d",
  "object": "template",
  "type": "meeting",
  "name": "שיחת מכירה",
  "instructions": "סכם כפגישת מכירה: צורכי הלקוח, התנגדויות, סיכוי סגירה, משימות המשך עם אחראי ותאריך, והודעת המשך קצרה ללקוח.",
  "built_in": false,
  "is_default": false,
  "format": "classic",
  "source_citations": false,
  "editable": true,
  "created_at": "2026-10-18T09:00:00.000Z",
  "updated_at": "2026-10-18T09:00:00.000Z",
  "outcome": "created"
}
GET/templates/{template_id}templates:read

Get a summary template

Parameters
ParametersTypeNotes
template_id · requiredstringin path
typemeeting | callSummary type. The focused built-in template exists for both.
curl "https://mesakem.com/api/v1/templates/summary_template_4a5b6c7d-8e9f-4a0b-9c1d-2e3f4a5b6c7d" \
  -H "Authorization: Bearer $MESAKEM_API_KEY"
Example response
{
  "id": "summary_template_4a5b6c7d-8e9f-4a0b-9c1d-2e3f4a5b6c7d",
  "object": "template",
  "type": "meeting",
  "name": "שיחת מכירה",
  "instructions": "סכם כפגישת מכירה: צורכי הלקוח, התנגדויות, סיכוי סגירה, משימות המשך עם אחראי ותאריך, והודעת המשך קצרה ללקוח.",
  "built_in": false,
  "is_default": false,
  "format": "classic",
  "source_citations": false,
  "editable": true,
  "created_at": "2026-10-18T09:00:00.000Z",
  "updated_at": "2026-10-18T09:00:00.000Z"
}
PATCH/templates/{template_id}templates:write

Update one of your templates

Parameters
ParametersTypeNotes
template_id · requiredstringin path
typemeeting | callSummary type. The focused built-in template exists for both.
Request body application/json
FieldTypeNotes
namestringup to 120 characters
instructionsstringup to 12000 characters
make_defaultboolean
curl -X PATCH "https://mesakem.com/api/v1/templates/summary_template_4a5b6c7d-8e9f-4a0b-9c1d-2e3f4a5b6c7d" \
  -H "Authorization: Bearer $MESAKEM_API_KEY" \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Discovery call (v2)"
  }'
Example response
{
  "id": "summary_template_4a5b6c7d-8e9f-4a0b-9c1d-2e3f4a5b6c7d",
  "object": "template",
  "type": "meeting",
  "name": "שיחת מכירה",
  "instructions": "סכם כפגישת מכירה: צורכי הלקוח, התנגדויות, סיכוי סגירה, משימות המשך עם אחראי ותאריך, והודעת המשך קצרה ללקוח.",
  "built_in": false,
  "is_default": false,
  "format": "classic",
  "source_citations": false,
  "editable": true,
  "created_at": "2026-10-18T09:00:00.000Z",
  "updated_at": "2026-10-18T09:00:00.000Z"
}
DELETE/templates/{template_id}→ 204 No Contenttemplates:write

Archive one of your templates

Built-in templates cannot be changed. If it was the default, the built-in template becomes the default again.

Parameters
ParametersTypeNotes
template_id · requiredstringin path
typemeeting | callSummary type. The focused built-in template exists for both.
curl -X DELETE "https://mesakem.com/api/v1/templates/summary_template_4a5b6c7d-8e9f-4a0b-9c1d-2e3f4a5b6c7d" \
  -H "Authorization: Bearer $MESAKEM_API_KEY"
POST/templates/{template_id}/defaulttemplates:write

Make a template the default for its summary type

Parameters
ParametersTypeNotes
template_id · requiredstringin path
typemeeting | callSummary type. The focused built-in template exists for both.
curl -X POST "https://mesakem.com/api/v1/templates/summary_template_4a5b6c7d-8e9f-4a0b-9c1d-2e3f4a5b6c7d/default" \
  -H "Authorization: Bearer $MESAKEM_API_KEY" \
  -H "Idempotency-Key: $(uuidgen)"
Example response
{
  "id": "summary_template_4a5b6c7d-8e9f-4a0b-9c1d-2e3f4a5b6c7d",
  "object": "template",
  "type": "meeting",
  "name": "שיחת מכירה",
  "instructions": "סכם כפגישת מכירה: צורכי הלקוח, התנגדויות, סיכוי סגירה, משימות המשך עם אחראי ותאריך, והודעת המשך קצרה ללקוח.",
  "built_in": false,
  "is_default": true,
  "format": "classic",
  "source_citations": false,
  "editable": true,
  "created_at": "2026-10-18T09:00:00.000Z",
  "updated_at": "2026-10-18T09:00:00.000Z"
}

Public links

GET/shares/{share_id}shares:read

Get a public link (meeting or room)

The object share.created / share.revoked webhooks name. The link's creator only.

Parameters
ParametersTypeNotes
share_id · requiredstringin path
curl "https://mesakem.com/api/v1/shares/pshare_7c6b5a49-3827-4615-9d0c-1b2a3c4d5e6f" \
  -H "Authorization: Bearer $MESAKEM_API_KEY"
Example response
{
  "id": "pshare_7c6b5a49-3827-4615-9d0c-1b2a3c4d5e6f",
  "object": "share",
  "resource": {
    "type": "meeting",
    "id": "run_6f1c2a4e-0d3b-4e5f-9a7b-1c2d3e4f5a6b"
  },
  "status": "ready",
  "share_url": "https://mesakem.com/s#…",
  "created_at": "2026-10-16T09:00:00.000Z",
  "revoked_at": null
}

Plans & limits

TrialPro & organizations
API accessLimited API — read-onlyFull API
Active keys210
Webhook endpoints1 (in Settings)Up to 10 per person
Manage webhooks with the API (webhooks:write)—Included
Writes: bot, tasks, uploads and sharing—Included
Rooms: readIncludedIncluded
Rooms: create and edit—Included
Phone callsIncludedIncluded
SearchIncludedIncluded
Summary templates: readIncludedIncluded
Summary templates: create and edit—Included

The technical rate limits are the same on every plan and are listed under "Rate limits & best practices".