Changelog for the HTTP API

Automatic thing creation for gateway or stand-alone devices authenticating with proper device certificates

The new exists filter function was added to the connectivity placeholders. With it, you can distinguish between automatically creating gateway and stand-alone devices, or edge and virtual devices that run behind a gateway. Bosch IoT Hub sends the gateway_id header only when automatically creating a device behind a gateway.

You can use the incomingConditions section in the payload mapping definition to distinguish for which type of device the mapping is active:

  • Add fn:filter(header:gateway_id, 'exists', 'false') for gateways and stand-alone devices.
  • Add fn:filter(header:gateway_id, 'exists') for edge devices behind a gateway.

Example of a connection which enables automatic thing creation for gateway or stand-alone devices:

{
  "id": "<your-connection-id>",
  "name": "Devices via Bosch IoT Hub",
  "connectionType": "amqp-10",
  "connectionStatus": "open",
  "uri": "amqps://messaging:xxx_hub:xxx@messaging.bosch-iot-hub.com:5671",
  "sources": [
    {
      "addresses": [
        "telemetry/xxx_hub",
        "event/xxx_hub"
      ],
      "consumerCount": 1,
      "authorizationContext": [
        "integration:xxx_things:hub"
      ],
      "enforcement": {
        "input": "{{ header:device_id }}",
        "filters": [
          "{{ thing:id }}"
        ]
      },
      "acknowledgementRequests": {
        "includes": [],
        "filter": "fn:filter(header:qos,'ne','0')"
      },
      "headerMapping": {},
      "payloadMapping": [
        "Ditto",
        "implicitStandaloneThingCreation",
        "status"
      ],
      "replyTarget": {
        "address": "{{ header:reply-to }}",
        "headerMapping": {
          "to": "command/xxx_hub/{{ thing:id }}",
          "subject": "{{ header:subject | fn:default(topic:action-subject) | fn:default(topic:criterion) }}-response",
          "correlation-id": "{{ header:correlation-id }}"
        },
        "expectedResponseTypes": [
          "error",
          "response"
        ],
        "enabled": true
      }
    },
    {
      "addresses": [
        "command_response/xxx_hub/replies"
      ],
      "consumerCount": 1,
      "authorizationContext": [
        "integration:xxx_things:hub"
      ],
      "headerMapping": {
        "correlation-id": "{{ header:correlation-id }}",
        "status": "{{ header:status }}"
      },
      "replyTarget": {
        "enabled": false
      }
    }
  ],
  "targets": [
    {
      "address": "command/xxx_hub",
      "topics": [
        "_/_/things/live/commands",
        "_/_/things/live/messages"
      ],
      "authorizationContext": [
        "integration:xxx_things:hub"
      ],
      "headerMapping": {
        "to": "command/xxx_hub/{{ thing:id }}",
        "reply-to": "{{ fn:default('command_response/xxx_hub/replies') | fn:filter(header:response-required,'ne','false') }}",
        "subject": "{{ header:subject | fn:default(topic:action-subject) }}",
        "correlation-id": "{{ header:correlation-id }}"
      }
    },
    {
      "address": "command/xxx_hub",
      "topics": [
        "_/_/things/twin/events",
        "_/_/things/live/events"
      ],
      "authorizationContext": [
        "integration:xxx_things:hub"
      ],
      "headerMapping": {
        "to": "command/xxx_hub/{{ thing:id }}",
        "subject": "{{ header:subject | fn:default(topic:action-subject) }}",
        "correlation-id": "{{ header:correlation-id }}"
      }
    }
  ],
  "clientCount": 1,
  "failoverEnabled": true,
  "validateCertificates": true,
  "processorPoolSize": 5,
  "mappingDefinitions": {
    "implicitStandaloneThingCreation": {
      "mappingEngine": "ImplicitThingCreation",
      "options": {
        "thing": {
          "thingId": "{{ header:device_id }}",
          "_policy": {
            "entries": {
              "DEVICE": {
                "subjects": {
                  "integration:{{solution:id}}:hub": {
                    "type": "iot-things-integration"
                  }
                },
                "resources": {
                  "policy:/": {
                    "revoke": [],
                    "grant": [
                      "READ"
                    ]
                  },
                  "thing:/": {
                    "revoke": [],
                    "grant": [
                      "READ",
                      "WRITE"
                    ]
                  },
                  "message:/": {
                    "revoke": [],
                    "grant": [
                      "READ",
                      "WRITE"
                    ]
                  }
                }
              },
              "DEFAULT": {
                "subjects": {
                  "iot-suite:/service-instance.{{solution:package-service-instance-id}}.iot-things": {
                    "type": "suite-auth"
                  }
                },
                "resources": {
                  "policy:/": {
                    "revoke": [],
                    "grant": [
                      "READ",
                      "WRITE"
                    ]
                  },
                  "thing:/": {
                    "revoke": [],
                    "grant": [
                      "READ",
                      "WRITE"
                    ]
                  },
                  "message:/": {
                    "revoke": [],
                    "grant": [
                      "READ",
                      "WRITE"
                    ]
                  }
                }
              }
            }
          }
        },
        "commandHeaders": {
          "reply-to": "command/xxx_hub"
        }
      },
      "incomingConditions": {
        "honoRegistration": "fn:filter(header:hono_registration_status, 'eq', 'NEW')",
        "notBehindGateway": "fn:filter(header:gateway_id, 'exists', 'false')"
      }
    },
    "status": {
      "mappingEngine": "ConnectionStatus",
      "options": {
        "thingId": "{{ header:device_id }}"
      }
    }
  },
  "tags": [
    "bosch-iot-hub"
  ]
}

tip Find an example for enabling the mapper via Things UI at Concepts > Connections > Automatically create things when a new device is registered.

Announcements for an subject expiration in a policy

The policies resources allow to store additional information in order to support announcements related to the subject expiration in a policy.

Example of a timely limited “guest” entry:

{
	"subjects": {
		"bosch:xxx-a-Bosch-id-xxx": {
			"type": "Bosch ID",
			"expiry": "2021-05-01T12:00:00Z",
			"announcement": {
				"beforeExpiry": "1d",
				"whenDeleted": true
			}
		}
	},
	"resources": {
		"thing:/": {
			"grant": [
				"READ"
			],
			"revoke": []
		}
	}
}

tip Find an example at Optional time limit in policy.

New merge functionality for things resources

The things resource and all of its subresources allow to merge an existing thing with the thing provided in the request payload by using the newly introduced HTTP PATCH method. Those parts that are not affected by the merge are not changed.

For example, it is now possible to update multiple properties of different features in a single request while not touching unchanged properties. Or you may add or update an attribute and a feature property in the same request without overwriting the complete thing.

The request payload of such a merge update has to be provided in JSON merge patch format. In short, a JSON merge patch resembles the original JSON structure of a thing and the fields provided in the patch are added to or updated in the existing thing.

note Please note however, that null values have a special meaning when applying a merge patch. A null value indicates the removal of existing fields in the updated thing. For more details and examples please refer to RFC-7396.

Concerning the permissions required to execute a PATCH, the authorized subject needs to have WRITE permission at all resources that are changed by the merge. Consequently, if the permissions is missing for some part of the merge, the merge is rejected and not applied at all.

Please also refer to the API documentation of the new PATCH method supporting the new content type application/merge-patch+json for more information.
E.g. to apply a merge at the things root resource, see
PATCH /things​/{thingId}​

New actions for policies

The policies resources allow automatically injecting or removing of a subject calculated with information extracted from the authenticated JSON Web Token (JWT).

tip Find details about the activateTokenIntegration action and the deactivateTokenIntegration action at Concepts > Policy as well as the Things HTTP API docs.

New option to define a search index per namespace

For namespaces which already exist at the time that we introduce the possibility to edit a search index, all indexable fields are applied.

For new namespaces, the user interface will guide you to make a selection. In case of doubt, choose “default” and change it later, e.g. when your business solution decides which fields are used in their search requests. See more at Manage the search index of a namespace.

note In case you need to edit the search index via API, see the Solutions resource PUT /solutions​/{solutionId}​/namespaces​/{namespaceId}.

New desired properties

The features resources allow to create, read, update and delete desiredProperties along with the other properties.

Please note however, that besides persisting the desired properties, and indexing the fields for search requests, filtering etc. for the time being, the Bosch IoT Things service does not implement their further processing. Such functionality will come with future releases.

tip Such desiredProperties fields can be used additionally or alternatively to other properties within get thing requests, search or count conditions, or filters.
Like for all other fields of a thing, the permission to read and write those fields is controlled via the policy.

New connection mapper for implicit thing creation

The new connection mapper is useful in case you want your connection to automatically create a thing as soon as the Bosch IoT Hub registers a device via a gateway. The gateway itself needs to enable such functionality, e.g. with the setting "authorities":["auto-provisioning-enabled"] stored in the Bosch IoT Hub device registry.

Example The following example connection holds the options for the implicitThingCreation.

{
  "name": "Devices via Bosch IoT Hub",
  "connectionType": "amqp-10",
  "connectionStatus": "open",
  "uri": "amqps://messaging-username@messaging.bosch-iot-hub.com:5671",
  "sources": [ ... ],
  "targets": [ ... ],
  "clientCount": 1,
  "failoverEnabled": true,
  "validateCertificates": true,
  "mappingDefinitions": {
    "status": {
      "mappingEngine": "ConnectionStatus",
      "options": {
        "thingId": "{{ header:device_id }}"
      }
    },
 	"implicitThingCreation": {
 		"mappingEngine": "ImplicitThingCreation",
 		"options": {
 			"thing": {
 				"thingId": "{{ header:device_id }}",
 				"_copyPolicyFrom": "{{ header:gateway_id }}",
 				"attributes": {
 					"Info": {
 						"gatewayId": "{{ header:gateway_id }}"
 					}
 				}
 			},
 			"commandHeaders": {
 				"reply-to": "command/your-Hub-tenant-ID"
 			}
 		},
 		"incomingConditions": {
 			"exampleCondition": "fn:filter(header:hono_registration_status, 'eq', 'NEW')"
 		}
 	}
 },
  "tags": [
    "bosch-iot-hub"
  ]
}

tip However, the easy way is to configure the template for the implicit thing creation via the Things UI > tab Connections/Integrations > connection Devices via Bosch IoT Hub.

By default, we will create a thing with the given device ID, a policy, using the function to copy the policy of the gateway, and an attribute named Info, which documents the gateway ID.

New _created field for things

A _created field is set automatically for all new things.

tip This new field allowed by the thing model facilitates to search for things, which have been created at a specific time or in a specific time frame.

Example:

How many things have been created after August 24, 2020?

https://search/things/count?filter=gt(_created,"2020-08-24")

Please note, that the date must be provided in ISO-8601 format.

Older things, which do not have this _created field, can be searched with the following filter:

https://search/things/count?filter=not(exists(_created))

This can also be combined with a filter for things with the _created field:

https://search/things/count?filter=or(not(exists(_created)),gt(_created,"2020-08-24"))

New sub-resource to retrieve subject IDs aka ‘Who am I’

You can find the subject IDs for your current authentication, using the Who Am I-REST call. Find the resource in the API docs, at the end of the Policies section

See also FAQ > How to find the authorization subject IDs that I can use in policies?

Bosch IoT Things API 1 - deprecated Feb 2020 - end of support April 2021

The API version 1 is deprecated as of Feb 2020 but will be supported for another year. As soon as we drop support we will announce it with our release notes.

However, if you start from scratch please use API 2 only.

Applications using API 1 can find migration instructions at Migration from API 1 to API 2.

New sub-resource to retrieve usage numbers

The solutions resource now additionally provides the usage sub-resources, which allows you to retrieve the calculated consumption of your data volume and transactions for the current month.
See Solutions resources.

Find an example at Getting started > Booking > Manage your solution.

note If you run into limits, feel free to upgrade your plan. Otherwise, in case you run out of transactions, you will need to wait until the start of the next month.

New Definition field for things

A definition can be derived from a device abstraction - so-called Information Model - that can be modeled with Eclipse Vorto.

The definition can optionally be related to a thing and/or a thing’s feature. It holds a fully qualified identifier, which follows the pattern namespace:name:version, while the namespace does not necessarily need to be the thing’s namespace but can be any namespace (Java package namespace).

Find an example at Concepts > Things.

tip This new definition field allowed by the thing model facilitates to search for things, which have the same definition.

Custom OAuth2 authorization provider support - NEW

The Solutions resource now offers additionally clients sub-resources, e.g.

GET - PUT - DELETE   /solutions/{solutionId}/clients

GET - PUT - DELETE   /solutions/{solutionId}/clients/{clientId}

Integration of project specific custom OAuth2 authorization provider (based on OpenID Connect Discovery 1.0) can be supported upon request.
Feel free to contact us via https://bosch-iot-suite.com/support/ .

To add such a subject to a policy of a specific thing see Policies > custom subject of your openid connect authentication provider

Removed deprecated prefixed for policies

Following prefixes which have been announced deprecated since January 2018 will not be supported with our service update in September 2019:

  • https://permissions.apps.bosch-iot-cloud.com/authentication - formerly allowed for a JSON Web Token issued by Bosch IoT Permission (authentication token)
  • https://permissions.apps.bosch-iot-cloud.com/authorization - formerly allowed for a JSON Web Token issued by Bosch IoT Permission (authorization token) identity.bosch.com - formerly allowed for a JSON Web Token issued by Bosch ID
  • https://identity.bosch.com/ - formerly allowed for a JSON Web Token issued by Bosch ID accounts.google.com - formerly allowed for a JSON Web Token issued by Google
  • https://accounts.google.com - formerly allowed for a JSON Web Token issued by Google

Connection logs - new

The Solutions resource now offers additionally a logs sub-resource.

GET /solutions/{solutionId}/connections/{connectionId}/logs

The Things dashboard already offers to display such log entries

Find details at Manage your connections > Metrics > Log entries.

Search improvements

The new service release comes with various search improvements:

Among others, the new Search now supports:

  • Various internal fields, which can be used in a search filter, or to be part of your search results
    • _modified
    • _revision
    • _namespace
    • See Search - fields
  • New paging options via cursor
    • You can for example limit the first search results to <your-number> items (default 25).
    • The cursor marks the position after the last entry of the previous search to “bookmark” where to start the next set of result.
    • The paging option limit({offset},{count}) is deprecated.
      In case you still use the old option, slow queries or timeouts might occur.
      Also, the old options might be removed without further notice.
      See Search > Paging options

At this occasion, various minor bugs have also been fixed.

Connection configuration

New placeholders and placeholder functions for configuring connections. While editing the sources and targets of your connection you can make use of them.

Find details at Concepts:

Suite Auth token

A new type of Web Token for authorization at the HTTP API, namely Suite Auth token, is supported.

Namespace deletion changes

Since Dec 2018, deletion of a namespace includes the full deletion of all entities within this namespace, such as things and policies. Deleting the entities will erase them from our data store without an option to restore.

In order to avoid that some authorized subject could delete all data just by trying out our interactive HTTP API documentation, the Solutions resource does not offer any longer the operations:

  • PUT /solutions/{solutionId}/namespaces
    Creates or Updates the namespaces of a Solution
  • DELETE/solutions/{solutionId}/namespaces
    Delete all namespaces of a specific Solution

However, in case you need to delete a namespace, please use the UI. The deletion of a namespace will require a second confirmation by the user. Then, it triggers the full deletion of all entities within this namespace. The progress bar displays an estimation on how long the procedure might need.

Messages to Bosch IoT Hub

Bosch IoT Things is prepared to support the command-and-control pattern of Bosch IoT Hub. This allows business applications to invoke operations on the devices connected via the Hub service.

A message sent via our HTTP Messages resource can be forwarded as a command to a specific Hub address, which you can configure at the connections. The result (from the device, via Hub) is matched to the request via correlation IDs.

As message buffering is not provided. Your message can only be delivered successfully, if the Hub connection is open and a consumer is ready to receive the command at the respective point in time (e.g. within a still open HTTP adapter request timeframe).

Hub-specific configurations (e.g. special reply-to headers, subject headers, source addresses) are prepared by selecting “Bosch IoT Hub” as the connection type in the “new connection wizard”. See Manage your connections.

Open API 3

Our new interactive HTTP API description comes with a new look and feel.

Compared to Swagger version 2, the main difference at the user interface is, that “Try it out” does not submit the request any longer, but only enables the entry fields. Enter at least all “required” parameters and submit the request by clicking “Execute”.

Find details provided by the Swagger team at their online presence:
https://swagger.io/blog/news/whats-new-in-openapi-3-0/

Find our API description at https://apidocs.bosch-iot-suite.com.

Conditional requests

Sometimes it is convenient and more fault-tolerant to create, modify or delete Things or elements of Things only if these elements either already exist or not exist or are on a specific revision state prior to the execution of the request. Therefore, we introduced support for “conditional requests” based on RFC-7232.

Using conditional requests, you can define a condition - or a list of conditions - and pass these via headers to the Things service. Our system checks the conditions and only processes the request in case they match.

The supported conditional headers are:

  • If-Match
    Read or write the resource only

    • if the current entity tag matches at least one of the entity tags provided in this header

    • or if the header is * and the entity exists

  • If-None-Match
    Read or write the resource only

    • if the current entity tag does not match any of the entity tags provided in this header
    • or if the header is * and the entity does not exist

tip Find examples on using such headers at
How to work with conditional requests?

New sub-resources for connection management

The solutions resource now additionally provides sub-resources to manage you connections.
See Solutions resources.

tip The easy way is to create connections via the user interface Manage your connections.

Enforced limited data volume for Free plans

In case a service subscription for a Free plan exceeds the agreed data volume, further PUT and POST requests are hindered.
However, DELETE requests are still handled, as such actions might help to reduce the data volume and overcome the situation.

Find details on alternative options at FAQ > How to avoid limited data volume?

New Messaging timeout parameter

All sub-resources provide now the optional timeout parameter. (In previous version this was available for claiming messages only). The value defines the time (in seconds) how long to block the HTTP request and wait for a response:

  • Default value (if omitted): 60 seconds.
  • Maximum value: 600 seconds.
  • Minimum value: 0 seconds (i.e. fire-and-forget)

As a result, the Messages resources now support the request-response pattern as well as fire-and-forget semantics.

New Namespace concept

All entities need a specific namespace as a prefix of their ID.
Find a summary at Concepts > Namespace.

Accordingly we have updated the solutions resource. It can now be used to reserve various namespaces for a solution and to define a default namespace.
See Solutions resources.

tip The Manage your namespace UI was updated respectively to support you on such tasks.

Policy for a JWT as a subject

Setting a JWT issuer as a subject ID prefix is deprecated.

We recommend to adapt your existing policies according to the Policies documentation.

New HTTP API 2 - Policy for fine-gained access control

With API 2 the Access Control List is replaced with the Policy. The new concept empowers developers to describe fine-grained policies for a complete Thing or a specific Feature.
Find details at Policies and Policies resources.

Compatibility

In case you have created a Thing with API 1 and try to GET it at API 2:

  • The ACL entries become effective.
  • In the JSON representation you will see no ACL entries nor Policies,
    but with the field selector “_policy” you might be able to see the subject IDs.
  • In case you want the Thing to keep compatibility with the API 1 do not use the /policy resource.
  • Searching should work.

In case you have created a Thing with API 2 and try to GET it at API 1:

  • The Policy entries become effective.
  • In the JSON representation you will see an empty ACL field.
  • You cannot convert to API 1 schema, but will need to use the API 2 to see the subject IDs.
  • Searching will not find the things as they have no ACLs.

New field holding the last modification on a thing

The new service release comes with improvements regarding the logging of the latest modification of the Thing. The timestamp - in ISO-8601 UTC format - is set on each modification of a Thing and can be found within the _modified field.
Find details at Note on special fields.

New - counting things

The new service release comes with improvements regarding the scalability of updating the Search index.
Further, we have introduced a new sub-resource to count() the Search results.
Find details at Search resources.

New - namespace management

The new service release comes with improvements regarding the Namespace management.
You can define a default namespace, thus in case your solution does not explicitly specify a namespace upon Thing creation, the complete thing ID would not be “:yourThingID” but “yourDefaultNamespace**:**yourThingID” instead.
Find details at Manage your namespace.

Search relations was replaced with search things

With our latest update the Relations are internally mapped to Things (which provide a relation feature).
In case you miss the Search Relations resource, please have look at Search resources.

Technical client authentication

In the previous versions the signature for the authentication as technical client Authenticate as a technical client contained for POST and PUT operations the JSON body.
This is no longer the case. If you use technical client authentication with a private key, please remove the body from the signature.

Claiming message

The service provides a new REST API for claiming to enable end-users to claim Things and proof ownership thereof.

post /things/{thingId}/inbox/claim
// Initiates claiming a specific Thing in order to gain access

The concept is described at Claiming.

Corporate information Data protection notice Legal information Support Free plans