Venues and the call sheet

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.

List venues

GET /venues stages

Parameters

  • limit integer query

    Page size, 1–200.

    1–200. Default 50

  • cursor string query

    The next_cursor of 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)
  • items object[] required
    4 fields in items
    • id string required
    • name string required
    • timezone string required

      IANA, e.g. Europe/Zurich.

    • address string
  • next_cursor string or null required

    Pass as cursor for the next page; null on the last page.

curl "https://www.wunderframe.com/api/v1/venues?limit=50" \
  -H "Authorization: Bearer $WUNDERFRAME_API_KEY"
Response 200
{
  "items": [
    {
      "id": "ven_belvedere",
      "name": "Hotel Belvedere",
      "timezone": "Europe/Zurich",
      "address": "Bahnhofstrasse 1, Zürich"
    }
  ],
  "next_cursor": null
}
Error example
Response 401
{
  "error": {
    "code": "unauthorized",
    "message": "Missing or invalid API key."
  }
}

Create a venue

POST /venues stages

Request body required

  • name string required
  • timezone string
  • address string

Responses

  • 201 The venue.
  • 400 The request is invalid — details.field names 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)
  • id string required
  • name string required
  • timezone string required

    IANA, e.g. Europe/Zurich.

  • address string
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"
}'
Response 201
{
  "id": "ven_belvedere",
  "name": "Hotel Belvedere",
  "timezone": "Europe/Zurich",
  "address": "Bahnhofstrasse 1, Zürich"
}
Error example
Response 400
{
  "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

PUT /stages/{id}/idle stages

A 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

  • id string required path

    The stage id.

Request body required

  • story_id string or null required

Responses

  • 200 Done.
  • 400 The request is invalid — details.field names 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_id string
  • idle object
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"
}'
Response 200
{
  "stage_id": "string",
  "idle": {}
}
Error example
Response 400
{
  "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

PUT /stages/{id}/presence stages

Turns 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

  • id string required path

    The stage id.

Request body required

  • enabled boolean required
  • distance string

    One of close, near, room

  • leave_s number

    1–600

  • arrive_s number

    0–30

Responses

  • 200 Done.
  • 400 The request is invalid — details.field names 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_id string
  • presence object
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
}'
Response 200
{
  "stage_id": "string",
  "presence": {}
}
Error example
Response 400
{
  "error": {
    "code": "invalid",
    "message": "The request is invalid — `details.field` names the field when there is one."
  }
}

A stage’s screen calibration

GET /stages/{id}/calibration stages

What 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

  • id string required path

    The 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_id string
  • calibration object
    10 fields in calibration
    • version number
    • at number

      Saved at (epoch ms).

    • by string

      One of editor, screen, api

    • camera string or null
    • aspect number
    • face object or null

      { share, min_face }: the face’s share of the frame width where visitors stand, and the least that counts.

    • box object or null

      { top, right, bottom, left }: the comfort zone, mirrored frame fractions (each 0–0.9).

    • reach object or null

      { x, y, palm }: the comfort zone in palms.

    • pinch object or null

      { open_gap, closed_gap, close, open }: palms.

    • test object or null

      { hits, targets, ms }

curl "https://www.wunderframe.com/api/v1/stages/wkFRBzMq6POZ_qYJHvgQf/calibration" \
  -H "Authorization: Bearer $WUNDERFRAME_API_KEY"
Response 200
{
  "stage_id": "string",
  "calibration": {
    "version": 0,
    "at": 0,
    "by": "editor",
    "camera": "string",
    "aspect": 0,
    "face": {},
    "box": {},
    "reach": {},
    "pinch": {},
    "test": {}
  }
}
Error example
Response 401
{
  "error": {
    "code": "unauthorized",
    "message": "Missing or invalid API key."
  }
}

Open the calibration wizard on a stage’s screens

POST /stages/{id}/calibration stages

Sends 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

  • id string required path

    The stage id.

Request body required

  • action string required

    One of calibrate

Responses

  • 200 Asked.
  • 400 The request is invalid — details.field names 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_id string
  • screens number
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"
}'
Response 200
{
  "stage_id": "string",
  "screens": 0
}
Error example
Response 400
{
  "error": {
    "code": "invalid",
    "message": "The request is invalid — `details.field` names the field when there is one."
  }
}

Set a stage’s screen calibration

PUT /stages/{id}/calibration stages

Stores 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

  • id string required path

    The stage id.

Request body required

  • calibration object required

Responses

  • 200 Saved.
  • 400 The request is invalid — details.field names 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_id string
  • calibration object
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
    }
  }
}'
Response 200
{
  "stage_id": "string",
  "calibration": {}
}
Error example
Response 400
{
  "error": {
    "code": "invalid",
    "message": "The request is invalid — `details.field` names the field when there is one."
  }
}

Reset a stage’s screen calibration

DELETE /stages/{id}/calibration stages

Back to the defaults. Its screens hear it at once.

Parameters

  • id string required path

    The 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_id string
  • calibration any or null
curl -X DELETE "https://www.wunderframe.com/api/v1/stages/wkFRBzMq6POZ_qYJHvgQf/calibration" \
  -H "Authorization: Bearer $WUNDERFRAME_API_KEY"
Response 200
{
  "stage_id": "string",
  "calibration": null
}
Error example
Response 401
{
  "error": {
    "code": "unauthorized",
    "message": "Missing or invalid API key."
  }
}

A stage’s photo booth

GET /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

  • id string required path

    The stage id.

Responses

  • 200 The booth.
  • 400 The request is invalid — details.field names 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_id string
  • booth object

    The settings, plus has_camera, can_choose (hand gestures or the touch fallback) and problem (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"
Response 200
{
  "stage_id": "string",
  "booth": {}
}
Error example
Response 400
{
  "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)

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

  • id string required path

    The stage id.

Request body required

  • mode string

    One of display, photobooth

  • engagement_id string or null

    Where booth photos go; required for photobooth.

  • countdown_s integer

    One of 3, 5

  • flash object
    4 fields in flash
    • on boolean
    • tone string

      3200, 4500 or 6000 K.

      One of warm, neutral, cool

    • kelvin number

      2700–6500

    • strength number

      0.3–1

  • retries integer

    0–5

  • keep_timeout_s integer

    5–120

  • qr_s integer

    10–120

  • mirror_preview boolean

Responses

  • 200 The booth.
  • 400 The request is invalid — details.field names 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_id string
  • booth object

    The settings, plus has_camera, can_choose (hand gestures or the touch fallback) and problem (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
  }
}'
Response 200
{
  "stage_id": "string",
  "booth": {}
}
Error example
Response 400
{
  "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

PATCH /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

  • id string required path

    The stage id.

Request body required

  • mode string

    One of display, photobooth

  • engagement_id string or null

    Where booth photos go; required for photobooth.

  • countdown_s integer

    One of 3, 5

  • flash object
    4 fields in flash
    • on boolean
    • tone string

      3200, 4500 or 6000 K.

      One of warm, neutral, cool

    • kelvin number

      2700–6500

    • strength number

      0.3–1

  • retries integer

    0–5

  • keep_timeout_s integer

    5–120

  • qr_s integer

    10–120

  • mirror_preview boolean

Responses

  • 200 The booth.
  • 400 The request is invalid — details.field names 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_id string
  • booth object

    The settings, plus has_camera, can_choose (hand gestures or the touch fallback) and problem (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
  }
}'
Response 200
{
  "stage_id": "string",
  "booth": {}
}
Error example
Response 400
{
  "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

PUT /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

  • id string required path

    The stage id.

Request body required

  • enabled boolean
  • touch boolean
  • hand boolean
  • click string

    One of pinch, dwell, both

  • swipe boolean
  • idle_timeout_s number

    5–600

  • languages string[] or null
  • guidance object
    9 fields in guidance
    • enabled boolean
    • show string

      One of presence, always_when_idle

    • steps string[]

      In order; leave out for the gestures this stage understands.

    • style string

      One of line, solid, glass

    • backdrop string

      One of blur, panel, none

    • palette string

      One of airport, night, light, paper, custom

    • colors object

      Hex colours for palette custom.

    • title string

      Deutsch|English|Français; "" = no title. Default "So geht’s|How it works|Comment ça marche".

    • captions object

      Per gesture (raise, point, pinch, dwell, swipe), "Deutsch|English|Français".

Responses

  • 200 Done.
  • 400 The request is invalid — details.field names 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_id string
  • interaction object
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"
  ]
}'
Response 200
{
  "stage_id": "string",
  "interaction": {}
}
Error example
Response 400
{
  "error": {
    "code": "invalid",
    "message": "The request is invalid — `details.field` names the field when there is one."
  }
}

List the call sheet

GET /bookings stages

Parameters

  • limit integer query

    Page size, 1–200.

    1–200. Default 50

  • cursor string query

    The next_cursor of 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)
  • items object[] required
    10 fields in items
    • id string required
    • stage_id string required
    • story_id string required
    • start string required

      HH:MM, the venue’s clock.

    • end string required

      At or before start = past midnight.

    • days integer[]

      0 = Sunday … 6 = Saturday.

    • repeat string

      One of once, daily, weekly, biweekly, monthly_weekday, monthly_date, yearly

    • date_start string or null
    • date_end string or null
    • enabled boolean
  • next_cursor string or null required

    Pass as cursor for the next page; null on the last page.

curl "https://www.wunderframe.com/api/v1/bookings?limit=50" \
  -H "Authorization: Bearer $WUNDERFRAME_API_KEY"
Response 200
{
  "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
Response 401
{
  "error": {
    "code": "unauthorized",
    "message": "Missing or invalid API key."
  }
}

Book a story on a stage

POST /bookings stages

Weekly by default (days needed); once needs date_start. The same rules and sentences as the call sheet.

Request body required

  • stage_id string required

    Stage id or name.

  • story_id string required

    Story id or title.

  • start string required
  • end string required
  • days integer[]
  • repeat string
  • date_start string
  • date_end string

Responses

  • 201 The booking.
  • 400 The request is invalid — details.field names 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)
  • id string required
  • stage_id string required
  • story_id string required
  • start string required

    HH:MM, the venue’s clock.

  • end string required

    At or before start = past midnight.

  • days integer[]

    0 = Sunday … 6 = Saturday.

  • repeat string

    One of once, daily, weekly, biweekly, monthly_weekday, monthly_date, yearly

  • date_start string or null
  • date_end string or null
  • enabled boolean
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
  ]
}'
Response 201
{
  "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
Response 400
{
  "error": {
    "code": "invalid",
    "message": "The request is invalid — `details.field` names the field when there is one."
  }
}