Meetily
Agent APIGuides

Back up and batch-process meetings

Export every meeting to Markdown or JSON on a schedule, and run diarization across many meetings.

This sends meeting content off your device

Meetily is privacy-first and local by default. This automation reads meeting content and writes it elsewhere (disk, Notion, Obsidian). You are the data controller for that transfer: get the participants' consent, scope the token to read only, and treat the destination as untrusted. Never hard-code a token in a script you share; read it from the environment or the loopback token file.

Three batch jobs: back up every meeting to files, re-diarize a set of meetings, and run a post-meeting ritual when a summary is ready.

Nightly backup

List meetings with pagination (limit is capped at 200; page with offset), and export each with GET /v1/meetings/:id/export?format=json|md|txt (JSON, Markdown, or plain text).

import pathlib
from meetily_agent import MeetilyClient

client = MeetilyClient()
out = pathlib.Path("meetily-backup")
out.mkdir(exist_ok=True)

offset = 0
while True:
    page = client.meetings.list(limit=200, offset=offset)
    meetings = page.get("meetings", [])
    if not meetings:
        break
    for m in meetings:
        md = client.meetings.export(m["id"], format="md")
        (out / f"{m['id']}.md").write_text(md if isinstance(md, str) else str(md))
    offset += len(meetings)

Batch re-diarize

Submit a diarization job per meeting and wait for each. A rerun that conflicts with one already running returns 409, so handle that.

from meetily_agent import MeetilyClient, MeetilyError

client = MeetilyClient()
meeting_ids = ["MEETING_A", "MEETING_B"]

for mid in meeting_ids:
    try:
        job = client.jobs.diarization(mid)
    except MeetilyError as e:
        if e.status == 409:
            print(f"skip {mid}: a job is already running")
            continue
        raise
    event, data = client.jobs.wait(job["job_id"], timeout=1800)
    print(mid, event)

Post-meeting ritual

To run a step when a summary is ready, wait for the summary.completed event rather than polling a process id. The simplest reliable approach is a webhook on summary.completed (see Webhooks); if you prefer polling, poll GET /v1/meetings/:id/summary until its status shows the summary is ready, then back it up.

import time
from meetily_agent import MeetilyClient

client = MeetilyClient()

def wait_for_summary(meeting_id, tries=60, delay=5):
    for _ in range(tries):
        s = client.meetings.summary(meeting_id)
        if s.get("status") == "completed" and s.get("result"):
            return s
        time.sleep(delay)
    raise TimeoutError("summary not ready")

Do not wait on meeting.* events

The meeting.created, meeting.updated, and meeting.deleted events never fire. To detect new meetings for a backup job, poll GET /v1/meetings instead.

Last updated on

On this page