Last updated: Feb 11, 2026, 10:39 AM UTC

Meeting Room API

The Meeting Room API lets your application start and stop live meeting transcriptions via simple REST calls. When a meeting is active, Sasha sends real-time events to your callback URL — transcript segments, participant changes, coaching insights, and status updates.


How It Works

Your application makes REST calls to control meeting transcription. Sasha joins the meeting as a bot participant, transcribes the conversation, and delivers events back to your application via HTTP callbacks.

sequenceDiagram participant App as Your Application participant Sasha as Sasha API participant Bot as Meeting Bot participant Meeting as Teams / Google Meet App->>Sasha: POST /api/v1/meetings/start Sasha->>Bot: Launch bot Bot->>Meeting: Join meeting Sasha-->>App: 201 { meetingId, status: "joining" } loop During meeting Meeting-->>Bot: Live audio Bot-->>Sasha: Transcription Sasha-->>App: POST callback (transcript, participants, insights) end App->>Sasha: POST /api/v1/meetings/stop Bot->>Meeting: Leave meeting Sasha-->>App: 200 { status: "stopping" }

Prerequisites

  • A Sasha Studio account with an active deployment
  • An API key — create one in My Account > API Tokens
  • A callback URL reachable from your Sasha instance (use ngrok to expose your local client to the remote Sasha server)

Quick Start

1. Start a meeting transcription

curl -X POST https://your-sasha.example.com/api/v1/meetings/start \
  -H "X-API-Key: sk_your_key" \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://teams.live.com/meet/abc123",
    "title": "Daily Standup",
    "callbackUrl": "https://your-app.com/events",
    "project": "acme-corp"
  }'

2. Receive events at your callback URL

Sasha POSTs events as they happen — transcript segments, participant joins/leaves, status changes, and coaching insights. Each event is signed with HMAC-SHA256 so you can verify authenticity.

3. Stop the transcription

curl -X POST https://your-sasha.example.com/api/v1/meetings/stop \
  -H "X-API-Key: sk_your_key" \
  -H "Content-Type: application/json" \
  -d '{ "meetingId": "meeting_1707234567890_abc123def" }'

API Reference

All endpoints require authentication via the X-API-Key header.

Join a Meeting

Join and transcribe a live meeting. Sasha joins as a bot participant.

POST /api/v1/meetings/start

Request body:

Field Type Required Description
url string Yes Meeting URL (Teams or Google Meet)
title string No Label for this meeting
callbackUrl string Yes URL where Sasha sends real-time events
project string No Sasha project to save the transcript into (see Projects API). Defaults to api
saveTranscript boolean No Save a transcript document in the project. Defaults to true

Response (201):

{
  "meetingId": "meeting_1707234567890_abc123def",
  "status": "joining",
  "platform": "teams",
  "project": "acme-corp",
  "documentPath": "deployed-md-files/docs/acme-corp/meetings/February 11th - Daily Standup.md"
}

Stop a Meeting

Stop transcribing and leave the meeting.

POST /api/v1/meetings/stop

Request body:

Field Type Required Description
meetingId string Yes The meeting ID returned from the start call

Response (200):

{
  "meetingId": "meeting_1707234567890_abc123def",
  "status": "stopping"
}

List Active Meetings

Returns all meetings currently being transcribed.

GET /api/v1/meetings/status

Response (200):

{
  "meetings": [
    {
      "meetingId": "meeting_1707234567890_abc123def",
      "status": "live",
      "platform": "teams",
      "title": "Daily Standup",
      "startedAt": "2026-02-10T14:00:00Z",
      "participantCount": 5,
      "segmentCount": 42,
      "project": "acme-corp",
      "documentPath": "deployed-md-files/docs/acme-corp/meetings/February 10th - Daily Standup.md"
    }
  ]
}

Get Transcript

Retrieve the full transcript for a meeting (live or completed).

GET /api/v1/meetings/{meetingId}/transcript

Response (200):

{
  "meetingId": "meeting_1707234567890_abc123def",
  "status": "live",
  "project": "acme-corp",
  "documentPath": "deployed-md-files/docs/acme-corp/meetings/February 10th - Daily Standup.md",
  "segments": [
    {
      "speaker": "Alice",
      "text": "So about the roadmap for Q2...",
      "timestamp": "2026-02-10T14:29:58.123Z"
    }
  ]
}

Download Transcript Document

Download the saved markdown transcript file for a meeting.

GET /api/v1/meetings/{meetingId}/document

Response (200):

Returns the markdown file with Content-Type: text/markdown and a Content-Disposition header for download. Only available when saveTranscript was true (the default) when joining the meeting.

Response (404):

{
  "error": "No saved document for this meeting"
}

Callback Events

When you provide a callbackUrl, Sasha POSTs events as they happen during the meeting. This is the core of the integration — your application receives live data without polling.

Event Format

Every callback is an HTTP POST with a JSON body:

{
  "type": "segment_finalized",
  "meetingId": "meeting_17234...",
  "sequence": 42,
  "timestamp": "2026-02-10T14:30:00.000Z",
  "payload": {
    "speaker": "Alice",
    "text": "So about the roadmap for Q2...",
    "timestamp": "2026-02-10T14:29:58.123Z"
  }
}

Callback Headers

Header Description
X-Sasha-Signature sha256=<HMAC-SHA256> for verification
X-Sasha-Event Event type (e.g., segment_finalized)
X-Sasha-Meeting-Id Meeting ID
X-Sasha-Delivery-Id Unique ID per delivery attempt

Event Types

Type Description
meeting_status Status changes: joining, lobby, live, leaving, ended, error
caption_partial Live evolving caption (high frequency, useful for real-time display)
segment_finalized Clean finalized transcript segment (use this for persistence)
coach_insight AI coaching insight with category
participant_joined Someone joined the meeting
participant_left Someone left the meeting
document_saved Transcript document was flushed to disk (includes documentPath, segmentsWritten, totalSegments)

HMAC Signature Verification

Every callback includes an X-Sasha-Signature header. Verify it to confirm the event came from Sasha and hasn't been tampered with.

Node.js

import crypto from 'crypto';

function verifySignature(body, signature, secret) {
  const expected = 'sha256=' + crypto
    .createHmac('sha256', secret)
    .update(body)
    .digest('hex');
  return crypto.timingSafeEqual(
    Buffer.from(signature),
    Buffer.from(expected)
  );
}

// In your Express handler:
app.post('/events', express.raw({ type: 'application/json' }), (req, res) => {
  const rawBody = req.body.toString('utf8');
  const sig = req.headers['x-sasha-signature'];

  if (!verifySignature(rawBody, sig, process.env.SIGNING_SECRET)) {
    return res.status(401).json({ error: 'Invalid signature' });
  }

  const event = JSON.parse(rawBody);
  // Process event...
  res.json({ received: true });
});

Python

import hmac
import hashlib

def verify_signature(body: bytes, signature: str, secret: str) -> bool:
    expected = 'sha256=' + hmac.new(
        secret.encode(), body, hashlib.sha256
    ).hexdigest()
    return hmac.compare_digest(signature, expected)

Reference Client

The official reference client is a working demo that shows the full integration flow — API calls, callback handling, HMAC verification, and a live event feed in the browser.

Repository: github.com/context-is-everything/sasha-meeting-api-client

git clone https://github.com/context-is-everything/sasha-meeting-api-client.git
cd sasha-meeting-api-client
npm install
node index.js

The reference client includes setup guides for ngrok (needed so the remote Sasha server can reach your local client), database schema suggestions for persisting transcripts, and example code for building on top of the API.


Project Integration

Transcripts are saved into Sasha projects — the same directories visible in the Knowledge panel. Use the project field when joining a meeting to control where the transcript is stored.

  • Default: Transcripts go into the api project
  • Custom project: Set "project": "acme-corp" to save into a specific project
  • No transcript: Set "saveTranscript": false to skip file creation (events still stream normally)
  • Browse saved transcripts: Use the Projects API to list projects and their meeting history

Troubleshooting

Problem Solution
401 Invalid API key Check the key hasn't been revoked in My Account > API Tokens
HMAC FAIL on events Ensure your signing secret matches the one shown when creating the API token
No events arriving Check that your callback URL is reachable from the remote Sasha server. Use ngrok to expose your local client
ECONNREFUSED Verify your Sasha URL is correct and the instance is running
Events show no secret Not an error — set your signing secret to enable HMAC verification