Copyright © 2020-2025 World Wide Web Consortium. W3C® liability, trademark and permissive document license rules apply.
This specification defines a Profiling Mechanism and a set of Profiles which enable out-of-the-box interoperability between Web Things and their Consumers on the Web of Things.
Being out-of-the-box interoperable means that any Consumer which conforms with a given Profile can interact with any Thing which conforms with the same Profile, without additional customization.
A Profile is a technical specification which provides a set of assertions to which conformant Consumers and Things must conform.
The Profiling Mechanism provides a means to denote that a
given Thing conforms to one or more Profiles, by referring to the
identifiers of those Profiles in
the profile member of its Thing
Description.
The specification defines three profiles:
The Profiles defined in this specification share a set of Common Constraints to which implementations of those Profiles must also conform. This includes constraints on units, date formats, security mechanisms, discovery mechanisms, link relations and errors.
Future versions of this specification, or extension specifications, may define additional Profiles.
This section describes the status of this document at the time of its publication. A list of current W3C publications and the latest revision of this technical report can be found in the W3C standards and drafts index.
This document was published by the Web of Things Working Group as a Working Draft using the Recommendation track.
Publication as a Working Draft does not imply endorsement by W3C and its Members.
This is a draft document and may be updated, replaced, or obsoleted by other documents at any time. It is inappropriate to cite this document as other than a work in progress.
This document was produced by a group operating under the W3C Patent Policy. W3C maintains a public list of any patent disclosures made in connection with the deliverables of the group; that page also includes instructions for disclosing a patent. An individual who has actual knowledge of a patent that the individual believes contains Essential Claim(s) must disclose the information in accordance with section 6 of the W3C Patent Policy.
This document is governed by the 18 August 2025 W3C Process Document.
The Web of Things (WoT) seeks to counter the fragmentation of the Internet of Things (IoT) by using and extending existing, standardized web technologies.
The W3C WoT Thing Description [wot-thing-description11] specification defines an information model and JSON-based representation format for describing the capabilities of connected devices and the interfaces with which to communicate with them. Thing Descriptions are designed to be protocol-agnostic and flexible enough to describe a wide range of existing ("brownfield") IoT devices.
In order to provide this level of flexibility the Thing Description specification includes a number of extension points including protocol bindings, payload bindings, security mechanisms, link relations and semantic contexts. As long as all of the capabilities of a device can be described using a Thing Description and a Consumer implements all of the extensions used, the Consumer should be able to interoperate with that device. However, the result of this extensible architecture is that any given Consumer can only interoperate with a subset of possible Web Things.
This specification is designed to complement the Thing Description [wot-thing-description11] specification, by enabling ad-hoc interoperability through the use of "Profiles". A Profile prescribes a finite set of extensions and defaults that a Thing can be constrained to in order to guarantee out-of-the-box interoperability with any Consumer which implements that profile.
Profiles are designed specifically for new ("greenfield") implementations where developers have the freedom to conform to a prescriptive protocol binding and set of common constraints, in order to benefit from this additional level of interoperability.
Future versions of this specification, or extension specifications, may define additional Profiles.
The Web of Things Interest Group collected use cases for the Web of Things from stakeholders representing various different industries. This includes both vertical domain-specific use cases and horizontal use cases which apply to multiple application domains [wot-usecases].
Several of the domain-specific use cases refer to the need for easy integration of devices from multiple vendors. This is especially important for cross-domain use cases which require "multi-vendor system integration" and "out-of-the-box interoperability".
A set of requirements for Profiles were derived from these use cases.
At a high level, out-of-the-box interoperability means that a Consumer is guaranteed to be able to use every capability of a Thing, without Thing-specific customization.
The full definition of out-of-the-box interoperability used in this specification includes multiple layers. The following classification adopts terminology from the "H2020 - CREATE-IoT Project - Recommendations for commonalities and interoperability profiles of IoT platforms" [H2020-CREATE-IoT] report. The definitions below have been adapted to reflect the scope of the WoT profile.
Technical Interoperability is usually associated with communication protocols and the infrastructure needed for those protocols to operate. This implies agreeing on a common protocol (e.g. HTTP / TCP/IP) and providing additional clarifications, where required.
Syntactic Interoperability is usually associated with data formats and encodings along with techniques for compressing them. Examples for these formats and encodings in the WoT are JSON, XML, JSON-LD, UTF-8 payloads.
Semantic Interoperability is associated with a common understanding of the behavior of communication partners. In the profile context, it includes a common interpretation of (synchronous and asynchronous) action semantics, a common event model, how to set/get multiple properties, writable properties, a common error model and error messages.
Domain specific ontologies, e.g. semantic interop of automotive and medical devices exceed the scope of the this specification.
Organizational Interoperability in the profile context implies that any Consumer which conforms with a given profile can interact with any Thing which conforms with the same Profile, without additional customization.
Organizational Interoperability also requires commonly agreed approaches to security, trust and privacy, i.e. a Consumer is provided access to Things only when these common terms and conditions are applied.
Devices created by various engineers, vendors and SDOs that satisfy the requirements of the profile specification can be integrated with compliant Consumers without additional customization. This works across infrastructures, regions and cultures.
As well as sections marked as non-normative, all authoring guidelines, diagrams, examples, and notes in this specification are non-normative. Everything else in this specification is normative.
The key words MAY, MUST, MUST NOT, OPTIONAL, RECOMMENDED, SHOULD, and SHOULD NOT in this document are to be interpreted as described in BCP 14 [RFC2119] [RFC8174] when, and only when, they appear in all capitals, as shown here.
A Thing or Consumer implementation complies with this specification if it follows the normative statements in the present document.
Fundamental WoT terminology such as Web Thing (Thing), Consumer, Thing Description, Property, Action, Event and Protocol Binding, are defined in Section 3 of the WoT Architecture specification [wot-architecture11].
In order to conform with a Profile, a Web Thing MUST conform with all the normative statements in the Profile's specification.
In order to denote that a given
Web Thing conforms to
one or more Profiles,
its Thing
Description MUST include a
profile member [wot-thing-description11].
The
value of the profile member MUST be set to either a valid URI
[RFC3986]
identifying a single Profile,
or an array of valid URIs identifying multiple Profiles.
In order to use a profile
member in a Thing Description, the
@context member MUST
contain the anyURI
https://www.w3.org/2022/wot/td/v1.1 in order to
denote that the document is using version 1.1 of the Thing
Description specification. [wot-thing-description11].
{
"@context": "https://www.w3.org/2022/wot/td/v1.1",
"id": "urn:dev:ops:32473-WoTLamp-1234",
"profile": "https://www.w3.org/2022/wot/profile/http-basic/v1",
"title": "My Lamp",
"description": "A web connected lamp",
...
}
{
"@context": "https://www.w3.org/2022/wot/td/v1.1",
"id": "urn:dev:ops:32473-WoTLamp-1234",
"profile": [
"https://www.w3.org/2022/wot/profile/http-basic/v1",
"https://www.w3.org/2022/wot/profile/http-sse/v1"
],
"title": "My Lamp",
"description": "A web connected lamp",
...
}
All Things and Consumers conforming to a Profile MUST satisfy the assertions specified in the WoT Thing Description 1.1 specification [wot-thing-description11], except for the assertion with text "TD 1.1 consumers MUST accept TDs satisfying the W3C WoT Thing Description 1.0 [wot-thing-description] specification."
A
Profile SHOULD NOT redefine defaults from protocol
binding templates [wot-binding-templates].
E.g., if a profile uses an HTTP protocol binding and the HTTP
Binding Template specifies that in an HTTP protocol binding the
default value of htv:methodName for a
readproperty operation is GET, the
profile should not redefine that value as
POST.
A
Profile SHOULD NOT require a Thing to respond in a way which would
be unexpected by a Consumer
which does not implement the Profile. E.g., a Profile may define details of a
protocol binding for a queryaction operation which
would not currently be possible to fully describe using a
protocol binding template in a Thing Description (due to
current limitations of the WoT Thing Description 1.1
specification), and would be consumable by a conformant
Consumer, but any other
action-related operations exposed by the Thing
Description ought to still respond in the way that a
Consumer which does not implement the Profile would expect.
Conforming to a Profile does not prevent a Web Thing from describing additional capabilities and protocol bindings in their Thing Description beyond those described in the Profile, as long as they conform with all of the normative assertions of the Profile.
Just because a Thing Description claims that the Thing it describes conforms to a given Profile, a Consumer should not assume that it does in fact conform. E.g. a Consumer should be able to recover gracefully if a Thing does not respond as specified to a given operation.
The following sections are applicable for profiles defined by this document.
Authors of Thing Descriptions should be aware that units that are common in their geographic region are not globally applicable and may lead to misinterpretation with drastic consequences.
It is highly RECOMMENDED to provide a unit, if
a value has a physical quantity.
It is highly RECOMMENDED to use the metric system (SI units) for devices that are used in global deployments.
Unless otherwise
specified, all date and time values MUST use the date-time format
defined in [RFC3339].
2022-09-21T23:20:50.52Z
In order to reduce ambiguity, RFC 3339 only permits an hour with a value between 00 and 23 (not 24), and time zones expressed as a numerical offset relative to UTC. The suffix "Z" when applied to a time denotes a UTC offset of 00:00.
Conformant Web Things MUST use at least one of the following security schemes [wot-thing-description11]:
NoSecuritySchemeBasicSecuritySchemeOAuth2SecurityScheme with the
code or client flowConformant Consumers MUST support all of the following security schemes [wot-thing-description11]:
NoSecuritySchemeBasicSecuritySchemeOAuth2SecurityScheme with the
code or client flowComboSecurityScheme with the
oneOf member containing at least one of the
schemes aboveA Thing MAY implement multiple security schemes.
If a Thing supports multiple security
schemes it MUST use the
ComboSecurityScheme to enumerate those schemes
using the oneOf member, so that only one
security scheme is required to be used at a time.
For the
BasicSecurityScheme the "in" field MUST be either omitted or be given its default
value of "header" as defined in [wot-thing-description11].
For the
BasicSecurityScheme the "name" field MUST be provided using the value
"Authorization" if a "proxy" endpoint is not given.
For the
BasicSecurityScheme the "name" field MUST be provided using the value
"Proxy-Authorization" if a "proxy" endpoint is
given.
Conformant Consumers MUST support security bootstrapping for all implemented security schemes, as defined in Security Bootstrapping in the WoT Discovery [wot-discovery] specification.
Conformant Things which require authentication in order to retrieve their Thing Description MUST implement security bootstrapping, as defined in Security Bootstrapping in the WoT Discovery [wot-discovery] specification.
A Web Thing's Thing Description [wot-thing-description11] MUST be retrievable from a Thing Description Server [wot-architecture11] using an HTTP URL [RFC9110] provided by a Direct Introduction Mechanism [wot-discovery].
links member that provide
hyperlinks to other web resources. This section defines
specific combinations of rel and
type members of a Link which conformant Consumers are expected to
interpret in a particular way.
| rel | type | Meaning |
|---|---|---|
icon |
image/* |
An icon representing the Thing |
alternate |
text/html |
A user interface to interact with the Thing |
service-doc |
text/plain or text/html
or text/pdf |
A user manual for the Thing |
item |
application/td+json |
The target Thing is a component of this Thing or a member of a collection of Things that this Thing represents |
collection |
application/td+json |
This Thing is a component of the target Thing or a group of Things that the target Thing represents |
If a Consumer encounters a link with "rel": "icon" and "type": "image/*" and it is capable of rendering images in the provided format, then it SHOULD interpret the link as an icon for the Thing and display it to the user.
If a Consumer encounters a link with "rel": "alternate" and "type": "text/html" and it is capable of rendering an HTML page and accepting user input, then it SHOULD interpret the link as a user interface for the Thing and provide a means for the user to follow that link and view and interact with the HTML page.
If a Consumer encounters a link with "rel": "service-doc" and "type": "text/plain", "type": "text/html" or "type": "text/pdf", and is capable of rendering documents in the provided format, then it SHOULD interpret the link as a user manual for the Thing and provide a means for the user to follow that link and read the user manual.
If a Consumer encounters a link with "rel": "item" and "type": "application/td+json" and is capable of rendering a hierarchical tree of Things, then it should interpret the link as an indication that the target is a sub-Thing of the current Thing and render this in a meaningful way to the user.
If a Consumer encounters a link with "rel": "collection" and "type": "application/td+json" and is capable of rendering a hierarchical tree of Things, then it should interpret the link as an indication that the target describes a Thing (e.g. a group, system of Things or Thing Directory) which contains the current Thing and render this in a meaningful way to the user.
If any of the operations defined in the protocol bindings of HTTP profiles are unsuccessful then the Web Thing MUST send an HTTP response with an HTTP error code which describes the reason for the failure.
It is RECOMMENDED that error responses use one of the following HTTP error codes:
400 Bad Request401 Unauthorized403 Forbidden404 Not Found500 Internal Server Error503 Service UnavailableA Web Thing MAY respond with 3xx status codes for the
purposes of redirection, caching or authentication.
A Web Thing MUST NOT respond with a 300 Multiple
Choices status code.
Web Things MAY respond with other valid HTTP error codes
(e.g. 418 I'm a teapot). Consumers MAY interpret other valid HTTP error codes as
a generic 4xx or 5xx error with no
special defined behavior.
If an HTTP error response contains a body, the content of that body MUST conform with the Problem Details format [RFC7807].
This section defines the HTTP Basic Profile, which includes a Protocol Binding for reading and writing properties and invoking, querying and cancelling actions.
This profile may be used in conjunction with the HTTP SSE Profile or the HTTP Webhook Profile in order to provide operations for observing properties and listening for events.
In order to conform with the HTTP Basic Profile, Web Things and Consumers MUST also conform with all of the assertions in the Common Constraints section.
In order to denote that a
given Web
Thing conforms to the HTTP Basic Profile, its Thing
Description MUST have a profile
member [wot-thing-description11]
with a value of
https://www.w3.org/2022/wot/profile/http-basic/v1.
This section defines a Protocol Binding which describes how a Consumer communicates with a Web Thing [wot-architecture11] using JSON [JSON] payloads over the HTTP protocol [RFC9112].
A Consumer or Web Thing conforming to the HTTP Basic Profile MUST implement this protocol binding.
The examples provided throughout this section describe how a Consumer would communicate with a Web Thing which produces the following Thing Description:
{
"@context": "https://www.w3.org/2022/wot/td/v1.1",
"id": "https://mywebthingserver.com/things/lamp",
"profile": "https://www.w3.org/2022/wot/profile/http-basic/v1",
"base": "https://mywebthingserver.com/things/lamp/",
"title": "My Lamp",
"description": "A web connected lamp",
"securityDefinitions": {
"oauth2": {
"scheme": "oauth2",
"flow": "code",
"authorization": "https://mywebthingserver.com/oauth/authorize",
"token": "https://mywebthingserver.com/oauth/token"
}
},
"security": "oauth2",
"properties": {
"on": {
"type": "boolean",
"title": "On/Off",
"description": "Whether the lamp is turned on",
"forms": [{"href": "properties/on"}]
},
"level" : {
"type": "integer",
"title": "Brightness",
"description": "The level of light from 0-100",
"unit": "percent",
"minimum" : 0,
"maximum" : 100,
"forms": [{"href": "properties/level"}]
}
},
"actions": {
"fade": {
"title": "Fade",
"description": "Fade the lamp to a given level",
"synchronous": false,
"input": {
"type": "object",
"properties": {
"level": {
"title": "Brightness",
"type": "integer",
"minimum": 0,
"maximum": 100,
"unit": "percent"
},
"duration": {
"title": "Duration",
"type": "integer",
"minimum": 0,
"unit": "milliseconds"
}
}
},
"forms": [{"href": "actions/fade"}]
}
},
"forms": [
{
"op": ["readallproperties", "writemultipleproperties"],
"href": "properties"
},
{
"op": "queryallactions",
"href": "actions"
}
]
}
The URL of a property resource to be used when reading the value of a Property MUST be obtained from a Thing Description by locating a Form inside the corresponding PropertyAffordance for which:
op member contains the value
readpropertyhref member is
http or https
contentType member is
application/jsonThe
resolved value of the href member MUST then be used as the URL of the
property resource.
In order to read the value of a Property, a Consumer MUST send an HTTP request to a Web Thing with:
GETAccept header set to
application/jsonGET /things/lamp/properties/on HTTP/1.1
Host: mythingserver.com
Accept: application/json
If a Web Thing receives an HTTP request following the format above and the Consumer has permission to read the corresponding Property, then upon successfully reading the value of the Property it MUST send an HTTP response with:
200Content-Type header set to
application/jsonHTTP/1.1 200 OK
Content-Type: application/json
false
The URL of a property resource to be used when writing the value of a Property MUST be obtained from a Thing Description by locating a Form inside the corresponding PropertyAffordance for which:
op member contains the value
writepropertyhref member is
http or https
contentType member is
application/jsonThe
resolved value of the href member MUST then be used as the URL of the
property resource.
In order to write the value of a Property, a Consumer MUST send an HTTP request to a Web Thing with:
PUTContent-Type header set to
application/jsonPUT /things/lamp/properties/on HTTP/1.1
Host: mythingserver.com
Content-Type: application/json
true
If a Web Thing receives an HTTP request following the format above and the Consumer has permission to write the corresponding Property, then upon successfully writing the value of the property it MUST send an HTTP response with:
204HTTP/1.1 204 No Content
The URL of a properties resource to be used when
reading the value of all Properties at once
MUST be obtained from a
Thing
Description by locating a Form
inside the top level
forms member for which:
op member contains the value
readallpropertieshref member is
http or https
contentType member is
application/json
The resolved value of the href member
MUST then be used as the URL of
the properties resource.
In order to read the value of all Properties, a Consumer MUST send an HTTP request to a Web Thing with:
GETAccept header set to
application/jsonGET /things/lamp/properties HTTP/1.1
Host: mythingserver.com
Accept: application/json
If a Web Thing receives an HTTP request following the format above, then upon successfully reading the values of all the readable Properties to which the Consumer has permission to access, it MUST send an HTTP response with:
200Content-Type header set to
application/jsonHTTP/1.1 200 OK
Content-Type: application/json
{
"on": false,
"level": 100
}
The URL of a properties resource to be used when
writing the value of multiple Properties at once
MUST be obtained from a
Thing
Description by locating a Form
inside the top level
forms member for which:
op member contains the value
writemultiplepropertieshref member is
http or https
contentType member is
application/json
The resolved value of the href member
MUST then be used as the URL of
the properties resource.
In order to write the value of multiple properties at once, a Consumer MUST send an HTTP request to a Web Thing with:
PUTContent-Type header set to
application/jsonPUT /things/lamp/properties HTTP/1.1
Host: mythingserver.com
Content-Type: application/json
{
"on": true,
"level": 50
}
If a Web Thing receives an HTTP request following the format above, then upon successfully writing the values of the requested writable Properties it MUST send an HTTP response with:
204HTTP/1.1 204 No Content
The readmultipleproperties
operation is excluded due to the complexities of the
request payload format and because it doesn't add much
functionality over readproperty and
readallproperties.
writeallproperties is excluded because it is
just a special case of
writemultipleproperties.
The URL of an action resource to be used when invoking an Action MUST be obtained from a Thing Description by locating a Form inside the corresponding ActionAffordance for which:
op member is
invokeactionhref member is
http or https
contentType member is
application/jsonThe
resolved value of the href member MUST then be used as the URL of the action
resource.
In order to invoke an Action on a Web Thing, a Consumer MUST send an HTTP request to the Web Thing with:
POSTAccept header set to
application/jsonContent-Type header set to
application/json (only if the action has
an input)POST /things/lamp/actions/fade HTTP/1.1
Host: mythingserver.com
Content-Type: application/json
Accept: application/json
{
"level": 100,
"duration": 5
}
If
the action does not have an input then the
Content-type header of the request
SHOULD NOT be set, and the body
should be empty.
A valid JSON value — such as
null, empty quotation marks
(""), or empty braces ({}) —
could be a valid action input and is not considered to
be an "empty" body.
If a Web Thing receives an HTTP request following the format above then it MUST respond with one of three response formats:
The
synchronous member of an
ActionAffordance MUST be set
to true or false.
If
the synchronous member of the
ActionAffordance [wot-thing-description11]
is set to true then the Web Thing MUST respond with a Synchronous Action
Response.
If
the synchronous member of the
ActionAffordance [wot-thing-description11]
is set to false then the Web Thing MUST respond with an Asynchronous Action
Response.
For
long-running actions which are not expected to finish
executing within the timeout period of an HTTP request
(e.g. 30 to 120 seconds), it is RECOMMENDED that a Web Thing respond with
an Asynchronous Action Response so that a Consumer may continue to
monitor the status of an action request with a
queryaction operation on a dynamically
created ActionStatus resource, after the
initial invokeaction response.
For short-lived actions which are expected to finish executing within the timeout period of an HTTP request, a Web Thing MAY wait until the action has completed to send a Synchronous Action Response.
If
a Web
Thing encounters an error in attempting to execute an
action before responding to the invokeaction
request, then it MUST send an
Error Response.
Conforming
Consumers MUST support all three types of response
to the initial invokeaction request.
After
the initial request, support for subsequent operations on
an ActionStatus resource is OPTIONAL.
The status of an asynchronous action invocation
request is represented by an
ActionStatus object which includes the
following members:
| Member | Description | Assignment | Type |
|---|---|---|---|
status |
The status of the action request. | mandatory |
string (one of
pending, running,
completed or
failed)
|
output |
The output data, if any, of a completed
action which MUST
conform with the output data
schema of the corresponding
ActionAffordance.
|
optional | any type |
error |
An error message, if any, associated with a
failed action which MUST use the JSON
serialization of the Problem Details format
[RFC7807]
(only needed in response to a
queryaction operation).
|
optional | object |
href |
The [URL] of an
ActionStatus resource which can
be used by queryaction and
cancelaction operations, the
URI scheme [RFC3986]
of which MUST
resolve to http or
https (only needed for an
Asynchronous
Action Response).
|
optional | string |
timeRequested |
A timestamp indicating the time at which the Thing received the request to execute the action. (See Date Format for date format constraints). | optional | string |
timeEnded |
A timestamp indicating the time at which the Thing successfully completed executing the action, or failed to execute the action. (See Date Format for date format constraints). | optional | string |
It is possible that a Thing's clock may not
be set to the correct time. If timings are important
then a Consumer may therefore
choose to treat the timeEnded member of
an ActionStatus object as being relative
to the timeRequested member, but not
necessarily as relative to its own internal clock, or
the clocks of other Things.
If providing a Synchronous Action Response for an action with an output, a Web Thing MUST send an HTTP response with:
200Content-Type header set to
application/jsonHTTP/1.1 200 OK
Content-Type: application/json
20
If providing a Synchronous Action Response for an action with no output, a Web Thing MUST send an HTTP response with:
204Content-Type header not setHTTP/1.1 204 No Content
A valid JSON value — such as
null, empty quotation marks
(""), or empty braces ({})
— could be a valid action output and is not
considered to be an "empty" body.
If providing an Asynchronous Action Response, a
Web Thing MUST send an HTTP response containing
the URL of an ActionStatus resource, the
URI
scheme [RFC3986]
of which MUST resolve to
http or https. The response
MUST have:
201Content-Type header set to
application/jsonLocation header set to the URL of
the ActionStatus resourceActionStatus
object serialized in JSON, with its
href member set to the URL of the
ActionStatus resource
HTTP/1.1 201 CREATED
Content-Type: application/json
Location: /things/lamp/actions/fade/123e4567-e89b-12d3-a456-426655
{
"status": "pending",
"href": "/things/lamp/actions/fade/123e4567-e89b-12d3-a456-426655",
"timeRequested": "2021-11-10T11:43:19.135Z"
}
In resource constrained environments, the
ActionStatus objects of older
completed/failed actions MAY
be deleted to make room for newly invoked
actions.
A queryaction operation is used to query
the current state of an ongoing action request.
A
Web
Thing which provides Asynchronous Action
Responses to an invokeaction operation
on an Action
MUST also support
queryaction operations on that same Action. A
Web
Thing which only provides Synchronous Action Responses
to an invokeaction operation on an Action SHOULD NOT support
queryaction operations on that same Action.
The
URL of an ActionStatus resource to be used
in a queryaction operation MUST be obtained from the
Location header of an Asynchronous Action
Response, or the href member of the
ActionStatus object in its body.
In order to query the status of an action request, a Consumer MUST send an HTTP request to a Web Thing with:
GETActionStatus resourceAccept header set to
application/jsonGET /things/lamp/actions/fade/123e4567-e89b-12d3-a456-426655
Host: mythingserver.com
Accept: application/json
If a Web
Thing receives an HTTP request following the format
above and the Consumer has permission
to query the corresponding ActionStatus
resource, then upon successfully reading the status of
the action request it MUST
send an HTTP response with:
200Content-Type header set to
application/jsonActionStatus
object representing the current status of the action
request, serialized in JSONHTTP/1.1 200 OK
Content-Type: application/json
{
"status": "running",
"timeRequested": "2021-11-10T11:43:19.135Z"
}
If
the queried action failed to execute, then the
status member of the
ActionStatus object MUST be set to
"failed". If
the queried action failed to execute, then the
error member MAY
provide additional error information conforming to the
Problem Details format [RFC7807].
HTTP/1.1 200 OK
Content-Type: application/json
{
"status": "failed",
"error": {
"type": "https://mythingserver.com/docs/errors/invalid-level",
"title": "Invalid value for level provided",
"invalid-params": [
{
"name": "level",
"reason": "Must be a valid number between 0 and 100"
}
]
},
"timeRequested": "2021-11-10T11:43:19.135Z",
"timeEnded": "2021-11-10T11:43:20.513Z"
}
A cancelaction operation is used to
cancel an ongoing action request.
A
Web
Thing which provides Asynchronous Action
Responses to an invokeaction operation
on an Action
MAY also support
cancelaction operations on that same
Action.
A
Web
Thing which only provides Synchronous Action Responses
to an invokeaction operation on an Action SHOULD NOT support
cancelaction operations on that same
Action.
The
URL of an ActionStatus resource to be used
in a cancelaction operation MUST be obtained from the
Location header of an Asynchronous Action
Response, or the href member of the
ActionStatus object in its body.
In order to cancel an action request, a Consumer MUST send an HTTP request to a Web Thing with:
DELETEActionStatus resourceDELETE /things/lamp/actions/fade/123e4567-e89b-12d3-a456-426655 HTTP/1.1
Host: mythingserver.com
If a Web Thing receives an HTTP request following the format above and the Consumer has permission to cancel the corresponding action request, then upon successfully cancelling the action it MUST send an HTTP response with:
204HTTP/1.1 204 No Content
The URL of an actions resource to be used when
querying the status of all ongoing action requests
MUST be obtained from a
Thing
Description by locating a Form
inside the top level
forms member for which:
op member contains the value
queryallactionshref member is
http or https
contentType member is
application/jsonThe
resolved value of the href member MUST then be used as the URL of the
actions resource.
In order to query the status of all ongoing action requests, a Consumer MUST send an HTTP request to a Web Thing with:
GETAccept header set to
application/jsonGET /things/lamp/actions HTTP/1.1
Host: mythingserver.com
Accept: application/json
If a Web Thing receives an HTTP request following the format above, then upon successfully retrieving the status of all ongoing action requests to which the Consumer has permission to access, it MUST send an HTTP response with:
200Content-Type header set to
application/jsonActionStatus objects
representing the action requests, serialized in JSON.
Each array in the result object MUST be sorted in reverse chronological order such that the most recent action request appears first.
HTTP/1.1 200 OK
Content-Type: application/json
{
"fade": [
{
"status": "completed",
"href": "/things/lamp/actions/fade/123e4567-e89b-12d3-a456-426655",
"timeRequested": "2021-11-10T11:43:19.135Z",
"timeEnded": "2021-11-10T11:43:20.513Z"
},
{
"status": "failed",
"href": "/things/lamp/actions/fade/123e4567-e89b-12d3-a456-558329",
"timeRequested": "2021-11-10T11:42:15.133Z",
"timeEnded": "2021-11-10T11:42:22.524Z"
},
{
"status": "running",
"href": "/things/lamp/actions/fade/123e4567-e89b-12d3-a457-434656",
"timeRequested": "2021-11-10T11:41:53.351Z"
},
{
"status": "pending",
"href": "/things/lamp/actions/fade/123e4567-e89b-12d3-a457-ea9519",
"timeRequested": "2021-11-10T11:39:53.651Z"
}
]
}
cancelaction operation, its
ActionStatus object is deleted and need
not be retained. For all other action requests it is
assumed that a Web Thing will store the
ActionStatus object so that its status may
later be queried with a queryaction or
queryallactions operation. It is not
expected that ActionStatus objects should
be retained indefinitely, they may be stored in
volatile memory and/or periodically pruned. The length
of time for which to retain ActionStatus
objects is expected to be implementation-specific and
may depend on application-specific requirements or
resource constraints.
This section defines the HTTP SSE Profile, including a Protocol Binding for observing Properties and listening for Events using Server-Sent Events [EVENTSOURCE].
This profile may be used in conjunction with the HTTP Basic Profile in order to provide operations to read and write properties and invoke, query and cancel actions.
In order to conform with the HTTP SSE Profile, Web Things and Consumers MUST also conform with all of the assertions in the Common Constraints section.
In order to denote that a
given Web
Thing conforms to the HTTP SSE Profile, its Thing
Description MUST have a profile
member [wot-thing-description11]
with a value of
https://www.w3.org/2022/wot/profile/http-sse/v1.
This section defines a Protocol Binding which describes how a Consumer communicates with a Web Thing [wot-architecture11] using Server-Sent Events [EVENTSOURCE].
A Consumer or Web Thing conforming to the HTTP SSE Profile MUST implement this protocol binding.
The examples provided throughout this section describe how a Consumer would communicate with a Web Thing which produces the following Thing Description:
{
"@context": "https://www.w3.org/2022/wot/td/v1.1",
"id": "https://mywebthingserver.com/things/lamp",
"profile": "https://www.w3.org/2022/wot/profile/http-sse/v1",
"base": "https://mywebthingserver.com/things/lamp/",
"title": "My Lamp",
"description": "A web connected lamp",
"securityDefinitions": {
"oauth2": {
"scheme": "oauth2",
"flow": "code",
"authorization": "https://mywebthingserver.com/oauth/authorize",
"token": "https://mywebthingserver.com/oauth/token"
}
},
"security": "oauth2",
"properties": {
"on": {
"type": "boolean",
"title": "On/Off",
"description": "Whether the lamp is turned on",
"forms": [
{
"href": "properties/on",
"op": ["observeproperty", "unobserveproperty"],
"subprotocol": "sse"
}
]
},
"level" : {
"type": "integer",
"title": "Brightness",
"description": "The level of light from 0-100",
"unit": "percent",
"minimum" : 0,
"maximum" : 100,
"forms": [
{
"href": "properties/level",
"op": ["observeproperty", "unobserveproperty"],
"subprotocol": "sse"
}
]
}
},
"events": {
"overheated": {
"title": "Overheated",
"data": {
"type": "number",
"unit": "degree celsius"
},
"description": "The lamp has exceeded its safe operating temperature",
"forms": [{
"href": "events/overheated",
"subprotocol": "sse"
}]
}
},
"forms": [
{
"op": ["observeallproperties", "unobserveallproperties"],
"href": "properties",
"subprotocol": "sse"
},
{
"op": ["subscribeallevents", "unsubscribeallevents"],
"href": "events",
"subprotocol": "sse"
}
]
}
The URL of a Property resource to be used when observing the value of a property MUST be obtained from a Thing Description by locating a Form inside the corresponding PropertyAffordance for which:
op member contains the value
observepropertyhref member is
http or https
subprotocol member has a value
of ssecontentType member is
application/jsonThe
resolved value of the href member MUST then be used as the URL of the
property resource.
In order to observe a Property, a Consumer MUST follow the Server-Sent Events [EVENTSOURCE] specification to open a connection with the Web Thing at the URL of the property resource.
This involves the Consumer sending an HTTP request to the Web Thing with:
GETAccept header set to
text/event-streamConnection header set to
keep-aliveGET /things/lamp/properties/level HTTP/1.1
Host: mythingserver.com
Accept: text/event-stream
Connection: keep-alive
For Consumers implemented in JavaScript
[ECMASCRIPT]
and executed in a runtime which exposes the
EventSource interface, a Server-Sent
Events connection can be initiated using the
EventSource constructor.
const levelSource = new EventSource('/things/lamp/properties/level');
If a Web Thing receives an HTTP request following the format above and the Consumer has permission to observe the corresponding property, then it MUST follow the Server-Sent Events [EVENTSOURCE] specification to maintain an open connection with the Consumer and push a property value to the Consumer each time the value of the specified Property changes.
This involves the Web Thing initially sending an HTTP response to the Consumer with:
200Content-Type header set to
text/event-streamHTTP/1.1 200 OK
Content-Type: text/event-stream
Whenever
the value of the specified Property changes while the
Web
Thing has an open connection with a Consumer, the Web Thing MUST send a property value to the Consumer using the event
stream format in the Server-Sent Events [EVENTSOURCE]
specification. For
each message sent, the Web Thing MUST set the event field to
the name of the
PropertyAffordance and populate the data
field with the property value, serialized in JSON and
following the data schema specified in the
PropertyAffordance. The
id field SHOULD be
set to a unique identifier for the property change, for
use when re-establishing a dropped connection (see
below). It
is RECOMMENDED that the
identifier is a timestamp representing the time at which
the property changed (see Date Format for date format
constraints).
event: level\n
data: 42\n
id: 2021-11-17T15:33:20.827Z\n\n
If
the connection between the Consumer and Web Thing drops (except
as a result of the unobserve operation
defined below), the Consumer MUST re-establish the connection following
the steps outlined in the Server-Sent Events
specification [EVENTSOURCE].
Once
the connection is re-established the Web Thing SHOULD, if possible, send any missed
property changes which occurred since the last change
specified by the Consumer in a
Last-Event-ID header.
Property values are
serialized in JSON and provided in the
data field of a Server-Sent Event
serialized in text/event-stream format.
The text/event-stream content type used in
HTTP headers is assumed to be implied by the
sse subprotocol, and the embedded
application/json content type is indicated
in contentType member of the Form (with
defaults applied).
In order to stop observing a Property, a Consumer MUST terminate the corresponding Server-Sent Events connection with the Web Thing as specified in the Server-Sent Events specification [EVENTSOURCE].
For Consumers implemented in
JavaScript [ECMASCRIPT]
and executed in a runtime which exposes the
EventSource interface, a Server-Sent
Events connection can be terminated using the
close() method on an
EventSource [EVENTSOURCE]
object.
levelSource.close();
The URL of a properties resource to be used when
observing changes to all properties of a Web Thing
MUST be obtained from a
Thing
Description by locating a Form
inside the top level
forms member of a Thing
Description for which:
op member contains the value
observeallpropertieshref member is
http or https
subprotocol member has a value
of ssecontentType member is
application/json
The resolved value of the href member
MUST then be used as the URL of
the properties resource.
In order to observe changes to all Properties of a Web Thing, a Consumer MUST follow the Server-Sent Events [EVENTSOURCE] specification to open a connection with the Web Thing at the URL of the properties resource.
This involves the Consumer sending an HTTP request to the Web Thing with:
GETAccept header set to
text/event-streamConnection header set to
keep-aliveGET /things/lamp/properties HTTP/1.1
Host: mythingserver.com
Accept: text/event-stream
Connection: keep-alive
For Consumers implemented in
JavaScript [ECMASCRIPT]
and executed in a runtime which exposes the
EventSource interface, a Server-Sent
Events connection can be initiated using the
EventSource constructor.
const lampPropertiesSource = new EventSource('/things/lamp/properties');
If a Web Thing receives an HTTP request following the format above then it MUST follow the Server-Sent Events [EVENTSOURCE] specification to maintain an open connection with the Consumer and push new property values to the Consumer for all Properties for which it has permission to observe.
This involves the Web Thing initially sending an HTTP response to the Consumer with:
200Content-Type header set to
text/event-streamHTTP/1.1 200 OK
Content-Type: text/event-stream
Whenever a Property changes while the
Web
Thing has an open connection with a Consumer, the
Web
Thing MUST send the new
property value to the Consumer using the event
stream format in the Server-Sent Events [EVENTSOURCE]
specification.
For each message sent, the Web Thing MUST set the event field to
the name of the
PropertyAffordance and populate the data
field with the new property value.
The property data MUST follow
the data schema specified in the
PropertyAffordance and MUST
be serialized in JSON.
The id field SHOULD
be set to a unique identifier for the event, for use when
re-establishing a dropped connection (see below).
It is RECOMMENDED that the
identifier is a timestamp representing the time at which
the Property changed
(see Date Format for date
format constraints).
event: level\n
data: 42\n
id: 2021-11-17T15:33:20.827Z\n\n
If the connection between the Consumer and Web Thing drops (except
as a result of the unobserveallproperties
operation defined below), the Consumer MUST re-establish the connection following
the steps outlined in the Server-Sent Events
specification [EVENTSOURCE].
Once the connection is re-established the Web Thing SHOULD, if possible, send any missed
property changes which occurred since the last change
specified by the Consumer in a
Last-Event-ID header.
Property values are serialized in JSON and
provided in the data field of a
Server-Sent Event serialized in
text/event-stream format. The
text/event-stream content type used in
HTTP headers is assumed to be implied by the
sse subprotocol, and the embedded
application/json content type is indicated
in contentType member of the Form (with
defaults applied).
In order to unobserve all properties, a Consumer MUST terminate the corresponding Server-Sent Events connection with the properties endpoint of the Web Thing, following the steps specified in the Server-Sent Events specification [EVENTSOURCE].
For Consumers implemented in
JavaScript [ECMASCRIPT]
and executed in a runtime which exposes the
EventSource interface, a Server-Sent
Events connection can be terminated using the
close() method on an
EventSource [EVENTSOURCE]
object.
lampPropertiesSource.close();
The HTTP SSE Profile uses Server-Sent Events [EVENTSOURCE] as a mechanism for Consumers to subscribe to events emitted by a Web Thing.
Consumers are not required
to implement the
EventSource JavaScript API from the
Server-Sent Events specification in order to conform with
this profile. Any programming language may be used to
consume an event stream.
The URL of an event resource to be used when subscribing to an Event MUST be obtained from a Thing Description by locating a Form inside the corresponding EventAffordance for which:
op member contains the value
subscribeeventhref member is
http or https
subprotocol member has a value
of ssecontentType member is
application/jsonThe
resolved value of the href member MUST then be used as the URL of the event
resource.
In order to subscribe to an Event, a Consumer MUST follow the Server-Sent Events [EVENTSOURCE] specification to open a connection with the Web Thing at the URL of the event resource.
This involves the Consumer sending an HTTP request to the Web Thing with:
GETAccept header set to
text/event-streamConnection header set to
keep-aliveGET /things/lamp/events/overheated HTTP/1.1
Host: mythingserver.com
Accept: text/event-stream
Connection: keep-alive
For Consumers implemented in
JavaScript [ECMASCRIPT]
and executed in a runtime which exposes the
EventSource interface, a Server-Sent
Events connection can be initiated using the
EventSource constructor.
const overheatedEventSource = new EventSource('/things/lamp/events/overheated');
If a Web Thing receives an HTTP request following the format above and the Consumer has permission to subscribe to the corresponding Event, then it MUST follow the Server-Sent Events [EVENTSOURCE] specification to maintain an open connection with the Consumer and push event data to the Consumer as events of the specified type are emitted.
This involves the Web Thing initially sending an HTTP response to the Consumer with:
200Content-Type header set to
text/event-streamHTTP/1.1 200 OK
Content-Type: text/event-stream
Whenever
an event of the specified type occurs while the Web Thing has an open
connection with a Consumer, the Web Thing MUST send event data to the Consumer using the event
stream format in the Server-Sent Events [EVENTSOURCE]
specification. For
each message sent, the Web Thing MUST set the event field to
the name of the
EventAffordance and populate the data
field with event data, if any. The
event data MUST follow the data
schema specified in the
EventAffordance and be serialized in JSON.
The
id field SHOULD be
set to a unique identifier for the event, for use when
re-establishing a dropped connection (see below).
It
is RECOMMENDED that the
identifier is a timestamp representing the time at which
the event occurred (see Date Format for date format
constraints).
event: overheated\n
data: 90\n
id: 2021-11-16T16:53:50.817Z\n\n
If
the connection between the Consumer and Web Thing drops (except
as a result of the unsubscribeevent
operation defined below), the Consumer MUST re-establish the connection following
the steps outlined in the Server-Sent Events
specification [EVENTSOURCE].
Once
the connection is re-established the Web Thing SHOULD, if possible, send any missed
events which occurred since the last event specified by
the Consumer in a
Last-Event-ID header.
Event payloads are serialized in JSON and
provided in the data field of a
Server-Sent Event serialized in
text/event-stream format. The
text/event-stream content type used in
HTTP headers is assumed to be implied by the
sse subprotocol, and the embedded
application/json content type is indicated
in contentType member of the Form (with
defaults applied).
In order to unsubscribe from an Event, a Consumer MUST terminate the corresponding Server-Sent Events connection with the Web Thing as specified in the Server-Sent Events specification [EVENTSOURCE].
For Consumers implemented in
JavaScript [ECMASCRIPT]
and executed in a runtime which exposes the
EventSource interface, a Server-Sent
Events connection can be terminated using the
close() method on an
EventSource [EVENTSOURCE]
object.
overheatedEventSource.close();
The URL of an events resource to be used when
subscribing to all Events emitted by a Web Thing
MUST be obtained from a
Thing
Description by locating a Form
inside the top level
forms member of a Thing
Description for which:
op member contains the value
subscribealleventshref member is
http or https
subprotocol member has a value
of ssecontentType member is
application/json
The resolved value of the href member
MUST then be used as the URL of
the events resource.
In order to subscribe to all Events emitted by a Web Thing, a Consumer MUST follow the Server-Sent Events [EVENTSOURCE] specification to open a connection with the Web Thing at the URL of the events resource.
This involves the Consumer sending an HTTP request to the Web Thing with:
GETAccept header set to
text/event-streamConnection header set to
keep-aliveGET /things/lamp/events HTTP/1.1
Host: mythingserver.com
Accept: text/event-stream
Connection: keep-alive
For Consumers implemented in
JavaScript [ECMASCRIPT]
and executed in a runtime which exposes the
EventSource interface, a Server-Sent
Events connection can be initiated using the
EventSource constructor.
const lampEventsSource = new EventSource('/things/lamp/events');
If a Web Thing receives an HTTP request following the format above then it MUST follow the Server-Sent Events [EVENTSOURCE] specification to maintain an open connection with the Consumer and push event data to the Consumer for all event types for which it has permission to subscribe.
This involves the Web Thing initially sending an HTTP response to the Consumer with:
200Content-Type header set to
text/event-streamHTTP/1.1 200 OK
Content-Type: text/event-stream
Whenever an event occurs while the Web Thing has an open
connection with a Consumer, the Web Thing MUST send event data to the Consumer using the
event stream format in the Server-Sent Events
[EVENTSOURCE]
specification.
For each message sent, the Web Thing MUST set the event field to
the name of the
EventAffordance and populate the data
field with event data, if any.
The event data MUST follow the
data schema specified in the
EventAffordance and be serialized in JSON.
The id field SHOULD
be set to a unique identifier for the event, for use when
re-establishing a dropped connection (see below).
It is RECOMMENDED that the
identifier is a timestamp representing the time at which
the event occurred (see Date Format for date format
constraints).
event: overheated\n
data: 90\n
id: 2021-11-16T16:53:50.817Z\n\n
If the connection between the Consumer and Web Thing drops (except
as a result of the unsubscribeallevents
operation defined below), the Consumer MUST re-establish the connection following
the steps outlined in the Server-Sent Events
specification [EVENTSOURCE].
Once the connection is re-established the Web Thing SHOULD, if possible, send any missed
events which occurred since the last event specified by
the Consumer in a
Last-Event-ID header.
Event payloads are serialized in JSON and
provided in the data field of a
Server-Sent Event serialized in
text/event-stream format. The
text/event-stream content type used in
HTTP headers is assumed to be implied by the
sse subprotocol, and the embedded
application/json content type is indicated
in contentType member of the Form (with
defaults applied).
In order to unsubscribe from all Events, a Consumer MUST terminate the corresponding Server-Sent Events connection with the events endpoint of the Web Thing, following the steps specified in the Server-Sent Events specification [EVENTSOURCE].
For Consumers implemented in
JavaScript [ECMASCRIPT]
and executed in a runtime which exposes the
EventSource interface, a Server-Sent
Events connection can be terminated using the
close() method on an
EventSource [EVENTSOURCE]
object.
lampEventsSource.close();
This section defines the HTTP Webhook Profile, including a Protocol Binding for observing Properties and listening for Events using Webhooks.
The HTTP Webhook profile MAY be used in conjunction with the HTTP Basic Profile in order to provide operations to read and write properties and invoke, query and cancel actions.
The HTTP Webhook profile MAY be used as an alternative event mechanism to the HTTP SSE Profile.
In order to conform with the HTTP Webhook Profile, Web Things and Consumers MUST also conform with all of the assertions in the Common Constraints section.
In order to implement the HTTP Webhook profile it must be possible for both the Thing and Consumer to act as both an HTTP client and HTTP server, accessible by each other over a network. This may not be possible in all deployment scenarios.
In order to denote that a given
Web Thing conforms to
the HTTP Webhook Profile, its Thing
Description MUST have a profile
member [wot-thing-description11]
with a value of
https://www.w3.org/2022/wot/profile/http-webhook/v1.
This section defines a Protocol Binding which describes how a Consumer and a Web Thing communicate using Webhooks.
A Consumer or Web Thing conforming to the HTTP Webhook Profile MUST implement this protocol binding.
The examples provided throughout this section describe how a Consumer would communicate with a Web Thing which produces the following Thing Description [wot-thing-description11]:
{
"@context": "https://www.w3.org/2022/wot/td/v1.1",
"id": "https://mywebthingserver.com/things/lamp",
"profile": [
"https://www.w3.org/2022/wot/profile/http-webhook/v1",
],
"base": "https://mywebthingserver.com/things/lamp/",
"title": "My Lamp",
"description": "A web connected lamp",
"securityDefinitions": {
"oauth2": {
"scheme": "oauth2",
"flow": "code",
"authorization": "https://mywebthingserver.com/oauth/authorize",
"token": "https://mywebthingserver.com/oauth/token"
}
},
"security": "oauth2",
"properties": {
"on": {
"type": "boolean",
"title": "On/Off",
"description": "Whether the lamp is turned on",
"forms": [
{
"op": "observeproperty",
"href": "properties/on",
"subprotocol": "webhook",
"contentType": "application/json",
"htv:methodName": "POST"
},
{
"op": "unobserveproperty",
"href": "properties/on/{subscriptionID}",
"subprotocol": "webhook",
"htv:methodName": "DELETE"
}
]
},
"level" : {
"type": "integer",
"title": "Brightness",
"description": "The level of light from 0-100",
"unit": "percent",
"minimum" : 0,
"maximum" : 100,
"forms": [
{
"op": "observeproperty",
"href": "properties/level",
"subprotocol": "webhook",
"contentType": "application/json",
"htv:methodName": "POST"
},
{
"op": "unobserveproperty",
"href": "properties/level/{subscriptionID}",
"subprotocol": "webhook",
"htv:methodName": "DELETE"
}
]
},
},
"events": {
"overheated": {
"title": "Overheated",
"data": {
"type": "number",
"unit": "degree celsius"
},
"description": "The lamp has exceeded its safe operating temperature",
"subscription": {
"type": "object",
"properties": {
"callbackURL": {
"type": "string",
"format": "uri",
"description": "Callback URL provided by subscriber for Webhook notifications."
}
}
}
"forms": [
{
"op": "subscribeevent",
"href": "events/overheated",
"subprotocol": "webhook",
"contentType": "application/json",
"htv:methodName": "POST"
},
{
"op": "unsubscribeevent",
"href": "events/overheated/{subscriptionID}",
"subprotocol": "webhook",
"htv:methodName": "DELETE"
}
]
}
},
"forms": [
{
"op": "observeallproperties",
"href": "properties",
"subprotocol": "webhook",
"htv:methodName": "POST"
},
{
"op": "unobserveallproperties",
"href": "properties/{subscriptionID}",
"suprotocol": "webhook",
"htv:methodName": "DELETE"
},
{
"op": "subscribeallevents",
"href": "events",
"subprotocol": "webhook",
"htv:methodName": "POST"
},
{
"op": "unsubscribeallevents",
"href": "events/{subscriptionID}",
"suprotocol": "webhook",
"htv:methodName": "DELETE"
}
]
}
The URL of a property resource to be used when observing the value of a Property MUST be obtained from a Thing Description [wot-thing-description11] by locating a Form inside the corresponding PropertyAffordance for which:
op member contains the value
observepropertyhref member is
http or https
contentType member has a value of
application/jsonsubprotocol member has a value
of webhook
The resolved value of the href member
MUST then be used as the URL of
the property resource.
POST /things/lamp/properties/level HTTP/1.1
Host: mythingserver.com
Content-Type: application/json
{
callbackURL: "https://myconsumer.com/listeners/d629c54e-a919-463b-8680-602a21f91fe9"
}
If a Web Thing receives an HTTP request following the format above and the Consumer has permission to observe the corresponding Property, then upon successfully registering a callback URL it MUST send an HTTP response to the Consumer with:
HTTP/1.1 201 Created
Location: /things/properties/level/74353483-3997-437a-a4f5-84d03784e517
Whilst the property observation subscription is registered, whenever a change in the value of the observed Property occurs, the Web Thing MUST send an HTTP request to the observing Consumer with:
POSTContent-Type header set to
application/jsonLink header with the URL set to
the URL of the corresponding property resource, and
rel set to selfDate header automatically set to
the time of the property change by the user agent,
using the HTTP
Date format from [rfc9110]
POST /listeners/d629c54e-a919-463b-8680-602a21f91fe9 HTTP/1.1
Host: myconsumer.com
Date: Fri, 4 Jul 2025 12:48:00 GMT
Content-type: application/json
Link: <https://mythingserver.com/things/mylamp1/properties/level>; rel="self"
90
When a Consumer receives an HTTP request following the format above to a valid callback URL, it MUST send an HTTP response to the Web Thing with:
200 OKHTTP/1.1 200 OK
In order to cancel the observation subscription of a property, a Consumer MUST send an HTTP request to the Web Thing with:
DELETELocation header of the HTTP response
during the observeproperty
operationDELETE /things/properties/level/74353483-3997-437a-a4f5-84d03784e517 HTTP/1.1
Host: mythingserver.com
If a Web Thing receives an HTTP request following the format above, and a property observation subscription exists with the provided URL, then upon successfully cancelling the subscription the Web Thing MUST send an HTTP response to the Consumer with:
204 No
ContentHTTP/1.1 204 No Content
The URL of a properties resource to be used when
observing the values of all Properties of a Web Thing
MUST be obtained from a
Thing
Description [wot-thing-description11]
by locating a Form
inside the top level
forms member of a Thing
Description for which:
op member contains the value
observeallpropertieshref member is
http or https
contentType member has a value of
application/jsonsubprotocol member has a value
of webhook
The resolved value of the href member
MUST then be used as the URL of
the properties resource.
In order to observe changes to all Properties of a Web Thing, a Consumer MUST send an HTTP request to the Web Thing with:
POST /things/lamp/properties HTTP/1.1
Host: mythingserver.com
Content-Type: application/json
{
callbackURL: "https://myconsumer.com/listeners/aa2d8e1f-dc6a-4fe0-a5c0-a42d9f532699"
}
If a Web Thing receives an HTTP request following the format above and the Consumer has permission to observe Properties of the Thing, then upon successfully registering a callback URL it MUST send an HTTP response to the Consumer with:
201 CreatedLocation header set to a unique URL
representing the individual observation
subscription, for use by the Consumer
when later cancelling the observation of all
Properties.
HTTP/1.1 201 Created
Location: /things/properties/a84fc5df-2667-4db2-a767-feb4640f2cf7
Whilst the properties observation subscription is registered, whenever a change in the value of any observable Property occurs, the Web Thing MUST send an HTTP request to the observing Consumer with:
POSTContent-Type header set to
application/jsonLink header with the URL set to
the URL of the corresponding
PropertyAffordance, and rel set to
self
Date header automatically set to
the time of the property change by the user agent,
using the HTTP
Date format from [rfc9110]
POST /listeners/aa2d8e1f-dc6a-4fe0-a5c0-a42d9f532699 HTTP/1.1
Host: myconsumer.com
Date: Fri, 4 Jul 2025 12:56:00 GMT
Content-type: application/json
Link: <https://mythingserver.com/things/mylamp1/properties/level>; rel="self"
86
When a Consumer receives an HTTP request following the format above to a valid callback URL, it MUST send an HTTP response to the Web Thing with:
200 OKHTTP/1.1 200 OK
In order to cancel the observation of all Properties, a Consumer MUST send an HTTP request to the Web Thing with:
DELETELocation header of the HTTP response
during the observeallproperties
operationDELETE /things/properties/a84fc5df-2667-4db2-a767-feb4640f2cf7 HTTP/1.1
Host: mythingserver.com
If a Web Thing receives an HTTP request following the format above, and a properties observation subscription exists with the provided URL, then upon successfully cancelling the observation subscription the Web Thing MUST send an HTTP response to the Consumer with:
204 No
ContentHTTP/1.1 204 No Content
The URL of an event resource to be used when subscribing to an Event MUST be obtained from a Thing Description [wot-thing-description11] by locating a Form inside the corresponding EventAffordance for which:
op member contains the value
subscribeeventhref member is
http or https
contentType member has a value of
application/jsonsubprotocol member has a value
of webhookThe
resolved value of the href member MUST then be used as the URL of the event
resource.
POST /things/lamp/events/overheated HTTP/1.1
Host: mythingserver.com
Content-Type: application/json
{
callbackURL: "https://myconsumer.com/listeners/e79dd0a5-4537-4ded-a10f-bb4eb2aca28d"
}
If a Web Thing receives an HTTP request following the format above and the Consumer has permission to subscribe to the corresponding Event, then upon successfully registering a callback URL it MUST send an HTTP response to the Consumer with:
201 CreatedLocation header set to a unique URL
representing the individual event subscription, for
use by the Consumer when later
cancelling the subscription.
HTTP/1.1 201 Created
Location: /things/events/overheated/ce527faa-a5ab-4f03-8f85-e4411d13edb5
Whilst the event subscription is registered, whenever an instance of the monitored Event occurs, the Web Thing MUST send an HTTP request to the subscribed Consumer with:
POSTContent-Type header set to
application/json (only if the event has
a data payload)Link header with the URL set to
the URL of the corresponding event resource, and
rel set to selfDate header automatically set to
the time the event occurred by the user agent, using
the HTTP
Date format from [rfc9110]
If the event does not include a data payload then the
Content-Type header of the request
SHOULD NOT be set, and the body
should be empty.
A valid JSON value — such as
null, empty quotation marks
(""), or empty braces ({}) —
could be a valid data payload and is not considered to
be an "empty" body.
POST /listeners/e79dd0a5-4537-4ded-a10f-bb4eb2aca28d HTTP/1.1
Host: myconsumer.com
Date: Fri, 4 Jul 2025 16:46:00 GMT
Content-type: application/json
Link: <https://mythingserver.com/things/mylamp1/events/overheated>; rel="self"
90
When a Consumer receives an HTTP request following the format above to a valid callback URL, it MUST send an HTTP response to the Web Thing with:
200 OKHTTP/1.1 200 OK
In order to cancel the subscription to an Event, a Consumer MUST send an HTTP request to the Web Thing with:
DELETELocation header of the HTTP response
during the subscribeevent operationDELETE /things/events/overheated/ce527faa-a5ab-4f03-8f85-e4411d13edb5 HTTP/1.1
Host: mythingserver.com
If a Web Thing receives an HTTP request following the format above, and an event subscription exists with the provided URL, then upon successfully cancelling the subscription the Web Thing MUST send an HTTP response to the Consumer with:
204 No
ContentHTTP/1.1 204 No Content
The URL of an events resource to be used when
subscribing to all Events of a Web Thing
MUST be obtained from a
Thing
Description [wot-thing-description11]
by locating a Form
inside the top level
forms member of the Thing
Description for which:
op member contains the value
subscribealleventshref member is
http or https
contentType member has a value of
application/jsonsubprotocol member has a value
of webhook
The resolved value of the href member
MUST then be used as the URL of
the events resource.
In order to subscribe to all Events of a Web Thing, a Consumer MUST send an HTTP request to the Web Thing with:
POST /things/lamp/events HTTP/1.1
Host: mythingserver.com
Content-Type: application/json
{
callbackURL: "https://myconsumer.com/listeners/bdd2aa13-387b-4c97-9725-52294a9fa5a9"
}
If a Web Thing receives an HTTP request following the format above and the Consumer has permission to subscribe to Events of the Thing, then upon successfully registering a callback URL it MUST send an HTTP response to the Consumer with:
201 CreatedLocation header set to a unique URL
representing the individual event subscription, for
use by the Consumer when later
cancelling the subscription.
HTTP/1.1 201 Created
Location: /things/events/929dbb69-eb66-46df-a0fe-93701d82e7ea
Whilst the events subscription is registered, whenever an event occurs, the Web Thing MUST send an HTTP request to the subscribed Consumer with:
POSTContent-Type header set to
application/json (only if the event
contains a data payload)Link header with the URL set to
the URL of the corresponding event resource, and
rel set to selfDate header automatically set to
the time the event occurred by the user agent, using
the HTTP
Date format from [rfc9110]
If the event does not include a data payload then the
Content-type header of the request
SHOULD NOT be set, and the body
should be empty.
A valid JSON value — such as
null, empty quotation marks
(""), or empty braces ({}) —
could be a valid data payload and is not considered to
be an "empty" body.
POST /listeners/bdd2aa13-387b-4c97-9725-52294a9fa5a9 HTTP/1.1
Host: myconsumer.com
Date: Fri, 4 Jul 2025 17:04:00 GMT
Content-type: application/json
Link: <https://mythingserver.com/things/mylamp1/events/overheated>; rel="self"
86
When a Consumer receives an HTTP request following the format above to a valid callback URL, it MUST send an HTTP response to the Web Thing with:
200 OKHTTP/1.1 200 OK
In order to cancel the subscription to all Events, a Consumer MUST send an HTTP request to the Web Thing with:
DELETELocation header of the HTTP response
during the subscribeallevents
operationDELETE /things/events/929dbb69-eb66-46df-a0fe-93701d82e7ea HTTP/1.1
Host: mythingserver.com
If a Web Thing receives an HTTP request following the format above, and an events subscription exists with the provided URL, then upon successfully cancelling the events subscription the Web Thing MUST send an HTTP response to the Consumer with:
204 No
ContentHTTP/1.1 204 No Content
The privacy considerations of the WoT Architecture [wot-architecture11] and WoT Thing Description [wot-thing-description11] specifications SHOULD be taken into account.
Please also see WoT Security and Privacy Guidelines [wot-security] for implementation advice.
The security considerations of the WoT Architecture [wot-architecture11] and WoT Thing Description [wot-thing-description11] specifications SHOULD be taken into account.
Please also see WoT Security and Privacy Guidelines [wot-security] for implementation advice.
The values of
title and description members at all
levels of a Thing Description may be
used to generate a user interface and SHOULD therefore be human readable strings which
can also be rendered by assistive technologies when
necessary.
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in: