Messages
Messages bundle and group relevant information for write operations, acknowledgements, errors, etc. and provide further context, e.g., position within a flow.
All messages must be JSON-formatted [RFC4627] using UTF-8 encoding [RFC3629]. All datetime must be formatted according to [RFC3339]. Decimals are separated by points (not comma).
The protocol defines the following messages:
- NewSetpoint (
NEWSPT
): Message specifying a new setpoint write request. - AcknowledgeSetpoint (
ACKSPT
): Message for acknowledging success/failure of a setpoint from the receiver to the issuer. - NewSchedule (
NEWSCHD
): Message specifying the request for the creation of a new schedule - UpdateSchedule (
UPSCHD
): Message specifying the request to update certain parameters of an active schedule. - DeleteSchedule (
DELSCHD
): Message specifying the request to stop and delete an active schedule. - AcknowledgeSchedule (
ACKSCHD
): Message for acknowledging success/failure of a schedule from the receiver to the issuer. - UpsertControls (
UPSRTCTRL
): Message to update or insert a new controls app. - AcknowledgeUpsertControls (
ACKUPSRTCTRL
): Message for acknowledging success/failure of aUPSRTCTRL
message. - ResetControls (
RESETCTRL
): Message to write reset values of a controls app to the BAS. - AcknowledgeResetControls (
ACKRESETCTRL
): Message for acknowledging success/failure of aRESETCTRL
message. - DeleteControls (
DELCTRL
): Message to delete a controls app. - AcknowledgeDeleteControls (
ACKDELCTRL
): Message for acknowledging success/failure of aDELCTRL
message. - Alive (
ALIVE
): Message to periodically send heartbeats implying a service running a controls app is alive.
Setpoints 🎯¶
NewSetpoint 🆕¶
The NewSetpoint message NEWSPT
contains all information required to write a setpoint.
Fields¶
NEWSPT
allows the fields summarized in Table 1.
Field | Type | Required | Comment |
---|---|---|---|
type | string | yes | Type of this message, i.e., NEWSPT . |
swop_version | string | yes | Used SWOP protocol version. |
datapoint | string | yes | The identifier of the datapoint to write to. Must be unique on the Edge device. |
value | bool, int, float, string | yes | The value to write. The required type depends on the target datapoint. |
priority | int | no | The priority to write at, if supported by the automation protocol. |
acknowledge | bool | no | Whether this operation must be acknowledged by the receiver. Defaults to false . |
dry_run | bool | no | Whether to perform a dry run of the requested action or not. Defaults to false . |
reference | string | no | Reference for this operation on the API side. |
Explanation¶
- The field
type
identifies this object as a setpoint object. - The field
swop_version
specifies the used version of SWOP. This caters to later versions of the protocol that may not be backwards compatible. - The field
datapoint
references the datapoint on the building automation network to write to. - The field
value
contains the value that should be written to the given datapoint. The type of value must be consistent with the type of the target datapoint or allow a loss-free conversion. E.g., converting an integer 10 to a float 10.0 is loss-free, while rounding a floatvalue = 10.3
to an integervalue = 10
is not loss-free. If value cannot be converted without information loss to the type expected by the target datapoint, the write operation must be aborted and an appropriate error returned.- The issuer can specify the special string value
'clear'
or'null'
(deprecated) to instruct the receiver to clear out this setpoint such that default control can take over again, e.g., in BACnet this involves writing null to the datapoint's priority array at the position specified by priority.
- The issuer can specify the special string value
- The field
priority
contains the priority at which the value should be written. For automation protocols that support priorities, such as BACnet, this field is optional but highly recommended. - The field
acknowledge
specifies whether the issuer expects this write operation to be acknowledged by the receiver. The exact scope and extent of the acknowledgement is left to the implementation of the receiver and also depends on the capabilities of the underlying automation network and is further discussed in the section on theACKSPT
message. - Using the field
dry_run
, the issuer may specify that this setpoint write operation should only be tested but not actually written to the target datapoint. The exact scope and extent of the test is left to the implementation of the receiver and also depends on the capabilities of the underlying automation network. - The field
reference
can be used by the issuer to provide a (unique) reference for state of this operation kept on the API side. It must be provided ifacknowledge
is true. If this field is given any other message related to this operation must contain this reference.
Examples¶
{
"type": "NEWSPT",
"swop_version": 0.2,
"datapoint": "bacnet93-4120-External-Room-Set-Temperature-RTs",
"value": 20.3,
"priority": 13
}
NEWSPT
message without acknowledgments. {
"type": "NEWSPT",
"swop_version": 0.2,
"datapoint": "bacnet93-4120-External-Room-Set-Temperature-RTs",
"value": 22.3,
"priority": 9,
"acknowledge": true,
"dry_run": true,
"reference": "80b8127d-757c-417d-a8bf-fa9980dc20de"
}
NEWSPT
message requesting a dry run of a setpoint write operation with acknowledgements. AcknowledgeSetpoint ✅¶
The Acknowledge Setpoint message ACKSPT
conveys an acknowledgement of success or error from the receiver of a write operation to the issuer.
Fields¶
ACKSPT
allows the fields summarized in Table 2.
Field | Type | Required | Comment |
---|---|---|---|
type | string | yes | Type of this message, i.e., ACKSPT . |
swop_version | string | yes | Used SWOP protocol version. |
reference | string | yes | Reference for this write operation. |
status | string | yes | The status of the setpoint write operation. |
message | string | no | A human readable success or error message. |
detail | object | no | Additional custom information. |
ACKSPT
message. Explanation¶
- The field
type
identifies this object as a setpoint object. - The field
swop_version
specifies the used version of SWOP. This caters to later versions of the protocol that may not be backwards compatible. - The field
reference
must repeat the reference provided by the issuer of this operation in the initialNEWSPT
message. - The field
status
indicates whether the setpoint has been written or failed. - The field
message
may be used to reply with a human readable message that can, e.g., be appended to the operation's log. - The field
detail
is an arbitrary JSON object with additional details about the success or failure of the referenced setpoint write operation. It may, e.g., be used to convey the state of the datapoint before this setpoint was written.
Examples¶
{
"type": "ACKSPT",
"swop_version": 0.2,
"reference": "f2d70718-fe44-46bd-a3e0-8c4008749851",
"status": "failed",
"message": "Setpoint could not be written.",
"detail": {
"status": "failed",
"value": "15,3",
"error": "ValueError: Could not cast to float."
}
}
ACKSPT
message reporting a conversion error. {
"type": "ACKSPT",
"swop_version": 0.2,
"reference": "f2d70718-fe44-46bd-a3e0-8c4008749851",
"status": "written",
"message": "Setpoint successfully written.",
"detail": {
"state_before": {
"priority_array": [
16, "null", "null", "null", "null", "null",
"null", "null", "null", "null", "null",
"null", "null", 16.4, "null", "null", "null"]
}
}
}
ACKSPT
message reporting a successful setpoint write operation. Schedules 🗓¶
NewSchedule 🆕¶
The NewSchedule message NEWSCHD
contains all information required to create a schedule. The receiver must acknowledge success or error of the creation of the requested schedule in an ACKSCHD
message (c.f. create schedule flow).
Repeat feature
The repeat feature of schedules, especially the syntax and semantics for specifying repeat intervals in the repeat
field, is still work in progress. The definition, explanation and examples of that feature given below are preliminary.
Fields¶
NEWSCHD
messages allow the following fields.
Field | Type | Required | Comment |
---|---|---|---|
type | string | yes | Type of this message, i.e., NEWSCHD . |
swop_version | string | yes | Used SWOP protocol version. |
reference | string | yes | Unique reference for this operation. |
name | string | yes | A human readable name for this schedule. |
description | string | no | A human readable description of this schedule. |
datapoint | string | yes | The identifier of the datapoint to write to. Must be unique on the Edge device. |
priority | int | no | The priority to write at, if supported by the automation protocol. |
setpoints | list of object | yes | A list of setpoints. Each setpoint is defined by a unique id , a start time, and a value . |
heartbeat | int | no | Duration in seconds after which the schedule deletes itself if no heartbeat is received. |
reset_value | bool, int, float, string | no | The value to write when the schedule finishes or fails. |
repeat | string | no | Repeat interval of this schedule. |
NEWSCHD
message. Explanation¶
- The field
type
identifies this message as a request for the creation of a new schedule. - The field
protocol_version
specifies the used version of SWOP. - The field
reference
contains a unique reference for this operation assigned by the issuer. It must be provided on all return messages to the issuer. - The field
name
allows the user/issuer to assign a short human-readable name to this schedule, e.g., Weekend Control. - The field
description
allows the user/issuer to put a human-readable description, e.g., explaining what kind of control this schedule realizes. - The field
datapoint
references the datapoint on the building automation network to write to. This must uniquely identify the target datapoint on the receiver side. The schedule write operation must be aborted and an appropriate error returned if the reference is ambiguous. - The field
priority
contains the priority at which the scheduled setpoints should be written. For automation protocols that support priorities, such as BACnet, this field is optional but highly recommended. - The field
setpoints
must contain a list of setpoints that are executed by this schedule. Each individual setpoint in this list is a dict containing fieldsid
- a unique id to identify this setpoint within the list of setpointsstart
- the datetime when this setpoint is executedvalue
- the value that is written with this setpoint. Valid values depend on the type of the datapoint and are generally booleans, integer and floats, and strings.- The special strings 'clear' / 'null' can be used.
- An additional special string value 'reset' indicates that the (possibly automatically determined) reset_value should be used for this setpoint.
- The field
heartbeat
specifies a duration in seconds instructing the receiver to cancel (stop and delete) this schedule if no update from the issuer is received for this many seconds. - The field
reset_value
specifies which value is written to datapoint after the schedule finishes, when it fails or when it is canceled. The type should match the type of the datapoint that is written to, e.g., bool for binary, int/float for analog, and int/string for multistate datapoints. Ifreset_value
is missing (null not string 'null'), the receiver must determine the value of datapoint before starting the schedule and use that value asreset_value
and should report it in anACKSCHD
message underdetail
to the issuer. As for setpoints, strings 'clear' and 'null' (deprecated) are valid values to instruct the receiver to clear out the setpoint when the schedule stops, fails or is deleted. - The
repeat
field allows to specify a repeat pattern for this schedule, e.g., repeat every week, repeat every 6 hours.
Examples¶
{
"type": "NEWSCHD",
"swop_version": 0.2,
"reference": "e6ff6518-7f9d-4e3e-8f16-3ed7fda5b793",
"name": "AVU weekend override",
"description": "A schedule to switch of the air ventilation unit in the metting room 00.23 on weekends.",
"datapoint": "bacnet512-4120L022VEGSHSB_Anlage-L22",
"priority": 13,
"setpoints": [
{"id": 0, "start": "2020-02-14 18:00:00+01:00", "value": "off"},
{"id": 1, "start": "2020-02-17 07:00:00+01:00", "value": "auto"}
],
"heartbeat": 3600,
"reset_value": "null",
"repeat": "weekly"
}
NEWSCHD
message describing a fictional schedule for a weekend override of an air ventilation unit. AcknowledgeSchedule ✅¶
The Acknowledge Schedule message ACKSCHD
conveys an acknowledgement of success or error about any event during a schedule operation from the receiver to the issuer. This includes among others the acknowledgement about the (non-)acceptance of a new schedule, updates about the execution state of the schedule such as when a setpoint from the schedule was written successfully, and notice of termination and/or failure of a schedule on error.
Fields¶
ACKSCHD
allows the fields summarized in Table 4.
Field | Type | Required | Comment |
---|---|---|---|
type | string | yes | Type of this message, i.e., ACKSCHD . |
swop_version | string | yes | Used SWOP protocol version. |
reference | string | yes | Unique reference of the schedule to acknowledge. |
status | string | yes | The current, possibly changed status of the schedule. |
time | string | yes | The time of the acknowledged event that occurred during execution of the schedule on the issuer side. |
message | string | no | A human readable success or error message. |
detail | object | no | Additional custom information. |
ACKSCHD
message. Explanation¶
- The field
type
identifies this object as an acknowledge schedule object. - The field
swop_version
specifies the used version of SWOP. This caters to later versions of the protocol that may not be backwards compatible. - The field
reference
must repeat the reference provided by the issuer of this operation in the initialNEWSCHD
message. - The field
status
indicates whether the schedule has been activated, terminated or failed. - The field
message
may be used to reply with a human readable message that can, e.g., be appended to the operation's log. - The field
detail
is an arbitrary JSON object with additional details about the success or failure of the referenced schedule operation. It may, e.g., be used to convey the state of the datapoint before this schedule was requested.
Examples¶
Example 6 shows the ACKSCHD
message that is sent to acknowledge creation of the schedule requested in Example 5.
{
"type": "ACKSCHD",
"swop_version": 0.2,
"reference": "e6ff6518-7f9d-4e3e-8f16-3ed7fda5b793",
"status": "active",
"time": "2020-02-13 18:00:00+01:00",
"message": "Schedule has been successfully activated."
}
ACKSCHD
message on creation of a new schedule. UpdateSchedule ✏️¶
The UpdateSchedule message UPSCHD
is used bidirectionally between issuer and receiver to exchange updates to an active schedule. Besides the actual updates contained, each UPSCHD
message is interpreted as a heartbeat from the issuer to the receiver. The receiver must acknowledge success or error of all updates (except empty UPSCHD
that just serve as heartbeats) in an ACKSCHD
message (c.f. update schedule flow).
Fields¶
UPSCHD
allows the fields summarized in Table 5.
Field | Type | Required | Comment |
---|---|---|---|
type | string | yes | Type of this message, i.e., UPSCHD . |
swop_version | string | yes | Used SWOP protocol version. |
reference | string | yes | Unique reference of the schedule to update. |
name | string | no | Updated name for the referenced schedule. |
description | string | no | Updated description for the referenced schedule. |
add_setpoints | list of object | no | A list of new setpoints to add to the referenced schedule. |
up_setpoints | list of object | no | A list of existing setpoints in the reference schedule to update. |
del_setpoints | list of object | no | A list of existing setpoints to delete from the referenced schedule. |
heartbeat | int | no | Updated heartbeat for the referenced schedule. |
reset_value | bool, int, float, string | no | The value to write when the schedule finishes or fails. |
repeat | string | no | Updated repeat interval for the referenced schedule. |
UPSCHD
message. Explanation¶
- The field
type
identifies this message as a request for the update of an existing schedule. - The field
protocol_version
specifies the used version of SWOP. - The field
reference
contains the unique reference of the schedule to update. - The field
name
anddescription
can be set to update the name and description of the schedule, respectively. - The field
add_setpoints
can hold a list of new setpoints to add to the schedule. Each setpoint in this list must containid
,value
andstart
and the assignedid
must be unique among the existing and new setpoints of this schedule. - The field
up_setpoints
can hold a list of setpoints to update. Each setpoint in this list must provide theid
field by which the existing setpoint to update is identified.
The existing setpoint'svalue
and/orstart
are then updated depending on which field is given. Theid
of an existing setpoint cannot be updated. - The field
del_setpoints
can hold a list of setpoints to delete. Each setpoint in this list must provide theid
field by which an existing setpoint to delete is identified. Other fields, i.e.,value
andstart
, are ignored. - The fields
heartbeat
,reset_value
, andrepeat
allow modifying the respective properties of the schedule.
Immutable schedule properties
The properties datapoint
and priority
of a schedule cannot be changed. Stop the schedule and create a new one if you need to change these.
Examples¶
We update the name and description of the schedule created in Example 5 and acknowledged in Example 6. We additionally change the start and end of the weekend override, add one hour of full ventilation to start and increase the heartbeat to two hours.
{
"type": "UPSCHD",
"swop_version": 0.2,
"reference": "e6ff6518-7f9d-4e3e-8f16-3ed7fda5b793",
"name": "Improved AVU weekend override",
"description": "A schedule to switch of the air ventilation unit in the meeting room 00.23 on weekends. Runs the ventilation on monday mornings for a full hour before switching to automatic mode of operation.",
"add_setpoints": [
{"id": 2, "start": "2020-02-17 07:00:00+01:00", "value": "on"}
],
"mod_setpoints": [
{"id": 0, "start": "2020-02-14 17:00:00+01:00"},
{"id": 1, "start": "2020-02-17 08:00:00+01:00"}
],
"heartbeat": 7200
}
UPSCHD
message describing a fictional update to the schedule from Example 5. DeleteSchedule ❌¶
The DeleteSchedule message DELSCHD
is used to stop an active schedule. The receiver must acknowledge success or error of this operation in an ACKSCHD
message (c.f. delete schedule flow).
Fields¶
DELSCHD
allows only the following three mandatory fields.
Field | Type | Required | Comment |
---|---|---|---|
type | string | yes | Type of this message, i.e., DELSCHD . |
swop_version | string | yes | Used SWOP protocol version. |
reference | string | yes | Unique reference of the schedule to delete. |
DELSCHD
message. Explanation¶
- The field
type
identifies this message as a request for the deletion of an existing schedule. - The field
swop_version
specifies the used version of SWOP. - The field
reference
contains the unique reference of the schedule to update.
Examples¶
We stop and delete the schedule that we created in Example 5, acknowledge in Example 6, and modified in Example 7.
{
"type": "DELSCHD",
"swop_version": 0.2,
"reference": "e6ff6518-7f9d-4e3e-8f16-3ed7fda5b793"
}
DELSCHD
message. Controls Apps¶
UpsertControls ⚙️¶
The UpsertControls message UPSRTCTRL
contains all information required to issue the creation of a controls app.
Fields¶
Field | Type | Required | Comment |
---|---|---|---|
type | string | yes | Type of this message, i.e., UPSRTCTRL . |
swop_version | string | yes | Used SWOP protocol version. |
reference | string | yes | Unique reference of the message to ensure integrity. |
controls_app_id | string | yes | Identifier of a controls app. |
service_id | string | yes | Identifier of the service running the controls app. |
reset_values | list of object | yes | List of reset values for a controls app. |
alive_timeout | integer | no | Timeout in seconds after which a controls app is reset, if no ALIVE message has been received by then. Defaults to 300s. |
max_alive_timeouts | integer | no | Amount of accepted timeouts before a controls app will actually be reset. Defaults to 1. |
UPSRTCTRL
message. Examples¶
{
"type": "UPSRTCTRL",
"swop_version": "0.2",
"reference": "2e770718-ccef-4539-ae1a-975a47cfd0a7",
"controls_app_id": "cef8160a-0023-4c8a-b839-a1ec8e7ac0b0",
"service_id": "controls_service_123",
"reset_values": [{"fqdn": "last-test", "value": 10.0, "priority": 13}],
"alive_timeout": 5,
"max_alive_timeouts": 1
}
AcknowledgeUpsertControls ✅¶
The AcknowledgeUpsertControls message ACKUPSRTCTRL
conveys an acknowledgement of success or error about any event during the controls app creation from the receiver to the issuer.
Fields¶
Field | Type | Required | Comment |
---|---|---|---|
type | string | yes | Type of this message, i.e., ACKUPSRTCTRL . |
swop_version | string | yes | Used SWOP protocol version. |
reference | string | yes | Unique reference of the message to ensure integrity. |
controls_app_id | string | yes | Identifier of a controls app. |
service_id | string | yes | Identifier of the service running the controls app. |
status | string | yes | The status of the UPSRTCTRL operation. Options: "added", "updated", "failed" |
time | string | yes | The time of the acknowledged event that occurred during execution of an UPSRTCTRL operation on the issuer side. |
message | string | no | A human readable success or error message. |
detail | object | no | Additional custom information. |
ACKUPSRTCTRL
message. Examples¶
{
"type": "ACKUPSRTCTRL",
"swop_version": "0.2",
"controls_app_id": "cef8160a-0023-4c8a-b839-a1ec8e7ac0b0",
"service_id": "edge_device_123",
"status": "updated",
"time": "2022-07-22T07:15:45.121503+00:00",
"message": "Successfully updated controls app cef8160a-0023-4c8a-b839-a1ec8e7ac0b0.",
"detail": null,
"reference": "2e770718-ccef-4539-ae1a-975a47cfd0a7"
}
ResetControls ⏮¶
The ResetControls message RESETCTRL
contains all information required to write reset values of a controls app to the BAS.
Fields¶
Field | Type | Required | Comment |
---|---|---|---|
type | string | yes | Type of this message, i.e., RESETCTRL . |
swop_version | string | yes | Used SWOP protocol version. |
reference | string | yes | Unique reference of the message to ensure integrity. |
controls_app_id | string | yes | Identifier of a controls app. |
RESETCTRL
message. Examples¶
{
"type": "RESETCTRL",
"swop_version": "0.2",
"reference": "1645775b-00ad-4dbd-ba5d-145fb8f60f15",
"controls_app_id": "cef8160a-0023-4c8a-b839-a1ec8e7ac0b0"
}
AcknowledgeResetControls ✅¶
The AcknowledgeResetControls message ACKRESETCTRL
conveys an acknowledgement of success or error from the receiver of a reset operation to the issuer.
Fields¶
Field | Type | Required | Comment |
---|---|---|---|
type | string | yes | Type of this message, i.e., ACKRESETCTRL . |
swop_version | string | yes | Used SWOP protocol version. |
reference | string | yes | Unique reference of the message to ensure integrity. |
controls_app_id | string | yes | Identifier of a controls app. |
service_id | string | yes | Identifier of the service running the controls app. |
status | string | yes | The status of the RESETCTRL operation. Options: "reset", "failed" |
time | string | yes | The time of the acknowledged event that occurred during execution of an RESETCTRL operation on the issuer side. |
message | string | no | A human readable success or error message. |
detail | object | no | Additional custom information. |
ACKRESETCTRL
message. Examples¶
{
"type": "ACKRESETCTRL",
"swop_version": "0.2",
"reference": "c512b163-6873-46a9-9562-13d343e13ffb",
"controls_app_id": "cef8160a-0023-4c8a-b839-a1ec8e7ac0b0",
"service_id": "edge_device_123",
"status": "reset",
"time": "2022-07-22T07:24:29.692596+00:00",
"message": "Successfully wrote reset values of controls app cef8160a-0023-4c8a-b839-a1ec8e7ac0b0 to the BAS.",
"detail": null
}
DeleteControls ❌¶
The DeleteControls message DELCTRL
is used to delete a controls app.
Fields¶
Field | Type | Required | Comment |
---|---|---|---|
type | string | yes | Type of this message, i.e., DELCTRL . |
swop_version | string | yes | Used SWOP protocol version. |
reference | string | yes | Unique reference of the schedule to delete. |
controls_app_id | string | yes | Identifier of a controls app. |
DELCTRL
message. Examples¶
{
"type": "DELCTRL",
"swop_version": "0.2",
"reference": "1645775b-00ad-4dbd-ba5d-145fb8f60f15",
"controls_app_id": "cef8160a-0023-4c8a-b839-a1ec8e7ac0b0"
}
AcknowledgeDeleteControls ✅¶
The AcknowledgeDeleteControls message ACKDELCTRL
conveys an acknowledgement of success or error from the receiver of a delete operation to the issuer.
Fields¶
Field | Type | Required | Comment |
---|---|---|---|
type | string | yes | Type of this message, i.e., ACKDELCTRL . |
swop_version | string | yes | Used SWOP protocol version. |
reference | string | yes | Unique reference of the schedule to delete. |
controls_app_id | string | yes | Identifier of a controls app. |
service_id | string | yes | Identifier of the service running the controls app. |
status | string | yes | The status of the DELCTRL operation. Options: "deleted", "failed" |
time | string | yes | The time of the acknowledged event that occurred during execution of an DELCTRL operation on the issuer side. |
message | string | no | A human readable success or error message. |
detail | object | no | Additional custom information. |
ACKDELCTRL
message. Examples¶
{
"type": "ACKDELCTRL",
"swop_version": "0.2",
"reference": "c512b163-6873-46a9-9562-13d343e13ffb",
"controls_app_id": "cef8160a-0023-4c8a-b839-a1ec8e7ac0b0",
"service_id": "edge_device_123",
"status": "reset",
"time": "2022-07-22T07:24:29.692596+00:00",
"message": "Successfully deleted controls app cef8160a-0023-4c8a-b839-a1ec8e7ac0b0.",
"detail": null
}
Alive 💗¶
The Alive message ALIVE
is used to periodically send a "heartbeat" to the receiver and back to the issuer to observe the connectivity of services.
Fields¶
Field | Type | Required | Comment |
---|---|---|---|
type | string | yes | Type of this message, i.e., ALIVE . |
swop_version | string | yes | Used SWOP protocol version. |
service_id | string | yes | The identifier of the sender of this message. |
timestamp | string | yes | The timestamp when this message was send in nanoseconds. |
ALIVE
message. Examples¶
{
"type": "ALIVE",
"swop_version": "0.2",
"sender_id": "controls_service_123",
"timestamp": 1658474210133333828
}
Extending messages ➕¶
Implementations may choose to add custom messages, objects, fields, and attributes aka vendor extensions. Following established conventions on the web, their identifiers should be prefixed with the string x-
for message fields or X-
for message types.