Import a recording made elsewhere
Upload an audio file recorded outside Meetily and get a transcript and summary from it, over the HTTP API.
If you have an audio file recorded somewhere else - your phone, another app, a colleague - you can bring it into Meetily and get a transcript and summary from it. This walkthrough uploads a file, waits for the job to finish, and reads back the summary.
Import is HTTP-only
Importing is available over the HTTP API only - there is no meetily-pro CLI subcommand and no MCP tool for it. In practice a developer or an AI assistant runs the upload for you, then you read the finished summary in the app or over the API. Every call below needs a write-scoped token; set $MEETILY_PRO_TOKEN to one first.
Before you start
Turn on the Automation API under Settings > Integrations so the gateway is running - see Enable & connect. The examples assume the default loopback address http://127.0.0.1:8420.
Step 1 — upload the file
Send POST /v1/jobs/import with a filename query parameter and the raw file bytes as the body (application/octet-stream). It returns 202 with a job_id.
curl -s -X POST "http://127.0.0.1:8420/v1/jobs/import?filename=standup.m4a" \
-H "Authorization: Bearer $MEETILY_PRO_TOKEN" \
--data-binary @standup.m4a
# -> {"job_id":"job-abc123"}Accepted extensions: mp4, m4a, wav, mp3, flac, ogg, aac, mkv, webm, wma. Only the extension is read from filename; the bytes are the body. Optional query params: title, language, model, provider.
Per-file and budget limits
Each file is capped at 2 GB (413 payload_too_large above that). Imports also share an aggregate byte, count, and memory budget across all in-flight uploads; when it's full, a new import is refused with 429 too_many_requests and code import_budget_full plus a Retry-After. Retry after the running imports drain.
Step 2 — wait for the job
Poll GET /v1/jobs/{id} until its state is succeeded. The job carries a meeting_id once one is assigned - that's your new meeting.
curl -s http://127.0.0.1:8420/v1/jobs/JOB_ID \
-H "Authorization: Bearer $MEETILY_PRO_TOKEN"
# -> {"id":"job-abc123","kind":"import","state":"running","meeting_id":null, ...}The terminal success state is `succeeded`, not `completed`
A job's state ends at succeeded (or failed/cancelled). There is no completed state - polling for one loops forever. (job.completed is the name of the webhook event, which is a separate thing from the job's state field.)
Instead of polling, you can hold one connection open and let the server tell you the moment it finishes:
curl -N -s "http://127.0.0.1:8420/v1/jobs/JOB_ID/wait?timeout=1800" \
-H "Authorization: Bearer $MEETILY_PRO_TOKEN"This is a Server-Sent-Events stream that emits exactly one event, then closes. On timeout it emits a single timeout event rather than an HTTP error.
Step 3 — read the summary
Once the import reaches succeeded, read the meeting summary with the meeting_id from step 2:
curl -s http://127.0.0.1:8420/v1/meetings/MEETING_ID/summary \
-H "Authorization: Bearer $MEETILY_PRO_TOKEN"If you want a fresh summary instead of the one generated automatically, regenerate it. This returns 202 with an operation_id you can wait on:
curl -s -X POST http://127.0.0.1:8420/v1/meetings/MEETING_ID/summary/regenerate \
-H "Authorization: Bearer $MEETILY_PRO_TOKEN" \
-H "content-type: application/json" \
-d '{"template_id":"daily_standup"}'
# -> {"operation_id":"op-...","wait_url":"/v1/meetings/MEETING_ID/summary/operations/op-.../wait", ...}All four fields in the regenerate body (model, model_name, template_id, language) are optional and fall back to the app's stored config when omitted.
Good to know
No pause, only cancel
Import jobs cannot be paused or resumed - POST /v1/jobs/{id}/pause on an import returns 409 import_not_pausable. You can cancel a running one with POST /v1/jobs/{id}/cancel, but to change the file or filename you cancel and re-upload rather than editing the job in place.
- If an import fails, the reason is on the job's
errorfield (path-redacted). - See Meetily APIs for the full jobs and meetings route surface.
Last updated on
