Video your agent can set up on its own.
Point a coding agent at Synento and it creates sessions, writes the integration, then proves the video works by reading back the recording. Every Synento session is already its own recording, so the proof is built in.
Try the live demo A two-way call in your browser, recorded as it happens. No account needed.
Give this to your coding agent
Read https://synento.com/llms.txt, then add live video to this app with Synento. Prove it works by reading back the session manifest.
- Reading llms.txt and the quickstart…
curl -s https://synento.com/llms.txt - Creating a session (Idempotency-Key set, safe to retry)
POST /v1/sessions Idempotency-Key: call-7f3a - Minting a connection token on the server
POST /v1/sessions/sess_7f3a/connection - Two browsers joined, camera and mic publishing
- Reading the session manifest back…
GET /v1/sessions/sess_7f3a/manifest - Verified: 2 participants, cam + mic, media landed
Every session
recorded, with no recording API to call
Instant
replay, as soon as the call ends
Zero
media servers for you to run
Idempotent
creates, so agent retries are safe
The agent loop
Agents write plausible code. Synento lets them prove it works.
Agent-written video usually fails in silence: the code compiles, the call connects, and no media ever arrives. With Synento the agent can check. The recording is the proof.
Discover
Your agent reads llms.txt, markdown docs and an OpenAPI 3.1 spec. No scraping and no guessing at endpoints.
Provision
Create a project and a session over plain REST. Every create accepts an Idempotency-Key, so a retry never makes a duplicate.
Integrate
Mint a short-lived connection token on the server and join from the browser with @synento/client. Two packages and one route.
Verify
Read the session manifest. A track with a non-null start_ts is media that really arrived: camera, mic and screen, per participant.
{
"user_id": "alice",
"tracks": [
{ "kind": "cam", "start_ts": 1790182704171 },
{ "kind": "mic", "start_ts": 1790182704188 }
]
}
{
"user_id": "bob",
"tracks": [
{ "kind": "cam", "start_ts": 1790182706412 },
{ "kind": "mic", "start_ts": 1790182706430 }
]
}How it works
One durable stream. Live, recorded and replayed.
Browsers encode with WebCodecs and send binary frames to per-participant durable streams. Viewers read the live edge, and replay and MP4 export read the same bytes later. Nothing is transcoded, and nothing is recorded twice.
Browser
WebCodecs encode
Synento relay
Never decodes a frame
Durable streams
One per track
- Live viewers
- Replay
- MP4 export
- Webhooks
Platform
What a video platform should do, without what it shouldn't need.
Recording isn't an add-on
The live session and the recording are the same streams. There is no recording job, no separate recording product and no surcharge.
No media servers to operate
No SFU to deploy, scale or get paged about. We relay bytes without ever decoding them.
Reconnects are boring
Connections resume where they stopped, because the stream is durable. A dropped network leaves a gap in the timeline, not a lost call.
Layout is a playback decision
Camera, mic and screen are stored as separate tracks with an event timeline. Pick grid, presenter or active speaker when you play back.
Signed webhooks
session.created, session.started, session.ended, recording.ready and export.completed, signed with HMAC-SHA256 and retried with backoff.
Redaction built in
Remove one participant from a recording with a single API call. That is usually all an erasure request needs.
Developer experience
From zero to a live call with two packages
Your API key stays on your server. The browser only ever sees a short-lived token scoped to one session and one user.
import { createSynentoClient, resolveWsUrl } from '@synento/node'
// Reads SYNENTO_API_KEY and SYNENTO_API_URL. Server-side only.
const synento = createSynentoClient()
// Once per call. The session is already its own recording.
export async function createCall() {
const session = await synento.createSession({ name: 'Standup' })
return session.id
}
// Once per participant: a short-lived token scoped to one session and user.
export async function POST(request: Request) {
const { sessionId, userId } = await request.json()
const token = await synento.createConnectionToken(sessionId, { userId })
return Response.json({
token: token.accessToken,
wsUrl: resolveWsUrl({
apiBaseUrl: process.env.SYNENTO_API_URL!,
requestOrigin: request.headers.get('origin'),
sessionId,
userId,
}),
})
}import { SynentoRoom } from '@synento/client'
const room = new SynentoRoom({
userId: 'alice',
// Called again on every reconnect, so tokens rotate on their own.
getToken: () =>
fetch('/api/synento', {
method: 'POST',
body: JSON.stringify({ sessionId, userId: 'alice' }),
}).then((res) => res.json()),
})
await room.connect()
const stream = await navigator.mediaDevices.getUserMedia({ audio: true, video: true })
await room.publishCamera(stream)
// That's it. There is no "start recording" call.# Create a session. Retrying with the same key returns the same session.
curl -X POST https://api.synento.com/v1/sessions \
-H "Authorization: Bearer $SYNENTO_API_KEY" \
-H "Idempotency-Key: standup-2026-09-23" \
-H "Content-Type: application/json" \
-d '{"name": "Standup"}'
# Mint a connection token for one participant.
curl -X POST https://api.synento.com/v1/sessions/$SESSION_ID/connection \
-H "Authorization: Bearer $SYNENTO_API_KEY" \
-H "Content-Type: application/json" \
-d '{"user_id": "alice"}'# Did media really arrive? Ask the recording.
curl -s https://api.synento.com/v1/sessions/$SESSION_ID/manifest \
-H "Authorization: Bearer $SYNENTO_API_KEY" \
| jq '.data.participants[] | {user_id, tracks: [.tracks[] | {kind, start_ts}]}'Machine-readable by default
Everything an agent needs is one GET away
No login walls and no JavaScript-only docs. Every docs page has a markdown twin, and the API is described by a spec your agent can load.
/llms.txtllms.txt
A map of the whole platform for language models, with links to every docs page as markdown.
/llms-full.txtllms-full.txt
Every public docs page in one plain-text file, ready to put in context.
/openapi.jsonOpenAPI 3.1
The public REST API as a spec, checked against the real server on every test run.
/docs/getting-started.mdMarkdown docs
Add .md to any docs URL, or send Accept: text/markdown.
/.well-known/api-catalogAPI catalog
RFC 9727 discovery at /.well-known/api-catalog.
- New
MCP server
Connect your agent to /mcp. It provisions, integrates and verifies the recording, holding only the access you approve.
Honest comparisons
Choose the right tool, even when it isn't us
Each comparison says plainly when the other product is the better fit.
- Synento vs DailyMature WebRTC with a prebuilt UI. Choose it for the lowest latency and the widest browser support.
- Synento vs LiveKitOpen-source and self-hostable. Choose it for simulcast, SVC and large-scale streaming.
- Synento vs Vonage Video (Tokbox)Long-established, with telephony. Choose it if you need SIP or dial-in.
Pricing
Start free. Recording is always included.
3,000 participant-minutes and 50 GiB of storage free every month. Free accounts pause at the allowance, so you never get a surprise bill.
Pro is $19 a month, with usage-based overage after that.
- Every session recorded, with no add-on
- Instant replay and windowed playback
- MP4 export
Compatibility
Runs wherever WebCodecs runs
We check browser support before a call starts, so nobody joins a call that can't work.
| Browser | Supported from |
|---|---|
| Chrome and Edge | 94+ |
| Safari (macOS and iOS) | 16.4+ |
| Firefox | 133+ |
| Older browsers | Detected before the call |
FAQ
Questions, answered
What does “agent-native” mean?
An AI coding agent can take Synento from nothing to a working, verified integration without a person clicking through a dashboard. The docs are machine-readable, the API is described by an OpenAPI spec, creates are idempotent, and the agent can check that media really arrived by reading the recording back.
Is there an MCP server?
Yes. Point your agent at the Synento MCP server and approve it in your browser. It can create sessions, mint a restricted key for your app and verify that camera and microphone actually arrived. It never holds an owner key. Agents without MCP can still use the REST API, the OpenAPI spec and the markdown docs.
Why WebCodecs rather than WebRTC?
WebRTC is built for ephemeral peer-to-peer media. Synento writes every frame to a durable stream, which is what makes recording, replay and export free by construction. The trade-off is latency: sub-second, but higher than peer-to-peer WebRTC.
What does recording cost?
Nothing extra. You pay per participant-minute and for storage beyond your allowance. There is no separate recording rate, because there is no separate recording.
Can I self-host Synento?
No. Synento is fully hosted, so there are no media servers for you to run. If self-hosting is a hard requirement, our LiveKit comparison explains when LiveKit is the better choice.
How do I get started?
Sign up with an email address. Once it is verified, create an API key, or connect your coding agent to Synento's MCP server and let it set up the project itself. The Free plan needs no credit card.
Give your agent a video platform it can verify.
Sign up, point your agent at llms.txt, and have a recorded call running before lunch.