Create a meeting and get the results
This guide walks through the full life of a meeting created through the API: you send a recording, Meetingize transcribes it with speaker diarization, writes the AI meeting report and, if you ask for it, generates documents. At each step you see what to call and what you get back.
You need an API key with the write:meetings scope (to create) and read:meetings + read:transcripts
(+ read:documents if you generate documents) to read the results.
Step 1: send the recording
Section titled “Step 1: send the recording”POST /v1/meetings creates a meeting from an audio or video file and starts its processing. Send either the
file itself (multipart) or a public https URL that Meetingize downloads.
# With a file (multipart/form-data)curl -s -X POST "https://app.meetingize.com/api/v1/meetings" \ -H "Authorization: Bearer $MEETINGIZE_API_KEY" \ -H "Idempotency-Key: $(uuidgen)" \ -F file=@rdv-dupont.m4a \ -F title="Annual review - Mr Dupont" \ -F recorded_at=2026-10-14T09:30:00Z \ -F language=fr \ -F 'participants=[{"name": "Paul Dupont", "email": "paul.dupont@example.com"}]' \ -F 'tags=["client", "dupont"]'# With a URL (application/json)curl -s -X POST "https://app.meetingize.com/api/v1/meetings" \ -H "Authorization: Bearer $MEETINGIZE_API_KEY" \ -H "Content-Type: application/json" \ -H "Idempotency-Key: $(uuidgen)" \ -d '{ "audio_url": "https://files.example.com/calls/2026-10-14-dupont.mp3", "title": "Annual review - Mr Dupont", "recorded_at": "2026-10-14T09:30:00Z", "language": "fr", "document_templates": ["tpl_42"], "metadata": {"crm_id": "C-1042"} }'Options
Section titled “Options”| Field | What it does |
|---|---|
file or audio_url | the recording, exactly one of them. Files up to 2 GB (mp3, m4a, wav, flac, ogg, webm, mp4…). URLs must be public https addresses |
title | meeting title (max 300 characters). Without it, the AI report names the meeting |
recorded_at | when the meeting took place (ISO 8601). Default: now |
language | ISO 639-1 code (fr, en…) or auto (default) |
recording_type | meeting (several speakers, diarization, default) or solo (dictation) |
participants | list of {name, email} (max 50). Speaker attribution can be added later |
tags | tag names (max 20) |
client_id or client | file the meeting in a client folder: an existing cli_<n> id (GET /v1/clients), or client = {"name", "email", "phone"} found by name or created |
transcribe_only | true: transcript only, no AI report and no documents (faster and cheaper) |
document_templates | up to 5 template ids (GET /v1/templates) to generate after the AI report |
persona | a persona id (GET /v1/personas): without document_templates, generates that persona’s templates (max 5) |
metadata | your own JSON object (max 4 KB), returned in jobs and webhook events |
In multipart requests, participants, tags and document_templates are JSON strings (tags and templates also
accept a comma-separated list).
What you get back
Section titled “What you get back”202 Accepted with the new meeting and its processing job. Keep id (the meeting) and job.id.
{ "id": "6f0c2a4e-1b7d-4c55-9a51-3e2d8f0b7c11", "object": "meeting", "title": "Annual review - Mr Dupont", "status": "queued", "recorded_at": "2026-10-14T09:30:00Z", "created_at": "2026-10-14T10:02:11Z", "language": "fr", "source": "api", "transcribe_only": false, "tags": ["client", "dupont"], "has_transcript": false, "has_summary": false, "web_url": "https://app.meetingize.com/meeting/detail?uuid=6f0c2a4e-1b7d-4c55-9a51-3e2d8f0b7c11", "summary": null, "participants": [ { "id": "par_311", "name": "Paul Dupont", "email": "paul.dupont@example.com", "speaker_labels": [] } ], "documents": [], "job": { "id": "job_9b0c2d1e", "object": "job", "kind": "meeting_processing", "status": "queued", "stage": "queued", "meeting_id": "6f0c2a4e-1b7d-4c55-9a51-3e2d8f0b7c11", "document_templates": ["tpl_42"], "document_job_ids": [], "metadata": { "crm_id": "C-1042" }, "created_at": "2026-10-14T10:02:11Z" }}Errors you may meet at this step: 400 validation_error (a field is wrong, see errors[]), 413 file_too_large,
402 insufficient_balance or spend_cap_reached (billing), 429 parallel_processing_limit
(your plan’s simultaneous processings are all busy, see limits).
Step 2: follow the processing
Section titled “Step 2: follow the processing”The job goes through these states:
status | stage | Meaning |
|---|---|---|
queued | queued | waiting for a worker |
processing | downloading | audio_url only: Meetingize is downloading the file |
processing | transcribing | transcription and speaker diarization |
processing | summarizing | the transcript is ready, the AI report is being written |
completed | done | transcript and AI report ready (transcript only with transcribe_only) |
failed | see error.code and error.message |
The meeting’s own status follows the same vocabulary (queued, processing, completed, failed).
Count roughly a quarter of the audio duration for the transcript, plus a minute or two for the report.
Option A: polling
Section titled “Option A: polling”curl -s "https://app.meetingize.com/api/v1/jobs/job_9b0c2d1e" -H "Authorization: Bearer $MEETINGIZE_API_KEY"{ "id": "job_9b0c2d1e", "object": "job", "kind": "meeting_processing", "status": "processing", "stage": "summarizing", "meeting_id": "6f0c2a4e-...", "progress": null }Poll every 10 to 30 seconds, and stop when status is completed or failed. Polling does not count against your
API allowance, only against the rate limit.
Option B: webhooks (recommended)
Section titled “Option B: webhooks (recommended)”Register an endpoint once (webhooks) and Meetingize calls you:
| Event | When | What you can read now |
|---|---|---|
transcription.completed | the diarized transcript is ready (stage summarizing) | the transcript |
processing.completed | the AI report is ready, job completed | transcript, report, participants |
document.generated | each requested document is ready | the document |
transcription.failed, processing.failed, document.failed | a step failed | error in the event |
{ "id": "evt_7d1f...", "object": "event", "type": "processing.completed", "created": "2026-10-14T10:09:42Z", "api_version": "2026-10-01", "data": { "object": { "id": "job_9b0c2d1e", "object": "job", "kind": "meeting_processing", "status": "completed", "stage": "done", "meeting_id": "6f0c2a4e-...", "document_job_ids": ["job_a41f..."], "metadata": { "crm_id": "C-1042" }, "meeting": { "id": "6f0c2a4e-...", "object": "meeting", "title": "Annual review - Mr Dupont", "status": "completed" } } }}Your metadata comes back in every event, which makes it easy to match the event with your own record.
Step 3: read the transcript
Section titled “Step 3: read the transcript”As soon as the stage reaches summarizing (event transcription.completed):
curl -s "https://app.meetingize.com/api/v1/meetings/6f0c2a4e-.../transcript" -H "Authorization: Bearer $MEETINGIZE_API_KEY"{ "object": "transcript", "meeting_id": "6f0c2a4e-...", "language": "fr", "duration_seconds": 2412, "speakers": ["SPEAKER_00", "SPEAKER_01"], "segments": [ { "start": 14.2, "end": 21.9, "speaker": "SPEAKER_00", "speaker_name": null, "text": "Je m'engage à vous envoyer une proposition d'allocation avant vendredi." } ]}Add ?format=md, txt, srt or vtt for text formats. Before that point the endpoint answers
409 transcript_not_ready.
Step 4: read the AI report
Section titled “Step 4: read the AI report”When the job is completed (event processing.completed):
curl -s "https://app.meetingize.com/api/v1/meetings/6f0c2a4e-.../summary?format=md" -H "Authorization: Bearer $MEETINGIZE_API_KEY"The JSON format returns markdown plus a structured object (short and long summary, minutes, key takeaways,
action items, speaker identification). GET /v1/meetings/{id} returns everything at once: metadata, report,
participants and documents. Not available with transcribe_only.
Step 5: get the documents
Section titled “Step 5: get the documents”Documents listed in document_templates (or the persona templates) are generated after the report. Each one is a
child job (document_job_ids, kind document_generation) that ends with a document.generated event:
curl -s "https://app.meetingize.com/api/v1/documents?meeting_id=6f0c2a4e-..." -H "Authorization: Bearer $MEETINGIZE_API_KEY"curl -s "https://app.meetingize.com/api/v1/documents/doc_1234?format=md" -H "Authorization: Bearer $MEETINGIZE_API_KEY"Formats: json (metadata and Markdown), md, pdf, docx. You can also generate documents later at any time with
POST /v1/meetings/{id}/documents (documents).
Step 6 (optional): fix the metadata
Section titled “Step 6 (optional): fix the metadata”PATCH /v1/meetings/{id} updates the title, the date, the tags, the client folder and the participants of a
meeting, for example
to say which speaker is who once you know it:
curl -s -X PATCH "https://app.meetingize.com/api/v1/meetings/6f0c2a4e-..." \ -H "Authorization: Bearer $MEETINGIZE_API_KEY" -H "Content-Type: application/json" \ -d '{"participants": {"update": [{"id": "par_311", "speaker_labels": ["SPEAKER_01"]}], "add": [{"name": "Claire Martin", "speaker_labels": ["SPEAKER_00"]}]}}'Participants changes are add, update (only the fields you send change; speaker_labels replaces the list) and
remove (a list of par_ ids). No email is ever sent to participants by the API.
DELETE /v1/meetings/{id} deletes the meeting with its recording, transcript, report and documents; it cannot be
undone.
Checklist
Section titled “Checklist”- Always send an
Idempotency-KeyonPOST: a retry never creates a second meeting. - Prefer webhooks to polling for integrations; keep polling as a fallback.
- Use
transcribe_onlywhen you only need the text: faster and cheaper. - Put your own identifiers in
metadata. - Respect
429andRetry-After(limits).