Docs API reference
Presenters
The people who present live on your screens. Import them from a speaker portal or CRM with your own ref, keep them in sync with an idempotent upsert, and upload their photos.
Every call needs an API key in the Authorization header. New to the API? Start with
the API overview.
- GET List presenters /presenters
- POST Create a presenter /presenters
- GET Get a presenter /presenters/{id}
- PATCH Update a presenter /presenters/{id}
- DELETE Delete a presenter /presenters/{id}
- GET Get a presenter by your ref /presenters/by-ref/{ref}
- PUT Create or update a presenter by your ref /presenters/by-ref/{ref}
- POST Import presenters in bulk /presenters/import
- PUT Upload a presenter photo /presenters/{id}/photo
- DELETE Remove a presenter photo /presenters/{id}/photo
List presenters
/presenters presentersSorted by name. Filter by your ref, search q in name, title and organization, or fetch only changes with updated_since.
Parameters
refstring queryOnly the presenter with this ref.
qstring querySearch name, title and organization.
updated_sinceinteger queryEpoch ms: only presenters changed since.
limitinteger queryPage size, 1–200.
1–200. Default
50cursorstring queryThe
next_cursorof the previous page.
Responses
- 200 A page of presenters.
- 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 (200)
itemsobject[] required11 fields in
itemsidstring required read-onlyrefstring or nullYour own id for the presenter. Unique in the workspace.
Pattern
^[A-Za-z0-9][A-Za-z0-9._:/-]{0,199}$namestring requiredUp to 200 characters
titlestringShown in the lower third.
Up to 200 characters
organizationstringUp to 200 characters
emailstring (email)biostringUp to 4000 characters
photo_asset_idstring or null read-onlyphoto_urlstring or null read-onlyA signed URL, valid for about an hour.
created_atinteger read-onlyupdated_atinteger read-only
next_cursorstring or null requiredPass as
cursorfor the next page;nullon the last page.
curl "https://www.wunderframe.com/api/v1/presenters?limit=50" \
-H "Authorization: Bearer $WUNDERFRAME_API_KEY"{
"items": [
{
"id": "wkFRBzMq6POZ_qYJHvgQf",
"ref": "speakerportal/1234",
"name": "Ada Lovelace",
"title": "Head of Research",
"organization": "Analytical Engines Ltd",
"email": "ada@example.com",
"bio": "Writes the first programs.",
"photo_url": "https://…signed…",
"photo_asset_id": "a1b2c3",
"created_at": 1789372800000,
"updated_at": 1789372800000
}
],
"next_cursor": null
}Error example
{
"error": {
"code": "invalid",
"message": "The request is invalid — `details.field` names the field when there is one."
}
}Create a presenter
/presenters presentersPrefer the upsert by ref for syncs: calling it twice is safe.
Request body required
refstring or nullPattern
^[A-Za-z0-9][A-Za-z0-9._:/-]{0,199}$namestringRequired when creating.
Up to 200 characters
titlestringUp to 200 characters
organizationstringUp to 200 characters
emailstring (email)biostringUp to 4000 characters
photo_urlstring (uri)A public https image (JPEG, PNG, WebP, GIF, ≤ 10 MB) that Wunderframe fetches and stores as the photo. Sending the same URL again later does not fetch it again, so repeated imports are cheap; use a new URL (or the photo endpoint) to replace the image.
Responses
- 201 Created.
- 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.
- 409 Conflicts with the current state.
- 413 Too large.
- 415 Unsupported media type.
Response fields (201)
idstring required read-onlyrefstring or nullYour own id for the presenter. Unique in the workspace.
Pattern
^[A-Za-z0-9][A-Za-z0-9._:/-]{0,199}$namestring requiredUp to 200 characters
titlestringShown in the lower third.
Up to 200 characters
organizationstringUp to 200 characters
emailstring (email)biostringUp to 4000 characters
photo_asset_idstring or null read-onlyphoto_urlstring or null read-onlyA signed URL, valid for about an hour.
created_atinteger read-onlyupdated_atinteger read-only
curl -X POST "https://www.wunderframe.com/api/v1/presenters" \
-H "Authorization: Bearer $WUNDERFRAME_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"ref": "speakerportal/1234",
"name": "Ada Lovelace",
"title": "Head of Research",
"organization": "Analytical Engines Ltd",
"email": "ada@example.com",
"bio": "Writes the first programs.",
"photo_url": "https://example.com/photos/ada.jpg"
}'{
"id": "wkFRBzMq6POZ_qYJHvgQf",
"ref": "speakerportal/1234",
"name": "Ada Lovelace",
"title": "Head of Research",
"organization": "Analytical Engines Ltd",
"email": "ada@example.com",
"bio": "Writes the first programs.",
"photo_url": "https://…signed…",
"photo_asset_id": "a1b2c3",
"created_at": 1789372800000,
"updated_at": 1789372800000
}Error example
{
"error": {
"code": "invalid",
"message": "The request is invalid — `details.field` names the field when there is one."
}
}Get a presenter
/presenters/{id} presentersParameters
idstring required pathThe presenter id.
Responses
- 200 The presenter.
- 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)
idstring required read-onlyrefstring or nullYour own id for the presenter. Unique in the workspace.
Pattern
^[A-Za-z0-9][A-Za-z0-9._:/-]{0,199}$namestring requiredUp to 200 characters
titlestringShown in the lower third.
Up to 200 characters
organizationstringUp to 200 characters
emailstring (email)biostringUp to 4000 characters
photo_asset_idstring or null read-onlyphoto_urlstring or null read-onlyA signed URL, valid for about an hour.
created_atinteger read-onlyupdated_atinteger read-only
curl "https://www.wunderframe.com/api/v1/presenters/wkFRBzMq6POZ_qYJHvgQf" \
-H "Authorization: Bearer $WUNDERFRAME_API_KEY"{
"id": "wkFRBzMq6POZ_qYJHvgQf",
"ref": "speakerportal/1234",
"name": "Ada Lovelace",
"title": "Head of Research",
"organization": "Analytical Engines Ltd",
"email": "ada@example.com",
"bio": "Writes the first programs.",
"photo_url": "https://…signed…",
"photo_asset_id": "a1b2c3",
"created_at": 1789372800000,
"updated_at": 1789372800000
}Error example
{
"error": {
"code": "unauthorized",
"message": "Missing or invalid API key."
}
}Update a presenter
/presenters/{id} presentersOnly the fields you send change. Send photo_url to replace the photo.
Parameters
idstring required pathThe presenter id.
Request body required
refstring or nullPattern
^[A-Za-z0-9][A-Za-z0-9._:/-]{0,199}$namestringRequired when creating.
Up to 200 characters
titlestringUp to 200 characters
organizationstringUp to 200 characters
emailstring (email)biostringUp to 4000 characters
photo_urlstring (uri)A public https image (JPEG, PNG, WebP, GIF, ≤ 10 MB) that Wunderframe fetches and stores as the photo. Sending the same URL again later does not fetch it again, so repeated imports are cheap; use a new URL (or the photo endpoint) to replace the image.
Responses
- 200 Updated.
- 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.
- 409 Conflicts with the current state.
Response fields (200)
idstring required read-onlyrefstring or nullYour own id for the presenter. Unique in the workspace.
Pattern
^[A-Za-z0-9][A-Za-z0-9._:/-]{0,199}$namestring requiredUp to 200 characters
titlestringShown in the lower third.
Up to 200 characters
organizationstringUp to 200 characters
emailstring (email)biostringUp to 4000 characters
photo_asset_idstring or null read-onlyphoto_urlstring or null read-onlyA signed URL, valid for about an hour.
created_atinteger read-onlyupdated_atinteger read-only
curl -X PATCH "https://www.wunderframe.com/api/v1/presenters/wkFRBzMq6POZ_qYJHvgQf" \
-H "Authorization: Bearer $WUNDERFRAME_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"title": "Chief Scientist"
}'{
"id": "wkFRBzMq6POZ_qYJHvgQf",
"ref": "speakerportal/1234",
"name": "Ada Lovelace",
"title": "Head of Research",
"organization": "Analytical Engines Ltd",
"email": "ada@example.com",
"bio": "Writes the first programs.",
"photo_url": "https://…signed…",
"photo_asset_id": "a1b2c3",
"created_at": 1789372800000,
"updated_at": 1789372800000
}Error example
{
"error": {
"code": "invalid",
"message": "The request is invalid — `details.field` names the field when there is one."
}
}Delete a presenter
/presenters/{id} presentersRefused with 409 conflict while the presenter is in a session that has not finished. Their photo stays in the media library.
Parameters
idstring required pathThe presenter id.
Responses
- 204 Deleted.
- 401 Missing or invalid API key.
- 403 The key lacks the scope, or the role is read-only.
- 404 Not found in this workspace.
- 409 Conflicts with the current state.
curl -X DELETE "https://www.wunderframe.com/api/v1/presenters/wkFRBzMq6POZ_qYJHvgQf" \
-H "Authorization: Bearer $WUNDERFRAME_API_KEY"204 — no body.
Error example
{
"error": {
"code": "unauthorized",
"message": "Missing or invalid API key."
}
}Get a presenter by your ref
/presenters/by-ref/{ref} presentersParameters
refstring required pathYour ref. May contain slashes:
/presenters/by-ref/speakerportal/1234.
Responses
- 200 The presenter.
- 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)
idstring required read-onlyrefstring or nullYour own id for the presenter. Unique in the workspace.
Pattern
^[A-Za-z0-9][A-Za-z0-9._:/-]{0,199}$namestring requiredUp to 200 characters
titlestringShown in the lower third.
Up to 200 characters
organizationstringUp to 200 characters
emailstring (email)biostringUp to 4000 characters
photo_asset_idstring or null read-onlyphoto_urlstring or null read-onlyA signed URL, valid for about an hour.
created_atinteger read-onlyupdated_atinteger read-only
curl "https://www.wunderframe.com/api/v1/presenters/by-ref/speakerportal/1234" \
-H "Authorization: Bearer $WUNDERFRAME_API_KEY"{
"id": "wkFRBzMq6POZ_qYJHvgQf",
"ref": "speakerportal/1234",
"name": "Ada Lovelace",
"title": "Head of Research",
"organization": "Analytical Engines Ltd",
"email": "ada@example.com",
"bio": "Writes the first programs.",
"photo_url": "https://…signed…",
"photo_asset_id": "a1b2c3",
"created_at": 1789372800000,
"updated_at": 1789372800000
}Error example
{
"error": {
"code": "unauthorized",
"message": "Missing or invalid API key."
}
}Create or update a presenter by your ref
/presenters/by-ref/{ref} presentersThe sync endpoint. Creates the presenter when no presenter has this ref (then name is required), otherwise updates the fields you send. Safe to repeat.
Parameters
refstring required pathYour ref. May contain slashes.
Request body required
refstring or nullPattern
^[A-Za-z0-9][A-Za-z0-9._:/-]{0,199}$namestringRequired when creating.
Up to 200 characters
titlestringUp to 200 characters
organizationstringUp to 200 characters
emailstring (email)biostringUp to 4000 characters
photo_urlstring (uri)A public https image (JPEG, PNG, WebP, GIF, ≤ 10 MB) that Wunderframe fetches and stores as the photo. Sending the same URL again later does not fetch it again, so repeated imports are cheap; use a new URL (or the photo endpoint) to replace the image.
Responses
- 200 Updated.
- 201 Created.
- 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.
- 409 Conflicts with the current state.
- 413 Too large.
- 415 Unsupported media type.
Response fields (200)
idstring required read-onlyrefstring or nullYour own id for the presenter. Unique in the workspace.
Pattern
^[A-Za-z0-9][A-Za-z0-9._:/-]{0,199}$namestring requiredUp to 200 characters
titlestringShown in the lower third.
Up to 200 characters
organizationstringUp to 200 characters
emailstring (email)biostringUp to 4000 characters
photo_asset_idstring or null read-onlyphoto_urlstring or null read-onlyA signed URL, valid for about an hour.
created_atinteger read-onlyupdated_atinteger read-only
Response fields (201)
idstring required read-onlyrefstring or nullYour own id for the presenter. Unique in the workspace.
Pattern
^[A-Za-z0-9][A-Za-z0-9._:/-]{0,199}$namestring requiredUp to 200 characters
titlestringShown in the lower third.
Up to 200 characters
organizationstringUp to 200 characters
emailstring (email)biostringUp to 4000 characters
photo_asset_idstring or null read-onlyphoto_urlstring or null read-onlyA signed URL, valid for about an hour.
created_atinteger read-onlyupdated_atinteger read-only
curl -X PUT "https://www.wunderframe.com/api/v1/presenters/by-ref/speakerportal/1234" \
-H "Authorization: Bearer $WUNDERFRAME_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"name": "Ada Lovelace",
"title": "Head of Research",
"organization": "Analytical Engines Ltd"
}'{
"id": "wkFRBzMq6POZ_qYJHvgQf",
"ref": "speakerportal/1234",
"name": "Ada Lovelace",
"title": "Head of Research",
"organization": "Analytical Engines Ltd",
"email": "ada@example.com",
"bio": "Writes the first programs.",
"photo_url": "https://…signed…",
"photo_asset_id": "a1b2c3",
"created_at": 1789372800000,
"updated_at": 1789372800000
}Error example
{
"error": {
"code": "invalid",
"message": "The request is invalid — `details.field` names the field when there is one."
}
}Import presenters in bulk
/presenters/import presentersUp to 500 upserts by ref in one call. Every item needs a ref. A row that fails is reported in failed and never stops the others.
Request body required
itemsobject[] requiredUp to 500 items
7 fields in
itemsrefstring or nullPattern
^[A-Za-z0-9][A-Za-z0-9._:/-]{0,199}$namestringRequired when creating.
Up to 200 characters
titlestringUp to 200 characters
organizationstringUp to 200 characters
emailstring (email)biostringUp to 4000 characters
photo_urlstring (uri)A public https image (JPEG, PNG, WebP, GIF, ≤ 10 MB) that Wunderframe fetches and stores as the photo. Sending the same URL again later does not fetch it again, so repeated imports are cheap; use a new URL (or the photo endpoint) to replace the image.
Responses
- 200 What happened to each row.
- 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 (200)
createdinteger requiredupdatedinteger requiredfailedobject[] required3 fields in
failedindexintegerrefstring or nullerrorobject2 fields in
errorcodestringmessagestring
curl -X POST "https://www.wunderframe.com/api/v1/presenters/import" \
-H "Authorization: Bearer $WUNDERFRAME_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"items": [
{
"ref": "speakerportal/1234",
"name": "Ada Lovelace",
"organization": "Analytical Engines Ltd"
},
{
"ref": "speakerportal/1235",
"name": "Grace Hopper",
"title": "Rear Admiral",
"photo_url": "https://example.com/grace.jpg"
}
]
}'{
"created": 41,
"updated": 3,
"failed": [
{
"index": 7,
"ref": null,
"error": {
"code": "invalid",
"message": "\"ref\" is required for import."
}
}
]
}Error example
{
"error": {
"code": "invalid",
"message": "The request is invalid — `details.field` names the field when there is one."
}
}Upload a presenter photo
/presenters/{id}/photo presentersSend the image itself as the body with Content-Type: image/jpeg (or png, webp, gif; ≤ 10 MB) and optionally X-Filename, or JSON { "url": "https://…" } for Wunderframe to fetch. The photo is stored in the media library.
Parameters
idstring required pathThe presenter id.
Request body required
JSON, or the file itself as the body with one of image/jpeg, image/png, image/webp as its Content-Type.
urlstring (uri) required
Responses
- 200 The presenter with its new photo.
- 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.
- 413 Too large.
- 415 Unsupported media type.
Response fields (200)
idstring required read-onlyrefstring or nullYour own id for the presenter. Unique in the workspace.
Pattern
^[A-Za-z0-9][A-Za-z0-9._:/-]{0,199}$namestring requiredUp to 200 characters
titlestringShown in the lower third.
Up to 200 characters
organizationstringUp to 200 characters
emailstring (email)biostringUp to 4000 characters
photo_asset_idstring or null read-onlyphoto_urlstring or null read-onlyA signed URL, valid for about an hour.
created_atinteger read-onlyupdated_atinteger read-only
curl -X PUT "https://www.wunderframe.com/api/v1/presenters/wkFRBzMq6POZ_qYJHvgQf/photo" \
-H "Authorization: Bearer $WUNDERFRAME_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"url": "https://example.com/photos/ada.jpg"
}'{
"id": "wkFRBzMq6POZ_qYJHvgQf",
"ref": "speakerportal/1234",
"name": "Ada Lovelace",
"title": "Head of Research",
"organization": "Analytical Engines Ltd",
"email": "ada@example.com",
"bio": "Writes the first programs.",
"photo_url": "https://…signed…",
"photo_asset_id": "a1b2c3",
"created_at": 1789372800000,
"updated_at": 1789372800000
}Error example
{
"error": {
"code": "invalid",
"message": "The request is invalid — `details.field` names the field when there is one."
}
}Remove a presenter photo
/presenters/{id}/photo presentersParameters
idstring required pathThe presenter id.
Responses
- 204 Removed. The image stays in the media library.
- 401 Missing or invalid API key.
- 403 The key lacks the scope, or the role is read-only.
- 404 Not found in this workspace.
curl -X DELETE "https://www.wunderframe.com/api/v1/presenters/wkFRBzMq6POZ_qYJHvgQf/photo" \
-H "Authorization: Bearer $WUNDERFRAME_API_KEY"204 — no body.
Error example
{
"error": {
"code": "unauthorized",
"message": "Missing or invalid API key."
}
}