Edited clips with JSON2Video
Cut the best moments of a Synento recording into a short vertical clip with subtitles, using JSON2Video.
Every Synento session is already a recording. This guide turns that recording into a 30–60 second clip you can share: the two or three moments that matter, in vertical 9:16, with subtitles burned in. It works for interview highlights, stand-up recaps, customer quotes and support review.
The flow has three steps:
- Get the MP4 of the session from Synento, and put it at a URL JSON2Video can read.
- Pick the moments: transcribe the audio and choose start and end times, by hand or with an LLM.
- Render the clip with JSON2Video: one API call that cuts, crops and adds subtitles.
You need a Synento project with its secret API key (sk_live_…, from the
dashboard), a JSON2Video API key, and somewhere to host a file for an hour,
such as an S3 or R2 bucket. JSON2Video's free plan includes enough credits to
try this guide several times; its renders carry a watermark.
This guide was written with the JSON2Video team. Here is a clip made with it from a 2-minute recording.
1. Get the MP4
Start the export
Ask for an export once the session has ended. layout=presenter fills the
frame with one person's camera (focus, their user id) and shows up to four
others as small thumbnails, which suits interviews and talks:
curl "https://api.synento.com/v1/sessions/{sessionId}/export?layout=presenter&orientation=vertical&focus=alice" \
-H "Authorization: Bearer sk_live_xxxxx"Response (202):
{ "data": { "job_id": "8d0c2f0e-…" }, "error": null }Pick the orientation by the cameras people used. Each camera keeps its own shape in the export, so:
- Phones (portrait cameras): use
orientation=vertical, as above. The 720×1280 file is already 9:16 and the camera fills it. - Laptop webcams (landscape cameras): leave
orientationout to get a 1280×720 file. In a vertical export a landscape camera becomes a band across the middle with black above and below. From a landscape export, JSON2Video crops the centre of the frame (step 3), where a webcam usually has the face. The thumbnails sit at the edges and are cropped away.
Avoid layout=grid for a vertical clip: side-by-side tiles end up as a thin
strip, or cut in half by the crop.
Two limits to know: every participant in the session needs camera video, and screen shares are not included in the MP4. See Exporting to MP4 for the full details.
Wait for it to finish
Check the job until status is completed:
curl https://api.synento.com/v1/exports/{jobId} \
-H "Authorization: Bearer sk_live_xxxxx"{
"data": {
"job_id": "8d0c2f0e-…",
"room_id": "9b1c4e7a2d3f4a8b9c0d1e2f3a4b5c6d",
"status": "completed",
"progress_pct": 100,
"download_url": "/v1/exports/8d0c2f0e-…/download"
},
"error": null
}Checking every 10 seconds or so is plenty. If you would rather be told, the
export.completed webhook fires when an export finishes.
Its payload names the session (session_id) but not the export and carries
no link to the file. To get the job id, repeat the same export request: it
returns the finished job ("reused": true) without encoding or charging again.
Make the file reachable
The download_url needs your secret API key, and JSON2Video cannot send one.
Download the file yourself, then host it at a short-lived link. With S3:
curl https://api.synento.com/v1/exports/{jobId}/download \
-H "Authorization: Bearer sk_live_xxxxx" \
--output session.mp4
aws s3 cp session.mp4 s3://your-bucket/clips/session.mp4
aws s3 presign s3://your-bucket/clips/session.mp4 --expires-in 3600The last command prints a signed URL. That is the SESSION_MP4_URL used
below. On Cloudflare R2, add --endpoint-url https://<account-id>.r2.cloudflarestorage.com
to both aws s3 commands; everything else is the same. An hour is enough, since JSON2Video only needs it while the render
runs. Never put your Synento API key in a URL.
2. Pick the moments
JSON2Video cuts the video where you tell it to. It does not choose the moments for you, so this step happens before the render.
Transcribe the MP4 with timestamps. The exported MP4 mixes everyone's audio into one track. Transcribe that file rather than anything else, so the times you get are times in the file you will cut. Any speech-to-text service that returns segment or word timestamps works: OpenAI Whisper, Deepgram, AssemblyAI, ElevenLabs Speech to Text, and others.
Choose two or three segments of 8–20 seconds each. You can do it by hand, or give the transcript to an LLM:
Below is the transcript of a recorded call, with start and end times in seconds.
Pick the 3 moments that best summarise the call for someone who did not attend.
Each moment must be a complete sentence or answer, between 8 and 20 seconds long.
Return only JSON: [{"start": 12.4, "end": 25.1, "why": "..."}]
<transcript>Move each start about 0.3 seconds earlier and each end about 0.3 seconds later, so no word is clipped: transcript timestamps often end a little before the speech does. When the next person starts talking straight away, end the cut where their first word begins instead, or the clip picks up the start of it.
3. Render the clip
Each moment becomes one scene. In each scene, seek is where the cut starts
in the MP4, in seconds, and duration is how long it lasts. resize: "cover"
fills the vertical frame, and position: "center-center" makes the crop take
the middle of a landscape export. Leave it out and JSON2Video keeps the left
edge instead, showing the thumbnails and cutting off the person in focus. The subtitles element sits at movie level: it
transcribes the finished clip and burns in the captions, so you do not need to
send the transcript again.
Save this as clip.json:
{
"resolution": "instagram-story",
"quality": "high",
"scenes": [
{
"elements": [
{ "type": "video", "src": "SESSION_MP4_URL", "seek": 2.5, "duration": 10.6, "resize": "cover", "position": "center-center" }
]
},
{
"elements": [
{ "type": "video", "src": "SESSION_MP4_URL", "seek": 59.7, "duration": 11, "resize": "cover", "position": "center-center" }
]
},
{
"elements": [
{ "type": "video", "src": "SESSION_MP4_URL", "seek": 104.3, "duration": 9.8, "resize": "cover", "position": "center-center" }
]
}
],
"elements": [
{
"type": "subtitles",
"settings": {
"style": "classic-progressive",
"position": "bottom-center",
"max-words-per-line": 3,
"font-size": 70
}
}
]
}instagram-story is 1080×1920. For other shapes, use full-hd (1920×1080)
for a horizontal clip, from a landscape export, or squared for 1:1.
Send it to JSON2Video:
curl -X POST "https://api.json2video.com/v2/movies" \
-H "x-api-key: YOUR_JSON2VIDEO_API_KEY" \
-H "Content-Type: application/json" \
-d @clip.jsonThe response contains a project id:
{ "success": true, "project": "bfLEfgAXt91xaS5U", "timestamp": "2026-10-23T11:01:24.023Z" }Rendering runs in the background, so check every 10 seconds or so until
movie.status is done (or error, with the reason in movie.message):
curl "https://api.json2video.com/v2/movies?project=PROJECT_ID" \
-H "x-api-key: YOUR_JSON2VIDEO_API_KEY"{
"success": true,
"movie": {
"status": "done",
"url": "https://json2video-cdn1.s3.amazonaws.com/clients/…/renders/….mp4",
"duration": 31.8,
"width": 1080,
"height": 1920
}
}movie.url is the finished clip. A 30-second clip took about 20 seconds to
render. You can then delete the copy you uploaded in step 1.
Cost
- JSON2Video bills per second of finished video, rounded up: a 31.8-second clip uses 32 credits, however long the original session was.
- Synento counts only the export, in exported participant-minutes: each person's time in the recording. A 2-minute call with 2 people is 4. Plans include 300 a month on Free and 3,000 on Pro, then $0.004 each on Pro. Asking for the same export again costs nothing.
Doing it with a coding agent
Both services have MCP servers, so an agent such as Claude Code or Cursor can do most of this for you. Connect both:
claude mcp add --transport http synento https://api.synento.com/mcp
npx -y @json2video/cli mcp install claudeThen run /mcp in Claude Code and choose synento to sign in. See
Connect your agent for other editors.
Synento's MCP server can find the session (list_sessions) and show what was
recorded (get_session_manifest), but it does not start exports. The key it
creates for your app (rk_live_…) cannot export either. So the agent also
needs your project's secret key: put it in an environment variable such as
SYNENTO_API_KEY rather than pasting it into the chat, and tell the agent
where it may upload the MP4.
Then ask, for example: "Find yesterday's interview session in Synento. Export it with the presenter layout focused on the guest, using SYNENTO_API_KEY (vertical if they were on a phone, landscape otherwise), upload the MP4 to my S3 bucket with a one-hour link, pick the three best answers from a transcript, and render a vertical highlight clip with subtitles through JSON2Video."
Variations
- Branding: add an
imageelement (your logo) at movie level, or a short title scene at the start with atextelement. - Follow the speaker: for an interview, export once per person
(
focus=alice, thenfocus=bob) and cut each moment from the export of whoever is talking, so the person speaking always fills the frame. Each export counts its exported participant-minutes, so two exports cost twice as much on the Synento side. - One clip per moment: send one render per segment instead of three scenes in one movie, for a set of short quotes.
- Subtitle style and language: see JSON2Video's subtitles reference for styles, colours and translation.
- Whole session with captions: one scene with the whole MP4
(
"duration": -1) and the subtitles element give a captioned copy of the call.
Reference
- Exporting to MP4: every export option and limit
- Webhooks: the
export.completedevent - JSON2Video quickstart
- Video element
(
seek,duration,resize,crop) - Subtitles element
- JSON2Video MCP server