Docs API reference
Sync data into records
Keep the words on your screens current from Studio Events, a CMS or any system that can send JSON.
The words on an event’s screens — session titles, speakers, rooms, times — already live in another system. Instead of typing them twice, let that system send them to Wunderframe whenever something changes. Screens that show the values update within seconds.
How the pieces fit
- A template scene has blanks such as
{title}and{speaker}. - A record holds the values for one ref — your key, for example
your-event/session/b-14. - Every filled scene with that ref plays the template with the record’s values.
You only ever send text by ref. The design, the order of scenes and the schedule stay in Wunderframe. New to templates? Read Templates and data first.
Set up
Build a template
Design one scene with blanks for every value your system sends — for example
{title},{speaker},{room}and{time}.Choose your refs
Use a stable id from your system, grouped with slashes:
your-event/session/b-14. Give the template a ref too, such asyour-event/session-template, so your system can name it.Create an API key
In Settings → Integrations, create a key with the
datascope.
Create a record
POST /records creates the record for a new ref with its values.
Every scene that plays the ref shows them straight away; a ref no scene plays yet is fine — its values appear as soon as
a scene uses it. If the ref already has a record, the call is refused with 409: change it instead (below).
curl -X POST "https://www.wunderframe.com/api/v1/records" \
-H "Authorization: Bearer $WUNDERFRAME_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"ref": "your-event/session/b-14",
"values": {
"title": "The AI-Native Startup",
"speaker": "Ada Lovelace",
"room": "Hall B",
"time": "14:00"
}
}'Sending the same values from a sync every time? PUT /records/{ref} creates the record when it is missing
and replaces it otherwise, so it is safe to repeat.
Send many changes
POST /records/batch is the endpoint for syncs. It takes up to
500 items; each item’s fields are merged into the record for its ref, so a partial update
(“the speaker changed”) keeps every other value.
curl -X POST "https://www.wunderframe.com/api/v1/records/batch" \
-H "Authorization: Bearer $WUNDERFRAME_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"items": [
{
"ref": "your-event/session/b-14",
"fields": {
"title": "The AI-Native Startup",
"speaker": "Ada Lovelace",
"room": "Hall B",
"time": "14:00"
}
},
{
"ref": "your-event/session/c-01",
"fields": {
"title": "Closing keynote",
"speaker": "Grace Hopper",
"room": "Main hall",
"time": "17:00"
},
"template": "your-event/session-template",
"title": "Closing keynote"
}
]
}'The second item names a template. No scene plays your-event/session/c-01 yet, so Wunderframe
creates a filled scene from the template, titled with title, ready to cast into a story.
{
"updated": 1,
"stored": 1,
"created": 1,
"unknown": []
}updated— items whose record already existed.stored— items whose record is new.created— filled scenes created from atemplate.unknown— refs no scene plays yet. Their values are kept and appear as soon as a scene uses the ref.
Change a single record
For one value at a time, PATCH the record. Only the blanks you send change, and the record is created if it
does not exist. Use PUT instead to replace every value, removing blanks you leave out.
curl -X PATCH "https://www.wunderframe.com/api/v1/records/your-event/session/b-14" \
-H "Authorization: Bearer $WUNDERFRAME_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"values": {
"speaker": "Grace Hopper"
}
}'A complete publish hook
Most agenda tools can run code, call a webhook or trigger an automation when content is published. Map your sessions to items and send them in batches:
// A publish hook for your agenda: send every changed session to Wunderframe.
const WUNDERFRAME = 'https://www.wunderframe.com/api/v1';
export async function onSessionsChanged(sessions) {
const items = sessions.map((s) => ({
ref: `your-event/session/${s.id}`,
fields: {
title: s.title,
speaker: s.speakers.map((p) => p.name).join(' & '),
room: s.room.name,
time: new Date(s.startsAt).toLocaleTimeString('de-CH', { hour: '2-digit', minute: '2-digit', timeZone: 'Europe/Zurich' })
}
}));
// Up to 500 items per call.
for (let i = 0; i < items.length; i += 500) {
const res = await fetch(`${WUNDERFRAME}/records/batch`, {
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.WUNDERFRAME_API_KEY}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({ items: items.slice(i, i + 500) })
});
const body = await res.json();
if (!res.ok) throw new Error(`Wunderframe refused the batch: ${body.error.message}`);
if (body.unknown.length) console.info('Stored, not on a screen yet:', body.unknown);
}
}Read what is stored
GET /records?prefix=your-event/session/ lists every record of a
group, sorted by ref. Each record shows its origin — api for values sent through the API, hand for values typed in the app — so you can spot local edits before your next sync overwrites them.