Docs API reference
Plan sessions and send invites
Book presenter sessions from your agenda tool and hand out invite links.
Your agenda tool knows which speaker presents where and when. This guide books those slots as Wunderframe sessions and creates each presenter’s personal link, so the operators on the day only have to watch backstage.
Before you start
Create a key with the sessions scope
In Settings → Integrations, create a key with
sessions— andpresentersif the same script imports speakers.Import your presenters
Sessions name presenters by id or by your presenter refs. Import them first with Import speakers from a CSV.
Create the first link in the app
Presenter links need a one-time setup by the workspace owner: open any session in Run → Sessions and create a link there once. Until then, creating links through the API answers
409 conflict.Find your stage and slide ids
A session needs the id of the stage it plays on, and usually a presenter slide — a scene with a presenter block. See the Stages reference to list your stages, or book one session in the app and read
stage_idandscene_idfrom the list below.
curl "https://www.wunderframe.com/api/v1/sessions?limit=5" \
-H "Authorization: Bearer $WUNDERFRAME_API_KEY"The agenda
Export your agenda in any shape; this guide uses a simple JSON file:
[
{
"id": "b-14",
"title": "The AI-Native Startup",
"stage_id": "st_hallB",
"scene_id": "sc_presenter",
"starts_at": "2026-10-08T14:00:00+02:00",
"duration_min": 30,
"speakers": ["speakerportal/1234", "speakerportal/1235"]
}
]Book sessions and create links
PUT /sessions/by-ref/{ref} creates the session the
first time (then stage_id and starts_at are required) and updates it on every later run. Then POST /sessions/{id}/invites creates a link for each
presenter who has none.
// plan-sessions.mjs — book sessions from agenda.json and print presenter links.
// Presenters must exist already (see "Import speakers from a CSV").
import { readFile } from 'node:fs/promises';
const BASE = 'https://www.wunderframe.com/api/v1';
const HEADERS = {
Authorization: `Bearer ${process.env.WUNDERFRAME_API_KEY}`,
'Content-Type': 'application/json'
};
async function call(method, path, body) {
const res = await fetch(BASE + path, { method, headers: HEADERS, body: body && JSON.stringify(body) });
const data = res.status === 204 ? null : await res.json();
if (!res.ok) throw Object.assign(new Error(data.error.message), { status: res.status, details: data.error.details });
return data;
}
const agenda = JSON.parse(await readFile('agenda.json', 'utf8'));
for (const slot of agenda) {
// 1. Create or update the session by your own id — safe to run again.
const session = await call('PUT', `/sessions/by-ref/agenda/${slot.id}`, {
title: slot.title,
stage_id: slot.stage_id,
scene_id: slot.scene_id,
starts_at: slot.starts_at,
duration_min: slot.duration_min,
go_live: 'at_start',
after_finish: 'release',
presenter_refs: slot.speakers
});
console.log(`\n${session.title} — ${session.starts_at_iso} (${session.status})`);
// 2. A link for every presenter who has none yet. Links are shown once: pass them on now.
for (const presenter of session.presenters) {
if (presenter.invite.status === 'active') {
console.log(` ${presenter.name}: already has a link`);
continue;
}
const { link } = await call('POST', `/sessions/${session.id}/invites`, { presenter_id: presenter.id });
console.log(` ${presenter.name}: ${link}`);
}
}The AI-Native Startup — 2026-10-08T12:00:00.000Z (scheduled)
Ada Lovelace: https://…/p/wfp.…
Grace Hopper: already has a linkSchedule rehearsals
Add a rehearsal a week or a day before. The same links open it, and nothing reaches a screen. Leave out starts_at to rehearse right now. The response includes a new link for any presenter who had none.
curl -X POST "https://www.wunderframe.com/api/v1/sessions/Zp4dW1qR8sN2mK7vB3xYc/rehearsals" \
-H "Authorization: Bearer $WUNDERFRAME_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"starts_at": "2026-10-07T14:00:00+02:00",
"duration_min": 30,
"note": "Tech check"
}'When the agenda changes
- A new time or length: run the script again, or
PATCHthe session with only the changed fields. - A different stage: allowed until the session is live; while it is live the change answers
409. - A presenter leaves the session: send the new
presenter_refslist. A presenter taken off the session loses their link. - Keep track:
GET /sessions?from=…&to=…&status=scheduled,backstage,readylists what is coming up, and each session shows whether its presenters have opened their link.
See the Sessions reference for every field, and Presenters and sessions for how each go-live mode behaves on the day.