# Message Metadata

MQTT messages will include some system and user properties to define metadata values that will help with flow control.

## Telemetry Metadata

### Telemetry Message

|Property|Required|Type|Key|Description|
|--------|--------|----|---|-----------|
|`ContentType`|no|system||String value to specify the binary format used in the payload, e.g., `application/json` or `application/protobuf`. When deserializing the message it must match the configured serializer.|
|`FormatIndicator`|yes|system|| 1 for character data (as JSON), 0 for unspecified.|
|`MessageExpiry`|no|system||The publish message can include an expiry time.|
|`CorrelationData`|no|system||A unique identifier for the message, must be GUID represented as a `byte[16]`|
|`SourceId`|no|user|`__srcId`|String representing an identifier of the telemetry sender.|
|`ProtocolVersion`|no|user|`__protVer`| The protocol version of the message. If not provided, a protocol version of 0.1 is assumed by the telemetry receiver. |

## Command Metadata

### Request Message

|Property|Required|Type|Key|Description|
|--------|--------|----|---|-----------|
|`ContentType`|no|system||String value to specify the binary format used in the payload, e.g., `application/json`, `application/protobuf`, or `application/avro`. When deserializing the message it must match the configured serializer.|
|`FormatIndicator`|yes|system|| 1 for character data (as JSON), 0 for unespecified.|
|`CorrelationData`|yes|system||A unique identifier for the request, must be GUID represented as a `byte[16]`. Correlation data is generated by the invoker and used to correlate responses.|
|`ResponseTopic`|yes|system||String with the topic used to receive the response.|
|`MessageExpiry`|yes|system||The publish message must include an expiry time for deduplication purposes.|
|`Timestamp`|no|user|`__ts`|A hybrid clock (HLC) value that can be used to identify the time when the message was produced.|
|`SourceId`|no|user|`__srcId`|String representing an identifier of the command invoker.|
|`ProtocolVersion`|no|user|`__protVer`| The protocol version of the request. If not provided, a protocol version of 0.1 is assumed by the receiving executor. | 

### Response Message

|Property|Required|Type|Key|Description|
|--------|--------|----|---|-----------|
|`ContentType`|no|system||String value to specify the binary format used in the payload, e.g., `application/json`, `application/protobuf`, or `application/avro`. When deserializing the message it must match the configured serializer.|
|`FormatIndicator`|yes|system|| 1 for character data (as JSON), 0 for unespecified.|
|`CorrelationData`|yes|system||As byteArray. The server will apply the value from the request message|
|`MessageExpiry`|no|system||The publish message can include an expiry time.|
|`Timestamp`|no|user|`__ts`|A hybrid clock (HLC) value that can be used to identify the time when the message was produced.|
|`SourceId`|no|user|`__srcId`|String representing an identifier of the command executor.|
|`Status`|yes|user|`__stat`|String with an HTTP status code, `200` means success, higher values are used for errors.|
|`StatusMessage`|no|user|`__stMsg`|String with the error message.|
|`IsApplicationError`|no|user|`__apErr`|String with value `true` if an error is at the application level.|
|`InvalidPropertyName`|no|user|`__propName`|String identifying the name of a property that is missing or has an invalid value.|
|`InvalidPropertyValue`|no|user|`__propVal`|String indicating the value of a property that is invalid.|
|`ProtocolVersion`|no|user|`__protVer`| The protocol version of the response. If not provided, a protocol version of 0.1 is assumed by the receiving invoker. |
|`SupportedProtocolMajorVersion`|no|user|`__supProtMajVer`| A space separated list of protocol major versions that the executor supports. Only provided if the request provided an unsupported protocol version. |
|`RequestProtocolVersion`|no|user|`__requestProtVer`| The full protocol version of the request that was rejected because it was unsupported by the executor. Only provided if the request provided an unsupported protocol version. |

### CloudEvents Header

Telemetry and RPC messages can include  [CloudEvents](https://github.com/cloudevents/spec/blob/main/cloudevents/spec.md) as defined by the [CloudEvents MQTT bindings](https://github.com/cloudevents/spec/blob/main/cloudevents/bindings/mqtt-protocol-binding.md), as we are only targeting MQTT5 we will use the [Binary Content Mode](https://github.com/cloudevents/spec/blob/main/cloudevents/bindings/mqtt-protocol-binding.md#31-binary-content-mode).

#### CloudEvents Properties

We will use the next properties

|Name|Required|Sample Value|Notes|
|---|--|--|--|
|`specversion`|yes|1.0| fixed |
|`type`|yes|ms.aio.telemetry| Defaults to ms.aio.telemetry (when sent by telemetry sender) or ms.aio.rpc.request (when sent by command invoker) or ms.aio.rpc.response (when sent by command executor), overridable by the user |
|`source`|yes|aio://mycluster/myoven| The origin of the event|
|`id`|yes|A234-1234-1234| Unique identifier of the message, produced by the TelemetrySender/CommandInvoker/CommandExecutor as a Guid|
|`subject`|no|aio/myoven/telemetry/temperature| The MQTT topic where the message was sent. Provided by the TelemetrySender/CommandInvoker/CommandExecutor.|
|`time`|no|2018-04-05T17:31:00Z| Time when the message was produced, UTC. Provided by the TelemetrySender/CommandInvoker/CommandExecutor.|
|`datacontenttype`|no|application/json| The content type of the message, obtained from the serializer|
|`dataschema`|no|sr://fabrikam-schemas/123123123234234234234234#1.0.0| Uri to resolve the schema|