Docs API reference
Venues and the call sheet
The places screens are in (each with its time zone), what a stage plays whenever nothing is booked, and the call sheet: stories booked on stages for time windows. A take or a rule still wins over a booking.
Every call needs an API key in the Authorization header. New to the API? Start with
the API overview.
- GET List venues /venues
- POST Create a venue /venues
- PUT Choose what a stage plays when nothing is booked /stages/{id}/idle
- PUT Notice people in front of a stage’s screen /stages/{id}/presence
- GET A stage’s screen calibration /stages/{id}/calibration
- POST Open the calibration wizard on a stage’s screens /stages/{id}/calibration
- PUT Set a stage’s screen calibration /stages/{id}/calibration
- DELETE Reset a stage’s screen calibration /stages/{id}/calibration
- GET A stage’s photo booth /stages/{id}/booth
- PUT Use a stage’s screen as a photo booth (PUT) /stages/{id}/booth
- PATCH Use a stage’s screen as a photo booth /stages/{id}/booth
- PUT Let visitors use a stage’s screen, in its languages /stages/{id}/interaction
- GET List the call sheet /bookings
- POST Book a story on a stage /bookings
List venues
/venues stagesParameters
limitinteger queryPage size, 1–200.
1–200. Default
50cursorstring queryThe
next_cursorof the previous page.
Responses
- 200 A page of venues.
- 401 Missing or invalid API key.
- 403 The key lacks the scope, or the role is read-only.
Response fields (200)
itemsobject[] required4 fields in
itemsidstring requirednamestring requiredtimezonestring requiredIANA, e.g. Europe/Zurich.
addressstring
next_cursorstring or null requiredPass as
cursorfor the next page;nullon the last page.
curl "https://www.wunderframe.com/api/v1/venues?limit=50" \
-H "Authorization: Bearer $WUNDERFRAME_API_KEY"{
"items": [
{
"id": "ven_belvedere",
"name": "Hotel Belvedere",
"timezone": "Europe/Zurich",
"address": "Bahnhofstrasse 1, Zürich"
}
],
"next_cursor": null
}Error example
{
"error": {
"code": "unauthorized",
"message": "Missing or invalid API key."
}
}Create a venue
/venues stagesRequest body required
namestring requiredtimezonestringaddressstring
Responses
- 201 The venue.
- 400 The request is invalid —
details.fieldnames the field when there is one. - 401 Missing or invalid API key.
- 403 The key lacks the scope, or the role is read-only.
Response fields (201)
idstring requirednamestring requiredtimezonestring requiredIANA, e.g. Europe/Zurich.
addressstring
curl -X POST "https://www.wunderframe.com/api/v1/venues" \
-H "Authorization: Bearer $WUNDERFRAME_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"name": "Hotel Belvedere",
"timezone": "Europe/Zurich"
}'{
"id": "ven_belvedere",
"name": "Hotel Belvedere",
"timezone": "Europe/Zurich",
"address": "Bahnhofstrasse 1, Zürich"
}Error example
{
"error": {
"code": "invalid",
"message": "The request is invalid — `details.field` names the field when there is one."
}
}Choose what a stage plays when nothing is booked
/stages/{id}/idle stagesA story it plays all day outside bookings, or null for the idle card with the venue’s name and clock. Its screens hear it at once.
Parameters
idstring required pathThe stage id.
Request body required
story_idstring or null required
Responses
- 200 Done.
- 400 The request is invalid —
details.fieldnames the field when there is one. - 401 Missing or invalid API key.
- 403 The key lacks the scope, or the role is read-only.
- 404 Not found in this workspace.
Response fields (200)
stage_idstringidleobject
curl -X PUT "https://www.wunderframe.com/api/v1/stages/wkFRBzMq6POZ_qYJHvgQf/idle" \
-H "Authorization: Bearer $WUNDERFRAME_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"story_id": "sto_news_tv"
}'{
"stage_id": "string",
"idle": {}
}Error example
{
"error": {
"code": "invalid",
"message": "The request is invalid — `details.field` names the field when there is one."
}
}Notice people in front of a stage’s screen
/stages/{id}/presence stagesTurns the stage’s camera on or off for presence rules (a stage rule with sensor presence: near, not_near, or near_for with { seconds }). distance is how close a face must be to count: close ≈ 1 m, near ≈ 2 m, room ≈ 4 m. leave_s: keep playing this long after they leave (default 10); arrive_s: seen this long before they count (default 1). Fields left out keep their value. Nothing is recorded — the screen only knows someone is there.
Parameters
idstring required pathThe stage id.
Request body required
enabledboolean requireddistancestringOne of
close,near,roomleave_snumber1–600
arrive_snumber0–30
Responses
- 200 Done.
- 400 The request is invalid —
details.fieldnames the field when there is one. - 401 Missing or invalid API key.
- 403 The key lacks the scope, or the role is read-only.
- 404 Not found in this workspace.
Response fields (200)
stage_idstringpresenceobject
curl -X PUT "https://www.wunderframe.com/api/v1/stages/wkFRBzMq6POZ_qYJHvgQf/presence" \
-H "Authorization: Bearer $WUNDERFRAME_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"enabled": true,
"distance": "close",
"leave_s": 10
}'{
"stage_id": "string",
"presence": {}
}Error example
{
"error": {
"code": "invalid",
"message": "The request is invalid — `details.field` names the field when there is one."
}
}A stage’s screen calibration
/stages/{id}/calibration stagesWhat the calibration wizard measured on the screen (spec 18 §5b): the face distance where visitors stand, the comfort zone a relaxed hand moves in (the active box), its reach in palms, and the pinch thresholds of this camera. Null = the defaults.
Parameters
idstring required pathThe stage id.
Responses
- 200 The calibration.
- 401 Missing or invalid API key.
- 403 The key lacks the scope, or the role is read-only.
- 404 Not found in this workspace.
Response fields (200)
stage_idstringcalibrationobject10 fields in
calibrationversionnumberatnumberSaved at (epoch ms).
bystringOne of
editor,screen,apicamerastring or nullaspectnumberfaceobject or null{ share, min_face }: the face’s share of the frame width where visitors stand, and the least that counts.
boxobject or null{ top, right, bottom, left }: the comfort zone, mirrored frame fractions (each 0–0.9).
reachobject or null{ x, y, palm }: the comfort zone in palms.
pinchobject or null{ open_gap, closed_gap, close, open }: palms.
testobject or null{ hits, targets, ms }
curl "https://www.wunderframe.com/api/v1/stages/wkFRBzMq6POZ_qYJHvgQf/calibration" \
-H "Authorization: Bearer $WUNDERFRAME_API_KEY"{
"stage_id": "string",
"calibration": {
"version": 0,
"at": 0,
"by": "editor",
"camera": "string",
"aspect": 0,
"face": {},
"box": {},
"reach": {},
"pinch": {},
"test": {}
}
}Error example
{
"error": {
"code": "unauthorized",
"message": "Missing or invalid API key."
}
}Open the calibration wizard on a stage’s screens
/stages/{id}/calibration stagesSends calibrate to every browser screen of the stage: the guided wizard opens on the screen (stand where visitors stand, trace a comfortable rectangle, open and pinch three times, a test), in German, English or French. Saving there stores it for the stage. Answers how many screens were asked.
Parameters
idstring required pathThe stage id.
Request body required
actionstring requiredOne of
calibrate
Responses
- 200 Asked.
- 400 The request is invalid —
details.fieldnames the field when there is one. - 401 Missing or invalid API key.
- 403 The key lacks the scope, or the role is read-only.
- 404 Not found in this workspace.
Response fields (200)
stage_idstringscreensnumber
curl -X POST "https://www.wunderframe.com/api/v1/stages/wkFRBzMq6POZ_qYJHvgQf/calibration" \
-H "Authorization: Bearer $WUNDERFRAME_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"action": "calibrate"
}'{
"stage_id": "string",
"screens": 0
}Error example
{
"error": {
"code": "invalid",
"message": "The request is invalid — `details.field` names the field when there is one."
}
}Set a stage’s screen calibration
/stages/{id}/calibration stagesStores a calibration (as the wizard makes it); a part that makes no sense is dropped. Usually made on the screen with *Calibrate this screen* instead. Its screens hear it at once.
Parameters
idstring required pathThe stage id.
Request body required
calibrationobject required
Responses
- 200 Saved.
- 400 The request is invalid —
details.fieldnames the field when there is one. - 401 Missing or invalid API key.
- 403 The key lacks the scope, or the role is read-only.
- 404 Not found in this workspace.
Response fields (200)
stage_idstringcalibrationobject
curl -X PUT "https://www.wunderframe.com/api/v1/stages/wkFRBzMq6POZ_qYJHvgQf/calibration" \
-H "Authorization: Bearer $WUNDERFRAME_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"calibration": {
"face": {
"share": 0.18
},
"box": {
"top": 0.55,
"right": 0.3,
"bottom": 0.02,
"left": 0.28
},
"reach": {
"x": 3.1,
"y": 2.6,
"palm": 0.14
},
"pinch": {
"open_gap": 1.1,
"closed_gap": 0.12,
"close": 0.46,
"open": 0.71
}
}
}'{
"stage_id": "string",
"calibration": {}
}Error example
{
"error": {
"code": "invalid",
"message": "The request is invalid — `details.field` names the field when there is one."
}
}Reset a stage’s screen calibration
/stages/{id}/calibration stagesBack to the defaults. Its screens hear it at once.
Parameters
idstring required pathThe stage id.
Responses
- 200 Reset.
- 401 Missing or invalid API key.
- 403 The key lacks the scope, or the role is read-only.
- 404 Not found in this workspace.
Response fields (200)
stage_idstringcalibrationany or null
curl -X DELETE "https://www.wunderframe.com/api/v1/stages/wkFRBzMq6POZ_qYJHvgQf/calibration" \
-H "Authorization: Bearer $WUNDERFRAME_API_KEY"{
"stage_id": "string",
"calibration": null
}Error example
{
"error": {
"code": "unauthorized",
"message": "Missing or invalid API key."
}
}A stage’s photo booth
/stages/{id}/booth stages*Use this screen as* Display only or Photo booth (spec 33 §5): on a Photo booth stage a photo-booth block lets visitors take a polaroid at the screen with hand gestures — consent line, live face framing, countdown, a warm screen flash, Keep or Again, and a take-home QR; the photo is posted to engagement_id with source: "booth" (its moderation and retention apply). Display only: the block shows the phone QR. flash.tone warm | neutral | cool sets kelvin (3200 / 4500 / 6000 K). Needs a camera and a way to choose on the stage (hands in /interaction; or /presence plus the touch fallback — presence alone gives problem no_interaction), and a photo-booth block in a scene it plays. Fields left out keep their value; its screens hear it at once.
Parameters
idstring required pathThe stage id.
Responses
- 200 The booth.
- 400 The request is invalid —
details.fieldnames the field when there is one. - 401 Missing or invalid API key.
- 403 The key lacks the scope, or the role is read-only.
- 404 Not found in this workspace.
Response fields (200)
stage_idstringboothobjectThe settings, plus
has_camera,can_choose(hand gestures or the touch fallback) andproblem(no_engagement, no_camera, no_interaction — the presence camera alone takes no input; null when it takes pictures).
curl "https://www.wunderframe.com/api/v1/stages/wkFRBzMq6POZ_qYJHvgQf/booth" \
-H "Authorization: Bearer $WUNDERFRAME_API_KEY"{
"stage_id": "string",
"booth": {}
}Error example
{
"error": {
"code": "invalid",
"message": "The request is invalid — `details.field` names the field when there is one."
}
}Use a stage’s screen as a photo booth (PUT)
/stages/{id}/booth stages*Use this screen as* Display only or Photo booth (spec 33 §5): on a Photo booth stage a photo-booth block lets visitors take a polaroid at the screen with hand gestures — consent line, live face framing, countdown, a warm screen flash, Keep or Again, and a take-home QR; the photo is posted to engagement_id with source: "booth" (its moderation and retention apply). Display only: the block shows the phone QR. flash.tone warm | neutral | cool sets kelvin (3200 / 4500 / 6000 K). Needs a camera and a way to choose on the stage (hands in /interaction; or /presence plus the touch fallback — presence alone gives problem no_interaction), and a photo-booth block in a scene it plays. Fields left out keep their value; its screens hear it at once.
Parameters
idstring required pathThe stage id.
Request body required
modestringOne of
display,photoboothengagement_idstring or nullWhere booth photos go; required for photobooth.
countdown_sintegerOne of
3,5flashobject4 fields in
flashonbooleantonestring3200, 4500 or 6000 K.
One of
warm,neutral,coolkelvinnumber2700–6500
strengthnumber0.3–1
retriesinteger0–5
keep_timeout_sinteger5–120
qr_sinteger10–120
mirror_previewboolean
Responses
- 200 The booth.
- 400 The request is invalid —
details.fieldnames the field when there is one. - 401 Missing or invalid API key.
- 403 The key lacks the scope, or the role is read-only.
- 404 Not found in this workspace.
Response fields (200)
stage_idstringboothobjectThe settings, plus
has_camera,can_choose(hand gestures or the touch fallback) andproblem(no_engagement, no_camera, no_interaction — the presence camera alone takes no input; null when it takes pictures).
curl -X PUT "https://www.wunderframe.com/api/v1/stages/wkFRBzMq6POZ_qYJHvgQf/booth" \
-H "Authorization: Bearer $WUNDERFRAME_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"mode": "photobooth",
"engagement_id": "eng_moments",
"flash": {
"on": true,
"tone": "warm",
"strength": 0.85
}
}'{
"stage_id": "string",
"booth": {}
}Error example
{
"error": {
"code": "invalid",
"message": "The request is invalid — `details.field` names the field when there is one."
}
}Use a stage’s screen as a photo booth
/stages/{id}/booth stages*Use this screen as* Display only or Photo booth (spec 33 §5): on a Photo booth stage a photo-booth block lets visitors take a polaroid at the screen with hand gestures — consent line, live face framing, countdown, a warm screen flash, Keep or Again, and a take-home QR; the photo is posted to engagement_id with source: "booth" (its moderation and retention apply). Display only: the block shows the phone QR. flash.tone warm | neutral | cool sets kelvin (3200 / 4500 / 6000 K). Needs a camera and a way to choose on the stage (hands in /interaction; or /presence plus the touch fallback — presence alone gives problem no_interaction), and a photo-booth block in a scene it plays. Fields left out keep their value; its screens hear it at once.
Parameters
idstring required pathThe stage id.
Request body required
modestringOne of
display,photoboothengagement_idstring or nullWhere booth photos go; required for photobooth.
countdown_sintegerOne of
3,5flashobject4 fields in
flashonbooleantonestring3200, 4500 or 6000 K.
One of
warm,neutral,coolkelvinnumber2700–6500
strengthnumber0.3–1
retriesinteger0–5
keep_timeout_sinteger5–120
qr_sinteger10–120
mirror_previewboolean
Responses
- 200 The booth.
- 400 The request is invalid —
details.fieldnames the field when there is one. - 401 Missing or invalid API key.
- 403 The key lacks the scope, or the role is read-only.
- 404 Not found in this workspace.
Response fields (200)
stage_idstringboothobjectThe settings, plus
has_camera,can_choose(hand gestures or the touch fallback) andproblem(no_engagement, no_camera, no_interaction — the presence camera alone takes no input; null when it takes pictures).
curl -X PATCH "https://www.wunderframe.com/api/v1/stages/wkFRBzMq6POZ_qYJHvgQf/booth" \
-H "Authorization: Bearer $WUNDERFRAME_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"mode": "photobooth",
"engagement_id": "eng_moments",
"flash": {
"on": true,
"tone": "warm",
"strength": 0.85
}
}'{
"stage_id": "string",
"booth": {}
}Error example
{
"error": {
"code": "invalid",
"message": "The request is invalid — `details.field` names the field when there is one."
}
}Let visitors use a stage’s screen, in its languages
/stages/{id}/interaction stages*Visitors can use this screen*: touch, a hand pointer (click: pinch, dwell or both), swiping, and idle_timeout_s (back to the story after that long without a visitor). languages: the languages the screen speaks, ISO 639 codes, the FIRST is the default (["de","en","fr"]) — a visitor switches with a language-switch block or a set_language button, everything on the screen follows, and the screen returns to the first when the visitor leaves; Live lists and tickers turn through them even without a visitor. [] removes them. guidance: the stage’s own gesture guide — a drawn hand laid over the screen while someone is there (show: "presence", the stage camera; or "always_when_idle") and nobody uses it, gone the moment a hand goes up; needs hand. Merged field by field over what the stage has. Fields left out keep their value.
Parameters
idstring required pathThe stage id.
Request body required
enabledbooleantouchbooleanhandbooleanclickstringOne of
pinch,dwell,bothswipebooleanidle_timeout_snumber5–600
languagesstring[] or nullguidanceobject9 fields in
guidanceenabledbooleanshowstringOne of
presence,always_when_idlestepsstring[]In order; leave out for the gestures this stage understands.
stylestringOne of
line,solid,glassbackdropstringOne of
blur,panel,nonepalettestringOne of
airport,night,light,paper,customcolorsobjectHex colours for palette custom.
titlestringDeutsch|English|Français; "" = no title. Default "So geht’s|How it works|Comment ça marche".
captionsobjectPer gesture (raise, point, pinch, dwell, swipe), "Deutsch|English|Français".
Responses
- 200 Done.
- 400 The request is invalid —
details.fieldnames the field when there is one. - 401 Missing or invalid API key.
- 403 The key lacks the scope, or the role is read-only.
- 404 Not found in this workspace.
Response fields (200)
stage_idstringinteractionobject
curl -X PUT "https://www.wunderframe.com/api/v1/stages/wkFRBzMq6POZ_qYJHvgQf/interaction" \
-H "Authorization: Bearer $WUNDERFRAME_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"enabled": true,
"touch": true,
"languages": [
"de",
"en",
"fr"
]
}'{
"stage_id": "string",
"interaction": {}
}Error example
{
"error": {
"code": "invalid",
"message": "The request is invalid — `details.field` names the field when there is one."
}
}List the call sheet
/bookings stagesParameters
limitinteger queryPage size, 1–200.
1–200. Default
50cursorstring queryThe
next_cursorof the previous page.
Responses
- 200 A page of bookings.
- 401 Missing or invalid API key.
- 403 The key lacks the scope, or the role is read-only.
Response fields (200)
itemsobject[] required10 fields in
itemsidstring requiredstage_idstring requiredstory_idstring requiredstartstring requiredHH:MM, the venue’s clock.
endstring requiredAt or before start = past midnight.
daysinteger[]0 = Sunday … 6 = Saturday.
repeatstringOne of
once,daily,weekly,biweekly,monthly_weekday,monthly_date,yearlydate_startstring or nulldate_endstring or nullenabledboolean
next_cursorstring or null requiredPass as
cursorfor the next page;nullon the last page.
curl "https://www.wunderframe.com/api/v1/bookings?limit=50" \
-H "Authorization: Bearer $WUNDERFRAME_API_KEY"{
"items": [
{
"id": "bk_1",
"stage_id": "stg_lobby",
"story_id": "sto_news_tv",
"start": "07:00",
"end": "19:00",
"days": [
1,
2,
3,
4,
5
],
"repeat": "weekly",
"date_start": null,
"date_end": null,
"enabled": true
}
],
"next_cursor": null
}Error example
{
"error": {
"code": "unauthorized",
"message": "Missing or invalid API key."
}
}Book a story on a stage
/bookings stagesWeekly by default (days needed); once needs date_start. The same rules and sentences as the call sheet.
Request body required
stage_idstring requiredStage id or name.
story_idstring requiredStory id or title.
startstring requiredendstring requireddaysinteger[]repeatstringdate_startstringdate_endstring
Responses
- 201 The booking.
- 400 The request is invalid —
details.fieldnames the field when there is one. - 401 Missing or invalid API key.
- 403 The key lacks the scope, or the role is read-only.
Response fields (201)
idstring requiredstage_idstring requiredstory_idstring requiredstartstring requiredHH:MM, the venue’s clock.
endstring requiredAt or before start = past midnight.
daysinteger[]0 = Sunday … 6 = Saturday.
repeatstringOne of
once,daily,weekly,biweekly,monthly_weekday,monthly_date,yearlydate_startstring or nulldate_endstring or nullenabledboolean
curl -X POST "https://www.wunderframe.com/api/v1/bookings" \
-H "Authorization: Bearer $WUNDERFRAME_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"stage_id": "stg_lobby",
"story_id": "sto_news_tv",
"start": "07:00",
"end": "19:00",
"days": [
1,
2,
3,
4,
5
]
}'{
"id": "bk_1",
"stage_id": "stg_lobby",
"story_id": "sto_news_tv",
"start": "07:00",
"end": "19:00",
"days": [
1,
2,
3,
4,
5
],
"repeat": "weekly",
"date_start": null,
"date_end": null,
"enabled": true
}Error example
{
"error": {
"code": "invalid",
"message": "The request is invalid — `details.field` names the field when there is one."
}
}