Docs API reference
Records
The words your screens show. A template scene has blanks (title, speaker, …); a record fills them for one ref, and every scene that plays that ref shows its values. Change a record and open screens update within seconds. **How records are organized.** There are no collections to create: a workspace has one set of records and the ref is the address. The parts between slashes work like folders — your-event/session/b-14, your-event/room/hall-b, cafeteria/menu/monday — so pick a pattern and list one branch with GET /records?prefix=your-event/session/. A record has no fixed fields: its values are the blanks it fills. **Create a record** with POST /records, change it with PATCH /records/{ref}, and sync many at once with POST /records/batch.
Every call needs an API key in the Authorization header. New to the API? Start with
the API overview.
List records
/records dataSorted by ref. Use prefix to list one group, e.g. every session of an event.
Parameters
prefixstring queryOnly refs starting with this text, e.g.
your-event/session/.limitinteger queryPage size, 1–200.
1–200. Default
50cursorstring queryThe
next_cursorof the previous page.
Responses
- 200 A page of records.
- 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[] required6 fields in
itemsrefstring requiredYour key for the record, e.g.
your-event/session/b-14. Slashes group records.Pattern
^[A-Za-z0-9][A-Za-z0-9._:/-]{0,199}$valuesmap of string requiredBlank name → text. Blank names start with a letter, then letters, digits or
_.Each value up to 2000 characters
originstring requiredWho wrote the values last:
handin the app,apithrough this API,sourcea connected data source,migrationmoved from a scene.One of
hand,api,source,migrationstaleboolean requiredThe data source that owns the record no longer contains it.
created_atinteger requiredEpoch ms.
updated_atinteger requiredEpoch ms.
next_cursorstring or null requiredPass as
cursorfor the next page;nullon the last page.
curl "https://www.wunderframe.com/api/v1/records?limit=50" \
-H "Authorization: Bearer $WUNDERFRAME_API_KEY"{
"items": [
{
"ref": "your-event/session/b-14",
"values": {
"title": "The AI-Native Startup",
"speaker": "Ada Lovelace",
"room": "Hall B"
},
"origin": "api",
"stale": false,
"created_at": 1789372800000,
"updated_at": 1789376400000
}
],
"next_cursor": null
}Error example
{
"error": {
"code": "invalid",
"message": "The request is invalid — `details.field` names the field when there is one."
}
}Create a record
/records dataCreates the record for a new ref with its values. Refused with 409 conflict when a record with that ref already exists — change it with PATCH /records/{ref} (merge) or PUT /records/{ref} (replace).
Every scene that plays this ref shows the values straight away. A ref no scene plays yet is fine: its values show as soon as a scene uses it.
Request body required
refstring requiredYour key for the record. Slashes group records:
your-event/session/b-14.Pattern
^[A-Za-z0-9][A-Za-z0-9._:/-]{0,199}$valuesmap of string or null requiredBlank name → text. Blank names start with a letter, then letters, digits or
_.nullstores an empty value.Up to 200 entries. Each value up to 2000 characters
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.
Response fields (201)
refstring requiredYour key for the record, e.g.
your-event/session/b-14. Slashes group records.Pattern
^[A-Za-z0-9][A-Za-z0-9._:/-]{0,199}$valuesmap of string requiredBlank name → text. Blank names start with a letter, then letters, digits or
_.Each value up to 2000 characters
originstring requiredWho wrote the values last:
handin the app,apithrough this API,sourcea connected data source,migrationmoved from a scene.One of
hand,api,source,migrationstaleboolean requiredThe data source that owns the record no longer contains it.
created_atinteger requiredEpoch ms.
updated_atinteger requiredEpoch ms.
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"
}
}'{
"ref": "your-event/session/b-14",
"values": {
"title": "The AI-Native Startup",
"speaker": "Ada Lovelace",
"room": "Hall B"
},
"origin": "api",
"stale": false,
"created_at": 1789372800000,
"updated_at": 1789376400000
}Error example
{
"error": {
"code": "invalid",
"message": "The request is invalid — `details.field` names the field when there is one."
}
}Get a record
/records/{ref} dataParameters
refstring required pathThe record ref. It may contain slashes and is used as-is:
/records/your-event/session/b-14.
Responses
- 200 The record.
- 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)
refstring requiredYour key for the record, e.g.
your-event/session/b-14. Slashes group records.Pattern
^[A-Za-z0-9][A-Za-z0-9._:/-]{0,199}$valuesmap of string requiredBlank name → text. Blank names start with a letter, then letters, digits or
_.Each value up to 2000 characters
originstring requiredWho wrote the values last:
handin the app,apithrough this API,sourcea connected data source,migrationmoved from a scene.One of
hand,api,source,migrationstaleboolean requiredThe data source that owns the record no longer contains it.
created_atinteger requiredEpoch ms.
updated_atinteger requiredEpoch ms.
curl "https://www.wunderframe.com/api/v1/records/your-event/session/b-14" \
-H "Authorization: Bearer $WUNDERFRAME_API_KEY"{
"ref": "your-event/session/b-14",
"values": {
"title": "The AI-Native Startup",
"speaker": "Ada Lovelace",
"room": "Hall B"
},
"origin": "api",
"stale": false,
"created_at": 1789372800000,
"updated_at": 1789376400000
}Error example
{
"error": {
"code": "invalid",
"message": "The request is invalid — `details.field` names the field when there is one."
}
}Create or replace a record
/records/{ref} dataThe record holds exactly the values you send; blanks you leave out are removed. Creates the record (201) when the ref has none yet, so it is safe to repeat.
Parameters
refstring required pathThe record ref. It may contain slashes and is used as-is:
/records/your-event/session/b-14.
Request body required
valuesmap of string or null requiredBlank name → text.
nullstores an empty value.Up to 200 entries. Each value up to 2000 characters
Responses
- 200 Replaced.
- 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.
Response fields (200)
refstring requiredYour key for the record, e.g.
your-event/session/b-14. Slashes group records.Pattern
^[A-Za-z0-9][A-Za-z0-9._:/-]{0,199}$valuesmap of string requiredBlank name → text. Blank names start with a letter, then letters, digits or
_.Each value up to 2000 characters
originstring requiredWho wrote the values last:
handin the app,apithrough this API,sourcea connected data source,migrationmoved from a scene.One of
hand,api,source,migrationstaleboolean requiredThe data source that owns the record no longer contains it.
created_atinteger requiredEpoch ms.
updated_atinteger requiredEpoch ms.
Response fields (201)
refstring requiredYour key for the record, e.g.
your-event/session/b-14. Slashes group records.Pattern
^[A-Za-z0-9][A-Za-z0-9._:/-]{0,199}$valuesmap of string requiredBlank name → text. Blank names start with a letter, then letters, digits or
_.Each value up to 2000 characters
originstring requiredWho wrote the values last:
handin the app,apithrough this API,sourcea connected data source,migrationmoved from a scene.One of
hand,api,source,migrationstaleboolean requiredThe data source that owns the record no longer contains it.
created_atinteger requiredEpoch ms.
updated_atinteger requiredEpoch ms.
curl -X PUT "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": {
"title": "The AI-Native Startup",
"speaker": "Ada Lovelace",
"room": "Hall B"
}
}'{
"ref": "your-event/session/b-14",
"values": {
"title": "The AI-Native Startup",
"speaker": "Ada Lovelace",
"room": "Hall B"
},
"origin": "api",
"stale": false,
"created_at": 1789372800000,
"updated_at": 1789376400000
}Error example
{
"error": {
"code": "invalid",
"message": "The request is invalid — `details.field` names the field when there is one."
}
}Create or update a record
/records/{ref} dataThe values you send change; every other blank keeps its value. Creates the record (201) when the ref has none yet.
Parameters
refstring required pathThe record ref. It may contain slashes and is used as-is:
/records/your-event/session/b-14.
Request body required
valuesmap of string or null requiredBlank name → text.
nullstores an empty value.Up to 200 entries. Each value up to 2000 characters
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.
Response fields (200)
refstring requiredYour key for the record, e.g.
your-event/session/b-14. Slashes group records.Pattern
^[A-Za-z0-9][A-Za-z0-9._:/-]{0,199}$valuesmap of string requiredBlank name → text. Blank names start with a letter, then letters, digits or
_.Each value up to 2000 characters
originstring requiredWho wrote the values last:
handin the app,apithrough this API,sourcea connected data source,migrationmoved from a scene.One of
hand,api,source,migrationstaleboolean requiredThe data source that owns the record no longer contains it.
created_atinteger requiredEpoch ms.
updated_atinteger requiredEpoch ms.
Response fields (201)
refstring requiredYour key for the record, e.g.
your-event/session/b-14. Slashes group records.Pattern
^[A-Za-z0-9][A-Za-z0-9._:/-]{0,199}$valuesmap of string requiredBlank name → text. Blank names start with a letter, then letters, digits or
_.Each value up to 2000 characters
originstring requiredWho wrote the values last:
handin the app,apithrough this API,sourcea connected data source,migrationmoved from a scene.One of
hand,api,source,migrationstaleboolean requiredThe data source that owns the record no longer contains it.
created_atinteger requiredEpoch ms.
updated_atinteger requiredEpoch ms.
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"
}
}'{
"ref": "your-event/session/b-14",
"values": {
"title": "The AI-Native Startup",
"speaker": "Ada Lovelace",
"room": "Hall B"
},
"origin": "api",
"stale": false,
"created_at": 1789372800000,
"updated_at": 1789376400000
}Error example
{
"error": {
"code": "invalid",
"message": "The request is invalid — `details.field` names the field when there is one."
}
}Delete a record
/records/{ref} dataScenes that played the record fall back to their own field values.
Parameters
refstring required pathThe record ref. It may contain slashes and is used as-is:
/records/your-event/session/b-14.
Responses
- 204 Deleted.
- 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.
curl -X DELETE "https://www.wunderframe.com/api/v1/records/your-event/session/b-14" \
-H "Authorization: Bearer $WUNDERFRAME_API_KEY"204 — no body.
Error example
{
"error": {
"code": "invalid",
"message": "The request is invalid — `details.field` names the field when there is one."
}
}Update many records
/records/batch dataUp to 500 items in one call. Each item's fields are merged into the record for its ref. If no scene plays the ref yet and template names a template scene, a filled scene is created from it.
The whole call is refused with 400 if any item is invalid, naming the first bad one.
Use it for syncs; to create or change a single record, use POST /records or PUT/PATCH /records/{ref}.
Request body required
itemsobject[] requiredUp to 500 items
4 fields in
itemsrefstring requiredPattern
^[A-Za-z0-9][A-Za-z0-9._:/-]{0,199}$fieldsmap of string or number or boolean or nullBlank name → value, merged into the record. Numbers and booleans are stored as text; values are cut at 2000 characters.
templatestringA template scene (its id or its ref). When no scene plays this
refyet, a filled scene is created from it.titlestringThe title of a scene created from
template.Up to 200 characters
Responses
- 200 What happened.
- 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)
updatedinteger requiredItems whose record already existed.
storedinteger requiredItems whose record is new.
createdinteger requiredFilled scenes created from a
template.unknownstring[] requiredRefs that no scene plays yet. Their values are stored all the same and show as soon as a scene uses the ref.
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"
}
},
{
"ref": "your-event/session/c-01",
"fields": {
"title": "Closing keynote",
"speaker": "Grace Hopper"
},
"template": "your-event/session-template",
"title": "17:00 · Closing keynote"
}
]
}'{
"updated": 12,
"stored": 2,
"created": 1,
"unknown": [
"your-event/session/c-01"
]
}Error example
{
"error": {
"code": "invalid",
"message": "The request is invalid — `details.field` names the field when there is one."
}
}