External Display
Returns a list of ExternalDisplays
GET/api/event/external_display
Query parameters
idinteger | |
deletedboolean | This property is used to mark an entity as deleted / archived | Default value: false |
namestring | |
deviceTypestring | Which kind of device this is, and therefore which driver renders for it. Today only the built-in e-paper renderer exists; a third-party display API becomes an additional type plus an additional driver, nothing else. |
deviceIdstring | Public identifier of the device, travelling in the request path. Deliberately not the secret: paths end up in access logs, proxy logs and support screenshots. Keeping an id there lets a device be identified in a log without the credential riding along. |
contentProfilestring | How much this particular sign is allowed to say. A door sign is a publicly visible output channel: that the renderer may read the data does not mean the sign may show it. The profile sits on the display, not on the room, because the same room can carry a hallway sign and a staff-side sign. |
languagestring | Language every word on this frame is rendered in. Sits on the display, not on the installation: a foyer board in a bilingual building can want English while the door signs behind it stay German. |
baseBookablestring | |
baseLocationstring | |
showBookingQrstring | Show a booking QR code when the bookable is free. Only honoured when the bookable actually accepts self-service bookings - a code that leads nowhere is worse than no code. |
lastSeenAtstring | Last successful fetch by the device. No log table on purpose: a display checks in every few minutes, which is roughly 288 rows per device per day, and only the last one is ever read. |
createdstring | |
updatedstring | |
searchStringstring | text to search for in the list |
orderFieldNamestring | name of the order field |
orderFieldSortstring | sorting modeAllowed: DESCASC |
pageinteger | page of the list |
pageSizeinteger | number of entries for each page |
withMaxPageNumberstring | returns the number of pages available as a header if this is set |
Responses
200Returns a list of ExternalDisplaysarray<ExternalDisplay>
Show fields (22)
idintegerPrimary key of the external display. Internal ID.
device_typestringWhich kind of device this is, and therefore which driver renders for it. Today only the built-in e-paper renderer exists; a third-party display API becomes an additional type plus an additional driver, nothing else.
device_idstringPublic identifier of the device, travelling in the request path. Deliberately not the secret: paths end up in access logs, proxy logs and support screenshots. Keeping an id there lets a device be identified in a log without the credential riding along.
previous_secret_valid_untilstring (date-time)Time until the previous secret of the display is still accepted.
base_bookableBaseBookable16Bookable the display shows.
Show fields (49)
ticketSeatingPlanIdintegerId of the seating plan of the room, also for the public serialization.
idintegerPrimary key of the bookable. Internal ID.
tokenstringPublic token of the bookable. Used in links instead of the ID.
bookable_typestringType of the bookable, for example room, court or vehicle.
floor_levelstringFloor the bookable is on.
floor_sizeintegerFloor size in square meters.
pets_allowedbooleanPets are allowed.
barrier_freebooleanThe bookable is barrier-free.
cargo_volumeintegerCargo volume in liters.
fuel_typestringFuel type of the vehicle.
seating_capacityintegerNumber of seats.
has_wait_listbooleanThe bookable has a waiting list once it is fully booked.
booking_limitintegerMaximum number of bookings.
billing_modestringHow bookings on this bookable are billed: BILLING_MODE_UPFRONT (null = upfront, invoice at booking time) or BILLING_MODE_USAGE (free reservation, deferred billing from real usage data) Also in Default: the member app shows "Nutzung erfassen" only for usage-billed bookables.
max_active_bookings_per_userintegerMaximum number of active (future, not cancelled) self-service bookings one person may hold on this bookable at the same time. Null = unlimited. Admin bookings are not limited.
max_advance_booking_hoursintegerMaximum number of hours a self-service booking may start in the future. Null = unlimited. Admin bookings are not limited.
inventory_managedbooleanKept as inventory (Inventar-Ausleihe): the office hands the item over and takes it back, with deposit and reminders. Only used while the setting event_inventory_enabled is on.
inventory_depositnumber (float)Deposit (Kaution) per piece asked on hand-over. Null = no deposit.
require_addressbooleanThe address must be entered when booking.
require_contactbooleanContact details must be entered when booking.
require_billingbooleanBilling details must be entered when booking.
require_booking_titlebooleanA title must be entered when booking.
allow_direct_billingbooleanrequire_agebooleanThe age must be entered when booking.
counter_update_modestringHow the usage counters of the bookable are updated.
createdstring (date-time)Point in time the entity was created.
updatedstring (date-time)Point in time the entity was last updated.
addressstringAddress as text.
address_streetstringStreet of the address.
address_house_numberstringHouse number of the address.
address_street_levelstringStreet and house number of the address.
address_costringCare-of line of the address.
address_citystringCity of the address.
address_zipstringPostal code of the address.
address_admin_level1stringFirst administrative level of the address, e.g. the federal state.
address_countrystringCountry code of the address.
address_full_countrystringFull name of the country of the address.
address_geo_latstringLatitude of the address.
address_geo_lngstringLongitude of the address.
address_external_provider_idstringfield to store the external provider id of the address. e.g. Google Maps PlaceID like google:ChIJVcKw5r90sEcRhdjNq6NItqE
main_phonestringMain phone number.
main_faxstringMain fax number.
main_emailstringMain e-mail address.
websitestringWebsite address.
namestringName of the entity.
deletedbooleanThis property is used to mark an entity as deleted / archived
short_identifierstringShort identifier of the entity.
image_urlstringURL of the image of the entity.
slug_identifierstringSlug used in URLs of the entity.
base_locationBaseLocation10Location the display is placed at.
Show fields (29)
idintegerPrimary key of the location. Internal ID.
tokenstringPublic token of the location. Used in links instead of the ID.
location_typestringType of the location, for example room, hall or outdoor area.
in_contact_centerbooleanThe location is shown in the contact center.
createdstring (date-time)Point in time the entity was created.
updatedstring (date-time)Point in time the entity was last updated.
addressstringAddress as text.
address_streetstringStreet of the address.
address_house_numberstringHouse number of the address.
address_street_levelstringStreet and house number of the address.
address_costringCare-of line of the address.
address_citystringCity of the address.
address_zipstringPostal code of the address.
address_admin_level1stringFirst administrative level of the address, e.g. the federal state.
address_countrystringCountry code of the address.
address_full_countrystringFull name of the country of the address.
address_geo_latstringLatitude of the address.
address_geo_lngstringLongitude of the address.
address_external_provider_idstringfield to store the external provider id of the address. e.g. Google Maps PlaceID like google:ChIJVcKw5r90sEcRhdjNq6NItqE
main_phonestringMain phone number.
main_faxstringMain fax number.
main_emailstringMain e-mail address.
websitestringWebsite address.
namestringName of the entity.
deletedbooleanThis property is used to mark an entity as deleted / archived
short_identifierstringShort identifier of the entity.
image_urlstringURL of the image of the entity.
slug_identifierstringSlug used in URLs of the entity.
is_ui_filterbooleanThis property is used to mark an entity as a filter for the frontend
content_profilestringHow much this particular sign is allowed to say. A door sign is a publicly visible output channel: that the renderer may read the data does not mean the sign may show it. The profile sits on the display, not on the room, because the same room can carry a hallway sign and a staff-side sign.
languagestringLanguage every word on this frame is rendered in. Sits on the display, not on the installation: a foyer board in a bilingual building can want English while the door signs behind it stay German.
show_booking_qrbooleanShow a booking QR code when the bookable is free. Only honoured when the bookable actually accepts self-service bookings - a code that leads nowhere is worse than no code.
notice_textstringFree-text notice, rendered as a footer line.
refresh_secondsintegerBaseline for the X-Refresh-After header, in seconds. The renderer shortens it when something happens sooner and never exceeds it by much.
last_seen_atstring (date-time)Last successful fetch by the device. No log table on purpose: a display checks in every few minutes, which is roughly 288 rows per device per day, and only the last one is ever read.
battery_voltagenumber (float)Battery voltage of the display in volts.
battery_warn_voltagenumber (float)Battery voltage below which this display counts as needing a new battery. Per display because the hardware differs by a factor of two: a LiPo door sign is flat around 3.5 V, a coin cell OpenDisplay tag around 2.4 V. Empty means the installation-wide default (event_external_display_battery_warn_voltage).
battery_warning_sent_atstring (date-time)When the health check found the battery below the threshold. Cleared once a reading is clearly above it again, so a replaced battery re-arms the warning. This is the display's maintenance flag as much as a send marker: it is set even when no recipient is configured.
offline_warning_sent_atstring (date-time)When the health check found the display silent for too long. Cleared by the next fetch of the device.
firmware_versionstringFirmware version of the display.
rssiintegerSignal strength of the display in dBm.
namestringName of the entity.
deletedbooleanThis property is used to mark an entity as deleted / archived
createdstring (date-time)Point in time the entity was created.
updatedstring (date-time)Point in time the entity was last updated.
curl --request GET \
--url https://your-instance.iw-erp.de/api/event/external_display \
--header 'x-iw-jwt-token: <TOKEN>'const options = {method: 'GET', headers: {'x-iw-jwt-token': '<TOKEN>'}};
fetch('https://your-instance.iw-erp.de/api/event/external_display', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));import requests
url = "https://your-instance.iw-erp.de/api/event/external_display"
headers = {"x-iw-jwt-token": "<TOKEN>"}
response = requests.get(url, headers=headers)
print(response.text)<?php
require_once('vendor/autoload.php');
$client = new \GuzzleHttp\Client();
$response = $client->request('GET', 'https://your-instance.iw-erp.de/api/event/external_display', [
'headers' => [
'x-iw-jwt-token' => '<TOKEN>',
],
]);
echo $response->getBody();using System.Net.Http.Headers;
var client = new HttpClient();
var request = new HttpRequestMessage
{
Method = HttpMethod.Get,
RequestUri = new Uri("https://your-instance.iw-erp.de/api/event/external_display"),
Headers =
{
{ "x-iw-jwt-token", "<TOKEN>" },
},
};
using (var response = await client.SendAsync(request))
{
response.EnsureSuccessStatusCode();
var body = await response.Content.ReadAsStringAsync();
Console.WriteLine(body);
}OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder()
.url("https://your-instance.iw-erp.de/api/event/external_display")
.get()
.addHeader("x-iw-jwt-token", "<TOKEN>")
.build();
Response response = client.newCall(request).execute();package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://your-instance.iw-erp.de/api/event/external_display"
req, _ := http.NewRequest("GET", url, nil)
req.Header.Add("x-iw-jwt-token", "<TOKEN>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}Dart with the iw_erp_api package
import 'package:iw_erp_api/clients/external_display_controller.dart';
import 'package:iw_erp_api/logic/iw_api_state.dart';
IwApiState().host = 'your-instance.iw-erp.de';
IwApiState().currentJwtApiToken = '<TOKEN>';
final result = await ExternalDisplayController.getAll();
if (result.success) {
print(result.data);
}[
{
"id": 42,
"language": "de",
"notice_text": "Text",
"name": "Beispiel",
"device_type": "string",
"device_id": "42",
"previous_secret_valid_until": "2026-10-15T09:30:00+02:00",
"base_bookable": {
"id": 42,
"require_booking_title": true,
"address_street": "Jakobistr. 39",
"address_city": "Hannover",
"address_zip": "30163",
"address_country": "DE",
"address_full_country": "DE",
"main_phone": "+49 511 123456",
"main_email": "lena.hartmann@example.org",
"name": "Beispiel"
},
"base_location": {
"id": 42,
"address_street": "Jakobistr. 39",
"address_city": "Hannover",
"address_zip": "30163",
"address_country": "DE",
"address_full_country": "DE",
"main_phone": "+49 511 123456",
"main_email": "lena.hartmann@example.org",
"name": "Beispiel",
"image_url": "https://vynst.de"
},
"content_profile": "string"
}
]Adds a new ExternalDisplay
POST/api/event/external_display
Request body application/json
dataExternalDisplay2Show fields (10)
device_typestringWhich kind of device this is, and therefore which driver renders for it. Today only the built-in e-paper renderer exists; a third-party display API becomes an additional type plus an additional driver, nothing else.
base_bookableBaseBookable17Bookable the display shows.
base_locationBaseLocation6Location the display is placed at.
content_profilestringHow much this particular sign is allowed to say. A door sign is a publicly visible output channel: that the renderer may read the data does not mean the sign may show it. The profile sits on the display, not on the room, because the same room can carry a hallway sign and a staff-side sign.
languagestringLanguage every word on this frame is rendered in. Sits on the display, not on the installation: a foyer board in a bilingual building can want English while the door signs behind it stay German.
show_booking_qrbooleanShow a booking QR code when the bookable is free. Only honoured when the bookable actually accepts self-service bookings - a code that leads nowhere is worse than no code.
notice_textstringFree-text notice, rendered as a footer line.
refresh_secondsintegerBaseline for the X-Refresh-After header, in seconds. The renderer shortens it when something happens sooner and never exceeds it by much.
battery_warn_voltagenumber (float)Battery voltage below which this display counts as needing a new battery. Per display because the hardware differs by a factor of two: a LiPo door sign is flat around 3.5 V, a coin cell OpenDisplay tag around 2.4 V. Empty means the installation-wide default (event_external_display_battery_warn_voltage).
deletedbooleanThis property is used to mark an entity as deleted / archived
Responses
200Add a new ExternalDisplayExternalDisplay
Show fields (22)
idintegerPrimary key of the external display. Internal ID.
device_typestringWhich kind of device this is, and therefore which driver renders for it. Today only the built-in e-paper renderer exists; a third-party display API becomes an additional type plus an additional driver, nothing else.
device_idstringPublic identifier of the device, travelling in the request path. Deliberately not the secret: paths end up in access logs, proxy logs and support screenshots. Keeping an id there lets a device be identified in a log without the credential riding along.
previous_secret_valid_untilstring (date-time)Time until the previous secret of the display is still accepted.
base_bookableBaseBookable16Bookable the display shows.
Show fields (49)
ticketSeatingPlanIdintegerId of the seating plan of the room, also for the public serialization.
idintegerPrimary key of the bookable. Internal ID.
tokenstringPublic token of the bookable. Used in links instead of the ID.
bookable_typestringType of the bookable, for example room, court or vehicle.
floor_levelstringFloor the bookable is on.
floor_sizeintegerFloor size in square meters.
pets_allowedbooleanPets are allowed.
barrier_freebooleanThe bookable is barrier-free.
cargo_volumeintegerCargo volume in liters.
fuel_typestringFuel type of the vehicle.
seating_capacityintegerNumber of seats.
has_wait_listbooleanThe bookable has a waiting list once it is fully booked.
booking_limitintegerMaximum number of bookings.
billing_modestringHow bookings on this bookable are billed: BILLING_MODE_UPFRONT (null = upfront, invoice at booking time) or BILLING_MODE_USAGE (free reservation, deferred billing from real usage data) Also in Default: the member app shows "Nutzung erfassen" only for usage-billed bookables.
max_active_bookings_per_userintegerMaximum number of active (future, not cancelled) self-service bookings one person may hold on this bookable at the same time. Null = unlimited. Admin bookings are not limited.
max_advance_booking_hoursintegerMaximum number of hours a self-service booking may start in the future. Null = unlimited. Admin bookings are not limited.
inventory_managedbooleanKept as inventory (Inventar-Ausleihe): the office hands the item over and takes it back, with deposit and reminders. Only used while the setting event_inventory_enabled is on.
inventory_depositnumber (float)Deposit (Kaution) per piece asked on hand-over. Null = no deposit.
require_addressbooleanThe address must be entered when booking.
require_contactbooleanContact details must be entered when booking.
require_billingbooleanBilling details must be entered when booking.
require_booking_titlebooleanA title must be entered when booking.
allow_direct_billingbooleanrequire_agebooleanThe age must be entered when booking.
counter_update_modestringHow the usage counters of the bookable are updated.
createdstring (date-time)Point in time the entity was created.
updatedstring (date-time)Point in time the entity was last updated.
addressstringAddress as text.
address_streetstringStreet of the address.
address_house_numberstringHouse number of the address.
address_street_levelstringStreet and house number of the address.
address_costringCare-of line of the address.
address_citystringCity of the address.
address_zipstringPostal code of the address.
address_admin_level1stringFirst administrative level of the address, e.g. the federal state.
address_countrystringCountry code of the address.
address_full_countrystringFull name of the country of the address.
address_geo_latstringLatitude of the address.
address_geo_lngstringLongitude of the address.
address_external_provider_idstringfield to store the external provider id of the address. e.g. Google Maps PlaceID like google:ChIJVcKw5r90sEcRhdjNq6NItqE
main_phonestringMain phone number.
main_faxstringMain fax number.
main_emailstringMain e-mail address.
websitestringWebsite address.
namestringName of the entity.
deletedbooleanThis property is used to mark an entity as deleted / archived
short_identifierstringShort identifier of the entity.
image_urlstringURL of the image of the entity.
slug_identifierstringSlug used in URLs of the entity.
base_locationBaseLocation10Location the display is placed at.
Show fields (29)
idintegerPrimary key of the location. Internal ID.
tokenstringPublic token of the location. Used in links instead of the ID.
location_typestringType of the location, for example room, hall or outdoor area.
in_contact_centerbooleanThe location is shown in the contact center.
createdstring (date-time)Point in time the entity was created.
updatedstring (date-time)Point in time the entity was last updated.
addressstringAddress as text.
address_streetstringStreet of the address.
address_house_numberstringHouse number of the address.
address_street_levelstringStreet and house number of the address.
address_costringCare-of line of the address.
address_citystringCity of the address.
address_zipstringPostal code of the address.
address_admin_level1stringFirst administrative level of the address, e.g. the federal state.
address_countrystringCountry code of the address.
address_full_countrystringFull name of the country of the address.
address_geo_latstringLatitude of the address.
address_geo_lngstringLongitude of the address.
address_external_provider_idstringfield to store the external provider id of the address. e.g. Google Maps PlaceID like google:ChIJVcKw5r90sEcRhdjNq6NItqE
main_phonestringMain phone number.
main_faxstringMain fax number.
main_emailstringMain e-mail address.
websitestringWebsite address.
namestringName of the entity.
deletedbooleanThis property is used to mark an entity as deleted / archived
short_identifierstringShort identifier of the entity.
image_urlstringURL of the image of the entity.
slug_identifierstringSlug used in URLs of the entity.
is_ui_filterbooleanThis property is used to mark an entity as a filter for the frontend
content_profilestringHow much this particular sign is allowed to say. A door sign is a publicly visible output channel: that the renderer may read the data does not mean the sign may show it. The profile sits on the display, not on the room, because the same room can carry a hallway sign and a staff-side sign.
languagestringLanguage every word on this frame is rendered in. Sits on the display, not on the installation: a foyer board in a bilingual building can want English while the door signs behind it stay German.
show_booking_qrbooleanShow a booking QR code when the bookable is free. Only honoured when the bookable actually accepts self-service bookings - a code that leads nowhere is worse than no code.
notice_textstringFree-text notice, rendered as a footer line.
refresh_secondsintegerBaseline for the X-Refresh-After header, in seconds. The renderer shortens it when something happens sooner and never exceeds it by much.
last_seen_atstring (date-time)Last successful fetch by the device. No log table on purpose: a display checks in every few minutes, which is roughly 288 rows per device per day, and only the last one is ever read.
battery_voltagenumber (float)Battery voltage of the display in volts.
battery_warn_voltagenumber (float)Battery voltage below which this display counts as needing a new battery. Per display because the hardware differs by a factor of two: a LiPo door sign is flat around 3.5 V, a coin cell OpenDisplay tag around 2.4 V. Empty means the installation-wide default (event_external_display_battery_warn_voltage).
battery_warning_sent_atstring (date-time)When the health check found the battery below the threshold. Cleared once a reading is clearly above it again, so a replaced battery re-arms the warning. This is the display's maintenance flag as much as a send marker: it is set even when no recipient is configured.
offline_warning_sent_atstring (date-time)When the health check found the display silent for too long. Cleared by the next fetch of the device.
firmware_versionstringFirmware version of the display.
rssiintegerSignal strength of the display in dBm.
namestringName of the entity.
deletedbooleanThis property is used to mark an entity as deleted / archived
createdstring (date-time)Point in time the entity was created.
updatedstring (date-time)Point in time the entity was last updated.
curl --request POST \
--url https://your-instance.iw-erp.de/api/event/external_display \
--header 'content-type: application/json' \
--header 'x-iw-jwt-token: <TOKEN>' \
--data '
{
"data": {
"language": "de",
"notice_text": "Text",
"device_type": "string",
"base_bookable": {
"address_street": "Jakobistr. 39",
"address_city": "Hannover",
"address_zip": "30163",
"address_country": "DE",
"address_full_country": "DE",
"main_phone": "+49 511 123456"
},
"base_location": {
"address_street": "Jakobistr. 39",
"address_city": "Hannover",
"address_zip": "30163",
"address_country": "DE",
"address_full_country": "DE",
"main_phone": "+49 511 123456"
},
"content_profile": "string"
}
}
'const options = {
method: 'POST',
headers: {'x-iw-jwt-token': '<TOKEN>', 'content-type': 'application/json'},
body: JSON.stringify({
data: {
language: 'de',
notice_text: 'Text',
device_type: 'string',
base_bookable: {
address_street: 'Jakobistr. 39',
address_city: 'Hannover',
address_zip: '30163',
address_country: 'DE',
address_full_country: 'DE',
main_phone: '+49 511 123456'
},
base_location: {
address_street: 'Jakobistr. 39',
address_city: 'Hannover',
address_zip: '30163',
address_country: 'DE',
address_full_country: 'DE',
main_phone: '+49 511 123456'
},
content_profile: 'string'
}
})
};
fetch('https://your-instance.iw-erp.de/api/event/external_display', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));import requests
url = "https://your-instance.iw-erp.de/api/event/external_display"
payload = { "data": {
"language": "de",
"notice_text": "Text",
"device_type": "string",
"base_bookable": {
"address_street": "Jakobistr. 39",
"address_city": "Hannover",
"address_zip": "30163",
"address_country": "DE",
"address_full_country": "DE",
"main_phone": "+49 511 123456"
},
"base_location": {
"address_street": "Jakobistr. 39",
"address_city": "Hannover",
"address_zip": "30163",
"address_country": "DE",
"address_full_country": "DE",
"main_phone": "+49 511 123456"
},
"content_profile": "string"
} }
headers = {
"x-iw-jwt-token": "<TOKEN>",
"content-type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)<?php
require_once('vendor/autoload.php');
$client = new \GuzzleHttp\Client();
$response = $client->request('POST', 'https://your-instance.iw-erp.de/api/event/external_display', [
'body' => '{"data":{"language":"de","notice_text":"Text","device_type":"string","base_bookable":{"address_street":"Jakobistr. 39","address_city":"Hannover","address_zip":"30163","address_country":"DE","address_full_country":"DE","main_phone":"+49 511 123456"},"base_location":{"address_street":"Jakobistr. 39","address_city":"Hannover","address_zip":"30163","address_country":"DE","address_full_country":"DE","main_phone":"+49 511 123456"},"content_profile":"string"}}',
'headers' => [
'content-type' => 'application/json',
'x-iw-jwt-token' => '<TOKEN>',
],
]);
echo $response->getBody();using System.Net.Http.Headers;
var client = new HttpClient();
var request = new HttpRequestMessage
{
Method = HttpMethod.Post,
RequestUri = new Uri("https://your-instance.iw-erp.de/api/event/external_display"),
Headers =
{
{ "x-iw-jwt-token", "<TOKEN>" },
},
Content = new StringContent("{\"data\":{\"language\":\"de\",\"notice_text\":\"Text\",\"device_type\":\"string\",\"base_bookable\":{\"address_street\":\"Jakobistr. 39\",\"address_city\":\"Hannover\",\"address_zip\":\"30163\",\"address_country\":\"DE\",\"address_full_country\":\"DE\",\"main_phone\":\"+49 511 123456\"},\"base_location\":{\"address_street\":\"Jakobistr. 39\",\"address_city\":\"Hannover\",\"address_zip\":\"30163\",\"address_country\":\"DE\",\"address_full_country\":\"DE\",\"main_phone\":\"+49 511 123456\"},\"content_profile\":\"string\"}}")
{
Headers =
{
ContentType = new MediaTypeHeaderValue("application/json")
}
}
};
using (var response = await client.SendAsync(request))
{
response.EnsureSuccessStatusCode();
var body = await response.Content.ReadAsStringAsync();
Console.WriteLine(body);
}OkHttpClient client = new OkHttpClient();
MediaType mediaType = MediaType.parse("application/json");
RequestBody body = RequestBody.create(mediaType, "{\"data\":{\"language\":\"de\",\"notice_text\":\"Text\",\"device_type\":\"string\",\"base_bookable\":{\"address_street\":\"Jakobistr. 39\",\"address_city\":\"Hannover\",\"address_zip\":\"30163\",\"address_country\":\"DE\",\"address_full_country\":\"DE\",\"main_phone\":\"+49 511 123456\"},\"base_location\":{\"address_street\":\"Jakobistr. 39\",\"address_city\":\"Hannover\",\"address_zip\":\"30163\",\"address_country\":\"DE\",\"address_full_country\":\"DE\",\"main_phone\":\"+49 511 123456\"},\"content_profile\":\"string\"}}");
Request request = new Request.Builder()
.url("https://your-instance.iw-erp.de/api/event/external_display")
.post(body)
.addHeader("x-iw-jwt-token", "<TOKEN>")
.addHeader("content-type", "application/json")
.build();
Response response = client.newCall(request).execute();package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://your-instance.iw-erp.de/api/event/external_display"
payload := strings.NewReader("{\"data\":{\"language\":\"de\",\"notice_text\":\"Text\",\"device_type\":\"string\",\"base_bookable\":{\"address_street\":\"Jakobistr. 39\",\"address_city\":\"Hannover\",\"address_zip\":\"30163\",\"address_country\":\"DE\",\"address_full_country\":\"DE\",\"main_phone\":\"+49 511 123456\"},\"base_location\":{\"address_street\":\"Jakobistr. 39\",\"address_city\":\"Hannover\",\"address_zip\":\"30163\",\"address_country\":\"DE\",\"address_full_country\":\"DE\",\"main_phone\":\"+49 511 123456\"},\"content_profile\":\"string\"}}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("x-iw-jwt-token", "<TOKEN>")
req.Header.Add("content-type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}Dart with the iw_erp_api package
import 'package:iw_erp_api/clients/external_display_controller.dart';
import 'package:iw_erp_api/logic/iw_api_state.dart';
import 'package:iw_erp_api/model/external_display.dart';
IwApiState().host = 'your-instance.iw-erp.de';
IwApiState().currentJwtApiToken = '<TOKEN>';
final result = await ExternalDisplayController.post(ExternalDisplay.fromJson({
"language": "de",
"notice_text": "Text",
"device_type": "string",
"base_bookable": {
"address_street": "Jakobistr. 39",
"address_city": "Hannover",
"address_zip": "30163",
"address_country": "DE",
"address_full_country": "DE",
"main_phone": "+49 511 123456"
},
"base_location": {
"address_street": "Jakobistr. 39",
"address_city": "Hannover",
"address_zip": "30163",
"address_country": "DE",
"address_full_country": "DE",
"main_phone": "+49 511 123456"
},
"content_profile": "string"
}));
if (result.success) {
print(result.data);
}{
"id": 42,
"language": "de",
"notice_text": "Text",
"name": "Beispiel",
"device_type": "string",
"device_id": "42",
"previous_secret_valid_until": "2026-10-15T09:30:00+02:00",
"base_bookable": {
"id": 42,
"require_booking_title": true,
"address_street": "Jakobistr. 39",
"address_city": "Hannover",
"address_zip": "30163",
"address_country": "DE",
"address_full_country": "DE",
"main_phone": "+49 511 123456",
"main_email": "lena.hartmann@example.org",
"name": "Beispiel"
},
"base_location": {
"id": 42,
"address_street": "Jakobistr. 39",
"address_city": "Hannover",
"address_zip": "30163",
"address_country": "DE",
"address_full_country": "DE",
"main_phone": "+49 511 123456",
"main_email": "lena.hartmann@example.org",
"name": "Beispiel",
"image_url": "https://vynst.de"
},
"content_profile": "string"
}Returns a single ExternalDisplay
GET/api/event/external_display/{identifier}
Path parameters
identifierrequiredstring |
Responses
200Returns a single ExternalDisplayExternalDisplay
Show fields (22)
idintegerPrimary key of the external display. Internal ID.
device_typestringWhich kind of device this is, and therefore which driver renders for it. Today only the built-in e-paper renderer exists; a third-party display API becomes an additional type plus an additional driver, nothing else.
device_idstringPublic identifier of the device, travelling in the request path. Deliberately not the secret: paths end up in access logs, proxy logs and support screenshots. Keeping an id there lets a device be identified in a log without the credential riding along.
previous_secret_valid_untilstring (date-time)Time until the previous secret of the display is still accepted.
base_bookableBaseBookable16Bookable the display shows.
Show fields (49)
ticketSeatingPlanIdintegerId of the seating plan of the room, also for the public serialization.
idintegerPrimary key of the bookable. Internal ID.
tokenstringPublic token of the bookable. Used in links instead of the ID.
bookable_typestringType of the bookable, for example room, court or vehicle.
floor_levelstringFloor the bookable is on.
floor_sizeintegerFloor size in square meters.
pets_allowedbooleanPets are allowed.
barrier_freebooleanThe bookable is barrier-free.
cargo_volumeintegerCargo volume in liters.
fuel_typestringFuel type of the vehicle.
seating_capacityintegerNumber of seats.
has_wait_listbooleanThe bookable has a waiting list once it is fully booked.
booking_limitintegerMaximum number of bookings.
billing_modestringHow bookings on this bookable are billed: BILLING_MODE_UPFRONT (null = upfront, invoice at booking time) or BILLING_MODE_USAGE (free reservation, deferred billing from real usage data) Also in Default: the member app shows "Nutzung erfassen" only for usage-billed bookables.
max_active_bookings_per_userintegerMaximum number of active (future, not cancelled) self-service bookings one person may hold on this bookable at the same time. Null = unlimited. Admin bookings are not limited.
max_advance_booking_hoursintegerMaximum number of hours a self-service booking may start in the future. Null = unlimited. Admin bookings are not limited.
inventory_managedbooleanKept as inventory (Inventar-Ausleihe): the office hands the item over and takes it back, with deposit and reminders. Only used while the setting event_inventory_enabled is on.
inventory_depositnumber (float)Deposit (Kaution) per piece asked on hand-over. Null = no deposit.
require_addressbooleanThe address must be entered when booking.
require_contactbooleanContact details must be entered when booking.
require_billingbooleanBilling details must be entered when booking.
require_booking_titlebooleanA title must be entered when booking.
allow_direct_billingbooleanrequire_agebooleanThe age must be entered when booking.
counter_update_modestringHow the usage counters of the bookable are updated.
createdstring (date-time)Point in time the entity was created.
updatedstring (date-time)Point in time the entity was last updated.
addressstringAddress as text.
address_streetstringStreet of the address.
address_house_numberstringHouse number of the address.
address_street_levelstringStreet and house number of the address.
address_costringCare-of line of the address.
address_citystringCity of the address.
address_zipstringPostal code of the address.
address_admin_level1stringFirst administrative level of the address, e.g. the federal state.
address_countrystringCountry code of the address.
address_full_countrystringFull name of the country of the address.
address_geo_latstringLatitude of the address.
address_geo_lngstringLongitude of the address.
address_external_provider_idstringfield to store the external provider id of the address. e.g. Google Maps PlaceID like google:ChIJVcKw5r90sEcRhdjNq6NItqE
main_phonestringMain phone number.
main_faxstringMain fax number.
main_emailstringMain e-mail address.
websitestringWebsite address.
namestringName of the entity.
deletedbooleanThis property is used to mark an entity as deleted / archived
short_identifierstringShort identifier of the entity.
image_urlstringURL of the image of the entity.
slug_identifierstringSlug used in URLs of the entity.
base_locationBaseLocation10Location the display is placed at.
Show fields (29)
idintegerPrimary key of the location. Internal ID.
tokenstringPublic token of the location. Used in links instead of the ID.
location_typestringType of the location, for example room, hall or outdoor area.
in_contact_centerbooleanThe location is shown in the contact center.
createdstring (date-time)Point in time the entity was created.
updatedstring (date-time)Point in time the entity was last updated.
addressstringAddress as text.
address_streetstringStreet of the address.
address_house_numberstringHouse number of the address.
address_street_levelstringStreet and house number of the address.
address_costringCare-of line of the address.
address_citystringCity of the address.
address_zipstringPostal code of the address.
address_admin_level1stringFirst administrative level of the address, e.g. the federal state.
address_countrystringCountry code of the address.
address_full_countrystringFull name of the country of the address.
address_geo_latstringLatitude of the address.
address_geo_lngstringLongitude of the address.
address_external_provider_idstringfield to store the external provider id of the address. e.g. Google Maps PlaceID like google:ChIJVcKw5r90sEcRhdjNq6NItqE
main_phonestringMain phone number.
main_faxstringMain fax number.
main_emailstringMain e-mail address.
websitestringWebsite address.
namestringName of the entity.
deletedbooleanThis property is used to mark an entity as deleted / archived
short_identifierstringShort identifier of the entity.
image_urlstringURL of the image of the entity.
slug_identifierstringSlug used in URLs of the entity.
is_ui_filterbooleanThis property is used to mark an entity as a filter for the frontend
content_profilestringHow much this particular sign is allowed to say. A door sign is a publicly visible output channel: that the renderer may read the data does not mean the sign may show it. The profile sits on the display, not on the room, because the same room can carry a hallway sign and a staff-side sign.
languagestringLanguage every word on this frame is rendered in. Sits on the display, not on the installation: a foyer board in a bilingual building can want English while the door signs behind it stay German.
show_booking_qrbooleanShow a booking QR code when the bookable is free. Only honoured when the bookable actually accepts self-service bookings - a code that leads nowhere is worse than no code.
notice_textstringFree-text notice, rendered as a footer line.
refresh_secondsintegerBaseline for the X-Refresh-After header, in seconds. The renderer shortens it when something happens sooner and never exceeds it by much.
last_seen_atstring (date-time)Last successful fetch by the device. No log table on purpose: a display checks in every few minutes, which is roughly 288 rows per device per day, and only the last one is ever read.
battery_voltagenumber (float)Battery voltage of the display in volts.
battery_warn_voltagenumber (float)Battery voltage below which this display counts as needing a new battery. Per display because the hardware differs by a factor of two: a LiPo door sign is flat around 3.5 V, a coin cell OpenDisplay tag around 2.4 V. Empty means the installation-wide default (event_external_display_battery_warn_voltage).
battery_warning_sent_atstring (date-time)When the health check found the battery below the threshold. Cleared once a reading is clearly above it again, so a replaced battery re-arms the warning. This is the display's maintenance flag as much as a send marker: it is set even when no recipient is configured.
offline_warning_sent_atstring (date-time)When the health check found the display silent for too long. Cleared by the next fetch of the device.
firmware_versionstringFirmware version of the display.
rssiintegerSignal strength of the display in dBm.
namestringName of the entity.
deletedbooleanThis property is used to mark an entity as deleted / archived
createdstring (date-time)Point in time the entity was created.
updatedstring (date-time)Point in time the entity was last updated.
curl --request GET \
--url https://your-instance.iw-erp.de/api/event/external_display/42 \
--header 'x-iw-jwt-token: <TOKEN>'const options = {method: 'GET', headers: {'x-iw-jwt-token': '<TOKEN>'}};
fetch('https://your-instance.iw-erp.de/api/event/external_display/42', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));import requests
url = "https://your-instance.iw-erp.de/api/event/external_display/42"
headers = {"x-iw-jwt-token": "<TOKEN>"}
response = requests.get(url, headers=headers)
print(response.text)<?php
require_once('vendor/autoload.php');
$client = new \GuzzleHttp\Client();
$response = $client->request('GET', 'https://your-instance.iw-erp.de/api/event/external_display/42', [
'headers' => [
'x-iw-jwt-token' => '<TOKEN>',
],
]);
echo $response->getBody();using System.Net.Http.Headers;
var client = new HttpClient();
var request = new HttpRequestMessage
{
Method = HttpMethod.Get,
RequestUri = new Uri("https://your-instance.iw-erp.de/api/event/external_display/42"),
Headers =
{
{ "x-iw-jwt-token", "<TOKEN>" },
},
};
using (var response = await client.SendAsync(request))
{
response.EnsureSuccessStatusCode();
var body = await response.Content.ReadAsStringAsync();
Console.WriteLine(body);
}OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder()
.url("https://your-instance.iw-erp.de/api/event/external_display/42")
.get()
.addHeader("x-iw-jwt-token", "<TOKEN>")
.build();
Response response = client.newCall(request).execute();package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://your-instance.iw-erp.de/api/event/external_display/42"
req, _ := http.NewRequest("GET", url, nil)
req.Header.Add("x-iw-jwt-token", "<TOKEN>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}Dart with the iw_erp_api package
import 'package:iw_erp_api/clients/external_display_controller.dart';
import 'package:iw_erp_api/logic/iw_api_state.dart';
IwApiState().host = 'your-instance.iw-erp.de';
IwApiState().currentJwtApiToken = '<TOKEN>';
final result = await ExternalDisplayController.get('42');
if (result.success) {
print(result.data);
}{
"id": 42,
"language": "de",
"notice_text": "Text",
"name": "Beispiel",
"device_type": "string",
"device_id": "42",
"previous_secret_valid_until": "2026-10-15T09:30:00+02:00",
"base_bookable": {
"id": 42,
"require_booking_title": true,
"address_street": "Jakobistr. 39",
"address_city": "Hannover",
"address_zip": "30163",
"address_country": "DE",
"address_full_country": "DE",
"main_phone": "+49 511 123456",
"main_email": "lena.hartmann@example.org",
"name": "Beispiel"
},
"base_location": {
"id": 42,
"address_street": "Jakobistr. 39",
"address_city": "Hannover",
"address_zip": "30163",
"address_country": "DE",
"address_full_country": "DE",
"main_phone": "+49 511 123456",
"main_email": "lena.hartmann@example.org",
"name": "Beispiel",
"image_url": "https://vynst.de"
},
"content_profile": "string"
}Updates an ExternalDisplay
PUT/api/event/external_display/{identifier}
Path parameters
identifierrequiredstring |
Request body application/json
dataExternalDisplay2Show fields (10)
device_typestringWhich kind of device this is, and therefore which driver renders for it. Today only the built-in e-paper renderer exists; a third-party display API becomes an additional type plus an additional driver, nothing else.
base_bookableBaseBookable17Bookable the display shows.
base_locationBaseLocation6Location the display is placed at.
content_profilestringHow much this particular sign is allowed to say. A door sign is a publicly visible output channel: that the renderer may read the data does not mean the sign may show it. The profile sits on the display, not on the room, because the same room can carry a hallway sign and a staff-side sign.
languagestringLanguage every word on this frame is rendered in. Sits on the display, not on the installation: a foyer board in a bilingual building can want English while the door signs behind it stay German.
show_booking_qrbooleanShow a booking QR code when the bookable is free. Only honoured when the bookable actually accepts self-service bookings - a code that leads nowhere is worse than no code.
notice_textstringFree-text notice, rendered as a footer line.
refresh_secondsintegerBaseline for the X-Refresh-After header, in seconds. The renderer shortens it when something happens sooner and never exceeds it by much.
battery_warn_voltagenumber (float)Battery voltage below which this display counts as needing a new battery. Per display because the hardware differs by a factor of two: a LiPo door sign is flat around 3.5 V, a coin cell OpenDisplay tag around 2.4 V. Empty means the installation-wide default (event_external_display_battery_warn_voltage).
deletedbooleanThis property is used to mark an entity as deleted / archived
Responses
200Update an ExternalDisplayExternalDisplay
Show fields (22)
idintegerPrimary key of the external display. Internal ID.
device_typestringWhich kind of device this is, and therefore which driver renders for it. Today only the built-in e-paper renderer exists; a third-party display API becomes an additional type plus an additional driver, nothing else.
device_idstringPublic identifier of the device, travelling in the request path. Deliberately not the secret: paths end up in access logs, proxy logs and support screenshots. Keeping an id there lets a device be identified in a log without the credential riding along.
previous_secret_valid_untilstring (date-time)Time until the previous secret of the display is still accepted.
base_bookableBaseBookable16Bookable the display shows.
Show fields (49)
ticketSeatingPlanIdintegerId of the seating plan of the room, also for the public serialization.
idintegerPrimary key of the bookable. Internal ID.
tokenstringPublic token of the bookable. Used in links instead of the ID.
bookable_typestringType of the bookable, for example room, court or vehicle.
floor_levelstringFloor the bookable is on.
floor_sizeintegerFloor size in square meters.
pets_allowedbooleanPets are allowed.
barrier_freebooleanThe bookable is barrier-free.
cargo_volumeintegerCargo volume in liters.
fuel_typestringFuel type of the vehicle.
seating_capacityintegerNumber of seats.
has_wait_listbooleanThe bookable has a waiting list once it is fully booked.
booking_limitintegerMaximum number of bookings.
billing_modestringHow bookings on this bookable are billed: BILLING_MODE_UPFRONT (null = upfront, invoice at booking time) or BILLING_MODE_USAGE (free reservation, deferred billing from real usage data) Also in Default: the member app shows "Nutzung erfassen" only for usage-billed bookables.
max_active_bookings_per_userintegerMaximum number of active (future, not cancelled) self-service bookings one person may hold on this bookable at the same time. Null = unlimited. Admin bookings are not limited.
max_advance_booking_hoursintegerMaximum number of hours a self-service booking may start in the future. Null = unlimited. Admin bookings are not limited.
inventory_managedbooleanKept as inventory (Inventar-Ausleihe): the office hands the item over and takes it back, with deposit and reminders. Only used while the setting event_inventory_enabled is on.
inventory_depositnumber (float)Deposit (Kaution) per piece asked on hand-over. Null = no deposit.
require_addressbooleanThe address must be entered when booking.
require_contactbooleanContact details must be entered when booking.
require_billingbooleanBilling details must be entered when booking.
require_booking_titlebooleanA title must be entered when booking.
allow_direct_billingbooleanrequire_agebooleanThe age must be entered when booking.
counter_update_modestringHow the usage counters of the bookable are updated.
createdstring (date-time)Point in time the entity was created.
updatedstring (date-time)Point in time the entity was last updated.
addressstringAddress as text.
address_streetstringStreet of the address.
address_house_numberstringHouse number of the address.
address_street_levelstringStreet and house number of the address.
address_costringCare-of line of the address.
address_citystringCity of the address.
address_zipstringPostal code of the address.
address_admin_level1stringFirst administrative level of the address, e.g. the federal state.
address_countrystringCountry code of the address.
address_full_countrystringFull name of the country of the address.
address_geo_latstringLatitude of the address.
address_geo_lngstringLongitude of the address.
address_external_provider_idstringfield to store the external provider id of the address. e.g. Google Maps PlaceID like google:ChIJVcKw5r90sEcRhdjNq6NItqE
main_phonestringMain phone number.
main_faxstringMain fax number.
main_emailstringMain e-mail address.
websitestringWebsite address.
namestringName of the entity.
deletedbooleanThis property is used to mark an entity as deleted / archived
short_identifierstringShort identifier of the entity.
image_urlstringURL of the image of the entity.
slug_identifierstringSlug used in URLs of the entity.
base_locationBaseLocation10Location the display is placed at.
Show fields (29)
idintegerPrimary key of the location. Internal ID.
tokenstringPublic token of the location. Used in links instead of the ID.
location_typestringType of the location, for example room, hall or outdoor area.
in_contact_centerbooleanThe location is shown in the contact center.
createdstring (date-time)Point in time the entity was created.
updatedstring (date-time)Point in time the entity was last updated.
addressstringAddress as text.
address_streetstringStreet of the address.
address_house_numberstringHouse number of the address.
address_street_levelstringStreet and house number of the address.
address_costringCare-of line of the address.
address_citystringCity of the address.
address_zipstringPostal code of the address.
address_admin_level1stringFirst administrative level of the address, e.g. the federal state.
address_countrystringCountry code of the address.
address_full_countrystringFull name of the country of the address.
address_geo_latstringLatitude of the address.
address_geo_lngstringLongitude of the address.
address_external_provider_idstringfield to store the external provider id of the address. e.g. Google Maps PlaceID like google:ChIJVcKw5r90sEcRhdjNq6NItqE
main_phonestringMain phone number.
main_faxstringMain fax number.
main_emailstringMain e-mail address.
websitestringWebsite address.
namestringName of the entity.
deletedbooleanThis property is used to mark an entity as deleted / archived
short_identifierstringShort identifier of the entity.
image_urlstringURL of the image of the entity.
slug_identifierstringSlug used in URLs of the entity.
is_ui_filterbooleanThis property is used to mark an entity as a filter for the frontend
content_profilestringHow much this particular sign is allowed to say. A door sign is a publicly visible output channel: that the renderer may read the data does not mean the sign may show it. The profile sits on the display, not on the room, because the same room can carry a hallway sign and a staff-side sign.
languagestringLanguage every word on this frame is rendered in. Sits on the display, not on the installation: a foyer board in a bilingual building can want English while the door signs behind it stay German.
show_booking_qrbooleanShow a booking QR code when the bookable is free. Only honoured when the bookable actually accepts self-service bookings - a code that leads nowhere is worse than no code.
notice_textstringFree-text notice, rendered as a footer line.
refresh_secondsintegerBaseline for the X-Refresh-After header, in seconds. The renderer shortens it when something happens sooner and never exceeds it by much.
last_seen_atstring (date-time)Last successful fetch by the device. No log table on purpose: a display checks in every few minutes, which is roughly 288 rows per device per day, and only the last one is ever read.
battery_voltagenumber (float)Battery voltage of the display in volts.
battery_warn_voltagenumber (float)Battery voltage below which this display counts as needing a new battery. Per display because the hardware differs by a factor of two: a LiPo door sign is flat around 3.5 V, a coin cell OpenDisplay tag around 2.4 V. Empty means the installation-wide default (event_external_display_battery_warn_voltage).
battery_warning_sent_atstring (date-time)When the health check found the battery below the threshold. Cleared once a reading is clearly above it again, so a replaced battery re-arms the warning. This is the display's maintenance flag as much as a send marker: it is set even when no recipient is configured.
offline_warning_sent_atstring (date-time)When the health check found the display silent for too long. Cleared by the next fetch of the device.
firmware_versionstringFirmware version of the display.
rssiintegerSignal strength of the display in dBm.
namestringName of the entity.
deletedbooleanThis property is used to mark an entity as deleted / archived
createdstring (date-time)Point in time the entity was created.
updatedstring (date-time)Point in time the entity was last updated.
curl --request PUT \
--url https://your-instance.iw-erp.de/api/event/external_display/42 \
--header 'content-type: application/json' \
--header 'x-iw-jwt-token: <TOKEN>' \
--data '
{
"data": {
"language": "de",
"notice_text": "Text",
"device_type": "string",
"base_bookable": {
"address_street": "Jakobistr. 39",
"address_city": "Hannover",
"address_zip": "30163",
"address_country": "DE",
"address_full_country": "DE",
"main_phone": "+49 511 123456"
},
"base_location": {
"address_street": "Jakobistr. 39",
"address_city": "Hannover",
"address_zip": "30163",
"address_country": "DE",
"address_full_country": "DE",
"main_phone": "+49 511 123456"
},
"content_profile": "string"
}
}
'const options = {
method: 'PUT',
headers: {'x-iw-jwt-token': '<TOKEN>', 'content-type': 'application/json'},
body: JSON.stringify({
data: {
language: 'de',
notice_text: 'Text',
device_type: 'string',
base_bookable: {
address_street: 'Jakobistr. 39',
address_city: 'Hannover',
address_zip: '30163',
address_country: 'DE',
address_full_country: 'DE',
main_phone: '+49 511 123456'
},
base_location: {
address_street: 'Jakobistr. 39',
address_city: 'Hannover',
address_zip: '30163',
address_country: 'DE',
address_full_country: 'DE',
main_phone: '+49 511 123456'
},
content_profile: 'string'
}
})
};
fetch('https://your-instance.iw-erp.de/api/event/external_display/42', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));import requests
url = "https://your-instance.iw-erp.de/api/event/external_display/42"
payload = { "data": {
"language": "de",
"notice_text": "Text",
"device_type": "string",
"base_bookable": {
"address_street": "Jakobistr. 39",
"address_city": "Hannover",
"address_zip": "30163",
"address_country": "DE",
"address_full_country": "DE",
"main_phone": "+49 511 123456"
},
"base_location": {
"address_street": "Jakobistr. 39",
"address_city": "Hannover",
"address_zip": "30163",
"address_country": "DE",
"address_full_country": "DE",
"main_phone": "+49 511 123456"
},
"content_profile": "string"
} }
headers = {
"x-iw-jwt-token": "<TOKEN>",
"content-type": "application/json"
}
response = requests.put(url, json=payload, headers=headers)
print(response.text)<?php
require_once('vendor/autoload.php');
$client = new \GuzzleHttp\Client();
$response = $client->request('PUT', 'https://your-instance.iw-erp.de/api/event/external_display/42', [
'body' => '{"data":{"language":"de","notice_text":"Text","device_type":"string","base_bookable":{"address_street":"Jakobistr. 39","address_city":"Hannover","address_zip":"30163","address_country":"DE","address_full_country":"DE","main_phone":"+49 511 123456"},"base_location":{"address_street":"Jakobistr. 39","address_city":"Hannover","address_zip":"30163","address_country":"DE","address_full_country":"DE","main_phone":"+49 511 123456"},"content_profile":"string"}}',
'headers' => [
'content-type' => 'application/json',
'x-iw-jwt-token' => '<TOKEN>',
],
]);
echo $response->getBody();using System.Net.Http.Headers;
var client = new HttpClient();
var request = new HttpRequestMessage
{
Method = HttpMethod.Put,
RequestUri = new Uri("https://your-instance.iw-erp.de/api/event/external_display/42"),
Headers =
{
{ "x-iw-jwt-token", "<TOKEN>" },
},
Content = new StringContent("{\"data\":{\"language\":\"de\",\"notice_text\":\"Text\",\"device_type\":\"string\",\"base_bookable\":{\"address_street\":\"Jakobistr. 39\",\"address_city\":\"Hannover\",\"address_zip\":\"30163\",\"address_country\":\"DE\",\"address_full_country\":\"DE\",\"main_phone\":\"+49 511 123456\"},\"base_location\":{\"address_street\":\"Jakobistr. 39\",\"address_city\":\"Hannover\",\"address_zip\":\"30163\",\"address_country\":\"DE\",\"address_full_country\":\"DE\",\"main_phone\":\"+49 511 123456\"},\"content_profile\":\"string\"}}")
{
Headers =
{
ContentType = new MediaTypeHeaderValue("application/json")
}
}
};
using (var response = await client.SendAsync(request))
{
response.EnsureSuccessStatusCode();
var body = await response.Content.ReadAsStringAsync();
Console.WriteLine(body);
}OkHttpClient client = new OkHttpClient();
MediaType mediaType = MediaType.parse("application/json");
RequestBody body = RequestBody.create(mediaType, "{\"data\":{\"language\":\"de\",\"notice_text\":\"Text\",\"device_type\":\"string\",\"base_bookable\":{\"address_street\":\"Jakobistr. 39\",\"address_city\":\"Hannover\",\"address_zip\":\"30163\",\"address_country\":\"DE\",\"address_full_country\":\"DE\",\"main_phone\":\"+49 511 123456\"},\"base_location\":{\"address_street\":\"Jakobistr. 39\",\"address_city\":\"Hannover\",\"address_zip\":\"30163\",\"address_country\":\"DE\",\"address_full_country\":\"DE\",\"main_phone\":\"+49 511 123456\"},\"content_profile\":\"string\"}}");
Request request = new Request.Builder()
.url("https://your-instance.iw-erp.de/api/event/external_display/42")
.put(body)
.addHeader("x-iw-jwt-token", "<TOKEN>")
.addHeader("content-type", "application/json")
.build();
Response response = client.newCall(request).execute();package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://your-instance.iw-erp.de/api/event/external_display/42"
payload := strings.NewReader("{\"data\":{\"language\":\"de\",\"notice_text\":\"Text\",\"device_type\":\"string\",\"base_bookable\":{\"address_street\":\"Jakobistr. 39\",\"address_city\":\"Hannover\",\"address_zip\":\"30163\",\"address_country\":\"DE\",\"address_full_country\":\"DE\",\"main_phone\":\"+49 511 123456\"},\"base_location\":{\"address_street\":\"Jakobistr. 39\",\"address_city\":\"Hannover\",\"address_zip\":\"30163\",\"address_country\":\"DE\",\"address_full_country\":\"DE\",\"main_phone\":\"+49 511 123456\"},\"content_profile\":\"string\"}}")
req, _ := http.NewRequest("PUT", url, payload)
req.Header.Add("x-iw-jwt-token", "<TOKEN>")
req.Header.Add("content-type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}Dart with the iw_erp_api package
import 'package:iw_erp_api/clients/external_display_controller.dart';
import 'package:iw_erp_api/logic/iw_api_state.dart';
import 'package:iw_erp_api/model/external_display.dart';
IwApiState().host = 'your-instance.iw-erp.de';
IwApiState().currentJwtApiToken = '<TOKEN>';
final result = await ExternalDisplayController.put(ExternalDisplay.fromJson({
"language": "de",
"notice_text": "Text",
"device_type": "string",
"base_bookable": {
"address_street": "Jakobistr. 39",
"address_city": "Hannover",
"address_zip": "30163",
"address_country": "DE",
"address_full_country": "DE",
"main_phone": "+49 511 123456"
},
"base_location": {
"address_street": "Jakobistr. 39",
"address_city": "Hannover",
"address_zip": "30163",
"address_country": "DE",
"address_full_country": "DE",
"main_phone": "+49 511 123456"
},
"content_profile": "string"
}));
if (result.success) {
print(result.data);
}{
"id": 42,
"language": "de",
"notice_text": "Text",
"name": "Beispiel",
"device_type": "string",
"device_id": "42",
"previous_secret_valid_until": "2026-10-15T09:30:00+02:00",
"base_bookable": {
"id": 42,
"require_booking_title": true,
"address_street": "Jakobistr. 39",
"address_city": "Hannover",
"address_zip": "30163",
"address_country": "DE",
"address_full_country": "DE",
"main_phone": "+49 511 123456",
"main_email": "lena.hartmann@example.org",
"name": "Beispiel"
},
"base_location": {
"id": 42,
"address_street": "Jakobistr. 39",
"address_city": "Hannover",
"address_zip": "30163",
"address_country": "DE",
"address_full_country": "DE",
"main_phone": "+49 511 123456",
"main_email": "lena.hartmann@example.org",
"name": "Beispiel",
"image_url": "https://vynst.de"
},
"content_profile": "string"
}Updates an ExternalDisplay
PATCH/api/event/external_display/{identifier}
Path parameters
identifierrequiredstring |
Request body application/json
dataExternalDisplay2Show fields (10)
device_typestringWhich kind of device this is, and therefore which driver renders for it. Today only the built-in e-paper renderer exists; a third-party display API becomes an additional type plus an additional driver, nothing else.
base_bookableBaseBookable17Bookable the display shows.
base_locationBaseLocation6Location the display is placed at.
content_profilestringHow much this particular sign is allowed to say. A door sign is a publicly visible output channel: that the renderer may read the data does not mean the sign may show it. The profile sits on the display, not on the room, because the same room can carry a hallway sign and a staff-side sign.
languagestringLanguage every word on this frame is rendered in. Sits on the display, not on the installation: a foyer board in a bilingual building can want English while the door signs behind it stay German.
show_booking_qrbooleanShow a booking QR code when the bookable is free. Only honoured when the bookable actually accepts self-service bookings - a code that leads nowhere is worse than no code.
notice_textstringFree-text notice, rendered as a footer line.
refresh_secondsintegerBaseline for the X-Refresh-After header, in seconds. The renderer shortens it when something happens sooner and never exceeds it by much.
battery_warn_voltagenumber (float)Battery voltage below which this display counts as needing a new battery. Per display because the hardware differs by a factor of two: a LiPo door sign is flat around 3.5 V, a coin cell OpenDisplay tag around 2.4 V. Empty means the installation-wide default (event_external_display_battery_warn_voltage).
deletedbooleanThis property is used to mark an entity as deleted / archived
Responses
200Update an ExternalDisplayExternalDisplay
Show fields (22)
idintegerPrimary key of the external display. Internal ID.
device_typestringWhich kind of device this is, and therefore which driver renders for it. Today only the built-in e-paper renderer exists; a third-party display API becomes an additional type plus an additional driver, nothing else.
device_idstringPublic identifier of the device, travelling in the request path. Deliberately not the secret: paths end up in access logs, proxy logs and support screenshots. Keeping an id there lets a device be identified in a log without the credential riding along.
previous_secret_valid_untilstring (date-time)Time until the previous secret of the display is still accepted.
base_bookableBaseBookable16Bookable the display shows.
Show fields (49)
ticketSeatingPlanIdintegerId of the seating plan of the room, also for the public serialization.
idintegerPrimary key of the bookable. Internal ID.
tokenstringPublic token of the bookable. Used in links instead of the ID.
bookable_typestringType of the bookable, for example room, court or vehicle.
floor_levelstringFloor the bookable is on.
floor_sizeintegerFloor size in square meters.
pets_allowedbooleanPets are allowed.
barrier_freebooleanThe bookable is barrier-free.
cargo_volumeintegerCargo volume in liters.
fuel_typestringFuel type of the vehicle.
seating_capacityintegerNumber of seats.
has_wait_listbooleanThe bookable has a waiting list once it is fully booked.
booking_limitintegerMaximum number of bookings.
billing_modestringHow bookings on this bookable are billed: BILLING_MODE_UPFRONT (null = upfront, invoice at booking time) or BILLING_MODE_USAGE (free reservation, deferred billing from real usage data) Also in Default: the member app shows "Nutzung erfassen" only for usage-billed bookables.
max_active_bookings_per_userintegerMaximum number of active (future, not cancelled) self-service bookings one person may hold on this bookable at the same time. Null = unlimited. Admin bookings are not limited.
max_advance_booking_hoursintegerMaximum number of hours a self-service booking may start in the future. Null = unlimited. Admin bookings are not limited.
inventory_managedbooleanKept as inventory (Inventar-Ausleihe): the office hands the item over and takes it back, with deposit and reminders. Only used while the setting event_inventory_enabled is on.
inventory_depositnumber (float)Deposit (Kaution) per piece asked on hand-over. Null = no deposit.
require_addressbooleanThe address must be entered when booking.
require_contactbooleanContact details must be entered when booking.
require_billingbooleanBilling details must be entered when booking.
require_booking_titlebooleanA title must be entered when booking.
allow_direct_billingbooleanrequire_agebooleanThe age must be entered when booking.
counter_update_modestringHow the usage counters of the bookable are updated.
createdstring (date-time)Point in time the entity was created.
updatedstring (date-time)Point in time the entity was last updated.
addressstringAddress as text.
address_streetstringStreet of the address.
address_house_numberstringHouse number of the address.
address_street_levelstringStreet and house number of the address.
address_costringCare-of line of the address.
address_citystringCity of the address.
address_zipstringPostal code of the address.
address_admin_level1stringFirst administrative level of the address, e.g. the federal state.
address_countrystringCountry code of the address.
address_full_countrystringFull name of the country of the address.
address_geo_latstringLatitude of the address.
address_geo_lngstringLongitude of the address.
address_external_provider_idstringfield to store the external provider id of the address. e.g. Google Maps PlaceID like google:ChIJVcKw5r90sEcRhdjNq6NItqE
main_phonestringMain phone number.
main_faxstringMain fax number.
main_emailstringMain e-mail address.
websitestringWebsite address.
namestringName of the entity.
deletedbooleanThis property is used to mark an entity as deleted / archived
short_identifierstringShort identifier of the entity.
image_urlstringURL of the image of the entity.
slug_identifierstringSlug used in URLs of the entity.
base_locationBaseLocation10Location the display is placed at.
Show fields (29)
idintegerPrimary key of the location. Internal ID.
tokenstringPublic token of the location. Used in links instead of the ID.
location_typestringType of the location, for example room, hall or outdoor area.
in_contact_centerbooleanThe location is shown in the contact center.
createdstring (date-time)Point in time the entity was created.
updatedstring (date-time)Point in time the entity was last updated.
addressstringAddress as text.
address_streetstringStreet of the address.
address_house_numberstringHouse number of the address.
address_street_levelstringStreet and house number of the address.
address_costringCare-of line of the address.
address_citystringCity of the address.
address_zipstringPostal code of the address.
address_admin_level1stringFirst administrative level of the address, e.g. the federal state.
address_countrystringCountry code of the address.
address_full_countrystringFull name of the country of the address.
address_geo_latstringLatitude of the address.
address_geo_lngstringLongitude of the address.
address_external_provider_idstringfield to store the external provider id of the address. e.g. Google Maps PlaceID like google:ChIJVcKw5r90sEcRhdjNq6NItqE
main_phonestringMain phone number.
main_faxstringMain fax number.
main_emailstringMain e-mail address.
websitestringWebsite address.
namestringName of the entity.
deletedbooleanThis property is used to mark an entity as deleted / archived
short_identifierstringShort identifier of the entity.
image_urlstringURL of the image of the entity.
slug_identifierstringSlug used in URLs of the entity.
is_ui_filterbooleanThis property is used to mark an entity as a filter for the frontend
content_profilestringHow much this particular sign is allowed to say. A door sign is a publicly visible output channel: that the renderer may read the data does not mean the sign may show it. The profile sits on the display, not on the room, because the same room can carry a hallway sign and a staff-side sign.
languagestringLanguage every word on this frame is rendered in. Sits on the display, not on the installation: a foyer board in a bilingual building can want English while the door signs behind it stay German.
show_booking_qrbooleanShow a booking QR code when the bookable is free. Only honoured when the bookable actually accepts self-service bookings - a code that leads nowhere is worse than no code.
notice_textstringFree-text notice, rendered as a footer line.
refresh_secondsintegerBaseline for the X-Refresh-After header, in seconds. The renderer shortens it when something happens sooner and never exceeds it by much.
last_seen_atstring (date-time)Last successful fetch by the device. No log table on purpose: a display checks in every few minutes, which is roughly 288 rows per device per day, and only the last one is ever read.
battery_voltagenumber (float)Battery voltage of the display in volts.
battery_warn_voltagenumber (float)Battery voltage below which this display counts as needing a new battery. Per display because the hardware differs by a factor of two: a LiPo door sign is flat around 3.5 V, a coin cell OpenDisplay tag around 2.4 V. Empty means the installation-wide default (event_external_display_battery_warn_voltage).
battery_warning_sent_atstring (date-time)When the health check found the battery below the threshold. Cleared once a reading is clearly above it again, so a replaced battery re-arms the warning. This is the display's maintenance flag as much as a send marker: it is set even when no recipient is configured.
offline_warning_sent_atstring (date-time)When the health check found the display silent for too long. Cleared by the next fetch of the device.
firmware_versionstringFirmware version of the display.
rssiintegerSignal strength of the display in dBm.
namestringName of the entity.
deletedbooleanThis property is used to mark an entity as deleted / archived
createdstring (date-time)Point in time the entity was created.
updatedstring (date-time)Point in time the entity was last updated.
curl --request PATCH \
--url https://your-instance.iw-erp.de/api/event/external_display/42 \
--header 'content-type: application/json' \
--header 'x-iw-jwt-token: <TOKEN>' \
--data '
{
"data": {
"language": "de",
"notice_text": "Text",
"device_type": "string",
"base_bookable": {
"address_street": "Jakobistr. 39",
"address_city": "Hannover",
"address_zip": "30163",
"address_country": "DE",
"address_full_country": "DE",
"main_phone": "+49 511 123456"
},
"base_location": {
"address_street": "Jakobistr. 39",
"address_city": "Hannover",
"address_zip": "30163",
"address_country": "DE",
"address_full_country": "DE",
"main_phone": "+49 511 123456"
},
"content_profile": "string"
}
}
'const options = {
method: 'PATCH',
headers: {'x-iw-jwt-token': '<TOKEN>', 'content-type': 'application/json'},
body: JSON.stringify({
data: {
language: 'de',
notice_text: 'Text',
device_type: 'string',
base_bookable: {
address_street: 'Jakobistr. 39',
address_city: 'Hannover',
address_zip: '30163',
address_country: 'DE',
address_full_country: 'DE',
main_phone: '+49 511 123456'
},
base_location: {
address_street: 'Jakobistr. 39',
address_city: 'Hannover',
address_zip: '30163',
address_country: 'DE',
address_full_country: 'DE',
main_phone: '+49 511 123456'
},
content_profile: 'string'
}
})
};
fetch('https://your-instance.iw-erp.de/api/event/external_display/42', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));import requests
url = "https://your-instance.iw-erp.de/api/event/external_display/42"
payload = { "data": {
"language": "de",
"notice_text": "Text",
"device_type": "string",
"base_bookable": {
"address_street": "Jakobistr. 39",
"address_city": "Hannover",
"address_zip": "30163",
"address_country": "DE",
"address_full_country": "DE",
"main_phone": "+49 511 123456"
},
"base_location": {
"address_street": "Jakobistr. 39",
"address_city": "Hannover",
"address_zip": "30163",
"address_country": "DE",
"address_full_country": "DE",
"main_phone": "+49 511 123456"
},
"content_profile": "string"
} }
headers = {
"x-iw-jwt-token": "<TOKEN>",
"content-type": "application/json"
}
response = requests.patch(url, json=payload, headers=headers)
print(response.text)<?php
require_once('vendor/autoload.php');
$client = new \GuzzleHttp\Client();
$response = $client->request('PATCH', 'https://your-instance.iw-erp.de/api/event/external_display/42', [
'body' => '{"data":{"language":"de","notice_text":"Text","device_type":"string","base_bookable":{"address_street":"Jakobistr. 39","address_city":"Hannover","address_zip":"30163","address_country":"DE","address_full_country":"DE","main_phone":"+49 511 123456"},"base_location":{"address_street":"Jakobistr. 39","address_city":"Hannover","address_zip":"30163","address_country":"DE","address_full_country":"DE","main_phone":"+49 511 123456"},"content_profile":"string"}}',
'headers' => [
'content-type' => 'application/json',
'x-iw-jwt-token' => '<TOKEN>',
],
]);
echo $response->getBody();using System.Net.Http.Headers;
var client = new HttpClient();
var request = new HttpRequestMessage
{
Method = HttpMethod.Patch,
RequestUri = new Uri("https://your-instance.iw-erp.de/api/event/external_display/42"),
Headers =
{
{ "x-iw-jwt-token", "<TOKEN>" },
},
Content = new StringContent("{\"data\":{\"language\":\"de\",\"notice_text\":\"Text\",\"device_type\":\"string\",\"base_bookable\":{\"address_street\":\"Jakobistr. 39\",\"address_city\":\"Hannover\",\"address_zip\":\"30163\",\"address_country\":\"DE\",\"address_full_country\":\"DE\",\"main_phone\":\"+49 511 123456\"},\"base_location\":{\"address_street\":\"Jakobistr. 39\",\"address_city\":\"Hannover\",\"address_zip\":\"30163\",\"address_country\":\"DE\",\"address_full_country\":\"DE\",\"main_phone\":\"+49 511 123456\"},\"content_profile\":\"string\"}}")
{
Headers =
{
ContentType = new MediaTypeHeaderValue("application/json")
}
}
};
using (var response = await client.SendAsync(request))
{
response.EnsureSuccessStatusCode();
var body = await response.Content.ReadAsStringAsync();
Console.WriteLine(body);
}OkHttpClient client = new OkHttpClient();
MediaType mediaType = MediaType.parse("application/json");
RequestBody body = RequestBody.create(mediaType, "{\"data\":{\"language\":\"de\",\"notice_text\":\"Text\",\"device_type\":\"string\",\"base_bookable\":{\"address_street\":\"Jakobistr. 39\",\"address_city\":\"Hannover\",\"address_zip\":\"30163\",\"address_country\":\"DE\",\"address_full_country\":\"DE\",\"main_phone\":\"+49 511 123456\"},\"base_location\":{\"address_street\":\"Jakobistr. 39\",\"address_city\":\"Hannover\",\"address_zip\":\"30163\",\"address_country\":\"DE\",\"address_full_country\":\"DE\",\"main_phone\":\"+49 511 123456\"},\"content_profile\":\"string\"}}");
Request request = new Request.Builder()
.url("https://your-instance.iw-erp.de/api/event/external_display/42")
.patch(body)
.addHeader("x-iw-jwt-token", "<TOKEN>")
.addHeader("content-type", "application/json")
.build();
Response response = client.newCall(request).execute();package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://your-instance.iw-erp.de/api/event/external_display/42"
payload := strings.NewReader("{\"data\":{\"language\":\"de\",\"notice_text\":\"Text\",\"device_type\":\"string\",\"base_bookable\":{\"address_street\":\"Jakobistr. 39\",\"address_city\":\"Hannover\",\"address_zip\":\"30163\",\"address_country\":\"DE\",\"address_full_country\":\"DE\",\"main_phone\":\"+49 511 123456\"},\"base_location\":{\"address_street\":\"Jakobistr. 39\",\"address_city\":\"Hannover\",\"address_zip\":\"30163\",\"address_country\":\"DE\",\"address_full_country\":\"DE\",\"main_phone\":\"+49 511 123456\"},\"content_profile\":\"string\"}}")
req, _ := http.NewRequest("PATCH", url, payload)
req.Header.Add("x-iw-jwt-token", "<TOKEN>")
req.Header.Add("content-type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}Dart with package:http (no controller in the iw_erp_api package)
import 'dart:convert';
import 'package:http/http.dart' as http;
final response = await http.patch(
Uri.parse('https://your-instance.iw-erp.de/api/event/external_display/42'),
headers: {'x-iw-jwt-token': '<TOKEN>', 'content-type': 'application/json'},
body: jsonEncode({
"data": {
"language": "de",
"notice_text": "Text",
"device_type": "string",
"base_bookable": {
"address_street": "Jakobistr. 39",
"address_city": "Hannover",
"address_zip": "30163",
"address_country": "DE",
"address_full_country": "DE",
"main_phone": "+49 511 123456"
},
"base_location": {
"address_street": "Jakobistr. 39",
"address_city": "Hannover",
"address_zip": "30163",
"address_country": "DE",
"address_full_country": "DE",
"main_phone": "+49 511 123456"
},
"content_profile": "string"
}
}),
);
print(response.body);{
"id": 42,
"language": "de",
"notice_text": "Text",
"name": "Beispiel",
"device_type": "string",
"device_id": "42",
"previous_secret_valid_until": "2026-10-15T09:30:00+02:00",
"base_bookable": {
"id": 42,
"require_booking_title": true,
"address_street": "Jakobistr. 39",
"address_city": "Hannover",
"address_zip": "30163",
"address_country": "DE",
"address_full_country": "DE",
"main_phone": "+49 511 123456",
"main_email": "lena.hartmann@example.org",
"name": "Beispiel"
},
"base_location": {
"id": 42,
"address_street": "Jakobistr. 39",
"address_city": "Hannover",
"address_zip": "30163",
"address_country": "DE",
"address_full_country": "DE",
"main_phone": "+49 511 123456",
"main_email": "lena.hartmann@example.org",
"name": "Beispiel",
"image_url": "https://vynst.de"
},
"content_profile": "string"
}Deletes a single ExternalDisplay
DELETE/api/event/external_display/{identifier}
Path parameters
identifierrequiredstring |
Responses
200Deletes a single ExternalDisplayExternalDisplay
Show fields (22)
idintegerPrimary key of the external display. Internal ID.
device_typestringWhich kind of device this is, and therefore which driver renders for it. Today only the built-in e-paper renderer exists; a third-party display API becomes an additional type plus an additional driver, nothing else.
device_idstringPublic identifier of the device, travelling in the request path. Deliberately not the secret: paths end up in access logs, proxy logs and support screenshots. Keeping an id there lets a device be identified in a log without the credential riding along.
previous_secret_valid_untilstring (date-time)Time until the previous secret of the display is still accepted.
base_bookableBaseBookable16Bookable the display shows.
Show fields (49)
ticketSeatingPlanIdintegerId of the seating plan of the room, also for the public serialization.
idintegerPrimary key of the bookable. Internal ID.
tokenstringPublic token of the bookable. Used in links instead of the ID.
bookable_typestringType of the bookable, for example room, court or vehicle.
floor_levelstringFloor the bookable is on.
floor_sizeintegerFloor size in square meters.
pets_allowedbooleanPets are allowed.
barrier_freebooleanThe bookable is barrier-free.
cargo_volumeintegerCargo volume in liters.
fuel_typestringFuel type of the vehicle.
seating_capacityintegerNumber of seats.
has_wait_listbooleanThe bookable has a waiting list once it is fully booked.
booking_limitintegerMaximum number of bookings.
billing_modestringHow bookings on this bookable are billed: BILLING_MODE_UPFRONT (null = upfront, invoice at booking time) or BILLING_MODE_USAGE (free reservation, deferred billing from real usage data) Also in Default: the member app shows "Nutzung erfassen" only for usage-billed bookables.
max_active_bookings_per_userintegerMaximum number of active (future, not cancelled) self-service bookings one person may hold on this bookable at the same time. Null = unlimited. Admin bookings are not limited.
max_advance_booking_hoursintegerMaximum number of hours a self-service booking may start in the future. Null = unlimited. Admin bookings are not limited.
inventory_managedbooleanKept as inventory (Inventar-Ausleihe): the office hands the item over and takes it back, with deposit and reminders. Only used while the setting event_inventory_enabled is on.
inventory_depositnumber (float)Deposit (Kaution) per piece asked on hand-over. Null = no deposit.
require_addressbooleanThe address must be entered when booking.
require_contactbooleanContact details must be entered when booking.
require_billingbooleanBilling details must be entered when booking.
require_booking_titlebooleanA title must be entered when booking.
allow_direct_billingbooleanrequire_agebooleanThe age must be entered when booking.
counter_update_modestringHow the usage counters of the bookable are updated.
createdstring (date-time)Point in time the entity was created.
updatedstring (date-time)Point in time the entity was last updated.
addressstringAddress as text.
address_streetstringStreet of the address.
address_house_numberstringHouse number of the address.
address_street_levelstringStreet and house number of the address.
address_costringCare-of line of the address.
address_citystringCity of the address.
address_zipstringPostal code of the address.
address_admin_level1stringFirst administrative level of the address, e.g. the federal state.
address_countrystringCountry code of the address.
address_full_countrystringFull name of the country of the address.
address_geo_latstringLatitude of the address.
address_geo_lngstringLongitude of the address.
address_external_provider_idstringfield to store the external provider id of the address. e.g. Google Maps PlaceID like google:ChIJVcKw5r90sEcRhdjNq6NItqE
main_phonestringMain phone number.
main_faxstringMain fax number.
main_emailstringMain e-mail address.
websitestringWebsite address.
namestringName of the entity.
deletedbooleanThis property is used to mark an entity as deleted / archived
short_identifierstringShort identifier of the entity.
image_urlstringURL of the image of the entity.
slug_identifierstringSlug used in URLs of the entity.
base_locationBaseLocation10Location the display is placed at.
Show fields (29)
idintegerPrimary key of the location. Internal ID.
tokenstringPublic token of the location. Used in links instead of the ID.
location_typestringType of the location, for example room, hall or outdoor area.
in_contact_centerbooleanThe location is shown in the contact center.
createdstring (date-time)Point in time the entity was created.
updatedstring (date-time)Point in time the entity was last updated.
addressstringAddress as text.
address_streetstringStreet of the address.
address_house_numberstringHouse number of the address.
address_street_levelstringStreet and house number of the address.
address_costringCare-of line of the address.
address_citystringCity of the address.
address_zipstringPostal code of the address.
address_admin_level1stringFirst administrative level of the address, e.g. the federal state.
address_countrystringCountry code of the address.
address_full_countrystringFull name of the country of the address.
address_geo_latstringLatitude of the address.
address_geo_lngstringLongitude of the address.
address_external_provider_idstringfield to store the external provider id of the address. e.g. Google Maps PlaceID like google:ChIJVcKw5r90sEcRhdjNq6NItqE
main_phonestringMain phone number.
main_faxstringMain fax number.
main_emailstringMain e-mail address.
websitestringWebsite address.
namestringName of the entity.
deletedbooleanThis property is used to mark an entity as deleted / archived
short_identifierstringShort identifier of the entity.
image_urlstringURL of the image of the entity.
slug_identifierstringSlug used in URLs of the entity.
is_ui_filterbooleanThis property is used to mark an entity as a filter for the frontend
content_profilestringHow much this particular sign is allowed to say. A door sign is a publicly visible output channel: that the renderer may read the data does not mean the sign may show it. The profile sits on the display, not on the room, because the same room can carry a hallway sign and a staff-side sign.
languagestringLanguage every word on this frame is rendered in. Sits on the display, not on the installation: a foyer board in a bilingual building can want English while the door signs behind it stay German.
show_booking_qrbooleanShow a booking QR code when the bookable is free. Only honoured when the bookable actually accepts self-service bookings - a code that leads nowhere is worse than no code.
notice_textstringFree-text notice, rendered as a footer line.
refresh_secondsintegerBaseline for the X-Refresh-After header, in seconds. The renderer shortens it when something happens sooner and never exceeds it by much.
last_seen_atstring (date-time)Last successful fetch by the device. No log table on purpose: a display checks in every few minutes, which is roughly 288 rows per device per day, and only the last one is ever read.
battery_voltagenumber (float)Battery voltage of the display in volts.
battery_warn_voltagenumber (float)Battery voltage below which this display counts as needing a new battery. Per display because the hardware differs by a factor of two: a LiPo door sign is flat around 3.5 V, a coin cell OpenDisplay tag around 2.4 V. Empty means the installation-wide default (event_external_display_battery_warn_voltage).
battery_warning_sent_atstring (date-time)When the health check found the battery below the threshold. Cleared once a reading is clearly above it again, so a replaced battery re-arms the warning. This is the display's maintenance flag as much as a send marker: it is set even when no recipient is configured.
offline_warning_sent_atstring (date-time)When the health check found the display silent for too long. Cleared by the next fetch of the device.
firmware_versionstringFirmware version of the display.
rssiintegerSignal strength of the display in dBm.
namestringName of the entity.
deletedbooleanThis property is used to mark an entity as deleted / archived
createdstring (date-time)Point in time the entity was created.
updatedstring (date-time)Point in time the entity was last updated.
curl --request DELETE \
--url https://your-instance.iw-erp.de/api/event/external_display/42 \
--header 'x-iw-jwt-token: <TOKEN>'const options = {method: 'DELETE', headers: {'x-iw-jwt-token': '<TOKEN>'}};
fetch('https://your-instance.iw-erp.de/api/event/external_display/42', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));import requests
url = "https://your-instance.iw-erp.de/api/event/external_display/42"
headers = {"x-iw-jwt-token": "<TOKEN>"}
response = requests.delete(url, headers=headers)
print(response.text)<?php
require_once('vendor/autoload.php');
$client = new \GuzzleHttp\Client();
$response = $client->request('DELETE', 'https://your-instance.iw-erp.de/api/event/external_display/42', [
'headers' => [
'x-iw-jwt-token' => '<TOKEN>',
],
]);
echo $response->getBody();using System.Net.Http.Headers;
var client = new HttpClient();
var request = new HttpRequestMessage
{
Method = HttpMethod.Delete,
RequestUri = new Uri("https://your-instance.iw-erp.de/api/event/external_display/42"),
Headers =
{
{ "x-iw-jwt-token", "<TOKEN>" },
},
};
using (var response = await client.SendAsync(request))
{
response.EnsureSuccessStatusCode();
var body = await response.Content.ReadAsStringAsync();
Console.WriteLine(body);
}OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder()
.url("https://your-instance.iw-erp.de/api/event/external_display/42")
.delete(null)
.addHeader("x-iw-jwt-token", "<TOKEN>")
.build();
Response response = client.newCall(request).execute();package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://your-instance.iw-erp.de/api/event/external_display/42"
req, _ := http.NewRequest("DELETE", url, nil)
req.Header.Add("x-iw-jwt-token", "<TOKEN>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}Dart with the iw_erp_api package
import 'package:iw_erp_api/clients/external_display_controller.dart';
import 'package:iw_erp_api/logic/iw_api_state.dart';
IwApiState().host = 'your-instance.iw-erp.de';
IwApiState().currentJwtApiToken = '<TOKEN>';
final result = await ExternalDisplayController.delete('42');
if (result.success) {
print(result.data);
}{
"id": 42,
"language": "de",
"notice_text": "Text",
"name": "Beispiel",
"device_type": "string",
"device_id": "42",
"previous_secret_valid_until": "2026-10-15T09:30:00+02:00",
"base_bookable": {
"id": 42,
"require_booking_title": true,
"address_street": "Jakobistr. 39",
"address_city": "Hannover",
"address_zip": "30163",
"address_country": "DE",
"address_full_country": "DE",
"main_phone": "+49 511 123456",
"main_email": "lena.hartmann@example.org",
"name": "Beispiel"
},
"base_location": {
"id": 42,
"address_street": "Jakobistr. 39",
"address_city": "Hannover",
"address_zip": "30163",
"address_country": "DE",
"address_full_country": "DE",
"main_phone": "+49 511 123456",
"main_email": "lena.hartmann@example.org",
"name": "Beispiel",
"image_url": "https://vynst.de"
},
"content_profile": "string"
}Returns what has to be flashed onto a device: its image URL and its secret.
GET/api/event/external_display/{identifier}/credentials
Separate from the detail endpoint so the secret is fetched deliberately and appears in exactly one response, instead of riding along in every list the management UI loads.
Path parameters
identifierrequiredstring |
Responses
200Device credentialsobject
Show fields (6)
device_idstringimage_urlstringsecretstringprevious_secretstringprevious_secret_valid_untilstringrefresh_secondsinteger
curl --request GET \
--url https://your-instance.iw-erp.de/api/event/external_display/42/credentials \
--header 'x-iw-jwt-token: <TOKEN>'const options = {method: 'GET', headers: {'x-iw-jwt-token': '<TOKEN>'}};
fetch('https://your-instance.iw-erp.de/api/event/external_display/42/credentials', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));import requests
url = "https://your-instance.iw-erp.de/api/event/external_display/42/credentials"
headers = {"x-iw-jwt-token": "<TOKEN>"}
response = requests.get(url, headers=headers)
print(response.text)<?php
require_once('vendor/autoload.php');
$client = new \GuzzleHttp\Client();
$response = $client->request('GET', 'https://your-instance.iw-erp.de/api/event/external_display/42/credentials', [
'headers' => [
'x-iw-jwt-token' => '<TOKEN>',
],
]);
echo $response->getBody();using System.Net.Http.Headers;
var client = new HttpClient();
var request = new HttpRequestMessage
{
Method = HttpMethod.Get,
RequestUri = new Uri("https://your-instance.iw-erp.de/api/event/external_display/42/credentials"),
Headers =
{
{ "x-iw-jwt-token", "<TOKEN>" },
},
};
using (var response = await client.SendAsync(request))
{
response.EnsureSuccessStatusCode();
var body = await response.Content.ReadAsStringAsync();
Console.WriteLine(body);
}OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder()
.url("https://your-instance.iw-erp.de/api/event/external_display/42/credentials")
.get()
.addHeader("x-iw-jwt-token", "<TOKEN>")
.build();
Response response = client.newCall(request).execute();package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://your-instance.iw-erp.de/api/event/external_display/42/credentials"
req, _ := http.NewRequest("GET", url, nil)
req.Header.Add("x-iw-jwt-token", "<TOKEN>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}Dart with the iw_erp_api package
import 'package:iw_erp_api/clients/external_display_controller.dart';
import 'package:iw_erp_api/logic/iw_api_state.dart';
IwApiState().host = 'your-instance.iw-erp.de';
IwApiState().currentJwtApiToken = '<TOKEN>';
final result = await ExternalDisplayController.credentials('42');
if (result.success) {
print(result.data);
}{
"image_url": "https://vynst.de",
"device_id": "42",
"secret": "string",
"previous_secret": "string",
"previous_secret_valid_until": "string",
"refresh_seconds": 1
}Issues a new secret, keeping the old one valid for a grace period.
POST/api/event/external_display/{identifier}/rotate_secret
Two secrets have to work at once: a rotation that does not reach the device would otherwise leave a dead sign on a customer wall, and nobody notices until someone walks past it.
Path parameters
identifierrequiredstring |
Responses
default
curl --request POST \
--url https://your-instance.iw-erp.de/api/event/external_display/42/rotate_secret \
--header 'x-iw-jwt-token: <TOKEN>'const options = {method: 'POST', headers: {'x-iw-jwt-token': '<TOKEN>'}};
fetch('https://your-instance.iw-erp.de/api/event/external_display/42/rotate_secret', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));import requests
url = "https://your-instance.iw-erp.de/api/event/external_display/42/rotate_secret"
headers = {"x-iw-jwt-token": "<TOKEN>"}
response = requests.post(url, headers=headers)
print(response.text)<?php
require_once('vendor/autoload.php');
$client = new \GuzzleHttp\Client();
$response = $client->request('POST', 'https://your-instance.iw-erp.de/api/event/external_display/42/rotate_secret', [
'headers' => [
'x-iw-jwt-token' => '<TOKEN>',
],
]);
echo $response->getBody();using System.Net.Http.Headers;
var client = new HttpClient();
var request = new HttpRequestMessage
{
Method = HttpMethod.Post,
RequestUri = new Uri("https://your-instance.iw-erp.de/api/event/external_display/42/rotate_secret"),
Headers =
{
{ "x-iw-jwt-token", "<TOKEN>" },
},
};
using (var response = await client.SendAsync(request))
{
response.EnsureSuccessStatusCode();
var body = await response.Content.ReadAsStringAsync();
Console.WriteLine(body);
}OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder()
.url("https://your-instance.iw-erp.de/api/event/external_display/42/rotate_secret")
.post(null)
.addHeader("x-iw-jwt-token", "<TOKEN>")
.build();
Response response = client.newCall(request).execute();package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://your-instance.iw-erp.de/api/event/external_display/42/rotate_secret"
req, _ := http.NewRequest("POST", url, nil)
req.Header.Add("x-iw-jwt-token", "<TOKEN>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}Dart with the iw_erp_api package
import 'package:iw_erp_api/clients/external_display_controller.dart';
import 'package:iw_erp_api/logic/iw_api_state.dart';
IwApiState().host = 'your-instance.iw-erp.de';
IwApiState().currentJwtApiToken = '<TOKEN>';
final result = await ExternalDisplayController.rotateSecret('42');
if (result.success) {
print(result.data);
}Renders the current frame as a PNG for the management UI.
GET/api/event/external_display/{identifier}/preview.png
The same pixels the device receives, before packing, so what an admin sees on screen is what is hanging on the wall.
Path parameters
identifierrequiredstring |
Query parameters
nowstring | Render a different time of the same day (HH:MM) |
Responses
200Current frame
curl --request GET \
--url https://your-instance.iw-erp.de/api/event/external_display/42/preview.png \
--header 'x-iw-jwt-token: <TOKEN>'const options = {method: 'GET', headers: {'x-iw-jwt-token': '<TOKEN>'}};
fetch('https://your-instance.iw-erp.de/api/event/external_display/42/preview.png', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));import requests
url = "https://your-instance.iw-erp.de/api/event/external_display/42/preview.png"
headers = {"x-iw-jwt-token": "<TOKEN>"}
response = requests.get(url, headers=headers)
print(response.text)<?php
require_once('vendor/autoload.php');
$client = new \GuzzleHttp\Client();
$response = $client->request('GET', 'https://your-instance.iw-erp.de/api/event/external_display/42/preview.png', [
'headers' => [
'x-iw-jwt-token' => '<TOKEN>',
],
]);
echo $response->getBody();using System.Net.Http.Headers;
var client = new HttpClient();
var request = new HttpRequestMessage
{
Method = HttpMethod.Get,
RequestUri = new Uri("https://your-instance.iw-erp.de/api/event/external_display/42/preview.png"),
Headers =
{
{ "x-iw-jwt-token", "<TOKEN>" },
},
};
using (var response = await client.SendAsync(request))
{
response.EnsureSuccessStatusCode();
var body = await response.Content.ReadAsStringAsync();
Console.WriteLine(body);
}OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder()
.url("https://your-instance.iw-erp.de/api/event/external_display/42/preview.png")
.get()
.addHeader("x-iw-jwt-token", "<TOKEN>")
.build();
Response response = client.newCall(request).execute();package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://your-instance.iw-erp.de/api/event/external_display/42/preview.png"
req, _ := http.NewRequest("GET", url, nil)
req.Header.Add("x-iw-jwt-token", "<TOKEN>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}Dart with the iw_erp_api package
import 'package:iw_erp_api/clients/external_display_controller.dart';
import 'package:iw_erp_api/logic/iw_api_state.dart';
IwApiState().host = 'your-instance.iw-erp.de';
IwApiState().currentJwtApiToken = '<TOKEN>';
final result = await ExternalDisplayController.preview('42');
print(result);