Copyright © 2026 COVESA®.
The Vehicle Information Service Specification (VISS) is a service for accessing vehicle information, including signals from sensors on control units within a vehicle's network. This information is exposed through a hierarchical, tree-like taxonomy as defined in the COVESA Hierarchical Information Model (HIM), and is provided in JSON format. The VISS service may be hosted within the vehicle or on external servers, using data that has already been off-boarded.
VISS enables a broad range of use cases, including predictive maintenance, usage-based insurance, fleet management, and real-time driver assistance services. In the context of artificial intelligence, VISS serves as a critical data access layer, providing high-quality, real-time vehicle data that can be utilized by AI algorithms for tasks such as anomaly detection, driver behavior analysis, energy optimization, and contextual decision-making.
The first version of VISS, which has been implemented and deployed in
production vehicles, supported only WebSocket as a transport
protocol.
The
second version
is generalized to work across also the HTTP and MQTT transport
protocols to improve the support for different use cases. It also
contains improved subscription capabilities and added an access control
mechanism.
The
third version
included the gRPC transport protocol but also simplified addition of
other transport protocols by placing the normative requirement on the
message payload only, and not also on what transport protocol to use.
Several new features were added such as file transfer, payload
encoding, and improved server capabilities representation.
This specification, the version 3.1, is a backwards compatible
extension of the third version of VISS. Instead of referencing to the
VSS rule set for how to define the content of a tree it refers to the
rule sets of the HIM vehicle data profile.This enables also other trees than the VSS
tree to be used, a server may manage a set of trees, a forest, that a
client can access. Other changes are support for the Unix domain socket protocol,
and minor adaptations to support the concept of having a forest of trees,
such as adding support for a client to do a forest inquiry.
There are three parts to this specification, CORE, [[TRANSPORT]], and
[[PAYLOAD ENCODING]]. This document, the VISS version 3.1 CORE
specification, describes the VISSv3.1 messaging layer.
The VISSv3.1 transport protocol specification describes the deviations
from the CORE definitions that are used in some transport protocols. It
also examplifies the JSON primary payload format using the Websocket
payloads. The VISSv3.1 payload encoding specification describes payload
encoding designs that may be applied e. g. for payloads in transit.
The specification is supplemented by the [[IMPLEMENTATION_GUIDELINES]]
document which provides recommendations on how to implement certain
features to ensure client interoperability on different implementations.
This specification describes the messaging API for the VISS protocol.
This includes the messaging layer and set of rules for structuring
data.
The specification is agnostic to which transport protocol is used
as long as it conforms to this messaging API and data rule set.
Transport protocols that cannot conform to the entire CORE
specification can still be conformant by describing their deviations in
the [[TRANSPORT]] specification.
The primary payload data format is JSON. The JSON schema () defines all of the payloads. If a transport protocol uses a
different payload encoding, such as gRPC, or a more bandwidth efficient
data representation is desired, then this encoding may be defined in
the [[PAYLOAD ENCODING]] specification. This encoding must contain a
solution for both encoding of the JSON payloads and decoding back to
the JSON format. A client MUST be able to access the message payload in
the JSON format.
The messages are exchanged between a server implementation holding the representation of data and a client using the data as shown in the figure below, where the payload also is encoded when in transit over the transport protocol.
The VISSv3.1 messaging layer builds on RESTful principles for the method exchange via the interface (refer to the section 5. Interface).
The VISSv3.1 data structuring rules (HIM vehicle data profile rule set) are the same through all transport protocols. The basis for structuring data held by a server is a tree structure.
The acronym 'VISSv3.1' is used to refer to this document, the VISS version 3.1 specification. The acronym 'HIM' is used to refer to the 'Hierarchical Information Model version 1.0 Vehicle Data profile' which is hosted by COVESA. The acronym 'VSS' is used to refer to the 'Vehicle Signal Specification' which is hosted by COVESA. The term 'WebSocket' when used in this specification, is as defined in the W3C WebSocket API and [[RFC6455]], the WebSocket Protocol.
scheme://authority/path?queryThe scheme describes the protocol to use to reach the addressed resource. For supported protocols, refer to the section 5. Transport Protocols in [[TRANSPORT]] specification.
The path URI component definition differs between the three
resources.
For the VISSv3 server the definition is as follows.
The path consists of a sequence of tree node names separated by a
delimiter. HIM specifies the dot (.) as delimiter, which
therefore is the recommended choice also in this specification.
However, in HTTP URLs the conventional delimiter is slash (/),
therefore also this delimiter is supported. To exemplify, the
path expression from traversing the nodes Vehicle, Car, Engine,
RPM can be "Vehicle.Car.Engine.RPM", or "Vehicle/Car/Engine/RPM".
Mixing delimiters in the same path expression SHOULD be
avoided.
The path MUST not contain any wildcard characters ("*"), for such
needs see .
For the Access Grant Token Server the path is "agts".
For the Access Token Server the path is "ats".
struct {
field1 datatype
field2 datatype
}
is represented by the following JSON object
{"field1":"X", "field2":"Y"}
where X and Y are the actual values of respective datatype. The
datatype of a field of the struct may be any datatype supported by HIM,
including a struct.This section describes the different methods and their arguments that govern the communication between a client and the server.
Transport protocols used to implement these methods MUST support the Read and Update methods, and MAY support the Subscribe, Unsubscribe, and Subscription methods.
Purpose: Get one or more values addressed by the given path.
The client MAY have to obtain an authorization token before accessing the requested values. If the server successfully processes the request, it MUST return a success response. If the server fails to fulfill the request, then the server MUST return an error message.
Arguments, of which path is mandatory:Purpose: Provide an altered value to the vehicle signal addressed by the path.
The client MAY have to obtain an authorization token before
updating a vehicle signal. If the server successfully processes
the request, it MUST return a success response. If it
cannot, it MUST return an error message. Only actuator
type signals can be updated. Please note that a success response
does not guarantee that the actuation attempt to change to the
updated target value has, or will, succeed. A client may monitor
the actuation progress through subsequent reads of the actuator
value.
The server MAY use the timestamp from the request to discard requests
that are older than the latest previously received request,
followed by an error response. For more information, refer to the .
Purpose: Get asynchronous messages containing the value(s) addressed by the path. The triggering conditions for these events are determined by the filter rules.
The client MAY have to obtain an authorization token before subscribing to vehicle signal(s). The server MUST issue an event message if a trigger rule is met. If the server successfully processes the request, it MUST return a success response. If the server fails to fulfill the request, then the server MUST return an error message. If an error occurs during the subscription period, the server SHOULD return an error message.
Arguments, of which path and filter are mandatory:Purpose: Terminates a subscription that was previously established through a subscribe request.
If the server successfully processes the request, it MUST return a success response, and it MUST stop issuing event messages associated to the subscription handle. If the server fails to fulfill the request, then the server MUST return an error message.
Arguments, of which subscriptionId is mandatory:Purpose: Sends asynchronous event messages to the client when a subscribe request trigger rule is met.
The server MUST issue an event message when a triggering rule associated with the subscription is met. If the server cannot fulfill the triggering rules it MUST issue an error message and terminate the subscription.
Arguments, of which all are mandatory:The server MUST notify the client of any errors that occur during their interaction, whether as a synchronous error response or an asynchronous error event resulting from a previous subscription request. The error message has three arguments, of which subscriptionId is mandatory only for error events. In the case of an error event being issued by the server, the associated subscription session SHALL thereafter be terminated by the server.
Arguments:
Timestamps in transport payloads MUST conform to the [[ISO8601]]
standard, using the UTC format with a trailing Z. Time resolution
SHALL at least be seconds, with subsecond resolution as an optional
degree of precision when desired. The time and date format shall be
as shown below, where the sub-second data and delimiter is
optional.
YYYY-MM-DDTHH:MM:SS.ssssssZ
The exceptions to this are timestamps within tokens which MUST
conform to Unix time, or if timestamp data compression is applied.
Transport protocols supported by this specification MUST make use of TLS v1.2 as defined in [[RFC5246]].
The enables the enforcement of data access restrictions for clients that have been granted access at the transport protocol level.
In addition to some privacy provisions within the specification itself, COVESA and W3C have activities seeking to establish systems and guidelines to provide further considerations for handling of sensitive information.
For certain use cases, such as when data is referenced only within the vehicle, is not transmitted externally, and does not persist across restarts, privacy concerns should be minimal or nonexistent.
This specification has granular access control capabilities, allowing restrictions on the information an application may access. Additionally, all data transmitted from a VISS service to a client application MUST be transported over an encrypted protocol to ensure privacy protection.
A client accessing vehicle data may require consent from an authorized entity, which varies based on jurisdiction and ownership. This specification supports integration with an External Consent Framework (ECF) to enable consent management within a VISS server, see . Consent SHOULD be revocable; however, the process for revocation is out of scope for this specification. It is expected to be handled out of band and may be governed by regulations or contractual agreements.
The paths filter operation allows a single request to retrieve
signal data from multiple data points in the tree. The himpath SHALL
point to the last node in the tree that is common for the relative
paths in the filter parameter object, that start off from this node.
If a path endpoint in the filter value is a branch, all leaf nodes
in the sub-tree below that branch SHALL be included. A path in the
filter value MAY contain the wildcard character (*), which
represents a single path segment.
Every path element in a value array must address at least one node
in the tree. If no matching node is found, the server SHALL return
an error message.
Different elements of the value array MAY address the same node, in
which case it is the responsibility of the server to resolve this to
a singleton in the event messages.
Examples can be found in the
section 5.1.2.1.2 Search Read
and
section 5.2.2.1.2 Search Read
in [[TRANSPORT]] specification.
By default, the server typically have access only to the latest,
most fresh data point representing a signal. However, under certain
conditions, it MAY temporarily store and provide access to
historical data points. One such scenario occurs when a vehicle
temporarily loses connectivity, for example, when entering a tunnel.
If the vehicle detects this loss of connectivity, it MAY begin
recording data. If recorded, this data MAY be accessed using the
history variant of the filter operation. The vehicle system makes
its own decision whether to record any data, and for how long this
data will be kept in storage. The history period in the filter
expression MUST extend backward in time from the current time,
excluding the current value. The number of data points in the
response depends on the history period size, and the sampling
frequency. Since the sampling frequency is server-defined, the
client SHOULD estimate the potential data volume before making a
request. If no historical data is available, the request SHALL
return a "404 Not Found" error. The period MUST conform to the
[[ISO8601]] duration format, expressed in days, hours, minutes, and
seconds. For example: "parameter": "PdddDThhHmmMssS". The number of
days MUST be less than 999. Only a single period can be
specified.
Examples can be found in the
section 5.1.2.1.3 History Read
and
section 5.2.2.1.3 History Read
in [[TRANSPORT]] specification.
The parameter object contains the period time X in between captures, {"period":"X"}. X is an integer and represents the period time in milliseconds. Example can be found in the section 5.1.2.3 Subscribe in [[TRANSPORT]] specification.
The range filter operation supports two types of ranges, as
described in the following sub-sections
The values MUST be of a numeric data type.
A single "boundary operator" evaluates the current signal value
relative to a single boundary. If the condition evaluates to
true, the server MUST issue an event message containing the
signal value to the subscribing client. The boundary operator
MUST be one of the values listed in the footer (**).
Examples
{"logic-op":"gt", "boundary": "5"} // x > 5
{"logic-op":"eq", "boundary": "5"} // x == 5
A multi boundary range evaluates the current signal value
relative to two boundaries. The logical outcome of the two
evaluations are applied as input to a logical AND/OR operation.
If the condition evaluates to true, the server MUST issue an
event message containing the signal value to the subscribing
client. In addition to the mandatory "logic-op" and "boundary"
key-value pairs in each JSON object, the first object MAY include
an optional "combination-op" key-value pair, which MUST have
either the value "AND" or "OR". If omitted, the result of the two
boundary evaluations SHALL default to an AND operation. The JSON
array MUST contain two objects. The boundary operator MUST be one
of the values listed in the footer (**).
Examples
[{"logic-op":"gt", "boundary": "5"},{"logic-op":"lt", "boundary":
"10"}] // x > 5 AND x < 10
[{"logic-op":"lt", "boundary": "5",
"combination-op":"OR"},{"logic-op":"gt", "boundary": "10"}] // x
< 5 OR x > 10
The curve logging filter operation compresses data by simplifying a
time-series signal while maintaining its essential characteristics.
The parameter object contains the maximum error limit, and the
buffer size, {"maxerr": "X", "bufsize":"Y"}, where X is a
floating-point value representing the maximum allowable error
between any sampled data point and the simplified curve, and Y is
the number of buffer elements. The data is processed when the buffer
becomes full, and only the essential data points are returned as a
time series per signal.
Example can be found in the
section 5.1.2.3.2 Curve Logging Subscribe
in [[TRANSPORT]] specification.
A metadata request allows a client to do a so called "signal
inquiry", i. e. to retrieve metadata associated with tree node(s),
rather than the actual signal data.
The metadata is retrieved from the tree that is deployed in the
vehicle. This request variant is sometimes referred to as a signal
discovery request.
The path in the request MAY point to either a leaf node or a branch
node. The "parameter" value in the filter expression sets the number
of descendant generations that metadata will maximally be returned
from. If it is set to zero then there is no limit set and the entire
sub-tree that has the addressed node as root will be returned. If it
is set to two then the metadata from the subtree root and its
immediate children will be returned. A metadata request can be
combined with a paths filter operation to address multiple nodes. If
it is combined with any other filter variant an error message is
returned.
The response is a JSON formatted object containing key-value pairs
for each addressed node. The server MAY support the metadata
request.
Example can be found in the
section 5.2.2.1.4 Signal Discovery Read
in [[TRANSPORT]] specification.
A metadata request can also be used by the client to retrieve
information about the set of trees that the server manages, a so
called "forest inquiry". This request must have a path starting
with the root node name "HIM" which may be appended with one dot
delimited segment name to address a specific tree in the forest.
The response contains all the addressed metadata in the HIM
configuration file except for the "local" property which holds
the path to the tree in the local file system.
The forest inquiry request is the only request type that is
allowed on the HIM configuration file data, all others will
get an error response.
A server that does not utilize a HIM file for representing the set of trees it manages,
if it e. g. manages a predefined, static set of trees,
MUST be able to respond to the request e. g. by having a predefined, static response
describing the trees it manages.
The response shall have the same content as if it was created
from a HIM configuration file describing the forest.
Filtering operations MAY be used to address multiple nodes in the tree within a single request. However, this MAY lead to specific issues in certain situations, as described below.
Error messages for multiple-signal requests are handled the same way as for single-signal requests, except when one or more signals are temporarily unavailable. In such cases, the server MAY use in-line error reporting, Refer to the section 4.1.1 In-line Error Reporting in [[TRANSPORT]] specification.
Response for a single value from a single node:
"data": {
"dp": {
"ts": "Z",
"value": "Y"
},
"path": "X"
}
Response for multiple values from a single node:
"data": {
"dp": [
{
"ts": "Z1",
"value": "Y1"
},
{
"ts": "Zn",
"value": "Yn"
}
],
"path": "X"
}
Response for a single value from multiple nodes:
"data": [
{
"dp": {
"ts": "Z1",
"value": "Y1"
},
"path": "X1"
},
{
"dp": {
"ts": "Zm",
"value": "Ym"
},
"path": "Xm"
}
]
Response for multiple values from multiple nodes:
"data": [
{
"dp": [
{
"ts": "Z11",
"value": "Y11"
},
{
"ts": "Z1n",
"value": "Y1n"
}
],
"path": "X1"
},
{
"dp": [
{
"ts": "Zm1",
"value": "Ym1"
},
{
"ts": "Zmn",
"value": "Ymn"
}
],
"path": "Xm"
}
]
In the case of a request for multiple values from multiple nodes,
the data point for different paths MAY contain single or multiple
objects, as the vehicle system MAY not have multiple values recorded
for all requested signals.
A subscription request MUST include a filter operation that defines the trigger event causing the server to dispatch an asynchronous event message. For "range" and "change" filter variants, triggering depends on the signal value. When a request addresses multiple signals, the triggering condition SHALL be evaluated for only one signal, specifically the first signal in the paths parameter array. The first path in the array MUST NOT contain wildcards, as it determines the triggering signal. If a wildcard expression is used, one of the resolved path addresses MUST be explicitly selected as the first array element, followed by the wildcard expression. If this results in a duplicate reference to the same signal, the server SHALL resolve it into a singleton in the event messages.
This section defines an access control model aligned with the
General Data Protection Regulation (GDPR). The general process begins with a client authenticating for a
specific role with the Access Grant Token Server. If this is successful
it receives an access grant token. This token can then be used one or
more times when making access requests to the Access Token Server.
These requests contain the AGT and a purpose. It is assumed that the
Ecosystem Manager has published a list of approved purposes that the
ecosystem serves, and any other purpose must be denied access. If the
request to the ATS is successful, the client receives an access token,
which can then be used in requests to the VISSv3 server to access one
or more signals associated with the approved purpose.
Access control MUST be supported. However, in this section, only the
parts that describe interactions between the
client and the VISSv3 server are
mandatory.
Access control SHALL NOT be applied to the tree nodes containing the
tree version data, nor to client requests for dynamic metadata about
server capabilities or access control selection tags applied to the
tree.
Two different flows are described, and the choice of flow depends on
the client's capabilities.
If a client supports public key
cryptographic operations, such as key pair generation and digital
signatures, and has access to a trusted execution environment (TEE)
that protects private keys from the regular execution environment,
then it can use the long-term flow.
Clients that lack these capabilities or
choose not to use them MUST select the short-term flow.
The advantage of the long-term flow is that the
client can be trusted with longer expiry
times of access grant tokens.
In the short-term flow, due to a shorter expiry time, the
client must contact the
Access Grant Token Server
more often to obtain a new
access grant token.
A client selects the type of flow by
either submitting a public key in the
access grant request, or
not. If a public key is submitted, the long-term flow is used;
otherwise, the short-term flow applies.
This section describes the payload structures of the messages used in the protocol flow.
Depending on the type of
proofs included in the
request, the client and the server MAY need to run an interactive
protocol to verify them. The protocol MAY also involve third
parties, such as the
ecosystem manager or the
resource owner. The
verification protocol itself is out of scope for this
specification.
In scenarios where both the client and the
Access Grant Token Server
are deployed inside the vehicle, the VIN parameter MAY be
omitted. In all other deployment scenarios, the VIN parameter
SHALL be included.
The client may need to send multiple requests before receiving an access token, even when a valid access grant token is available. This is because, if consent is required, the Access Token Server (ATS) will forward the consent request to the External Consent Framework (ECF), and an immediate response from the ECF may not be available. In such cases, the ATS will respond to the initial access token request with a session handle, which the client MUST use in subsequent requests for the access token. Once the ATS receives a response from the ECF, it will process the client’s follow-up request in one of two ways:
The Access Token Server acts as a Policy Enforcement Point (PEP), making access control decisions based on the submitted access grant token and declared purpose.
This is a VISSv3 request including an access token as described in general in the section 5.1 Methods, and in detail for various transport protocols in the [[TRANSPORT]] specification. The first time a token is submitted in a request, it MUST be included in full. If the server supports access token caching and returns a token handle to the client, then subsequent requests MAY use the token handle instead of the complete access token.
This is a VISSv3 response as described in general in the section 5.1 Methods, and in detail for various transport protocols in the [[TRANSPORT]] specification. It is identical to the response for an unprotected resource request, with no differences in structure or content.
| Permission | read-only | read-write |
|---|---|---|
| get set subscribe |
||
| Ok | Ok | |
| Nok | Ok | |
| Ok | Ok |
The access token needs to be
refreshed periodically, which is determined by the expiry time.
If the
access grant token that the
client originally used to obtain the
now-expired access token is still
valid, then the client can revisit the
Access Token Server with
this access grant token to
obtain a new access token.
However, if the
access grant token is also
expired, then the client MUST obtain a
new
access grant token first,
before revisiting the
Access Token Server.
The server SHOULD support caching of a limited number of
access tokens. The
access token MUST be added to the
cache after a first successful request and it MUST be removed
once they expire. If an access token is cached then the server
SHALL return a token handle of at least 24 bytes long. The client
MAY then use this instead of the complete access token in
following requests that require this access token. If the client
decides to include the access token handle in a request, the
server must then fetch the corresponding access token from the
cache, and verify its validity before deciding to grant the
request.
The server MAY decide to remove any token from the cache at any
time. If the client later references a removed token using its
handle, the server WILL return a "401, invalid_token" error, and
the client MUST resend the whole
access token.
For any client request denied due to
access control, the VISSv3 server MUST return a "401,
invalid_token" error message.
The resource owner is typically the owner and/or driver of the vehicle. If consent is required to grant access to the protected resource, then the request SHOULD be directed to the resource owner. The process of obtaining consent is out of scope for this specification.
The Ecosystem manager is the entity responsible for managing the access control system. This typically includes managing the Access Grant Token Server, and the Access Token Server, maintaining the Policy documents, and ensuring that a PKI domain is available for use by other actors in the ecosystem. .
The three client sub-actors must
provide authentication credentials to the
Access Grant Token Server.
These credentials MAY be certificates issued by a Certificate
Authority (CA) recognized by
Access Grant Token Server.
The details of these interactions are out of scope for this
specification.
{
"alg": "ES256",
"typ": "JWT"
},
{
"vin": "vehicle-id",
"iat": 1609452095,
"exp": 1609459199,
"clx": "user+app+dev",
"aud": "covesa.global/VISSv3",
"jti": "5967e92e-40e8-5f39-892d-cc0da890db1d"
}
{
"alg": "ES256",
"typ": "JWT"
},
{
"vin": "vehicle-id",
"iat": 1609452095,
"exp": 1609459199,
"clx": "user+app+dev",
"pub": client_pub_key,
"aud": "covesa.global/VISSv3",
"jti": "5967e92e-40e8-5f39-892d-cc0da890db1d"
}
{
"alg": "HS256",
"typ": "JWT"
},
{
"vin": "vehicle-id",
"iat": 1609452095,
"exp": 1609459199,
"scp": "PurposeX" || signal-set,
"clx": "user+app+dev",
"aud": "covesa.global/VISSv3",
"jti": "5967e93f-40f9-5f39-893e-cc0da890db2e"
}
Long-term access grant tokens MUST to be accompanied by a Proof of Possession (PoP) for the private key corresponding to the public key included in the access grant token. This requirement enables a longer validity for this kind of tokens, ranging from a several days to a even a year. By adding the PoP, an eavesdropper is prevented to reuse an access token request, impersonating the client. Without a PoP, the longer the validity of an access grant token, the higher the risk an attacker could intercept and reuse it. PoP for JWT are defined in [[RFC7800]]. In essence, PoP enables the requester to proof to the server that it has access to a private key, without disclosing it. Traditionally, this is done by the server generating a random challenge, or nonce, and ask the client to sign it with its private key. Along with the public key, the server would be able to verify the PoP. This scheme would require an extra step in the protocols, where the client ask for the nonce.
To avoid this extra step, the client MAY generate the nonce itself. In this case, the server must ensure that nonces are not reused. While logging previously used nonces on the server may work in small-scale environments, a more scalable approach is to use an incremental nonce based on a timestamp. One of the drawbacks of this proposal is that the server has no means to check whether the PoP has been precomputed or not. However, this is irrelevant from the eavesdropper point of view.
If PoP freshness is a critical requirement, the nonce could be derived from a public source of randomness, such as the League of Entropy or Interoperable Randomness Beacons. That would provide the server a mean to check freshness of the PoP but on the other hand, it would require the client to access the public source of randomness every time it needs to create a PoP which is against the main design goals for the long term access grant token.
The Policy documents are typically owned and created by the ecosystem manager. They MUST be handled securely to protect their integrity. The ecosystem manager SHALL securely provision them to the Access Token Servers in the access control ecosystem.
{"purposes":
[{"short": "fuel-status",
"long": "Fuel level and remaining range.",
"contexts":[{"user":"Independent","app":["OEM", "Third party"], "device":"Cloud"}, {"user":"Owner", "app":"Third party", "device":"Nomadic"}, {"user":"Driver", "app":"OEM", "device":"Vehicle"}],
"signal_access":
[{"path": "Vehicle.Powertrain.FuelSystem.Level", "access_permission": "read-only"},
{"path": "Vehicle.Powertrain.FuelSystem.Range", "access_permission": "read-only"}]
},
{}]
}
The purpose list SHALL be securely provisioned to the
Access Token Server. The
provisioning protocol is out of scope for this specification. If the
Access Token Server does not
possess a valid purpose list, it MUST reject all
access tokens requests.
{"scope":
[{"contexts":[ { "user":["Driver", "Passenger"], "app":"Third party", "device":"Vehicle"}, { } ],
"no_access":
["Vehicle.Drivetrain.Transmission.Speed",
"Vehicle.CurrentLocation.Latitude",
"Vehicle.CurrentLocation.Longitude"]
},
{}]
}
The scope list SHALL be securely provisioned to the
Access Token Server. The
provisioning protocol is out of scope for this specification. If the
Access Token Server does not
have access to a scope list, it SHALL NOT apply any scope
restrictions for client context.
A server receiving a client request that involves obtaining a consent status SHALL send a request to the ECF on which it SHALL receive a response containing the consent status. The request SHALL contain the data from the list in the previous section. The response SHALL contain the data shown in the table above. This communication SHALL be carried out using a secure channel (e.g., TLS).
The primary payloads that are sent over any transport protocol SHALL
conform with the JSON schema in this appendix, unless otherwise
specified in the VISSv3 [[TRANSPORT]] or VISSv3 [[PAYLOAD ENCODING]]
specifications.
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://covesa.global/vissv3.1.bundled.schema.json",
"title": "VISSv3",
"description": "VISS version 3.1 bundled schema",
"type": "object",
"properties": {
"action": {
"type": "string"
}
},
"required": [
"action"
],
"oneOf": [
{
"properties": {
"action": {
"const": "get"
}
},
"$ref": "/vissv3.1/get-message.schema.json"
},
{
"properties": {
"action": {
"const": "set"
}
},
"$ref": "/vissv3.1/set-message.schema.json"
},
{
"properties": {
"action": {
"const": "subscribe"
}
},
"$ref": "/vissv3.1/subscribe-message.schema.json"
},
{
"properties": {
"action": {
"const": "unsubscribe"
}
},
"$ref": "/vissv3.1/unsubscribe-message.schema.json"
},
{
"properties": {
"action": {
"const": "subscription"
}
},
"$ref": "/vissv3.1/subscription-event.schema.json"
}
],
"$defs": {
"https://covesa.global/vissv3.1/get-message.schema.json": {
"$id": "https://covesa.global/vissv3.1/get-message.schema.json",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"title": "VISSv3-get-message",
"description": "VISSv3 get request and response messages",
"type": "object",
"oneOf": [
{
"properties": {
"path": {
"description": "The path",
"type": "string"
},
"filter": {
"$ref": "https://covesa.global/vissv3.1/filter.schema.json"
},
"authorization": {
"description": "The access token",
"type": "string"
},
"dc": {
"description": "The data compression scheme",
"type": "string"
},
"requestId": {
"description": "The request id",
"type": "string"
}
},
"required": [
"path"
]
},
{
"properties": {
"data": {
"$ref": "https://covesa.global/vissv3.1/data.schema.json"
},
"ts": {
"description": "The time stamp",
"type": "string"
},
"requestId": {
"description": "The request id",
"type": "string"
}
},
"required": [
"data",
"ts"
]
},
{
"properties": {
"metadata": {
"type": "object",
"description": "The metadata"
},
"ts": {
"description": "The time stamp",
"type": "string"
},
"requestId": {
"description": "The request id",
"type": "string"
}
},
"required": [
"metadata",
"ts"
]
},
{
"properties": {
"error": {
"$ref": "https://covesa.global/vissv3.1/error.schema.json"
},
"ts": {
"description": "The time stamp",
"type": "string"
},
"requestId": {
"description": "The request id",
"type": "string"
}
},
"required": [
"error",
"ts"
]
}
]
},
"https://covesa.global/vissv3.1/set-message.schema.json": {
"$id": "https://covesa.global/vissv3.1/set-message.schema.json",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"title": "VISSv3-set-message",
"description": "VISSv3 set request and response messages",
"type": "object",
"oneOf": [
{
"properties": {
"path": {
"description": "The path",
"type": "string"
},
"value": {
"description": "The value",
"$ref": "https://covesa.global/vissv3.1/value.schema.json"
},
"authorization": {
"description": "The access token",
"type": "string"
},
"requestId": {
"description": "The request id",
"type": "string"
},
"ts": {
"description": "The time stamp",
"type": "string"
}
},
"required": [
"path",
"value"
]
},
{
"properties": {
"ts": {
"description": "The time stamp",
"type": "string"
},
"requestId": {
"description": "The request id",
"type": "string"
}
},
"required": [
"ts"
]
},
{
"properties": {
"error": {
"$ref": "https://covesa.global/vissv3.1/error.schema.json"
},
"ts": {
"description": "The time stamp",
"type": "string"
},
"requestId": {
"description": "The request id",
"type": "string"
}
},
"required": [
"error",
"ts"
]
}
]
},
"https://covesa.global/vissv3.1/subscribe-message.schema.json": {
"$id": "https://covesa.global/vissv3.1/subscribe-message.schema.json",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"title": "VISSv3-subscribe-message",
"description": "VISSv3 subscribe request and response messages",
"type": "object",
"oneOf": [
{
"properties": {
"path": {
"description": "The path",
"type": "string"
},
"filter": {
"oneOf": [
{
"$ref": "/vissv3.1/filter.schema.json"
},
{
"type": "array",
"items": {
"$ref": "/vissv3.1/filter.schema.json"
},
"minItems": 1,
"maxItems": 2
}
]
},
"authorization": {
"description": "The access token",
"type": "string"
},
"dc": {
"description": "The data compression scheme",
"type": "string"
},
"requestId": {
"description": "The request id",
"type": "string"
}
},
"required": [
"path",
"filter"
]
},
{
"properties": {
"authorization": {
"description": "The access token handle",
"type": "string"
},
"subscriptionId": {
"description": "The subscription Id",
"type": "string"
},
"ts": {
"description": "The time stamp",
"type": "string"
},
"requestId": {
"description": "The request id",
"type": "string"
}
},
"required": [
"subscriptionId",
"ts"
]
},
{
"properties": {
"error": {
"$ref": "https://covesa.global/vissv3.1/error.schema.json"
},
"ts": {
"description": "The time stamp",
"type": "string"
},
"requestId": {
"description": "The request id",
"type": "string"
}
},
"required": [
"error",
"ts"
]
}
]
},
"https://covesa.global/vissv3.1/unsubscribe-message.schema.json": {
"$id": "https://covesa.global/vissv3.1/unsubscribe-message.schema.json",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"title": "VISSv3-unsubscribe-message",
"description": "VISSv3 unsubscribe request and response messages",
"type": "object",
"oneOf": [
{
"properties": {
"subscriptionId": {
"description": "The subscription Id",
"type": "string"
},
"requestId": {
"description": "The request id",
"type": "string"
}
},
"required": [
"subscriptionId"
]
},
{
"properties": {
"ts": {
"description": "The time stamp",
"type": "string"
},
"requestId": {
"description": "The request id",
"type": "string"
}
},
"required": [
"ts"
]
},
{
"properties": {
"error": {
"$ref": "https://covesa.global/vissv3.1/error.schema.json"
},
"ts": {
"description": "The time stamp",
"type": "string"
},
"requestId": {
"description": "The request id",
"type": "string"
}
},
"required": [
"error",
"ts"
]
}
]
},
"https://covesa.global/vissv3.1/subscription-event.schema.json": {
"$id": "https://covesa.global/vissv3.1/subscription-event.schema.json",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"title": "VISSv3-subscription-event",
"description": "VISSv3 subscription event",
"type": "object",
"oneOf": [
{
"properties": {
"subscriptionId": {
"description": "The subscription Id",
"type": "string"
},
"data": {
"$ref": "https://covesa.global/vissv3.1/data.schema.json"
},
"ts": {
"description": "The time stamp",
"type": "string"
},
"requestId": {
"description": "The request id",
"type": "string"
}
},
"required": [
"subscriptionId",
"data",
"ts"
]
},
{
"properties": {
"subscriptionId": {
"description": "The subscription Id",
"type": "string"
},
"error": {
"$ref": "https://covesa.global/vissv3.1/error.schema.json"
},
"ts": {
"description": "The time stamp",
"type": "string"
},
"requestId": {
"description": "The request id",
"type": "string"
}
},
"required": [
"subscriptionId",
"error",
"ts"
]
}
]
},
"https://covesa.global/vissv3.1/filter.schema.json": {
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://covesa.global/vissv3.1/filter.schema.json",
"title": "VISSv3.1-filter",
"description": "VISS version 3.1 filter",
"type": "object",
"properties": {
"variant": {
"type": "string"
}
},
"required": [
"variant"
],
"oneOf": [
{
"properties": {
"variant": {
"const": "paths"
},
"parameter": {
"type": "array",
"items": {
"type": "string"
}
}
},
"required": [
"parameter"
]
},
{
"properties": {
"variant": {
"const": "timebased"
},
"parameter": {
"properties": {
"period": {
"type": "string"
}
},
"required": [
"period"
]
}
},
"required": [
"parameter"
]
},
{
"oneOf": [
{
"properties": {
"variant": {
"const": "range"
},
"parameter": {
"type": "object",
"properties": {
"logic-op": {
"type": "string",
"enum": [
"eq",
"ne",
"gt",
"gte",
"lt",
"lte"
]
},
"boundary": {
"type": "string"
}
},
"required": [
"logic-op",
"boundary"
]
}
},
"required": [
"parameter"
]
},
{
"properties": {
"variant": {
"const": "range"
},
"parameter": {
"type": "array",
"items": {
"type": "object",
"properties": {
"logic-op": {
"type": "string",
"enum": [
"eq",
"ne",
"gt",
"gte",
"lt",
"lte"
]
},
"boundary": {
"type": "string"
},
"combination-op": {
"type": "string",
"enum": [
"AND",
"OR"
]
}
},
"required": [
"logic-op",
"boundary"
]
},
"minItems": 2,
"maxItems": 2
}
},
"required": [
"parameter"
]
}
]
},
{
"properties": {
"variant": {
"const": "change"
},
"parameter": {
"properties": {
"logic-op": {
"type": "string",
"enum": [
"eq",
"ne",
"gt",
"gte",
"lt",
"lte"
]
},
"diff": {
"type": "string"
}
},
"required": [
"logic-op",
"diff"
]
}
},
"required": [
"parameter"
]
},
{
"properties": {
"variant": {
"const": "curvelog"
},
"parameter": {
"properties": {
"maxerr": {
"type": "string"
},
"bufsize": {
"type": "string"
}
},
"required": [
"maxerr",
"bufsize"
]
}
},
"required": [
"parameter"
]
},
{
"properties": {
"variant": {
"const": "history"
},
"parameter": {
"type": "string"
}
},
"required": [
"parameter"
]
},
{
"oneOf": [
{
"properties": {
"variant": {
"const": "metadata"
},
"parameter": {
"type": "string"
}
},
"required": [
"parameter"
]
},
{
"properties": {
"variant": {
"const": "metadata"
},
"parameter": {
"type": "array",
"items": {
"type": "string"
}
}
},
"required": [
"parameter"
]
}
]
}
]
},
"https://covesa.global/vissv3.1/data.schema.json": {
"$id": "https://covesa.global/vissv3.1/data.schema.json",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"title": "VISSv3-data-representation",
"description": "VISSv3 data representation",
"oneOf": [
{
"type": "object",
"$ref": "/vissv3.1/data-object.schema.json"
},
{
"type": "array",
"items": {
"$ref": "/vissv3.1/data-object.schema.json"
}
}
]
},
"https://covesa.global/vissv3.1/data-object.schema.json": {
"$id": "https://covesa.global/vissv3.1/data-object.schema.json",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"title": "VISSv3-data-object",
"description": "VISSv3 data object",
"properties": {
"path": {
"description": "The path",
"type": "string"
},
"dp": {
"description": "The data point",
"oneOf": [
{
"$ref": "/vissv3.1/datapoint.schema.json"
},
{
"type": "array",
"items": {
"$ref": "/vissv3.1/datapoint.schema.json"
},
"minItems": 1
}
]
}
}
},
"https://covesa.global/vissv3.1/datapoint.schema.json": {
"$id": "https://covesa.global/vissv3.1/datapoint.schema.json",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"title": "VISSv3-datapoint",
"description": "VISSv3 datapoint",
"type": "object",
"properties": {
"value": {
"description": "The value",
"$ref": "https://covesa.global/vissv3.1/value.schema.json"
},
"ts": {
"description": "The time stamp",
"type": "string"
}
},
"required": [
"value",
"ts"
]
},
"https://covesa.global/vissv3.1/error.schema.json": {
"$id": "https://covesa.global/vissv3.1/error.schema.json",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"title": "VISSv3-error",
"description": "VISSv3 error data",
"type": "object",
"properties": {
"number": {
"description": "The status code",
"type": "string",
"enum": [
"400",
"401",
"403",
"404",
"408",
"429",
"502",
"503",
"504"
]
},
"reason": {
"description": "The reason",
"type": "string",
"enum": [
"bad_request",
"invalid_data",
"invalid_token",
"forbidden_request",
"unavailable_data",
"request_timeout",
"too_many_requests",
"bad_gateway",
"service_unavailable",
"gateway_timeout"
]
},
"description": {
"description": "The access token",
"type": "string"
}
},
"required": [
"number",
"reason",
"description"
]
},
"https://covesa.global/vissv3.1/value.schema.json": {
"$id": "https://covesa.global/vissv3.1/value.schema.json",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"title": "VISSv3-value",
"description": "VISSv3 value data",
"oneOf": [
{
"type": "string"
},
{
"type": "array",
"items": {
"type": "string"
},
"minItems": 1
},
{
"type": "object",
"patternProperties": {
".*": {
"oneOf": [
{
"type": "string"
},
{
"type": "object"
}
]
}
},
"minItems": 1
}
]
}
}
}
A client that intends to connect to a server may be interested in what capabilities the server offers. The server shall expose this information via a dedicated Server tree, which the client can access to discover supported optional features. However, for the client to retrieve this information, it must have information about at least one transport protocol that the server supports. The VISS API should not make any assumptions on the communication network topology. Therefore it should not mandate any transport protocol, instead it should assume that a client can obtain necessary information via out-of-band mechanisms to configure its communication in order to successfully connect to the vehicle server. How that is done is out of scope for this specification, but as an example a solution may be designed around a cloud based repository to which servers can register their capabilities, and clients can inquire about obtaining this information. When a client has obtained the information how to connect to the server, then the server MUST respond to read requests for data from the Server tree.
The Server tree MUST contain the structures listed below. Additional parts are optional. Server capabilities that extends this specification, or change anything defined in this specification SHALL be declared in the Server tree.
#
# The server capabilities declaration.
#
Server:
type: branch
description: Root for the server capabilities.
Server.Support:
type: branch
description: Top branch declaring the server supported features.
Server.Support.Protocol:
type: attribute
datatype: string[]
description: List of supported transport protocols.
Server.Support.Security:
type: attribute
datatype: string[]
description: List of supported security related features.
Server.Support.Filter:
type: attribute
datatype: string[]
description: List of supported filter features.
Server.Support.Encoding:
type: attribute
datatype: string[]
description: List of supported payload encoding features.
Server.Support.Filetransfer:
type: attribute
datatype: string[]
description: List of supported file transfer features.
Server.Support.DataCompression:
type: attribute
datatype: string[]
description: List of supported data compression features.
Server.Config:
type: branch
description: Top branch declaring the configuration of server supported features.
Server.Config.Protocol:
type: branch
description: Top branch declaring the configuration of server supported protocols.
Server.Config.Protocol.Http:
type: branch
description: Top branch for the server supported HTTP protocol.
Server.Config.Protocol.Http.Primary:
type: branch
description: HTTP configuration for the primary payload format.
Server.Config.Protocol.Http.Primary.PortNum:
type: attribute
datatype: uint32
description: HTTP port number for the primary payload format.
Server.Config.Protocol.Websocket:
type: branch
description: Top branch for the server supported Websocket protocol.
Server.Config.Protocol.Websocket.Primary:
type: branch
description: Websocket configuration for the primary payload format.
Server.Config.Protocol.Websocket.Primary.PortNum:
type: attribute
datatype: uint32
description: Websocket protocol port number for the primary payload format.
Server.Config.Protocol.Websocket.Protobuf:
type: branch
description: Websocket configuration for the protobuf encoded payload format.
Server.Config.Protocol.Websocket.Protobuf.PortNum:
type: attribute
datatype: uint32
description: Websocket protocol port number for the protobuf encoded payload format.
Server.Config.Protocol.Mqtt:
type: branch
description: Top branch for the server supported MQTT protocol.
Server.Config.Protocol.Mqtt.PortNum:
type: attribute
datatype: uint32
description: MQTT port number.
Server.Config.Protocol.Mqtt.Primary:
type: branch
description: MQTT configuration for the primary payload format.
Server.Config.Protocol.Mqtt.Primary.Topic:
type: attribute
datatype: string
description: MQTT topic name for the primary payload format.
Server.Config.Protocol.Mqtt.Protobuf:
type: branch
description: MQTT configuration for the protobuf encoded payload format.
Server.Config.Protocol.Mqtt.Protobuf.Topic:
type: attribute
datatype: string
description: MQTT topic name for the protobuf encoded payload format.
Server.Config.Protocol.Mqtt.Protobuf.DataCompression:
type: attribute
datatype: string[]
description: List of supported data compression variants.
Server.Config.Protocol.Grpc:
type: branch
description: Top branch for the server supported gRPC protocol.
Server.Config.Protocol.Grpc.Protobuf:
type: branch
description: gRPC configuration with the protobuf encoded payload format.
Server.Config.Protocol.Grpc.Protobuf.PortNum:
type: attribute
datatype: uint32
description: gRPC port number for the protobuf encoded payload format.
Server.Config.Protocol.UDS:
type: branch
description: Top branch for the server supported Unix Domain Socket protocol.
Server.Config.Protocol.UDS.Socket:
type: attribute
datatype: string
description: UDS socket file path.
Server.Config.AccessControl:
type: branch
description: Access control configuration.
Server.Config.AccessControl.AgtsUrl:
type: attribute
datatype: string
description: Access Grant Token Server URL including port number and path.
Server.Config.AccessControl.AtsPortNum:
type: attribute
datatype: uint32
description: Access Token Server port number.
Server.Config.AccessControl.Flow:
type: attribute
datatype: string
description: Supported access control flows.
Server.Config.Consent:
type: branch
description: Consent configuration.
Server.Config.Consent.Ecf:
type: attribute
datatype: string
description: External Consent Framework description.
A feature that is supported in at least one configuration shall be
registered on the Support branch. The Config branch shall contain the
information needed for a client to utilize the feature, for all
configurations that has the feature supported. If a server e. g.
supports file transfer upload and download then this shall be found at
the Support branch, and then on the Config branch it shall be
registered for which transport protocol(s) it is supported, and e. g.
which port number is then used. Configuration data that is given a
value in the specification documents does not have to be present on the
Config branch.
| Protocol | Description |
|---|---|
| ws | [[TRANSPORT]], Transport Protocols: section 5.1 Secure WebSocket |
| http | [[TRANSPORT]], Transport Protocols: section 5.2 HTTPS |
| mqtt | [[TRANSPORT]], Transport Protocols: section 5.3 MQTT |
| grpc | [[TRANSPORT]], Transport Protocols: section 5.4 gRPC |
| uds | [[TRANSPORT]], Transport Protocols: section 5.5 Unix Domain Sockets |
| Filter | Description |
|---|---|
| timebased | Time-based event trigger condition |
| change | Change-based event trigger condition |
| paths | Multiple signal paths |
| range | Range-based event trigger condition |
| curvelog | Curve logging-based event trigger condition |
| history | Historic data access |
| metadata | Metadata access |
| File transfer | Description |
|---|---|
| download | File download to vehicle |
| upload | File upload to client |
| Data compression | Description |
|---|---|
| pathuid | Static UID path compression |
| pathlocal | Request local path compression |
| timestamplocal | Response local timestamp compression |
| Security | Description |
|---|---|
| accesscontrol | Access control |
| consent | Consent |
| Access Control Flow | Description |
|---|---|
| short_term | Short term access flow |
| long_term | Long term access flow |
| signalset_claim | Signal set claim |
typedef FileDescriptor struct {
name string
hash string
uid string
}
The FileDescriptor name member SHALL have a dot separated file
extension that identifies the file format.
{
"action": "set",
"path": "Vehicle.Cabin.Infotainment.privateMap",
"value": {
"name": "privateMap.kml",
"hash": "2aae6c35c94fcfb415dbe95f408b9ce91ee846ed",
"uid": "2d878213"
}
}
The Ok response would in primary payload format look like:
{"action": "set", "ts": "2024-08-20T11:30:00Z"}
If the SET request on the control channel receives an error message
then the client shall not issue any SET requests on the data
channel.
{"action": "get", "path": "Vehicle.Cabin.DashCam.Clip"}
The Ok response would in primary payload format look like:
{
"action": "get",
"data": {
"path": "Vehicle.Cabin.DashCam.Clip",
"dp" {
"value": {"name": "dashCamClip.mp4", "hash": "2aae6c35c94fcfb415dbe95f408b9ce91ee846ed", "uid": "2d878213"},
"ts": "2024-08-20T11:30:00Z"
}
},
"ts": "2025-01-09T12:13:14Z"
}
If the GET request on the control channel receives an error message
then the client shall not start the file upload session on the data
channel by issuing the initial status message.
DownloadFile:
type: actuator
datatype: Types.Resources.FileDescriptor
description: File that may be downloaded to the vehicle.
UploadFile:
type: sensor
datatype: Types.Resources.FileDescriptor
description: File stored at the vehicle that may be uploaded to a client.
The Types.Resources.FileDescriptor definition in the Types tree must
mirror the struct definition above.
struct {
schema string
port uint32
path string
filename string
}
Schema is the file transfer protocol schema.
"dc": "A+B"
The expression A+B instructs the server what compression scheme it
shall apply to paths and/or timestamps in its response(s) to this
request. This expression must consist of two values separated by a plus
sign, "A + B", where the first value A represents which path
compression that is selected, and the second value B represents which
timestamp compression that is selected. The value 0 means that no
compression scheme is selected, values 1, 2, 4, or 8 represents the
compression scheme associated with bits no 0, 1, 2, or 3 in the figure
below.
To enable the server to support this path compression the tree
must include the static UIDs for each node. The VSS-Tools
exporter tools can be used to assign a static UID to each tree
node as described
here.
The server will then in the response message(s) replace the path
with the static UID value. The static UID is represented as a hex
value string starting with the characters "0x" then followed by 8
hexadecimal values. The client needs to obtain means for decoding
the static UIDs into corresponding paths, see the
VSS-tools description.
The server shall respond with an error message if the client
applies the path compression in its request.
The principle for request local path compression is that the server will in the response message(s) replace the path(s) with an integer index. In the case that the request only contains one path reference, then the index is always set to zero. For requests that reference more than one path via the usage of the paths filter, the first response from the server will contain the paths uncompressed, but any following responses will replace the paths with an index. The value of the index is then assigned according to a sorted list of the paths included in the first response, i. e. the first path in the sorted list is assigned the value zero, the second the value 1, and so on. The index logically represent an integer value but it is in the message payload represented as a string.
The request relative time stamp compression builds on that response messages always contain a timestamp that represent the time when the response message was issued by the server. This timestamp will then be the base time that the timestamps for the data point(s) in the response will contain an offset to. This offset will be represented as an integer representing milliseconds, prepended with a plus (+) or minus (-) sign. The uncompressed ISO8601 based timestamp contains 24 characters, so for very large offset values leading to low compression rates the server may decide to keep the uncompressed timestamp. The client will be able to analyze whether it is a compressed timestamp or not by examining the first character of the string. If it is an integer it is an uncompressed timestamp, as the compressed timestamps starts with a plus or a minus character.
{"action":"subscribe","path":"Vehicle.CurrentLocation","filter":[{"variant":"paths","parameter":["Latitude", "Longitude"]}, {"variant":"timebased","parameter":{"period":"3000"}}], "dc":"2+1","requestId":"286"}
{"action":"subscribe","requestId":"286","subscriptionId":"1","ts":"2025-01-10T11:46:09.955Z"}
{"action":"subscription","data":[{"dp":{"ts":"-123","value":"56.02"},"path":"Vehicle.CurrentLocation.Latitude"},{"dp":{"ts":"-123","value":"12.36"},"path":"Vehicle.CurrentLocation.Longitude"}],"subscriptionId":"1","ts":"2025-01-10T11:46:12.957Z"}
{"action":"subscription","data":[{"dp":{"ts":"-15","value":"56.03"},"path":"0"},{"dp":{"ts":"-15","value":"12.37"},"path":"1"}],"subscriptionId":"1","ts":"2025-01-10T11:46:15.956Z"}