Event sync

Docs API reference

Event sync

For an event system that owns the program — Maravilla Studio’s Event Suite, or your own: send the whole event (rooms, speakers, sessions, tracks, translations) and Wunderframe makes or updates the agenda records, presenters, rooms, live sessions and shows, idempotently by your keys. Set the workspace brand from the event’s brand kit.

Apply an event

POST /events/apply authoring

The event’s whole program for one day (ref without a slash; one ref per day of a multi-day event). Rooms, speakers and sessions are addressed by your keys ([A-Za-z0-9_-], up to 64), so a second call with the same keys updates and a session that is gone keeps its record (see notes). Sessions take optional track, track_color (#RRGGBB), studio_path and extra — translated columns <field>_<de|en|fr|it> written into the agenda record. language: de, en, fr or it. dry_run: true writes nothing and returns what would change. Needs authoring, data, presenters, sessions and shows.

Request body required

  • event object required

    The EventPlan (see the description).

  • dry_run boolean

    Default false

  • origin string

    One of studio, api

Responses

  • 200 What was (or would be) made.
  • 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 (200)
  • dry_run boolean required
  • counts object required
    3 fields in counts
    • create integer
    • update integer
    • keep integer
  • steps object[] required
    6 fields in steps
    • kind string
    • ref string
    • title string
    • action string

      One of create, update, keep

    • note string
    • id string
  • clashes object[]
    3 fields in clashes
    • room string
    • a string
    • b string
  • notes string[]
  • stages object[]
    4 fields in stages
    • key string
    • name string
    • id string or null
    • player_url string or null
curl -X POST "https://www.wunderframe.com/api/v1/events/apply" \
  -H "Authorization: Bearer $WUNDERFRAME_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "event": {
    "ref": "st-0123456789abcdef",
    "title": "Digital Forum",
    "date": "2026-11-05",
    "time_zone": "Europe/Zurich",
    "language": "de",
    "rooms": [
      {
        "key": "a1b2c3d4e5f60718",
        "name": "Saal A",
        "label": "EG"
      }
    ],
    "speakers": [
      {
        "key": "9f8e7d6c5b4a3210",
        "name": "Ada Lovelace",
        "title": "Head of Research",
        "organization": "Analytical Engines Ltd",
        "photo_url": "https://example.com/ada.jpg"
      }
    ],
    "sessions": [
      {
        "key": "0f1e2d3c4b5a6978",
        "title": "Keynote",
        "room": "all",
        "start": "09:00",
        "end": "09:45",
        "kind": "plenary",
        "speakers": [
          "9f8e7d6c5b4a3210"
        ],
        "track": "Digital",
        "track_color": "#1fb6ff",
        "takeaway": "Where AI meets the venue",
        "studio_path": "/events/digital-forum/agenda/keynote",
        "extra": {
          "title_fr": "Discours d’ouverture",
          "title_en": "Keynote"
        }
      }
    ]
  },
  "dry_run": true,
  "origin": "studio"
}'
Response 200
{
  "dry_run": true,
  "counts": {
    "create": 9,
    "update": 0,
    "keep": 0
  },
  "steps": [
    {
      "kind": "record",
      "ref": "st-0123456789abcdef/agenda/0f1e2d3c4b5a6978",
      "title": "Keynote",
      "action": "create"
    }
  ],
  "clashes": [],
  "notes": [],
  "stages": []
}
Error example
Response 400
{
  "error": {
    "code": "invalid",
    "message": "The request is invalid — `details.field` names the field when there is one."
  }
}

Set the brand

PUT /brand brand

The workspace brand guest pages and screens share. primary_color (or accent_color) becomes the accent, with the words on it picked for contrast; logo_url (public https) is fetched once as the logo for light backgrounds. What is not sent stays.

Request body required

  • name string

    Up to 200 characters

  • primary_color string

    Pattern ^#[0-9a-fA-F]{3,6}$

  • accent_color string

    Pattern ^#[0-9a-fA-F]{3,6}$

  • logo_url string (uri)

Responses

  • 200 The brand as saved, and contrast warnings.
  • 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 (200)
  • brand object
    4 fields in brand
    • colors map of string
    • fonts object
      2 fields in fonts
      • heading string
      • body string
    • logo_asset_id string or null
    • logo_on_dark_asset_id string or null
  • warnings string[]
curl -X PUT "https://www.wunderframe.com/api/v1/brand" \
  -H "Authorization: Bearer $WUNDERFRAME_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "name": "Digital Forum",
  "primary_color": "#e4007c",
  "accent_color": "#1fb6ff",
  "logo_url": "https://example.com/logo.png"
}'
Response 200
{
  "brand": {
    "colors": {
      "background": "#0b1020",
      "surface": "#151b33",
      "text": "#ffffff",
      "muted": "#a3a9c2",
      "accent": "#e4007c",
      "accent_text": "#ffffff"
    },
    "fonts": {
      "heading": "outfit",
      "body": "outfit"
    },
    "logo_asset_id": "ast_1",
    "logo_on_dark_asset_id": null
  },
  "warnings": [
    "string"
  ]
}
Error example
Response 400
{
  "error": {
    "code": "invalid",
    "message": "The request is invalid — `details.field` names the field when there is one."
  }
}

Exchange a connect code

POST /connect/token none

After a workspace owner approved your site at /connect/studio?redirect_uri=…&state=…&code_challenge=… (PKCE S256), exchange the one-minute code for an API key. No API key needed: the code and its verifier are the credential.

Request body required

  • code string required
  • code_verifier string required
  • redirect_uri string (uri) required

Responses

  • 200 The key, shown once.
  • 400 The request is invalid — details.field names the field when there is one.
Response fields (200)
  • api_key string required

    Shown once: wfi.<id>.<secret>, with the connector’s scopes.

  • workspace_id string required
  • workspace_name string required
curl -X POST "https://www.wunderframe.com/api/v1/connect/token" \
  -H "Authorization: Bearer $WUNDERFRAME_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "code": "wfc_…",
  "code_verifier": "dBjftJeZ4CVP-mB92K27uhbUJU1p1r_wW1gFWFOEjXk",
  "redirect_uri": "https://studio.example.com/settings/wunderframe"
}'
Response 200
{
  "api_key": "wfi.0123456789abcdef.…",
  "workspace_id": "ws_team_1a2b3c",
  "workspace_name": "Digital Forum"
}
Error example
Response 400
{
  "error": {
    "code": "invalid",
    "message": "The request is invalid — `details.field` names the field when there is one."
  }
}