Guides
Templates
Set a meeting or a webinar up once — who gets in, the layout, your brand and scenes, where it streams and whether it goes live by itself, what’s recorded, a call to action — then start every one like it, from the dashboard or from your own app.
What a template holds
A template is for meetings — everyone can take part — or webinars, which have an audience and a stage. It belongs to your workspace: anyone in it can use one. It holds everything about how a call is set up, except when it is, what it’s called and who’s invited:
| Part | What it sets |
|---|---|
| Getting in | A waiting room; a webinar’s backstage; for a meeting booked with it, registration and guests starting without the host. |
| In the call | Who may unmute and share their screen; whether only hosts draw on the whiteboard — and then whether everyone follows the host’s view of it, and whether participants’ cursors are hidden; and the layout everyone starts with. |
| Brand | Your workspace’s logo — top right, in the call’s top bar and the corner of the stream and recording — and, for a webinar, speakers’ names and titles. The logo and colour themselves are your brand’s. |
| Recording colours | The colours of the chat, questions, polls, raised hands, speakers’ titles and scenes on its recordings and live streams, to match the call in your app. Set them on the dashboard, or as look.theme: see Theming. |
| Scenes | A webinar’s: the scene the stream and recording open on, and what each one says. See below. A meeting opens on the call. |
| Live stream | Up to 5 of your saved destinations, the picture’s shape, what shows over it — and whether it goes live by itself as a host arrives. |
| Recording | Recording automatically, and what the recording shows over the picture. |
| Call to action | A call to action ready to put up in a tap. |
Passwords are never part of one: give a room its password when you create it.
Making one
In the dashboard, Templates → Webinar template (or Meeting template): name it, set it up, save. Anywhere you set a call up — Start a webinar, or booking one on the Schedule — Save as a template keeps what’s on screen as a new one. Stream destinations added while you do are saved for your workspace, their keys never shown again. Or make one through the API — below.
Using one on the dashboard
- Start a webinar (and Templates → a webinar template → Start a webinar): the page opens set up from it, to change anything before you start.
- Start a meeting at /meet from a meeting template.
- Book one: the schedule editor opens set up from it — and its Start from list applies any template to a booking, which keeps that setup for every session.
Your next meeting or webinar starts the way you left the last one — unless your workspace has a default template. A template is how you keep a setup you’ll want again, and share it with everyone in your workspace.
The default template
One meeting template can be your workspace’s default. Every meeting that doesn’t name a template is then set up from it:
- Rooms your app creates —
POST /v1/roomswithouttemplatesets a new room up from it, any settings you send over it. Rooms that already exist are left as they are. - Meetings started at /meet — the form opens set up from it, and says so; Don’t use it starts the way you left your last meeting instead.
- New bookings — the schedule editor opens set up from it.
On the dashboard, Templates → a meeting template → Make default; the one before stops being the default. Only your workspace’s owner and account managers can choose it. Through the API, send "default": true when you create or update a template, and false to have none.
To create a room from no template while you have a default, send "template": null. Webinars never take it: a webinar starts from a webinar template you name, or the way you left your last one.
Creating rooms from one
Find its id
Each template’s card in the dashboard has Copy id, and its page shows the request below, ready to copy. Or list them:
curl https://api.inlinemeet.com/v1/templates?kind=webinar \
-H "Authorization: Bearer $INLINEMEET_API_KEY"Create the room with it
Name it as template when you create the room. The new room is set up from it — settings, look, scenes, layout, where it streams, its call to action — and the answer says what it got:
curl -X POST https://api.inlinemeet.com/v1/rooms \
-H "Authorization: Bearer $INLINEMEET_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "code": "spring-launch", "name": "Spring launch", "template": "6703a1f0e1b2c3d4e5f60b12" }'{
"code": "spring-launch",
"name": "Spring launch",
"webinar": true,
"backstage": true,
"autoRecord": true,
"look": { "logo": true, "titles": true, "lines": { "starting": "We go live at 4pm sharp" } },
"scene": "starting",
"layout": "spotlight",
"template": "6703a1f0e1b2c3d4e5f60b12",
"prepared": {
"savedIds": ["6702c0d1e1b2c3d4e5f60a77"],
"orientation": "landscape",
"autoStart": true,
"cta": { "headline": "See it on your own data", "label": "Book a demo", "url": "https://acme.example/demo" }
},
…
}Let people in as usual
Mint join tokens as you always do — a host with role: "moderator", speakers with stage: true, everyone else as the audience. When the first host arrives, the stream goes live by itself if the template says so, and the call UI’s Live tab has its destinations and call to action ready.
// Your server: one room per event, set up from the template, then a token per person.
const api = (path, body) =>
fetch(`https://api.inlinemeet.com/v1${path}`, {
method: 'POST',
headers: { Authorization: `Bearer ${process.env.INLINEMEET_API_KEY}`, 'Content-Type': 'application/json' },
body: JSON.stringify(body),
}).then((r) => r.json());
const room = await api('/rooms', { code: event.slug, name: event.title, template: process.env.WEBINAR_TEMPLATE_ID });
const host = await api(`/rooms/${room.code}/tokens`, { identity: user.id, name: user.name, role: 'moderator' });What the room gets
| From the template | In the room |
|---|---|
| kind | webinar true for a webinar template, false for a meeting one. |
| waitingRoom, backstage, participantsCanUnmute, whiteboardLocked, whiteboardFollowHost, whiteboardHideCursors | The room settings of the same names. |
| autoRecord, recordingActivity | The same — left out where the room can’t record (recordingsDisabled, or a plan without recording). |
| look, scene, layout | The room’s look (lines and recording colours included), the scene it opens on, and layout. A template without colours of its own takes away any the room had: it uses your brand’s again. |
| stream.activity | streamActivity: what a stream shows over the picture. |
| stream.savedIds, orientation, autoStart, cta | prepared: where it streams, whether it goes live by itself, and its call to action. Destinations no longer saved are dropped; going live needs a plan that streams. |
| guestScreenShare, registration, joinBeforeHost | For meetings started or booked on the dashboard. A room you create decides screen sharing per token (publish.screenShare). |
Your own settings over it
Settings you send beside template win — a webinar template, but with a waiting room this time:
curl -X POST https://api.inlinemeet.com/v1/rooms \
-H "Authorization: Bearer $INLINEMEET_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "code": "spring-launch", "template": "6703a1f0e1b2c3d4e5f60b12", "waitingRoom": true, "password": "spring-26" }'Creating a room is idempotent: sent again for a room that exists, template leaves it as it is, so it stays safe to call on every join. To set an existing room up again from a template — the same one, changed since, or another — update it with template. That applies at once, to anyone already in the call:
curl -X PATCH https://api.inlinemeet.com/v1/rooms/spring-launch \
-H "Authorization: Bearer $INLINEMEET_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "template": "6703a1f0e1b2c3d4e5f60b12" }'Going live by itself
With stream.autoStart, the room goes live to the template’s destinations as soon as a moderator joins — no one presses Go live. It does so once per call: a host who ends the stream, or whose connection drops and comes back, isn’t put back on the air. A webinar that opens backstage goes live on its Starting soon scene, without sound, until a host starts it; then the stream shows the stage. Everything else is as for any live stream: each destination’s state, adding and removing them while live, and the stream.started, stream.ended and stream.failed webhooks.
Without autoStart, the destinations are still prepared: the Live tab opens with them ticked, so a host goes live in one tap when they’re ready.
Scenes and what they say
A scene covers the call on the stream and the recording — Starting soon, Be right back, Thanks for watching — with your logo, colour and the call’s title. A template says which one the call opens on (scene; null for the call itself), and what each one says instead of its usual line — up to 80 characters:
"look": {
"logo": true,
"titles": true,
"lines": {
"starting": "We go live at 4pm sharp",
"break": "Ten minutes — grab a coffee",
"ending": "Slides and recording on their way to your inbox"
}
},
"scene": "starting"Hosts switch scenes, and change what one says, from the call’s Live tab. A room’s look.lines works the same through PATCH /v1/rooms/:code; "" or null puts a scene’s usual line back.
In the embedded call UI
- Layout: leave out
defaultLayoutonCallRoomand the room’s own decides — the template’s. Pass it and yours wins. - The Live tab starts from the room’s prepared destinations, and offers its call to action ready to put up: forward
GET …/streamsandGET …/ctaas they are (the catch-all route does), which carryrememberedandpreset. - Your logo shows in the call’s top bar while the room’s
look.logois on. Turn it off for one call in its Settings → Branding, or for your app with<CallRoom logo={false}>. - Your own setup pages can show what a template will look like without a call:
<ScenePreview scene="starting" title=… logoUrl=… color=… lines=… />draws a scene as streams show it, and<CallLookPreview logoUrl=… color=… />the call with the logo top right and a speaker’s title in the brand’s colour — both exported by the call UI.
Managing them through the API
Templates made here and on the dashboard are the same: list, get, create, update and delete them at /v1/templates. In a setup you send, only the parts you name change; the rest is as a plain meeting has it.
curl -X POST https://api.inlinemeet.com/v1/templates \
-H "Authorization: Bearer $INLINEMEET_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"name": "Weekly class",
"kind": "meeting",
"setup": {
"waitingRoom": true,
"participantsCanUnmute": false,
"layout": "spotlight",
"autoRecord": true,
"recordingActivity": { "qna": true, "polls": true }
}
}'A template, as the API answers it:
{
"id": "6703a1f0e1b2c3d4e5f60b12",
"name": "Product launch webinar",
"kind": "webinar",
"scope": null,
"default": false,
"setup": {
"waitingRoom": false,
"backstage": true,
"registration": false,
"joinBeforeHost": false,
"participantsCanUnmute": true,
"guestScreenShare": false,
"whiteboardLocked": true,
"whiteboardFollowHost": true,
"whiteboardHideCursors": false,
"layout": "spotlight",
"autoRecord": true,
"recordingActivity": { "chat": true, "qna": true, "polls": true, "reactions": false, "hands": false },
"look": { "logo": true, "titles": true, "lines": { "starting": "We go live at 4pm sharp" } },
"scene": "starting",
"stream": {
"savedIds": ["6702c0d1e1b2c3d4e5f60a77"],
"orientation": "landscape",
"activity": { "chat": true, "qna": true, "polls": true, "reactions": true, "hands": false },
"autoStart": true
},
"cta": { "headline": "See it on your own data", "label": "Book a demo", "url": "https://acme.example/demo" }
},
"createdAt": "2026-10-09T10:12:00.000Z",
"updatedAt": "2026-10-09T11:40:00.000Z"
}Its setup
| Field | Description |
|---|---|
waitingRoom, backstage, autoRecord, whiteboardLocked, whiteboardFollowHost, whiteboardHideCursorsboolean | As the room settings of the same names. backstage is a webinar’s; the last two only count with the whiteboard locked. |
participantsCanUnmute, guestScreenShareboolean | Who may speak up and share their screen, in a meeting. |
registration, joinBeforeHostboolean | For meetings booked on the dashboard with it. |
layout'auto' | 'grid' | 'spotlight' | 'sidebar' | How the call opens for everyone. |
scene'starting' | 'break' | 'ending' | null | The scene the stream and recording open on. |
lookobject | logo, titles, each scene’s lines, and theme: the colours of its recordings and streams, as the call’s --im-* tokens without the prefix — { "surface": "#ffffff", "accent": "#1e5b22", … }, or null for your brand’s. See Theming. |
recordingActivityobject | What the recording shows over the picture: chat, qna, polls, reactions, hands. |
streamActivityobject | The same for the stream — answered as stream.activity. |
streamobject | savedIds (up to 5), orientation, autoStart. |
ctaobject | null | { headline?, label, url } — a call to action ready to put up. |
Your customers’ own: scopes
If your app serves customers of its own — schools, classes, teams, clients — each can have templates, a brand and saved stream destinations nobody else sees. Name the customer with scope: any 1–64 letters, digits, :, ., _ or -, such as school:42. What you make with a scope is that scope’s alone:
- Templates:
POST /v1/templateswith"scope"in the body;GET /v1/templates?scope=school:42lists only that scope’s, and reading, changing or deleting one needs the same?scope=. Without a scope you get your workspace’s own — the ones the dashboard shows — and never a scope’s. - Rooms:
POST /v1/roomswith"scope"puts the room in it. Itstemplatemust be one of the scope’s, and so must any template it’s set up from again. A room created before it had a scope takes one the first time you name it; a room in another scope answers409 scope_mismatch. A scope has a default template of its own ("default": trueon one of its templates), which its new rooms naming none are set up from — never your workspace’s. - Brand:
PUT /v1/brandwith"scope"sets that customer’s logo and colour. Its rooms show them; whatever it hasn’t set comes from your workspace’s. For its recordings in its own app’s colours, give its templates alook.theme. - Saved destinations: saved with a scope (
POST /v1/stream-destinations, orsave: truewhen a host goes live in one of its rooms), a destination can be used only by that scope’s templates and rooms. The call’s Live tab lists only the room’s scope’s.
# A template for one school, then a room of theirs set up from it
curl -X POST https://api.inlinemeet.com/v1/templates -H "Authorization: Bearer $INLINEMEET_API_KEY" -H "Content-Type: application/json" -d '{ "scope": "school:42", "name": "Assembly", "kind": "meeting", "setup": { "waitingRoom": true } }'
curl -X POST https://api.inlinemeet.com/v1/rooms -H "Authorization: Bearer $INLINEMEET_API_KEY" -H "Content-Type: application/json" -d '{ "scope": "school:42", "code": "assembly-mon", "template": "6703a1f0e1b2c3d4e5f60b12" }'Turning streaming and webinars off
Two room settings are your app’s rather than its hosts’: allowLiveStreaming and allowWebinar. Off, the call doesn’t offer going live, or the switch that makes it a webinar — and the API refuses them (403 streaming_disabled, 403 webinar_disabled). Turning streaming off stops a stream in progress; turning webinars off makes a webinar a meeting again. Set them when you create or update a room; a host can’t turn them back on from the call, as long as your backend forwards the call’s Settings tab to PATCH /v1/rooms/:code/settings, which never takes them. The call UI’s own liveStreaming and webinar props hide the same buttons for your app as a whole.
Good to know
- Changing or deleting a template never touches rooms already set up from it. Deleting the default leaves none.
- On the dashboard, whoever made a template, the workspace’s owner and account managers can change it; anyone can use it. Only the owner and account managers choose the default. An API key can change any of the workspace’s.
- A webinar template needs a plan with webinars: creating a room from one on a plan without them answers
402 plan_required. Going live by itself needs a plan that streams; without one the destinations are dropped. - A saved destination forgotten since is dropped from the rooms it would have streamed to — the rest still go live.
- A workspace keeps up to 100 templates of its own, and each scope up to 100.