Network Working Group B. Brinckman Internet-Draft R. Mohan Intended status: Standards Track Cisco Systems Expires: 24 March 2026 B. Sanford Philips 20 September 2025 An Application Layer Interface for Non-IP device control (NIPC) draft-ietf-asdf-nipc-13 Abstract This memo describes an API that allows applications to perform operations against a gateway serving one or more devices described by an SDF model. The document describes RESTful application layer interface to perform operations on those devices, as well as a CBOR- based publish-subscribe interface for streaming data. Status of This Memo This Internet-Draft is submitted in full conformance with the provisions of BCP 78 and BCP 79. Internet-Drafts are working documents of the Internet Engineering Task Force (IETF). Note that other groups may also distribute working documents as Internet-Drafts. The list of current Internet- Drafts is at https://datatracker.ietf.org/drafts/current/. Internet-Drafts are draft documents valid for a maximum of six months and may be updated, replaced, or obsoleted by other documents at any time. It is inappropriate to use Internet-Drafts as reference material or to cite them other than as "work in progress." This Internet-Draft will expire on 24 March 2026. Copyright Notice Copyright (c) 2025 IETF Trust and the persons identified as the document authors. All rights reserved. Brinckman, et al. Expires 24 March 2026 [Page 1] Internet-Draft NIPC September 2025 This document is subject to BCP 78 and the IETF Trust's Legal Provisions Relating to IETF Documents (https://trustee.ietf.org/ license-info) in effect on the date of publication of this document. Please review these documents carefully, as they describe your rights and restrictions with respect to this document. Code Components extracted from this document must include Revised BSD License text as described in Section 4.e of the Trust Legal Provisions and are provided without warranty as described in the Revised BSD License. Table of Contents 1. Introduction . . . . . . . . . . . . . . . . . . . . . . . . 4 1.1. Scope . . . . . . . . . . . . . . . . . . . . . . . . . . 4 1.2. Non-IP Gateway . . . . . . . . . . . . . . . . . . . . . 5 1.3. Terminology . . . . . . . . . . . . . . . . . . . . . . . 6 2. Architecture . . . . . . . . . . . . . . . . . . . . . . . . 7 2.1. Overview . . . . . . . . . . . . . . . . . . . . . . . . 7 2.2. Onboarding . . . . . . . . . . . . . . . . . . . . . . . 7 2.3. Registrations . . . . . . . . . . . . . . . . . . . . . . 8 2.3.1. SDF model registrations . . . . . . . . . . . . . . . 8 2.3.2. Data application registrations . . . . . . . . . . . 8 2.4. NIPC Operations . . . . . . . . . . . . . . . . . . . . . 8 2.4.1. Properties APIs . . . . . . . . . . . . . . . . . . . 8 2.4.2. Actions . . . . . . . . . . . . . . . . . . . . . . . 8 2.4.3. Events . . . . . . . . . . . . . . . . . . . . . . . 9 2.4.4. Connection management for NIPC Operations . . . . . . 9 2.4.5. Extensions . . . . . . . . . . . . . . . . . . . . . 9 2.5. Events publish subscribe interface . . . . . . . . . . . 9 2.6. Protocols . . . . . . . . . . . . . . . . . . . . . . . . 9 2.6.1. NIPC APIs . . . . . . . . . . . . . . . . . . . . . . 10 2.6.2. NIPC publish/subscribe events . . . . . . . . . . . . 10 2.7. Paths . . . . . . . . . . . . . . . . . . . . . . . . . . 10 2.7.1. General . . . . . . . . . . . . . . . . . . . . . . . 10 2.7.2. NIPC Registrations . . . . . . . . . . . . . . . . . 11 2.7.3. NIPC Operations . . . . . . . . . . . . . . . . . . . 11 2.8. Schema . . . . . . . . . . . . . . . . . . . . . . . . . 12 2.8.1. SDF model registrations . . . . . . . . . . . . . . . 12 2.8.2. NIPC Operations . . . . . . . . . . . . . . . . . . . 12 2.8.3. SDF Name . . . . . . . . . . . . . . . . . . . . . . 13 2.8.4. Responses . . . . . . . . . . . . . . . . . . . . . . 13 3. NIPC Registrations . . . . . . . . . . . . . . . . . . . . . 14 3.1. SDF model registrations APIs . . . . . . . . . . . . . . 14 3.1.1. Register an SDF model . . . . . . . . . . . . . . . . 15 3.1.2. Get all SDF models . . . . . . . . . . . . . . . . . 15 3.1.3. Get an SDF model . . . . . . . . . . . . . . . . . . 16 3.1.4. Delete an SDF model . . . . . . . . . . . . . . . . . 16 3.1.5. Update an SDF model . . . . . . . . . . . . . . . . . 17 3.2. Data application registrations APIs . . . . . . . . . . . 17 Brinckman, et al. Expires 24 March 2026 [Page 2] Internet-Draft NIPC September 2025 3.2.1. Register a data application . . . . . . . . . . . . . 18 3.2.2. Update a data application . . . . . . . . . . . . . . 20 3.2.3. Get a data application . . . . . . . . . . . . . . . 20 3.2.4. Delete a data application . . . . . . . . . . . . . . 21 4. NIPC APIs . . . . . . . . . . . . . . . . . . . . . . . . . . 21 4.1. NIPC Property APIs . . . . . . . . . . . . . . . . . . . 22 4.1.1. Write multiple values . . . . . . . . . . . . . . . . 22 4.1.2. Read multiple values . . . . . . . . . . . . . . . . 24 4.2. NIPC Event APIs . . . . . . . . . . . . . . . . . . . . . 25 4.2.1. Enable event reporting . . . . . . . . . . . . . . . 26 4.2.2. Disable event reporting . . . . . . . . . . . . . . . 27 4.2.3. Get status of one or more events . . . . . . . . . . 27 4.2.4. Enable event reporting on a group of devices . . . . 28 4.2.5. Disable event reporting on a group of devices . . . . 29 4.2.6. Get event status on a group of devices . . . . . . . 30 4.3. NIPC Action APIs . . . . . . . . . . . . . . . . . . . . 30 4.3.1. Perform an action . . . . . . . . . . . . . . . . . . 31 4.3.2. Check action status . . . . . . . . . . . . . . . . . 31 4.4. NIPC explicit connections management APIs . . . . . . . . 32 4.4.1. Connect to a device . . . . . . . . . . . . . . . . . 32 4.4.2. Update a connection . . . . . . . . . . . . . . . . . 36 4.4.3. Disconnect from a device . . . . . . . . . . . . . . 38 4.4.4. Get connection status . . . . . . . . . . . . . . . . 39 5. NIPC Extensibility . . . . . . . . . . . . . . . . . . . . . 40 5.1. Protocol extensions . . . . . . . . . . . . . . . . . . . 41 5.2. API extensions . . . . . . . . . . . . . . . . . . . . . 41 6. NIPC Error Handling . . . . . . . . . . . . . . . . . . . . . 42 7. Publish/Subscribe Interface . . . . . . . . . . . . . . . . . 44 7.1. CDDL Definition . . . . . . . . . . . . . . . . . . . . . 44 7.2. CBOR Examples . . . . . . . . . . . . . . . . . . . . . . 46 8. Examples . . . . . . . . . . . . . . . . . . . . . . . . . . 47 8.1. Property Read/Write . . . . . . . . . . . . . . . . . . . 47 8.2. Enabling an Event . . . . . . . . . . . . . . . . . . . . 49 9. Security Considerations . . . . . . . . . . . . . . . . . . . 52 9.1. API authorization . . . . . . . . . . . . . . . . . . . . 52 10. IANA Considerations . . . . . . . . . . . . . . . . . . . . . 52 10.1. Media Type Registration . . . . . . . . . . . . . . . . 52 10.2. API extensions . . . . . . . . . . . . . . . . . . . . . 53 10.3. Well-known URIs . . . . . . . . . . . . . . . . . . . . 55 10.4. Problem Details for NIPC APIs . . . . . . . . . . . . . 56 11. References . . . . . . . . . . . . . . . . . . . . . . . . . 58 11.1. Normative References . . . . . . . . . . . . . . . . . . 58 11.2. Informative References . . . . . . . . . . . . . . . . . 60 Appendix A. OpenAPI definition . . . . . . . . . . . . . . . . . 61 Appendix B. Protocol mapping . . . . . . . . . . . . . . . . . . 91 B.1. Protocol mapping OpenAPI model . . . . . . . . . . . . . 91 B.2. Protocol map for BLE . . . . . . . . . . . . . . . . . . 93 B.3. Protocol map for Zigbee . . . . . . . . . . . . . . . . . 97 Brinckman, et al. Expires 24 March 2026 [Page 3] Internet-Draft NIPC September 2025 Appendix C. NIPC API extensions . . . . . . . . . . . . . . . . 99 C.1. NIPC API write binary blob extension . . . . . . . . . . 99 C.2. NIPC API bulk operations extension . . . . . . . . . . . 102 C.3. NIPC API write file extension . . . . . . . . . . . . . . 112 C.4. NIPC API conditional read extension . . . . . . . . . . . 117 C.5. NIPC API conditional event extension . . . . . . . . . . 123 C.6. NIPC API property extensions . . . . . . . . . . . . . . 129 Appendix D. Example SDF model with protocol mappings for BLE . . 133 Authors' Addresses . . . . . . . . . . . . . . . . . . . . . . . 136 1. Introduction 1.1. Scope Low-power sensors, actuators and other connected devices introduced in environments and use cases such as building management, healthcare, workplaces, manufacturing, logistics and hospitality are often battery-powered. With limited power budget, they may not be able to support the IP protocol on their wired or wireless interfaces, hence they support protocols that require a lower power budget. Promiment examples of such protocols are [BLE53] and [Zigbee22]. These devices typically do require to communicate with devices or applications that are connected to IP-based networking infrastructure. Therefore, applications on the IP network that need to communicate or receive telemetry from these non-IP low-power devices must do so through a gateway function on the IP network. This gateway functions then translates the communication to the non- IP protocol that the low-power device supports. +-------------+ +---------+ +--------+ | Application |<------------>| Gateway |<------------>| Non-IP | | | IP-based | | Non-IP | Device | +-------------+ Operation +---------+ Operation +--------+ Figure 1: Gateway for non-IP Devices There have been efforts to define Gateway functions for devices that support a particular protocol, such as a BLE GATT REST API for BLE Gateways ([Gatt-REST-API]), however they have been limited to a single protocol or a particular use case. In absence of an open standard describing how applications on an IP network communicate with non-IP devices, bespoke and vendor-specific implementations have proliferated. This results in parallel infrastructure of both gateways and non-IP networks being deployed on a case by case basis, each connecting separately into the IP network, with a distinct set of APIs. At the same time, wireless access points supporting both IP-based wireless connectivity as well as non-IP based wireless technologies are deployed ubiquitiously. Many of these wireless Brinckman, et al. Expires 24 March 2026 [Page 4] Internet-Draft NIPC September 2025 access points are equipped with radios that can transmit and receive different frame types, such as [BLE53] and [Zigbee22]. This specification aims to define a Gateway API for these Non-IP protocols that can be leveraged by this wireless infrastructure in order to connect Non-IP devices into IP networks. The specification aims to be extensible, in order to support existing and future non-IP protocols. A standardized Non-IP Gateway interface has following benefits: * Avoid the need for parallel Non-IP infrastructure. * Avoid the need for applications to perform bespoke integrations for different environments. * Faster and more cost-effective adoption of Non-IP devices in IP network environments. 1.2. Non-IP Gateway A non-IP gateway MUST provide at least following functions: * Authentication and authorization of application clients that will leverage the gateway API to communicate with Non-IP devices. * Access to a database of onboarded devices. Onboarding ensures that the Non-IP Gateway can identify a specific device and has sufficient context about the device to service gateway API requests. * The ability to consume an interaction model for a class of devices. This allows the gateway to understand how to interact with a device. * An API that allows for bi-directional communication to non-IP devices. * One or more channels to process requests, responses, and asymmetric communications with the non-IP radio resources (Access Points) at its disposal. * The ability to stream telemetry received from non-IP devices in real-time to applications on the IP network. The definition of the onboarding function is out of scope of this document, but can be provided by a provisioning interface such as [RFC7644] leveraging [I-D.ietf-scim-device-model]. NIPC performs operations on a device or group object, hence it requires device Brinckman, et al. Expires 24 March 2026 [Page 5] Internet-Draft NIPC September 2025 onboarding to be performed prior to performing a NIPC operation on a device. NIPC APIs will reference a device or group id generated at the time of onboarding as a unique identifier. The Application gateway is a network function, so its goal is to proxy payloads between Non-IP and IP networks. It is not intended to be a middleware function that interprets, decodes or modifies these payloads. +------------------------------------------+ | | +-----------+ Request | +---------+ | | onboarding+-------------->| SCIM | | | app |<--------------+ Server | | +-----------+ Ctrl Endpt| +---------+ | | | +-----------+ | +------------+ +-------+ +--------+ | | Control +----REST------>| NIPC +-->| AP +-->| Device | | | & | | | Gateway | +-------+ +--------+ | | Telemetry |<--pub/sub-----+ | | | Apps | | +------------+ | +-----------+ | | | Network Deployment | +------------------------------------------+ Figure 2: Basic Architecture Figure 2 shows us applications, the NIPC application layer gateway (ALG), an access point (AP), and a device (D). The applications, application layer gateway and access point are deployed on an IP- Network. The AP supports a Non-IP interface, which it uses to communicate with the device. The Application is deployed in a different administrative domain than the network elements (ALG & AP). The role of the application layer gateway is to provide a gateway function to applications wishing to communicate with non-IP devices in the network domain served by the gateway. Applications implementing Non-IP Control can leverage RESTful interfaces to communicate with Non-IP devices in the network domain and subscribe to events leveraging a CBOR-based pub/sub interface. 1.3. Terminology The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and "OPTIONAL" 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. Brinckman, et al. Expires 24 March 2026 [Page 6] Internet-Draft NIPC September 2025 2. Architecture 2.1. Overview Non-IP protocols, such as BLE or Zigbee, typically define a number of basic operations that are similar across protocols. Examples of this are read and write data. NIPC provides a unified API to support those operations. To perform NIPC operations on a device, the gateways needs 2 things: 1) Information about the instance of the device or thing: The device must be onboarded on the gateway (e.g. by means of SCIM). This allows the NIPC Gateway to retrieve the device object, identified by an id referenced in the path of the NIPC API. 2) Information about the interaction model: The Gateway must be able to perform protocol- neutral operations, and hence requires a mapping of protocol-neutral operations to protocol specific operations. These are supplied to the gateway by means of an SDF model, described in [I-D.ietf-asdf-sdf]. +------------+ | SCIM | | object | +----------------+ | {id} +---------->| | +------------+ | NIPC Operation | | - Property | | - Action | +------------+ | - Event | | SDF +---------->| | | model | +----------------+ +------------+ Figure 3: NIPC prerequisites Once these 2 prerequisites have been fulfilled, applications that are authorized can perform NIPC operations on device ids. NIPC operations are operations on properties, or constitute actions or events on devices, as per the affordances defined in an SDF model. 2.2. Onboarding In order to perform a NIPC operation on a device, the device has to have its identity declared to the NIPC gateway. We refer to this as 'onboarding'. Apart from the device identity, it is also necessary that the device object contains all required information to bootstrap trust with the device, as well as establish connectivity, as NIPC operations assume that connectivity is there. Allthough onboarding could theoretically be performed in other ways, it is strongly Brinckman, et al. Expires 24 March 2026 [Page 7] Internet-Draft NIPC September 2025 recommended to leverage [RFC7644] with [I-D.ietf-scim-device-model], as the SCIM device schema has been developed to contain all nessary attributes and extensions to support NIPC. 2.3. Registrations NIPC registrations APIs allow applications to declare information that is not related to a device instance. Registrations can be information about an interaction model for a class of devices, or information about an application that is required to interact with the gateway. 2.3.1. SDF model registrations The SDF model for a class of devices determines how a gateway may interact with these devices in a protocol-neutral way. In order to do that, the SDF model must contain protocol mappings, mapping protocol-neutral SDF affordances to protocol-specific ones as defined in [I-D.mohan-asdf-sdf-protocol-mapping]. The SDF affordances supported by the device, as well as its protocol-mappings, are provide to the gateway by means of an SDF model registration. SDF models are described in [I-D.ietf-asdf-sdf]. 2.3.2. Data application registrations An application authorized to perform NIPC operations on devices needs to be able to define which applications can receive streaming event data from the gateway. The data-app registrations API allows mapping of an event to a data app as well as a protocol. 2.4. NIPC Operations NIPC operations are protocol-neutral operations on SDF affordances, more specifically properties, actions & events. NIPC operations can happen against affordances that were registered in an SDF model. If connection management is required to execute a NIPC operation, it is assumed that the gateway implictly establishes and tears down required connections. 2.4.1. Properties APIs Property APIs allow applications perform operations on properties, such as to read or write values to them. 2.4.2. Actions Action APIs perform actions on devices, such as enabling or disabling a feature on a device. Brinckman, et al. Expires 24 March 2026 [Page 8] Internet-Draft NIPC September 2025 2.4.3. Events Event APIs allow apps to enable or disable event reporting on devices. Events are reported over the events publish/subscribe interface. 2.4.4. Connection management for NIPC Operations For protocols that require connection management before executing an operation, a NIPC gateway will perform implicit connection management. When executing a NIP operation, a NIPC Gateway can set up a connection with a device as well as tear down the connection after the operation has completed. A NIPC Gateway may support explicit connection management as well. Explicit connection management can be used by an app that wants to perform multiple NIPC operations in a single connection. Explicit connection management can be performed by calling the /devices/{id}/connections API. After establishing an explicit connection to a device, an application calls a NIPC Operation, the Gateway will leverage the existing connection and will also not tear the connection down after the operation completes. The app will have to explicitly close the connection. 2.4.5. Extensions NIPC is extendable as a NIPC gateway may want to provide a way to execute a complex set of NIPC operations in a single API call, or may want to perform an operation that can deliver an outcome more efficiently than a NIPC API. An example of an extension that uses compound operation is the bulk API. Extensions must leverage the /extensions path element. In order to assure inter-operability, extensions must be IANA registered Section 10.2. 2.5. Events publish subscribe interface Events are published on a publish/subscribe interface. Events can be of different types: * Streaming data from devices: Streaming data is activated/ deactivated with the NIPC events API * Broadcasts from devices * Connection events: Devices connecting & disconnecting 2.6. Protocols Brinckman, et al. Expires 24 March 2026 [Page 9] Internet-Draft NIPC September 2025 2.6.1. NIPC APIs NIPC is a protocol that is based on RESTful HTTP [RFC9114]. Along with HTTP headers and URIs, NIPC uses JSON [RFC7159] payloads to convey NIPC operations, such as registrations, actions, event and property operations. This is the case for both request and response parameters, as well as errors. NIPC uses the JSON media type "application/nipc+json" that is registered in Section 10.1, except for the SDF model registrations APIs, where the media type reflects the content as an SDF model, and hence is media type "application/ sdf+json". The NIPC property APIs also support the use of other media types to describe the content of the property. 2.6.2. NIPC publish/subscribe events NIPC publish/subscribe events are encoded in CBOR ([RFC8949]) and can be delivered over either: * MQTT * Webhook * Websocket 2.7. Paths 2.7.1. General The NIPC HTTP protocol is described in terms of a path relative to a Base URI. The Base URI MUST NOT contain a query string, as clients MAY append additional path information and query parameters as part of forming the request. The base URI is a URL that most often consists of the "https" protocol scheme, a domain name, and an initial path [RFC3986]. That initial path for NIPC is recommended to be /nipc. For example: "https://example.com/nipc/" Additionally a version number may be added, for example: "https://example.com/nipc/v1/" After the base or version number, the path must contain a collection identifier. The collection identifier can be one of the following: * /registrations: for NIPC registration APIs * /devices: for NIPC operations on devices Brinckman, et al. Expires 24 March 2026 [Page 10] Internet-Draft NIPC September 2025 * /groups: for NIPC operations on groups of devices * /extensions: for NIPC extension APIs The well-known URI /.well-known/nipc defined in Section 10.3 can be used to discover the base path of the NIPC APIs and the supported versions and extensions. The response to a GET request on this URI MUST be a JSON document that contains the base path, and optionally the supported versions and extension APIs. The paths MUST be a URI template as defined in [RFC6570]. The following is an example of a template defining the NIPC base path as well as supported extensions on a server. { "base_path": "/nipc", "versions": [ "/v1" ], "extensions": [ "/extensions/{id}/bulk", "/extensions/{id}/properties/blob", "/extensions/{id}/properties/file", "/extensions/{id}/properties/read/conditional", "/extensions/{id}/events/conditional", "/extensions/{id}/properties/write" ] } Figure 4: Example response for /.well-known/nipc 2.7.2. NIPC Registrations Registrations leverage the base path + /registrations. NIPC supports SDF model registrations and data-app registrations. paths: * /registrations/models * /registrations/data-apps 2.7.3. NIPC Operations Every NIPC Operations API pertains to either a device or group of devices, identified by an id, hence the id will be reflected as the first parameter in the path. For example: "https://example.com/nipc/v1/{id}" Brinckman, et al. Expires 24 March 2026 [Page 11] Internet-Draft NIPC September 2025 The second parameter in the path refers to the NIPC operation that the API will perform on the device. This can be: * properties * events * actions * extensions These are described in Section 2.4. 2.8. Schema The NIPC schema leans heavily on the SDF schema, as defined in [I-D.ietf-asdf-sdf]. NIPC operations map directly to SDF affordances. 2.8.1. SDF model registrations In order to perform a NIPC operation on a device, an SDF interaction model needs to be declared that provides protocol mappings for the SDF affordances the operations will be performed on. The SDF model can be registered by means of a registrations API POST with the SDF model in the body of the request. A registered SDF model can be fetched by a registrations API GET with an sdfReference. 2.8.2. NIPC Operations NIPC operations require 2 key parameters: 1) A device ID identifying the device the operation should be executed on 2) an SDF reference for the SDF affordance the operations pertains to 2.8.2.1. Device ID All NIPC operations are executed against a device or a group of devices. Devices or groups of devices are identified by a unique uuid. +===========+=====+======+======================================+ | Attribute | Req | Type | Example | +===========+=====+======+======================================+ | id | T | uuid | 12345678-1234-5678-1234-56789abcdef4 | +-----------+-----+------+--------------------------------------+ Table 1: Definition of a device our group of devices Brinckman, et al. Expires 24 March 2026 [Page 12] Internet-Draft NIPC September 2025 Id is the unique uuid of the device. This id is generated when registering the device, for example against a SCIM server. As such, this id is a common identifier, known both to the application as well as the NIPC Server. 2.8.3. SDF Name NIPC operations happen against SDF affordances and are referenced with an global sdfName, which is the full path including the namespace. The operations are either Properties, Events or Actions and their references are of type string For example: +===========+=====+========+===================================+ | Attribute | Req | Type | Example | +===========+=====+========+===================================+ | Property | T | string | https://example.com/heartrate#/ | | | | | sdfObject/thermostat/sdfProperty/ | | | | | temperature | +-----------+-----+--------+-----------------------------------+ Table 2: Definition of a NIPC operation on a property 2.8.4. Responses A NIPC Gateway will respond to a NIPC operation request synchronously, and provide the result of the completed operation in the HTTP response. The exception to the above are NIPC extensions, Section 5.2. These contain compound statements, and thus require the gateway to execute multiple NIPC operations. In this case the NIPC gateway will return HTTP status code 202 after receiving the request and verifying it is able to execute it. The client can then perform an HTTP GET of the extensions API to get the execution status for the request. If a callback URL address was defined in the request, the NIPC Gateway can optionally perform a callback with a response to the compound request after the compound statement completes. Actions also follow an asynchronous pattern, returning HTTP status code 202 when the action is accepted, along with a Location header pointing to the action instance for status tracking. Brinckman, et al. Expires 24 March 2026 [Page 13] Internet-Draft NIPC September 2025 A failure response will consist of a HTTP status code of 4xx or 5xx, and will follow the [RFC9457] Problem Details format with application/problem+json media type. The response will contain a type field with a URI identifying the error type, and a human- readable detail field. The type field is a URI and is described in Section 6. Failure response: Example of a failure response: =============== NOTE: '\\' line wrapping per RFC 8792 =============== { "type": "https://www.iana.org/assignments/nipc-problem-types#inval\ \id-id", "status": 400, "title": "Invalid Device ID", "detail": "Device ID 12345678-1234-5678-1234-56789abcdef4 does not\ \ exist or is not a device" } Figure 5: Example failure response where- * "type" is a URI identifying the specific error type * "status" is the HTTP status code * "title" is a brief, human-readable summary of the error type * "detail" is a human-readable explanation specific to this occurrence 3. NIPC Registrations NIPC allows an application to register an SDF model for a class of devices, as well as a data application that will receive streaming data from the gateway. 3.1. SDF model registrations APIs These APIs allow applications to register an SDF model for a class of devices. These APIs use the application/sdf+json media type, as described in Section 7.1 of [I-D.ietf-asdf-sdf]. Brinckman, et al. Expires 24 March 2026 [Page 14] Internet-Draft NIPC September 2025 3.1.1. Register an SDF model Method: POST /registrations/models Description: Registers one or more SDF models for a class of devices Request Body: * an SDF document in JSON format containing one of more sdfThings or sdfObjects, similar to the example in Appendix D. Response: Example of a response: [ { "sdfName": "https://example.com/heartrate#/sdfObject/healthsensor" } ] Figure 6: Example of a response to an SDF model registration where- * "sdfName" is the name of the top-level sdfThing or sdfObject in the SDF model 3.1.2. Get all SDF models Method: GET /registrations/models Description: Gets all SDF models registered with the gateway Response: Example of a response: [ { "sdfName": "https://example.com/heartrate#/sdfObject/healthsensor" }, { "sdfName": "https://example.com/thermometer#/sdfObject/thermometer" } ] Figure 7: Example get all SDF models response Brinckman, et al. Expires 24 March 2026 [Page 15] Internet-Draft NIPC September 2025 where- * "sdfName" is the name of the top-level sdfThing or sdfObject in the SDF model 3.1.3. Get an SDF model Method: GET /registrations/models{?sdfName} Description: Gets an SDF model registered with the gateway Query Parameters: * sdfName: the name of the top-level sdfThing or sdfObject in the SDF model. Response: The SDF model is returned in JSON format, similar to the example in Appendix D. 3.1.4. Delete an SDF model Method: DELETE /registrations/models{?sdfName} Description: Deletes an SDF model registered with the gateway Query Parameters: * sdfName: the name of the top-level sdfThing or sdfObject in the SDF model. Response: Example of a response: { "sdfName": "https://example.com/heartrate#/sdfObject/healthsensor" } Figure 8: Example delete SDF model response where- * "sdfName" is the name of the top-level sdfThing or sdfObject in the SDF model Brinckman, et al. Expires 24 March 2026 [Page 16] Internet-Draft NIPC September 2025 3.1.5. Update an SDF model Method: PUT /registrations/models{?sdfName} Description: Updates an SDF model registered with the gateway Query Parameters: * sdfName: the name of the top-level sdfThing or sdfObject in the SDF model. Request Body: * an SDF model in JSON format, similar to the example in Appendix D. Response: Example of a response: { "sdfName": "https://example.com/heartrate#/sdfObject/healthsensor" } Figure 9: Example update SDF model response where- * "sdfName" is the name of the top-level sdfThing or sdfObject in the SDF model 3.2. Data application registrations APIs These APIs allow applications to register a data application that will receive streaming data from the gateway. These APIs operate on a data app ID. This ID corresponds to the endpoint app ID of the telemetry endpoint app that is registered with the SCIM server. The endpoint app is defined in Section 6 of [I-D.ietf-scim-device-model]. Apart from the endpoint, the API also registers the protocol the data-app supports. These can be one of the following: * mqttClient: The data-app is an MQTT client, which means that the gateway is an MQTT broker. * mqttBroker: The data-app is an MQTT broker. The registration API has to include the MQTT broker configuration data, such as the URI, credentials and MQTT topic to publish to. Brinckman, et al. Expires 24 March 2026 [Page 17] Internet-Draft NIPC September 2025 * webhook: The data-app supports a webhook the gateway can pusbish to. The registration API has to include the webhook URI & credentials. * websocket: The data-app supports a websocket interface. The registration API has to include the websocket URI & credentials. 3.2.1. Register a data application Method: POST /registrations/data-apps{?dataAppId} Description: Registers a data application with the gateway Query Parameters: * dataAppId: the id of the data application Request Body: * events: a list of events that the data application wants to receive streaming data for. The request body also contains one of the following: * mqttClient: a boolean that denotes that the data application is an MQTT client that will receive streaming data over MQTT * mqttBroker: an object that contains the MQTT broker information where the broker will publish the streaming data. - URI: the URI of the MQTT broker - username: the username to authenticate with the MQTT broker - password: the password to authenticate with the MQTT broker - brokerCACert: the base64-encoded CA certificate of the MQTT broker (optional) - customTopic: By default, the topic will be composed of data- app///. You can configure a custom topic to publish the streaming data to (optional) * webhook: an object that contains a webhook URL along with any credentials that are required to authenticate the webhook. The webhook URL is the endpoint where the streaming data will be sent. Brinckman, et al. Expires 24 March 2026 [Page 18] Internet-Draft NIPC September 2025 - URI: the webhook URL - headers: An object that contains the headers to be sent with the webhook request. The headers can contain any authentication information required by the webhook server. - serverCACert: the base64-encoded CA certificate of the webhook server (optional) * websocket: an object that contains a websocket URL along with any credentials that are required to authenticate the websocket. The websocket URL is the endpoint where the streaming data will be sent. - URI: the websocket URL - headers: An object that contains the headers to be sent with the websocket request. The headers can contain any authentication information required by the websocket server. - serverCACert: the base64-encoded CA certificate of the websocket server (optional) Example of a request body: =============== NOTE: '\' line wrapping per RFC 8792 ================ { "events": [ { "event": "https://example.com/heartrate#/sdfObject/healthsenso\ r/sdfEvent/fallDetected" } ], "mqttClient": true } Figure 10: Example with mqttClient Example of a request body for a data application that is an MQTT broker: Brinckman, et al. Expires 24 March 2026 [Page 19] Internet-Draft NIPC September 2025 =============== NOTE: '\' line wrapping per RFC 8792 ================ { "events": [ { "event": "https://example.com/heartrate#/sdfObject/healthsenso\ r/sdfEvent/fallDetected" } ], "mqttBroker": { "URI": "mqtt.example.com:1883", "username": "user", "password": "password", "customTopic": "custom/topic" } } Figure 11: Example with mqttBroker Response: If successful, the response will be identical to the request body. 3.2.2. Update a data application Method: PUT /registrations/data-apps{?dataAppId} Description: Updates a data application with the gateway Query Parameters: * dataAppId: the id of the data application Request Body: Same as the request body for the register data application API. Response: If successful, the response will be identical to the request body. 3.2.3. Get a data application Method: GET /registrations/data-apps{?dataAppId} Description: Gets a data application registered with the gateway Query Parameters: Brinckman, et al. Expires 24 March 2026 [Page 20] Internet-Draft NIPC September 2025 * dataAppId: the id of the data application Response: The response will be identical to the request body for the register data application API. 3.2.4. Delete a data application Method: DELETE /registrations/data-apps{?dataAppId} Description: Deletes a data application registered with the gateway Query Parameters: * dataAppId: the id of the data application Response: The response will be identical to the request body for the register data application API. 4. NIPC APIs The primary goal of the NIPC APIs is to perform operations on SDF Affordances, such as properties, events & actions.This allows a user of the NIPC API to get or update properties of devices, perform actions on devices, and consume events from devices. The NIPC APIs consists of 3 main collections which reflect SDF Affordances as defined in Section 1.2 of [I-D.ietf-asdf-sdf]: * NIPC Property APIs: These APIs allow applications to get and update device properties. * NIPC Event APIs: These APIs allow applications to enable or disable event reporting on devices. * NIPC Action APIs: These APIs allow applications to perform actions on devices. Brinckman, et al. Expires 24 March 2026 [Page 21] Internet-Draft NIPC September 2025 One or more SDF models must be registered in order to use these NIPC Property, Event and Action APIs. The SDF models can be a top-level sdfThing with multiple sdfObjects or a top-level sdfObject. These APIs depend on the SDF affordances (i.e. sdfProperty, sdfEvent and sdfAction) defined in the SDF model and a device ID that is defined in [I-D.ietf-scim-device-model]. An SDF affordance can be referenced using the global name of the SDF affordance as described in Section 4 of [I-D.ietf-asdf-sdf]. The SDF global name will be used against the registered SDF model to determine the protocol-specific protocolmap that the NIPC API will operate on. The SDF global name is also percent-encoded as per Section 2.1 of [RFC3986]. 4.1. NIPC Property APIs These APIs allow applications to get and update device properties. These operations may require a connection to the device to be established. This connection can be established as part of the same API call implicitly. If a connection is already active for this device, the existing connection willi be leveraged without modifying it. These APIs support multiple media types based on Content-Type and Accept headers to accommodate different data formats. When using application/nipc+json, the request and response bodies follow the format shown in the examples above, with binary data encoded as base64 in the "value" field. For other content types, the data is transmitted according to the specific format requirements of that media type. 4.1.1. Write multiple values Method: PUT /devices/{id}/properties{?propertyName} Description: Write values to one or more properties on a device Parameters: * id: the id of the device Query Parameters: Brinckman, et al. Expires 24 March 2026 [Page 22] Internet-Draft NIPC September 2025 * propertyName: a single property to update. If this parameter is provided, the request body can contain any conten type payload with the value to write to the property. If this parameter is not provided, the request body MUST contain an application/nipc+json payload with an array of properties to update, each containing a property and a value. Request Body: * If the query parameter propertyName is provided, the request body can contain any content type payload with the value to write to the property. The value is encoded as per the content type of the payload. or * an array of properties to update, each containing a property and a value. The value is the raw binary data, encoded in base64 with padding as per Section 5 of [RFC4648]. Example body updating multiple properties: =============== NOTE: '\' line wrapping per RFC 8792 ================ [ { "property": "https://example.com/heartrate#/sdfObject/thermostat\ /sdfProperty/temperature", "value": "dGVzdA==" }, { "property": "https://example.com/heartrate#/sdfObject/thermostat\ /sdfProperty/humidity", "value": "eGVzdB==" } ] Figure 12: Example updating multiple properties Response: If the Accept header is set to application/nipc+json, the response will be an array with a status field set to 200 for each property that was updated, or a problem type object for each property that failed to update. Brinckman, et al. Expires 24 March 2026 [Page 23] Internet-Draft NIPC September 2025 If the Accept header is set to any other media type and the propertyName query parameter is provided, the response will be 204 No Content with no body. Example of a response: =============== NOTE: '\' line wrapping per RFC 8792 ================ [ { "status": 200 }, { "type": "https://www.iana.org/assignments/nipc-problem-types#inv\ alid-property", "status": 400, "title": "Invalid Property", "detail": "Property https://example.com/heartrate#/sdfObject/the\ rmostat/sdfProperty/temperature does not exist or is not writable" } ] Figure 13: Example update multiple properties response where- * "properties" is an array of properties that were updated, each containing a property and a value A failure will generate a standard failed response. Please refer to Figure 5 definition of failed response. 4.1.2. Read multiple values Method: GET /devices/{id}/properties{?propertyName*} Description: Read values from one or more properties on a device Parameters: * id: the id of the device Query Parameters: * propertyName: The property to read. This can be a single property or multiple properties. If multiple properties are provided, the request body MUST contain an application/nipc+json payload with an array of properties to read. Brinckman, et al. Expires 24 March 2026 [Page 24] Internet-Draft NIPC September 2025 Response: If the Accept header is set to application/nipc+json, the response will be an array of properties, each containing a property and a value. The value is the raw binary data read from the property, encoded in base64 with padding as per Section 5 of [RFC4648]. Example of a response: =============== NOTE: '\' line wrapping per RFC 8792 ================ [ { "property": "https://example.com/heartrate#/sdfObject/thermostat\ /sdfProperty/temperature", "value": "dGVzdA==" }, { "property": "https://example.com/heartrate#/sdfObject/thermostat\ /sdfProperty/humidity", "value": "eGVzdB==" } ] Figure 14: Example read multiple properties response where- * "property" is the property that was read from * "value" is the bytes that were read in base64 encoding A failure will generate a standard failed response. Please refer to Figure 5 definition of failed response. 4.2. NIPC Event APIs These APIs allow applications to enable or disable event reporting on devices. These operations may require a connection to the device to be established. This connection can be established as part of the same API call implicitly. If a connection is already active for this device, the existing connection will be leveraged without modifying it. The event is the global name of an sdfEvent. Brinckman, et al. Expires 24 March 2026 [Page 25] Internet-Draft NIPC September 2025 The ID in the path is the id of the device or group of devices. An event can be enabled on a group of devices if it is supported by the underlying protocol. For example, if the underlying protocol is BLE, the event can be enabled on a group of devices if the event is an advertisement event or connection status event. If the data application registered for this event is an MQTT broker or client, the event is used to construct the MQTT topic for the event. The topic is constructed using the data application ID, the default namespace for the event, and the event itself. For example, if the data application ID is "12345678-1234-5678-1234-56789abcdef4" and the event is "https://example.com/thermometer#/sdfThing/thermometer/sdfEvent/ isPresent", the topic will be: =============== NOTE: '\' line wrapping per RFC 8792 ================ data-app/// data-app/12345678-1234-5678-1234-56789abcdef4/thermometer/sdfThing/\ thermometer/sdfEvent/isPresent A data application can subscribe to this topic using the topic or it can use MQTT wildcards to subscribe to data-app/+/temperature/# to receive all events for the temperature namespace. If a custom topic is provided for an MQTT broker, the custom topic is used as the MQTT topic instead. 4.2.1. Enable event reporting Method: POST /devices/{id}/events{?eventName} Description: Enables an event on a specific device Parameters: * id: the id of the device Query Parameters: * eventName: the event to enable The eventName is a URL encoded string that is the absolute URI that is the global name of an sdfEvent. Response: Brinckman, et al. Expires 24 March 2026 [Page 26] Internet-Draft NIPC September 2025 Returns HTTP status code 201 Created with a Location header pointing to the created event instance. Example of a successful response: =============== NOTE: '\' line wrapping per RFC 8792 ================ HTTP/1.1 201 Created Location: /devices/12345678-1234-5678-1234-56789abcdef4/events?insta\ nceId=87654321-4321-8765-4321-fedcba9876543 The Location header contains the URI for the created event instance, which can be used to check status or disable the event. A failure will generate a standard failed response. Please refer to Figure 5 definition of failed response. 4.2.2. Disable event reporting Method: DELETE /devices/{id}/events{?instanceId} Description: Disables an event on a specific device Parameters: * id: the id of the device or group of devices Query Parameters: * instanceId: the instance ID of the event to disable (obtained from the Location header when the event was enabled) Response: Returns HTTP status code 204 No Content on successful disable. HTTP/1.1 204 No Content A failure will generate a standard failed response. Please refer to Figure 5 definition of failed response. 4.2.3. Get status of one or more events Method: GET /devices/{id}/events{?instanceId*} Description: Get the status of one or more events on a specific device Brinckman, et al. Expires 24 March 2026 [Page 27] Internet-Draft NIPC September 2025 Parameters: * id: the id of the device or group of devices Query Parameters: * instanceId: a comma separated list of event instance IDs to filter by (optional) Response: Example of a response: =============== NOTE: '\' line wrapping per RFC 8792 ================ [ { "instanceId": "87654321-4321-8765-4321-fedcba9876543", "event": "https://example.com/heartrate#/sdfObject/healthsensor/\ sdfEvent/fallDetected" } ] Figure 15: Example get multiple events status response where- * "instanceId" is the unique instance ID for each enabled event * "event" is the event URI for each enabled event A failure will generate a standard failed response. Please refer to Figure 5 definition of failed response. 4.2.4. Enable event reporting on a group of devices Method: POST /groups/{id}/events Description: Enables an event on a group of devices Parameters: * id: the id of the group of devices Query Parameters: * eventName: the event to enable Brinckman, et al. Expires 24 March 2026 [Page 28] Internet-Draft NIPC September 2025 The eventName is a URL encoded string that is the absolute URI that is the global name of an sdfEvent. Response: Returns HTTP status code 201 Created with a Location header pointing to the created event instance. Example of a successful response: =============== NOTE: '\' line wrapping per RFC 8792 ================ HTTP/1.1 201 Created Location: /groups/12345678-1234-5678-1234-56789abcdef4/events?instan\ ceId=87654321-4321-8765-4321-fedcba9876543 The Location header contains the URI for the created event instance, which can be used to check status or disable the event. A failure will generate a standard failed response. Please refer to Figure 5 definition of failed response. 4.2.5. Disable event reporting on a group of devices Method: DELETE /groups/{id}/events{?instanceId} Description: Disables an event on a group of devices Parameters: * id: the id of the group of devices Query Parameters: * instanceId: the instance ID of the event to disable (obtained from the Location header when the event was enabled) Response: Returns HTTP status code 204 No Content on successful disable. HTTP/1.1 204 No Content A failure will generate a standard failed response. Please refer to Figure 5 definition of failed response. Brinckman, et al. Expires 24 March 2026 [Page 29] Internet-Draft NIPC September 2025 4.2.6. Get event status on a group of devices Method: GET /groups/{id}/events{?instanceId*} Description: Get the status of one or more events on a group of devices Parameters: * id: the id of the group of devices Query Parameters: * instanceId: a list of event instance IDs to filter by (optional) Response: Example of a response: =============== NOTE: '\' line wrapping per RFC 8792 ================ [ { "instanceId": "87654321-4321-8765-4321-fedcba9876543", "event": "https://example.com/heartrate#/sdfObject/healthsensor/\ sdfEvent/fallDetected" } ] Figure 16: Example get multiple group events status response where- * "instanceId" is the unique instance ID for each enabled event * "event" is the event URI for each enabled event A failure will generate a standard failed response. Please refer to Figure 5 definition of failed response. 4.3. NIPC Action APIs These APIs allow applications to perform actions on devices. These operations may require a connection to the device to be established. This connection can be established as part of the same API call implicitly. If a connection is already active for this device, the existing connection will be leveraged without modifying it. Brinckman, et al. Expires 24 March 2026 [Page 30] Internet-Draft NIPC September 2025 4.3.1. Perform an action Method: POST /devices/{id}/actions{?actionName} Description: Perform an action on a specific device Parameters: * id: the id of the device Query Parameters: * actionName: the action to perform Request Body: The request body is optional and may contain a value. The media type of the value can be defined by the underlying protocol, for example it could be octet-stream for binary data. Response: Actions are performed asynchronously. A successful request returns HTTP status code 202 Accepted with a Location header pointing to the action instance for status checking. Example of a successful response: =============== NOTE: '\' line wrapping per RFC 8792 ================ HTTP/1.1 202 Accepted Location: /devices/12345678-1234-5678-1234-56789abcdef4/actions?inst\ anceId=87654321-4321-8765-4321-fedcba9876543 The Location header contains the URI for the action instance, which can be used to check the action status. 4.3.2. Check action status Method: GET /devices/{id}/actions{?instanceId} Description: Check the status of an action on a specific device Parameters: * id: the id of the device Query Parameters: Brinckman, et al. Expires 24 March 2026 [Page 31] Internet-Draft NIPC September 2025 * instanceId: the instance ID of the action (obtained from the Location header) Response: Example of a response: { "status": "COMPLETED" } Figure 17: Example action status response where "status" indicates the current state of the action (e.g., "IN_PROGRESS" or "COMPLETED"). A failure will generate a standard failed response. Please refer to Figure 5 definition of failed response. 4.4. NIPC explicit connections management APIs A lot of protocols do not require connection management, so for these protocols, these APIs will not apply. NIPC Gateways perform implicit connection management for protocols that require connection management (such as BLE), so in principle the user of the NIPC API does not have to perform connection management. In some cases however, a user might want to keep a connection open, perform an action, evaluate the result and perform a second action based on that result. In this case it is useful to perform explicit connection management so the connections remains established to execute subsequent actions. These APIs allow applications to explicitly manage device connections. The examples in this section will be based on BLE, which requires connection management. 4.4.1. Connect to a device Method: POST /devices/{id}/connections Description: Connect to a device Parameters: * id: the id of the device Request Body: * Connection retry parameters Brinckman, et al. Expires 24 March 2026 [Page 32] Internet-Draft NIPC September 2025 * A protocol map object. In the case of BLE, if no protocol map is included, service discovery is performed to discover all supported properties when connecting to a device. Optionally, service discovery may be limited to properties defined in the "ble" protocol extension. The services to be discovered can be added in an array. Property discover can be buffered across connections, so the API also supports caching parameters. Example body of a connection without specific discovery of properties: { "retries": 3, "retryMultipleAPs": true } Figure 18: Example connection where- * "retries" defines the number of retries in case the operations does not succeed * "retryMultipleAPs" can be used in case there is an infrastructure with multiple access points or radios that can reach the device. If set to "true" a different access point may be used for retries. In case the application would like to discover specific properties of a device, a protocol mapping can be added that defines what properties should be discovered. Example body of a BLE connection with specific discovery of properties: Brinckman, et al. Expires 24 March 2026 [Page 33] Internet-Draft NIPC September 2025 { "retries": 3, "retryMultipleAPs": true, "sdfProtocolMap": { "ble": { "services": [ { "serviceID": "12345678-1234-5678-1234-56789abcdef4" } ], "cached": false, "cacheIdlePurge": 3600, "autoUpdate": true, "bonding": "default" } } } Figure 19: Example connection with explicit discovery of connections where in the BLE protocol object: * "services" is an array of services defined by their serviceIDs. * "cached" refers to whether the services need to be cached for subsequent connects, in order not to perform service discovery on each request. * "cacheIdlePurge" defines how long (in seconds) the cache should be maintained before purging. * some devices support notifications on changes in services, "autoUpdate" allows the network to update services based on notification (on by default) * "bonding" allows you to override the bonding method configured when onboarding the device Response: Success responses include a protocol mapping with an array of discovered properties, as defined in the specific protocol. For example, for BLE, this is an array of supported services, which in turn contains an array of charateristics, which in turn contains an array of descriptors, as shown in Figure 20. Brinckman, et al. Expires 24 March 2026 [Page 34] Internet-Draft NIPC September 2025 services - serviceID | |> characteristics - charactericID - flags | |> Descriptors - descriptorID Figure 20: BLE Services Example of a response: { "id": "12345678-1234-5678-1234-56789abcdef4", "sdfProtocolMap": { "ble": [ { "serviceID": "12345678-1234-5678-1234-56789abcdef4", "characteristics": [ { "characteristicID": "12345678-1234-5678-1234-56789abcdef4", "flags": [ "read", "write" ], "descriptors": [ { "descriptorID": "12345678-1234-5678-1234-56789abcdef4" } ] } ] } ] } } Figure 21: Example connection response where- * "id" is the id of the device Brinckman, et al. Expires 24 March 2026 [Page 35] Internet-Draft NIPC September 2025 * "sdfProtocolMap" contains an Array of BLE services as shown in Figure 20 A failure will generate a standard failed response. Please refer to Figure 5 definition of failed response. 4.4.2. Update a connection Method: PUT /devices/{id}/connections Description: Update cached ServiceMap for a device. Full service discovery will be performed, unless specific services are described in the API body. Parameters: * id: the id of the device Request Body: * A protocol map object. In the case of BLE, if no protocol map is included, service discovery is performed to discover all supported properties when connecting to a device. Optionally, service discovery may be limited to properties defined in the "ble" protocol extension. The services to be discovered can be added in an array. Property discover can be buffered across connections, so the API also supports caching parameters. Example body of an update connection: { "sdfProtocolMap": { "ble": { "services": [ { "serviceID": "12345678-1234-5678-1234-56789abcdef4" } ], "cached": false, "cacheIdlePurge": 3600, "autoUpdate": true } } } Figure 22: Example service discovery response where in the BLE protocol object: Brinckman, et al. Expires 24 March 2026 [Page 36] Internet-Draft NIPC September 2025 * "services" is an array of services defined by their serviceIDs * "cached" refers to whether the services need to be cached for subsequent connects, in order not to perform service discovery on each request * "cacheIdlepurge" defines how long the cache should be maintained before purging * some devices support notifications on changes in services, "autoUpdate" allows the network to update services based on notification (on by default) Response: Success responses include a protocol mapping with an array of discovered properties, as defined in the specific protocol. For example, for BLE, this is an array of supported services, which in turn contains an array of charateristics, which in turn contains an array of descriptors, as shown in Figure 20. Example of a response: Brinckman, et al. Expires 24 March 2026 [Page 37] Internet-Draft NIPC September 2025 { "id": "12345678-1234-5678-1234-56789abcdef4", "sdfProtocolMap": { "ble": [ { "serviceID": "12345678-1234-5678-1234-56789abcdef4", "characteristics": [ { "characteristicID": "12345678-1234-5678-1234-56789abcdef4", "flags": [ "read", "write" ], "descriptors": [ { "descriptorID": "12345678-1234-5678-1234-56789abcdef4" } ] } ] } ] } } Figure 23: Example connection response where- * "id" is the id of the device * "sdfProtocolMap" contains an Array of BLE services as shown in Figure 20 A failure will generate a standard failed response. Please refer to Figure 5 definition of failed response. 4.4.3. Disconnect from a device Method: DELETE /devices/{id}/connections Description: Disconnect from a device Parameters: * id: the id of the device Brinckman, et al. Expires 24 March 2026 [Page 38] Internet-Draft NIPC September 2025 Response: Returns HTTP status code 200 OK with device ID on successful disconnect. Example of a response: { "id": "12345678-1234-5678-1234-56789abcdef4" } Figure 24: Example disconnect response where "id" is the id of the device. A failure will generate a standard failed response. Please refer to Figure 5 definition of failed response. 4.4.4. Get connection status Method: GET /devices/{id}/connections Description: Get connection status for a device. Success when device(s) is/are connected, includes service map for the device if available. Failure when a device is not connected. Parameters: * id: the id of the device Response: Example of a response: Brinckman, et al. Expires 24 March 2026 [Page 39] Internet-Draft NIPC September 2025 { "id": "12345678-1234-5678-1234-56789abcdef4", "sdfProtocolMap": { "ble": [ { "serviceID": "12345678-1234-5678-1234-56789abcdef4", "characteristics": [ { "characteristicID": "12345678-1234-5678-1234-56789abcdef4", "flags": [ "read", "write" ], "descriptors": [ { "descriptorID": "12345678-1234-5678-1234-56789abcdef4" } ] } ] } ] } } Figure 25: Example connection status response where- * "id" is the id of the device * "sdfProtocolMap" contains an Array of BLE services as shown in Figure 20 A failure will generate a standard failed response. Please refer to Figure 5 definition of failed response. 5. NIPC Extensibility NIPC is extensible in two ways: * Protocol mapping: New protocol mapping can extend NIPC with support for new non-IP protocols Brinckman, et al. Expires 24 March 2026 [Page 40] Internet-Draft NIPC September 2025 * API extensions: API extensions leverage compound statements of basic NIPC action APIs to simplify common operations for applications. 5.1. Protocol extensions NIPC supports mapping protocol specific properties to NIPC properties as described in [I-D.mohan-asdf-sdf-protocol-mapping]. BLE and Zigbee are used as examples, but protocol mapping is extensible to other protocols, so now non-IP protocols can be supported by NIPC without a schema change. The protocol objects need to be extended with the new protocol as well. Protocol objects will be extended as follows: +=============+========+===========================================+ | Attribute | Type | Example | +=============+========+===========================================+ | ble | object | an object with BLE-specific properties | +-------------+--------+-------------------------------------------+ | zigbee | object | an object with Zigbee-specific properties | +-------------+--------+-------------------------------------------+ | newProtocol | object | an object with newProtocol-specific props | +-------------+--------+-------------------------------------------+ Table 3: Adding Protocol mappings In the new protocol object, protocol specific properties can be added. 5.2. API extensions /extensions The extension APIs allow for extensibility of the APIs. Extensions must be IANA registered. Extension APIs can leverage the basic NIPC defined APIs and combine them in compound statements in order to streamline application operation against devices, make operations more expediant and convenient in one API call. an example of this is the bulk API extension. They can also introduce new functionality that is specific to a use case or protocol, such as the BLE transmit API. the OpenAPI model Appendix C below, we have defined a few example extensions. The extensions can contain long running operations, such as firmware updates, or other bulk operations that can be performed on a device. For long running operations, the extension API will return a 202 Accepted status code and a location header with the URL to check the Brinckman, et al. Expires 24 March 2026 [Page 41] Internet-Draft NIPC September 2025 status of the operation. The status of the operation can be checked by calling the status extension API with the same device ID. The status extension API will return a 200 OK status code when the operation is in progress. When the operation is complete, the status extension API will return a 303 See Other status code with a location header with the URL to check the status of the operation. The GET operation on the extension API will return a 200 OK status code with the actual response once the operation is complete. 6. NIPC Error Handling The error types in the NIPC APIs use URI-based error type identifiers as defined in Section 10.4. The error types can be generic or specific to the API category. The error types are organized into the following categories: * Generic: Broadly applicable errors, including authorization, invalid identifiers, and generic failures. * Property APIs: Errors related to property APIs (read/write). * Event APIs: Errors related to event APIs (enable/disable). * Protocol specific: Errors related to protocol-specific operations. * Extension APIs: Errors related to extension APIs. The specific error types are defined in the table below: +======================+==============================+===========+ | Error Type | Description | Category | +======================+==============================+===========+ | invalid-id | Invalid device ID or gateway | Generic | | | doesn't recognize the ID | | +----------------------+------------------------------+-----------+ | invalid-sdf-url | Invalid SDF URL or SDF | Generic | | | affordance not found | | +----------------------+------------------------------+-----------+ | extension-operation- | Operation was not executed | Generic | | not-executed | since the previous operation | | | | failed | | +----------------------+------------------------------+-----------+ | sdf-model-already- | SDF model already registered | Generic | | registered | | | +----------------------+------------------------------+-----------+ | sdf-model-in-use | SDF model in use | Generic | +----------------------+------------------------------+-----------+ | property-not- | Property not readable | Property | Brinckman, et al. Expires 24 March 2026 [Page 42] Internet-Draft NIPC September 2025 | readable | | APIs | +----------------------+------------------------------+-----------+ | property-not- | Property not writable | Property | | writable | | APIs | +----------------------+------------------------------+-----------+ | event-already- | Event already enabled | Event | | enabled | | APIs | +----------------------+------------------------------+-----------+ | event-not-enabled | Event not enabled | Event | | | | APIs | +----------------------+------------------------------+-----------+ | event-not-registered | Event not registered for any | Event | | | data application | APIs | +----------------------+------------------------------+-----------+ | protocolmap-ble- | Device already connected | Protocol | | already-connected | | specific | +----------------------+------------------------------+-----------+ | protocolmap-ble-no- | No connection found for | Protocol | | connection | device | specific | +----------------------+------------------------------+-----------+ | protocolmap-ble- | BLE connection timeout | Protocol | | connection-timeout | | specific | +----------------------+------------------------------+-----------+ | protocolmap-ble- | BLE bonding failed | Protocol | | bonding-failed | | specific | +----------------------+------------------------------+-----------+ | protocolmap-ble- | BLE connection failed | Protocol | | connection-failed | | specific | +----------------------+------------------------------+-----------+ | protocolmap-ble- | BLE service discovery failed | Protocol | | service-discovery- | | specific | | failed | | | +----------------------+------------------------------+-----------+ | protocolmap-ble- | Invalid BLE service or | Protocol | | invalid-service-or- | characteristic ID | specific | | characteristic | | | +----------------------+------------------------------+-----------+ | protocolmap-zigbee- | Zigbee connection timeout | Protocol | | connection-timeout | | specific | +----------------------+------------------------------+-----------+ | protocolmap-zigbee- | Invalid Zigbee endpoint or | Protocol | | invalid-endpoint-or- | cluster ID | specific | | cluster | | | +----------------------+------------------------------+-----------+ | extension-transmit- | Invalid transmit data | Transmit | | invalid-data | | APIs | +----------------------+------------------------------+-----------+ | extension-firmware- | Firmware rollback | Extension | Brinckman, et al. Expires 24 March 2026 [Page 43] Internet-Draft NIPC September 2025 | rollback | | APIs | +----------------------+------------------------------+-----------+ | extension-firmware- | Firmware update failed | Extension | | update-failed | | APIs | +----------------------+------------------------------+-----------+ Table 4: Error Codes The appropriate HTTP status code is returned in the response. 7. Publish/Subscribe Interface The publish/subscribe interface, or data streaming interface, is an MQTT publishing interface. Pub/sub topics can be created and managed by means of the /registrations/data-apps API. In this memo, we propose the data format to be CBOR [RFC8949]. 7.1. CDDL Definition We have a CDDL [RFC8610] definition where we define the DataSubscription struct that will be used by all the messages published to the MQTT broker. The DataSubscription struct is a CBOR map that will contain the raw data in bytes and a timestamp of the data. Optionally, the message will also have a deviceID that corresponds to the SCIM ID of the device if the payload is associated to a known device. Other fields in the CDDL such as apMacAddress and rssi can be optionally included but these fields can expose the underlying network topology. Each message also has a subscription choice group that will define the type of data that is being published. Each MQTT message can be a collection of DataSubscription structs. This collection is represented as DataBatch in the CDDL. Brinckman, et al. Expires 24 March 2026 [Page 44] Internet-Draft NIPC September 2025 start = DataBatch DataBatch = [* DataSubscription] DataSubscription = { ? data: bytes, timestamp: float, ; epoch in seconds ? deviceID: text, ? apMacAddress: text, subscription } subscription = ( bleSubscription: BleSubscription // bleAdvertisement: BleAdvertisement // bleConnectionStatus: BleConnectionStatus // zigbeeSubscription: ZigbeeSubscription // rawPayload: RawPayload ) BleSubscription = { serviceID: text, characteristicID: text } BleAdvertisement = { macAddress: text, ? rssi: nint, } BleConnectionStatus = { macAddress: text, connected: bool, ? reason: int } ZigbeeSubscription = { endpointID: int, clusterID: int, attributeID: int attributeType: int } RawPayload = { contextID: text } Brinckman, et al. Expires 24 March 2026 [Page 45] Internet-Draft NIPC September 2025 7.2. CBOR Examples This section contains a few examples of the DataSubscription struct depicted in CBOR diagnostic notation. [ { "data": h'02011A020A0C16FF4C001007721F41B0392078', "deviceID": "75fde96d-886f-4ac0-a1d5-df79f76e7c9c", "timestamp": 1727484393, "bleAdvertisement": { "macAddress": "C1:5C:00:00:00:01", "rssi": -25 } } ] Figure 26: Onboarded BLE Device Advertisement [ { "data": h'02011A020A0C16FF4C001007721F41B0392078', "timestamp": 1727484393, "bleAdvertisement": { "macAddress": "C1:5C:00:00:00:01", "rssi": -25 } } ] Figure 27: Non-onboarded BLE Device Advertisement [ { "data": h'434630374346303739453036', "deviceID": "75fde96d-886f-4ac0-a1d5-df79f76e7c9c", "timestamp": 1727484393, "bleSubscription": { "serviceID": "a4e649f4-4be5-11e5-885d-feff819cdc9f", "characteristicID": "c4c1f6e2-4be5-11e5-885d-feff819cdc9f" } } ] Figure 28: BLE GATT Notification Brinckman, et al. Expires 24 March 2026 [Page 46] Internet-Draft NIPC September 2025 [ { "deviceID": "75fde96d-886f-4ac0-a1d5-df79f76e7c9c", "timestamp": 1727484393, "bleConnectionStatus": { "macAddress": "C1:5C:00:00:00:01", "connected": true } } ] Figure 29: BLE Connection status event [ { "data": h'434630374346303739453036', "deviceID": "75fde96d-886f-4ac0-a1d5-df79f76e7c9c", "timestamp": 1727484393, "zigbeeSubscription": { "endpointID": 1, "clusterID": 6, "attributeID": 12, "type": 1 } } ] Figure 30: Zigbee Attribute Notification 8. Examples This section contains a few examples on how applications can leverage NIPC operations to communicate with BLE and Zigbee devices. 8.1. Property Read/Write In this example, we will connect to a device and read and write from a property. The sequence of operations for this are: * Onboard a device using the SCIM Interface (out of scope of this memo) * Register an SDF model for the device Brinckman, et al. Expires 24 March 2026 [Page 47] Internet-Draft NIPC September 2025 ============== NOTE: '\' line wrapping per RFC 8792 ============== POST /registrations/models Content-Type: application/sdf+json Accept: application/nipc+json Host: localhost { ... } HTTP/1.1 200 OK content-type: application/nipc+json [ { "sdfName": "https://example.com/thermometer#/sdfThing/thermom\ eter" } ] Request Body: JSON object with the SDF model, from Appendix D * Read a property from the BLE device ============== NOTE: '\' line wrapping per RFC 8792 ============== GET /devices/12345678-1234-5678-1234-56789abcdef4/properties?prop\ ertyName=https%3A%2F%2Fexample.com%2Fthermometer%23%2FsdfThing%2F\ thermometer%2FsdfProperty%2Fdevice_name Accept: application/nipc+json Host: localhost HTTP/1.1 200 OK content-type: application/nipc+json [ { "property": "https://example.com/thermometer#/sdfThing/thermo\ meter/sdfProperty/device_name", "value": "dGVzdA==" } ] * Write to a property on the BLE device Brinckman, et al. Expires 24 March 2026 [Page 48] Internet-Draft NIPC September 2025 ============== NOTE: '\' line wrapping per RFC 8792 ============== PUT /devices/12345678-1234-5678-1234-56789abcdef4/properties Content-Type: application/nipc+json Host: localhost [ { "property": "https://example.com/thermometer#/sdfThing/thermo\ meter/sdfProperty/device_name", "value": "dGVzdA==" } ] HTTP/1.1 200 OK content-type: application/nipc+json [ { "property": "https://example.com/thermometer#/sdfThing/thermo\ meter/sdfProperty/device_name", "value": "dGVzdA==" } ] 8.2. Enabling an Event In this example, we will onboard a device, and setup an advertisement subscription event for that device. The sequence of operations for this are: * Onboard a device and endpoint app using the SCIM Interface (out of scope of this memo) * Register an SDF model for the device Brinckman, et al. Expires 24 March 2026 [Page 49] Internet-Draft NIPC September 2025 ============== NOTE: '\' line wrapping per RFC 8792 ============== POST /registrations/data-apps?dataAppId=23456789-1234-5678-1234-567\ 89abcdef4 Content-Type: application/nipc+json Accept: application/nipc+json Host: localhost { "events": [ "https://example.com/thermometer#/sdfThing/thermometer/sdfEve\ nt/isPresent" ], "mqttClient": true } HTTP/1.1 200 OK content-type: application/nipc+json { "events": [ "https://example.com/thermometer#/sdfThing/thermometer/sdfEve\ nt/isPresent" ], "mqttClient": true } Request Body: JSON object with the SDF model, from Appendix D * Register the data app with the event Brinckman, et al. Expires 24 March 2026 [Page 50] Internet-Draft NIPC September 2025 ============== NOTE: '\' line wrapping per RFC 8792 ============== POST /registrations/data-apps?dataAppId=23456789-1234-5678-1234-567\ 89abcdef4 Content-Type: application/nipc+json Accept: application/nipc+json Host: localhost { "events": [ "https://example.com/thermometer#/sdfThing/thermometer/sdfEve\ nt/isPresent" ], "mqttClient": true } HTTP/1.1 200 OK content-type: application/nipc+json { "events": [ "https://example.com/thermometer#/sdfThing/thermometer/sdfEve\ nt/isPresent" ], "mqttClient": true } * Enable the advertisement event ============== NOTE: '\' line wrapping per RFC 8792 ============== POST /devices/12345678-1234-5678-1234-56789abcdef4/events?eventNa\ me=https%23%2F%2Fexample.com%2Fthermometer%23%2FsdfThing%2Fthermo\ meter%2FsdfEvent%2FisPresent Host: localhost Content-Length: 0 HTTP/1.1 201 Created Location: /devices/12345678-1234-5678-1234-56789abcdef4/events?in\ stanceId=87654321-4321-8765-4321-fedcba9876543 * Check the status of the event Brinckman, et al. Expires 24 March 2026 [Page 51] Internet-Draft NIPC September 2025 ============== NOTE: '\' line wrapping per RFC 8792 ============== GET /devices/12345678-1234-5678-1234-56789abcdef4/events?instance\ Id=87654321-4321-8765-4321-fedcba9876543 Host: localhost HTTP/1.1 200 OK content-type: application/nipc+json { "event": "https://example.com/thermometer#/sdfThing/thermometer\ /sdfEvent/isPresent" } 9. Security Considerations 9.1. API authorization In order to enable a network wishing to offer NIPC ALG functions, the network administrator authorizes application(s) to perform operations on the Gateway. This happens out of band and may be accomplished by means of exchanging tokens or public keys. Authorization can be role-based. The 3 primary roles are: 1. Onboarding: Authorize an onboarding application against a SCIM server co-located with the gateway. 2. Control: Authorize applications that may control devices. 3. Data: Authorize applications that may receive telemetry. It is possible to further refine roles down to an API basis. 10. IANA Considerations This section provides guidance to the Internet Assigned Numbers Authority (IANA) regarding registration of values related to NIPC, in accordance with [RFC8126]. 10.1. Media Type Registration This document registers the "application/nipc+json" media type for messages of the NIPC APIs defined in this document carrying parameters encoded in JSON. Type name: application Subtype name: nipc+json Brinckman, et al. Expires 24 March 2026 [Page 52] Internet-Draft NIPC September 2025 Required parameters: none Optional parameters: none Encoding considerations: Encoding considerations are identical to those specified for the "application/json" media type. Security considerations: See the Section 9 section of this document. Interoperability considerations: none Published specification: This document, the NIPC API specification. Applications that use this media type: Fragment identifier considerations: none Additional information: * Deprecated alias names for this type: none * Magic number(s): none * File extension(s): none * Macintosh file type code(s): none Person & email address to contact for further information: Intended usage: LIMITED USE Restrictions on usage: To be used for NIPC APIs as defined in this document. Author: Change controller: IETF 10.2. API extensions IANA is requested to create a new registry called "NIPC API extensions". The registry must contain following attributes: * Extension URI * Extension name Brinckman, et al. Expires 24 March 2026 [Page 53] Internet-Draft NIPC September 2025 * Description * Openapi model describing the extension. This model must be reviewed by an expert. Following API extensions are described in this document: Brinckman, et al. Expires 24 March 2026 [Page 54] Internet-Draft NIPC September 2025 +=================================+===========+===========+=========+ |Extension URI |Extension |Description|Model | | |name | |reference| +=================================+===========+===========+=========+ |/extensions/{id}/bulk |Bulk API |Call |Appendix | | | |multiple |C | | | |NIPC's in a| | | | |single | | | | |request | | +---------------------------------+-----------+-----------+---------+ |/extensions/{id}/properties/file |File write |Write a |Appendix | | |API |file with |C | | | |multiple | | | | |property | | | | |ops | | +---------------------------------+-----------+-----------+---------+ |/extensions/{id}/properties/blob |Binary |Write a |Appendix | | |write API |binary blob|C | | | |with | | | | |multiple | | | | |property | | | | |ops | | +---------------------------------+-----------+-----------+---------+ |/extensions/{id}/properties/read/|Read |Read a |Appendix | |conditional |conditional|property |C | | |API |until a | | | | |condition | | | | |is | | | | |fulfilled | | +---------------------------------+-----------+-----------+---------+ |/extensions/{id}/events/ |Event |Enable an |Appendix | |conditional |conditional|event until|C | | |API |a condition| | | | |is | | | | |fulfilled | | +---------------------------------+-----------+-----------+---------+ |/extensions/{id}/transmit |Transmit |Transmits a|Appendix | | |API |payload to |C | | | |a device | | +---------------------------------+-----------+-----------+---------+ Table 5 10.3. Well-known URIs IANA is requested to register the following well-known URI in the "Well-Known URIs" registry as defined by [RFC8615]: Brinckman, et al. Expires 24 March 2026 [Page 55] Internet-Draft NIPC September 2025 +============+===================+==============================+ | URI Suffix | Change Controller | Specification Document | +============+===================+==============================+ | nipc | IETF | This document, Section 2.7.1 | +------------+-------------------+------------------------------+ Table 6 The well-known URI for NIPC is: /.well-known/nipc 10.4. Problem Details for NIPC APIs IANA is requested to create a new registry, the "NIPC Problem Type" registry, with following URL: https://www.iana.org/assignments/nipc- problem-types. Registrations MUST use the prefix "https://iana.org/assignments/nipc- problem-types#" for the type URI. The registration requests MUST use the template defined in Section 4.2 of [RFC9457]. IANA is requested to register the following URIs in the "NIPC Problem Type" registry: +===================================+===================+===========+ | Problem Type URI | Description | Reference | +===================================+===================+===========+ | https://www.iana.org/assignments/ | Invalid device | This | | nipc-problem-types#invalid-id | ID or gateway | document | | | doesn't | | | | recognize the ID | | +-----------------------------------+-------------------+-----------+ | https://www.iana.org/assignments/ | Invalid SDF URL | This | | nipc-problem-types#invalid-sdf- | or SDF | document | | url | affordance not | | | | found | | +-----------------------------------+-------------------+-----------+ | https://www.iana.org/assignments/ | Operation was | This | | nipc-problem-types#extension- | not executed | document | | operation-not-executed | since the | | | | previous | | | | operation failed | | +-----------------------------------+-------------------+-----------+ | https://www.iana.org/assignments/ | SDF model | This | | nipc-problem-types#sdf-model- | already | document | Brinckman, et al. Expires 24 March 2026 [Page 56] Internet-Draft NIPC September 2025 | already-registered | registered | | +-----------------------------------+-------------------+-----------+ | https://www.iana.org/assignments/ | SDF model in use | This | | nipc-problem-types#sdf-model-in- | | document | | use | | | +-----------------------------------+-------------------+-----------+ | https://www.iana.org/assignments/ | Property not | This | | nipc-problem-types#property-not- | readable | document | | readable | | | +-----------------------------------+-------------------+-----------+ | https://www.iana.org/assignments/ | Property read | This | | nipc-problem-types#property-read- | failed | document | | failed | | | +-----------------------------------+-------------------+-----------+ | https://www.iana.org/assignments/ | Property not | This | | nipc-problem-types#property-not- | writable | document | | writable | | | +-----------------------------------+-------------------+-----------+ | https://www.iana.org/assignments/ | Property write | This | | nipc-problem-types#property- | failed | document | | write-failed | | | +-----------------------------------+-------------------+-----------+ | https://www.iana.org/assignments/ | Event already | This | | nipc-problem-types#event-already- | enabled | document | | enabled | | | +-----------------------------------+-------------------+-----------+ | https://www.iana.org/assignments/ | Event not | This | | nipc-problem-types#event-not- | enabled | document | | enabled | | | +-----------------------------------+-------------------+-----------+ | https://www.iana.org/assignments/ | Event not | This | | nipc-problem-types#event-not- | registered for | document | | registered | any data | | | | application | | +-----------------------------------+-------------------+-----------+ | https://www.iana.org/assignments/ | Device already | This | | nipc-problem-types#protocolmap- | connected | document | | ble-already-connected | | | +-----------------------------------+-------------------+-----------+ | https://www.iana.org/assignments/ | No connection | This | | nipc-problem-types#protocolmap- | found for device | document | | ble-no-connection | | | +-----------------------------------+-------------------+-----------+ | https://www.iana.org/assignments/ | BLE connection | This | | nipc-problem-types#protocolmap- | timeout | document | | ble-connection-timeout | | | +-----------------------------------+-------------------+-----------+ | https://www.iana.org/assignments/ | BLE bonding | This | Brinckman, et al. Expires 24 March 2026 [Page 57] Internet-Draft NIPC September 2025 | nipc-problem-types#protocolmap- | failed | document | | ble-bonding-failed | | | +-----------------------------------+-------------------+-----------+ | https://www.iana.org/assignments/ | BLE connection | This | | nipc-problem-types#protocolmap- | failed | document | | ble-connection-failed | | | +-----------------------------------+-------------------+-----------+ | https://www.iana.org/assignments/ | BLE service | This | | nipc-problem-types#protocolmap- | discovery failed | document | | ble-service-discovery-failed | | | +-----------------------------------+-------------------+-----------+ | https://www.iana.org/assignments/ | Invalid BLE | This | | nipc-problem-types#protocolmap- | service or | document | | ble-invalid-service-or- | characteristic | | | characteristic | ID | | +-----------------------------------+-------------------+-----------+ | https://www.iana.org/assignments/ | Zigbee | This | | nipc-problem-types#protocolmap- | connection | document | | zigbee-connection-timeout | timeout | | +-----------------------------------+-------------------+-----------+ | https://www.iana.org/assignments/ | Invalid Zigbee | This | | nipc-problem-types#protocolmap- | endpoint or | document | | zigbee-invalid-endpoint-or- | cluster ID | | | cluster | | | +-----------------------------------+-------------------+-----------+ | https://www.iana.org/assignments/ | Invalid transmit | This | | nipc-problem-types#extension- | data | document | | broadcast-invalid-data | | | +-----------------------------------+-------------------+-----------+ | https://www.iana.org/assignments/ | Firmware | This | | nipc-problem-types#extension- | rollback | document | | firmware-rollback | | | +-----------------------------------+-------------------+-----------+ | https://www.iana.org/assignments/ | Firmware update | This | | nipc-problem-types#extension- | failed | document | | firmware-update-failed | | | +-----------------------------------+-------------------+-----------+ Table 7 Each Problem Type URI is intended for use as the "type" member in Problem Details responses as described. 11. References 11.1. Normative References Brinckman, et al. Expires 24 March 2026 [Page 58] Internet-Draft NIPC September 2025 [I-D.ietf-asdf-sdf] Koster, M., Bormann, C., and A. Keränen, "Semantic Definition Format (SDF) for Data and Interactions of Things", Work in Progress, Internet-Draft, draft-ietf- asdf-sdf-24, 27 July 2025, . [I-D.ietf-scim-device-model] Shahzad, M., Iqbal, H., and E. Lear, "Device Schema Extensions to the SCIM model", Work in Progress, Internet- Draft, draft-ietf-scim-device-model-18, 3 September 2025, . [I-D.mohan-asdf-sdf-protocol-mapping] Mohan, R., Brinckman, B., and L. Corneo, "Protocol Mapping for SDF", Work in Progress, Internet-Draft, draft-mohan- asdf-sdf-protocol-mapping-00, 18 August 2025, . [RFC2119] Bradner, S., "Key words for use in RFCs to Indicate Requirement Levels", BCP 14, RFC 2119, DOI 10.17487/RFC2119, March 1997, . [RFC3986] Berners-Lee, T., Fielding, R., and L. Masinter, "Uniform Resource Identifier (URI): Generic Syntax", STD 66, RFC 3986, DOI 10.17487/RFC3986, January 2005, . [RFC4648] Josefsson, S., "The Base16, Base32, and Base64 Data Encodings", RFC 4648, DOI 10.17487/RFC4648, October 2006, . [RFC6570] Gregorio, J., Fielding, R., Hadley, M., Nottingham, M., and D. Orchard, "URI Template", RFC 6570, DOI 10.17487/RFC6570, March 2012, . [RFC7159] Bray, T., Ed., "The JavaScript Object Notation (JSON) Data Interchange Format", RFC 7159, DOI 10.17487/RFC7159, March 2014, . Brinckman, et al. Expires 24 March 2026 [Page 59] Internet-Draft NIPC September 2025 [RFC7644] Hunt, P., Ed., Grizzle, K., Ansari, M., Wahlstroem, E., and C. Mortimore, "System for Cross-domain Identity Management: Protocol", RFC 7644, DOI 10.17487/RFC7644, September 2015, . [RFC8126] Cotton, M., Leiba, B., and T. Narten, "Guidelines for Writing an IANA Considerations Section in RFCs", BCP 26, RFC 8126, DOI 10.17487/RFC8126, June 2017, . [RFC8174] Leiba, B., "Ambiguity of Uppercase vs Lowercase in RFC 2119 Key Words", BCP 14, RFC 8174, DOI 10.17487/RFC8174, May 2017, . [RFC8610] Birkholz, H., Vigano, C., and C. Bormann, "Concise Data Definition Language (CDDL): A Notational Convention to Express Concise Binary Object Representation (CBOR) and JSON Data Structures", RFC 8610, DOI 10.17487/RFC8610, June 2019, . [RFC8615] Nottingham, M., "Well-Known Uniform Resource Identifiers (URIs)", RFC 8615, DOI 10.17487/RFC8615, May 2019, . [RFC8949] Bormann, C. and P. Hoffman, "Concise Binary Object Representation (CBOR)", STD 94, RFC 8949, DOI 10.17487/RFC8949, December 2020, . [RFC9114] Bishop, M., Ed., "HTTP/3", RFC 9114, DOI 10.17487/RFC9114, June 2022, . [RFC9457] Nottingham, M., Wilde, E., and S. Dalal, "Problem Details for HTTP APIs", RFC 9457, DOI 10.17487/RFC9457, July 2023, . 11.2. Informative References [BLE53] Bluetooth SIG, "Bluetooth Core Specification, Version 5.3", 2021. [Gatt-REST-API] Bluetooth SIG, "A RESTful API used to access data in devices using the functionality defined in the Bluetooth GATT profile", 2017, . Brinckman, et al. Expires 24 March 2026 [Page 60] Internet-Draft NIPC September 2025 [Zigbee22] Connectivity Standards Alliance, "zigbee Specification, Version 22 1.0", 2017. Appendix A. OpenAPI definition The following non-normative model is provide for convenience of the implementor. file "openapi.yml" =============== NOTE: '\\' line wrapping per RFC 8792 =============== # yaml-language-server: $schema=https://json-schema.org/draft/2020-1\ \2/schema openapi: 3.0.3 info: title: Non IP Device Control (NIPC) API description: |- This API specifies RESTful application layer interface for gateways providing operations against non-IP devices. The described interface is extensible. The examples includes leverage Bluetooth Low Energy and Zigbee as they are commonly deployed. termsOfService: http://swagger.io/terms/ contact: email: bbrinckm@cisco.com license: name: TBD url: TBD version: 0.13.0 externalDocs: description: NIPC IETF draft url: https://datatracker.ietf.org/doc/draft-ietf-asdf-nipc/ servers: - url: "{gw_host}/nipc/draft-13" variables: gw_host: default: localhost description: Gateway Host tags: - name: NIPC property APIs description: |- APIs that allow apps to get and update device properties. If the underlying protocol requires connection management, it will be performed as part of the API call. - name: NIPC event APIs description: |- APIs that allow apps to enable or disable event reporting on devices. If the underlying protocol requires connection Brinckman, et al. Expires 24 March 2026 [Page 61] Internet-Draft NIPC September 2025 management, it will be performed as part of the API call. - name: NIPC action APIs description: |- APIs that perform actions on devices. - name: NIPC management APIs description: |- APIs that manage device connections. - name: NIPC registration APIs description: |- APIs that register sdf models or data applications paths: ### NIPC Property APIs /devices/{id}/properties: put: tags: - NIPC property APIs summary: Update a value of one or more properties on a device description: |- Write a value to a property or multiple properties to a device. If underlying protocol requires a connection to be set up, this API call will perform the necessary connection management. If a connection is already active for this device, the existing connection will be leveraged without modifying it. operationId: UpdateProperties parameters: - name: id in: path description: The ID of the device. Group ID is not allowed. required: true schema: type: string format: uuid example: 12345678-1234-5678-1234-56789abcdef4 - name: propertyName in: query description: |- The SDF property name that needs to be written to. required: false allowReserved: true schema: type: string example: "https://example.com/heartrate#/sdfObject/thermos\ \tat/sdfProperty/temperature" requestBody: description: |- The value to be written to the property or properties. Brinckman, et al. Expires 24 March 2026 [Page 62] Internet-Draft NIPC September 2025 If multiple properties are specified, the request body should be application/nipc+json. content: application/nipc+json: schema: $ref: '#/components/schemas/PropertyValueArray' "*/*": schema: description: |- Any other content type, such as application/octet-stream, application/json that will be written to the device. required: true responses: '204': description: |- Success, no content, used for a single property write '200': description: Success, used for multiple property writes content: application/nipc+json: schema: allOf: - $ref: '#/components/schemas/PropertyValueRespons\ \eArray' default: description: Error response content: application/problem+json: schema: $ref: '#/components/schemas/FailureResponse' get: tags: - NIPC property APIs summary: |- Read a value from one or multiple properties on a device description: |- Read a value to a property or multiple properties from a device. If underlying protocol requires a connection to be set up, this API call will perform the necessary connection management. If a connection is already active for this device, the existing connection will be leveraged without modifying it. operationId: GetProperties parameters: - name: id in: path Brinckman, et al. Expires 24 March 2026 [Page 63] Internet-Draft NIPC September 2025 description: The ID of the device. Group ID is not allowed. required: true schema: type: string format: uuid example: 12345678-1234-5678-1234-56789abcdef4 - name: propertyName in: query description: Properties to be read required: true allowReserved: true schema: type: array items: type: string example: "https://example.com/heartrate#/sdfObject/therm\ \ostat/sdfProperty/temperature" responses: '200': description: Success content: application/nipc+json: schema: allOf: - $ref: '#/components/schemas/Id' - $ref: '#/components/schemas/PropertyValueReadRes\ \ponseArray' "*/*": schema: type: string description: |- Any other content type, such as application/octet-stream, application/json that will be read from the device. default: description: Error response content: application/problem+json: schema: $ref: '#/components/schemas/FailureResponse' ### NIPC Event APIs /devices/{id}/events: post: tags: - NIPC event APIs summary: Enable an event on a specific device description: |- Brinckman, et al. Expires 24 March 2026 [Page 64] Internet-Draft NIPC September 2025 Enable an event on a specific device or for a group of devices. If the underlying protocol requires a connection to be set up, this API call will perform the necessary connection management. If a connection is already active for this device, the existing connection will be leveraged without modifying it. operationId: EnableEvent parameters: - name: id in: path description: device id or group id required: true schema: type: string format: uuid example: 12345678-1234-5678-1234-56789abcdef4 - name: eventName in: query description: event that needs to be enabled required: true allowReserved: true schema: type: string example: "https://example.com/heartrate#/sdfObject/healths\ \ensor/sdfEvent/fallDetected" responses: '201': description: Success headers: Location: description: Location of the created event schema: type: string format: uri example: "/devices/{id}/events?instanceId={instanceI\ \d}" default: description: Error response content: application/problem+json: schema: $ref: '#/components/schemas/FailureResponse' delete: tags: - NIPC event APIs summary: Disable an event on a specific device description: |- Brinckman, et al. Expires 24 March 2026 [Page 65] Internet-Draft NIPC September 2025 Disable an event on a specific device or a group of devices. If the underlying protocol requires a connection to be set up, this API call will perform the necessary connection management. If a connection is already active for this device, the existing connection will be leveraged without modifying it. operationId: DisableEvent parameters: - name: id in: path description: device id or group id required: true schema: type: string format: uuid example: 12345678-1234-5678-1234-56789abcdef4 - name: instanceId in: query description: instance id of the event that needs to be disab\ \led required: true schema: type: string format: uuid example: 12345678-1234-5678-1234-56789abcdef4 responses: '204': description: Success, no content default: description: Error response content: application/problem+json: schema: $ref: '#/components/schemas/FailureResponse' get: tags: - NIPC event APIs summary: Get status of events on a device description: |- Get status of an event or multiple events on a specific devi\ \ce operationId: GetEvents parameters: - name: id in: path description: The ID of the device. required: true Brinckman, et al. Expires 24 March 2026 [Page 66] Internet-Draft NIPC September 2025 schema: type: string format: uuid example: 12345678-1234-5678-1234-56789abcdef4 - name: instanceId in: query description: |- Instance ID of the events that need to be filtered required: false schema: type: array items: type: string format: uuid example: 12345678-1234-5678-1234-56789abcdef4 responses: '200': description: Success content: application/nipc+json: schema: $ref: '#/components/schemas/EventStatusResponseArray' default: description: Error response content: application/problem+json: schema: $ref: '#/components/schemas/FailureResponse' /groups/{id}/events: post: tags: - NIPC event APIs summary: Enable an event on a group of devices description: |- Enable an event on a group of devices. If the underlying protocol requires a connection to be set up, this API call will perform the necessary connection management. If a connection is already active for this device, the existing connection will be leveraged without modifying it. operationId: EnableGroupEvent parameters: - name: id in: path description: |- group id for which the event needs to be enabled required: true Brinckman, et al. Expires 24 March 2026 [Page 67] Internet-Draft NIPC September 2025 schema: type: string format: uuid example: 12345678-1234-5678-1234-56789abcdef4 - name: eventName in: query description: event that needs to be enabled required: true allowReserved: true schema: type: string example: "https://example.com/heartrate#/sdfObject/healths\ \ensor/sdfEvent/fallDetected" responses: '201': description: Success, event enabled headers: Location: description: Location of the created event schema: type: string format: uri example: "/groups/{id}/events?instanceId={instanceId\ \}" default: description: Error response content: application/problem+json: schema: $ref: '#/components/schemas/FailureResponse' delete: tags: - NIPC event APIs summary: Disable an event on a group of devices description: |- Disable an event on a group of devices. If the underlying protocol requires a connection to be set up, this API call will perform the necessary connection management. If a connection is already active for this device, the existing connection will be leveraged without modifying it. operationId: DisableGroupEvent parameters: - name: id in: path description: |- group id for which the event needs to be disabled required: true schema: Brinckman, et al. Expires 24 March 2026 [Page 68] Internet-Draft NIPC September 2025 type: string format: uuid example: 12345678-1234-5678-1234-56789abcdef4 - name: instanceId in: query description: instance id of the event that needs to be disab\ \led required: true schema: type: string format: uuid example: 12345678-1234-5678-1234-56789abcdef4 responses: '204': description: Success, no content default: description: Error response content: application/problem+json: schema: $ref: '#/components/schemas/FailureResponse' get: tags: - NIPC event APIs summary: Get status of events on a group of devices description: |- Get status of an event or multiple events on a group of devi\ \ces. operationId: GetGroupEvents parameters: - name: id in: path description: group id of the SCIM group required: true schema: type: string format: uuid example: 12345678-1234-5678-1234-56789abcdef4 - name: instanceId in: query description: |- Instance IDs of the events that need to be filtered required: false schema: type: array items: type: string format: uuid Brinckman, et al. Expires 24 March 2026 [Page 69] Internet-Draft NIPC September 2025 example: 12345678-1234-5678-1234-56789abcdef4 responses: '200': description: Success, events retrieved content: application/nipc+json: schema: $ref: '#/components/schemas/EventStatusResponseArray' default: description: Error response content: application/problem+json: schema: $ref: '#/components/schemas/FailureResponse' ### NIPC action APIs /devices/{id}/actions: post: tags: - NIPC action APIs summary: Perform an action on a device description: |- Perform an action on a device. If the underlying protocol requires a connection to be set up, this API call will perform the necessary connection management. If a connection is already active for this device, the existing connection will be leveraged without modifying it. operationId: ActionProperty parameters: - name: id in: path description: The ID of the device. Group ID is not allowed. required: true schema: type: string format: uuid example: 12345678-1234-5678-1234-56789abcdef4 - name: actionName in: query description: action that needs to be performed required: true allowReserved: true schema: type: string example: "https://example.com/heartrate#/sdfObject/healths\ \ensor/sdfAction/start" requestBody: Brinckman, et al. Expires 24 March 2026 [Page 70] Internet-Draft NIPC September 2025 content: application/octet-stream: schema: type: string format: binary required: false responses: '202': description: Accepted, action is being performed headers: Location: description: Location of the action schema: type: string format: uri example: "/devices/{id}/actions?instanceId={instance\ \Id}" default: description: Error response content: application/problem+json: schema: $ref: '#/components/schemas/FailureResponse' get: tags: - NIPC action APIs summary: Get status of an action on a device description: |- Get status of an action on a specific device or a group of devices. Success is action is active, failure if action not active. operationId: GetAction parameters: - name: id in: path description: The ID of the device. Group ID is not allowed. required: true schema: type: string format: uuid example: 12345678-1234-5678-1234-56789abcdef4 - name: instanceId in: query description: |- instance id of the action that needs to be checked required: true schema: type: string Brinckman, et al. Expires 24 March 2026 [Page 71] Internet-Draft NIPC September 2025 format: uuid example: 12345678-1234-5678-1234-56789abcdef4 responses: '200': description: Success, action is active content: application/nipc+json: schema: $ref: '#/components/schemas/ActionResponse' default: description: Error response content: application/problem+json: schema: $ref: '#/components/schemas/FailureResponse' /devices/{id}/connections: post: tags: - NIPC management APIs summary: Connect a device description: |- Connect a device. 3 retries by default, optionally retry policy can be defined in the API body. If the protocol requires service discovery, full service discovery will be performed, unless specific services are described in the API body. operationId: ActionCreateConnection parameters: - name: id in: path description: The ID of the device. Group ID is not allowed. required: true schema: type: string format: uuid example: 12345678-1234-5678-1234-56789abcdef4 requestBody: content: application/nipc+json: schema: anyOf: - $ref: '#/components/schemas/Connection' - $ref: './protocolmaps/ProtocolMap.yaml#/components\ \/schemas/ProtocolMap-ServiceList' required: false responses: '200': Brinckman, et al. Expires 24 March 2026 [Page 72] Internet-Draft NIPC September 2025 description: Success content: application/nipc+json: schema: allOf: - $ref: '#/components/schemas/Id' - $ref: './protocolmaps/ProtocolMap.yaml#/componen\ \ts/schemas/ProtocolMap-ServiceMap' default: description: Error response content: application/problem+json: schema: $ref: '#/components/schemas/FailureResponse' put: tags: - NIPC management APIs summary: Update cached ServiceMap for a device. description: |- Update cached ServiceMap for a device. Full service discovery will be performed, unless specific services are described in the API body. operationId: ActionUpdateServiceMap parameters: - name: id in: path description: The ID of the device. Group ID is not allowed. required: true schema: type: string format: uuid example: 12345678-1234-5678-1234-56789abcdef4 requestBody: content: application/nipc+json: schema: $ref: './protocolmaps/ProtocolMap.yaml#/components/sch\ \emas/ProtocolMap-ServiceList' required: false responses: '200': description: Success content: application/nipc+json: schema: allOf: - $ref: '#/components/schemas/Id' Brinckman, et al. Expires 24 March 2026 [Page 73] Internet-Draft NIPC September 2025 - $ref: './protocolmaps/ProtocolMap.yaml#/componen\ \ts/schemas/ProtocolMap-ServiceMap' default: description: Error response content: application/problem+json: schema: $ref: '#/components/schemas/FailureResponse' delete: tags: - NIPC management APIs summary: Disconnect a device description: |- Disconnect a device. operationId: ActionDeleteConnection parameters: - name: id in: path description: The ID of the device. Group ID is not allowed. required: true schema: type: string format: uuid example: 12345678-1234-5678-1234-56789abcdef4 responses: '200': description: Success content: application/nipc+json: schema: allOf: - $ref: '#/components/schemas/Id' default: description: Error response content: application/problem+json: schema: $ref: '#/components/schemas/FailureResponse' get: tags: - NIPC management APIs summary: Get connection state for a device description: |- Get connection status for a device. Success when device(s) is/are connected, includes service map for the device if available. Failure when a device is not connected Brinckman, et al. Expires 24 March 2026 [Page 74] Internet-Draft NIPC September 2025 operationId: ActionGetConnection parameters: - name: id in: path description: The ID of the device. Group ID is not allowed. required: true schema: type: string format: uuid example: 12345678-1234-5678-1234-56789abcdef4 responses: '200': description: Success content: application/nipc+json: schema: allOf: - $ref: '#/components/schemas/Id' - $ref: './protocolmaps/ProtocolMap.yaml#/componen\ \ts/schemas/ProtocolMap-ServiceMap' default: description: Error response content: application/problem+json: schema: $ref: '#/components/schemas/FailureResponse' ### Registrations /registrations/models: post: tags: - NIPC registration APIs summary: Register an sdfObject description: |- Register an sdfObject, including Properties, Events and actions operationId: registerSdfObject requestBody: content: application/sdf+json: schema: $ref: '#/components/schemas/SdfModel' required: true responses: '200': description: Success content: Brinckman, et al. Expires 24 March 2026 [Page 75] Internet-Draft NIPC September 2025 application/nipc+json: schema: type: array items: allOf: - $ref: '#/components/schemas/SdfReference' default: description: Error response content: application/problem+json: schema: allOf: - $ref: '#/components/schemas/FailureResponse' get: tags: - NIPC registration APIs summary: Get all registered SDF model names description: |- Get all registered SDF model names. operationId: getSdfRefs parameters: - name: sdfName in: query description: |- sdfName can be a reference to an sdfThing or sdfObject required: false allowReserved: true schema: type: string example: "https://example.com/heartrate#/sdfObject/healt\ \hsensor" responses: '200': description: Success content: application/sdf+json: schema: $ref: '#/components/schemas/SdfModel' default: description: Error response content: application/problem+json: schema: allOf: - $ref: '#/components/schemas/FailureResponse' put: tags: Brinckman, et al. Expires 24 March 2026 [Page 76] Internet-Draft NIPC September 2025 - NIPC registration APIs summary: Update an SDF model description: |- Update an SDF model, including Properties, Events and actions operationId: updateSdf parameters: - name: sdfName in: query description: |- sdfName can be a reference to an sdfThing or sdfObject required: true allowReserved: true schema: type: string example: "https://example.com/heartrate#/sdfObject/healt\ \hsensor" requestBody: content: application/sdf+json: schema: $ref: '#/components/schemas/SdfModel' required: true responses: '200': description: Success content: application/nipc+json: schema: allOf: - $ref: '#/components/schemas/SdfReference' default: description: Error response content: application/problem+json: schema: allOf: - $ref: '#/components/schemas/FailureResponse' delete: tags: - NIPC registration APIs summary: Delete an sdfObject description: |- Delete an sdfObject, including Properties, Events and actions operationId: deleteSdfObject parameters: Brinckman, et al. Expires 24 March 2026 [Page 77] Internet-Draft NIPC September 2025 - name: sdfName in: query description: sdfObject name required: true schema: type: string example: "https://example.com/heartrate#/sdfObject/healt\ \hsensor" responses: '200': description: Success content: application/nipc+json: schema: allOf: - $ref: '#/components/schemas/SdfReference' default: description: Error response content: application/problem+json: schema: allOf: - $ref: '#/components/schemas/FailureResponse' /registrations/data-apps: post: tags: - NIPC registration APIs summary: Register a dataApp description: |- Register a dataApp that is able to receive device data. operationId: registerDataApp parameters: - name: dataAppId in: query description: id of the data app that will be registered required: true schema: type: string format: uuid example: 12345678-1234-5678-1234-56789abcdef4 requestBody: content: application/nipc+json: schema: $ref: '#/components/schemas/DataApp' required: true responses: Brinckman, et al. Expires 24 March 2026 [Page 78] Internet-Draft NIPC September 2025 '200': description: Success content: application/nipc+json: schema: allOf: - $ref: '#/components/schemas/DataApp' default: description: Error response content: application/problem+json: schema: allOf: - $ref: '#/components/schemas/FailureResponse' put: tags: - NIPC registration APIs summary: Update registration of a dataApp description: |- Update registration of a dataApp that is able to receive dev\ \ice data. operationId: UpdateDataApp parameters: - name: dataAppId in: query description: id of the data app that will be updated required: true schema: type: string format: uuid example: 12345678-1234-5678-1234-56789abcdef4 requestBody: content: application/nipc+json: schema: $ref: '#/components/schemas/DataApp' required: true responses: '200': description: Success content: application/nipc+json: schema: allOf: - $ref: '#/components/schemas/DataApp' default: description: Error response Brinckman, et al. Expires 24 March 2026 [Page 79] Internet-Draft NIPC September 2025 content: application/problem+json: schema: allOf: - $ref: '#/components/schemas/FailureResponse' delete: tags: - NIPC registration APIs summary: Delete registration of a dataApp description: |- Delete registration of a dataApp that is able to receive device data. operationId: DeleteDataApp parameters: - name: dataAppId in: query description: id of the data app that will be updated required: true schema: type: string format: uuid example: 12345678-1234-5678-1234-56789abcdef4 responses: '200': description: Success content: application/nipc+json: schema: allOf: - $ref: '#/components/schemas/DataApp' default: description: Error response content: application/problem+json: schema: allOf: - $ref: '#/components/schemas/FailureResponse' get: tags: - NIPC registration APIs summary: Get registration of a dataApp description: |- Get registrationdetails of a dataApp that is able to receive device data. operationId: GetDataApp parameters: Brinckman, et al. Expires 24 March 2026 [Page 80] Internet-Draft NIPC September 2025 - name: dataAppId in: query description: id of the data app that will be updated required: true schema: type: string format: uuid example: 12345678-1234-5678-1234-56789abcdef4 responses: '200': description: Success content: application/nipc+json: schema: allOf: - $ref: '#/components/schemas/DataApp' default: description: Error response content: application/problem+json: schema: allOf: - $ref: '#/components/schemas/FailureResponse' components: schemas: # Base objects ## A SCIM id, can be a device or a group Id: required: - id type: object properties: id: type: string format: uuid description: |- A SCIM-generated UUID, can be a device or group example: 12345678-1234-5678-1234-56789abcdef4 ## A property Property: required: - property type: object properties: property: type: string Brinckman, et al. Expires 24 March 2026 [Page 81] Internet-Draft NIPC September 2025 example: "https://example.com/heartrate#/sdfObject/thermos\ \tat/sdfProperty/temperature" ActionResponse: required: - action type: object properties: status: type: string example: COMPLETED description: |- Status of the action, can be IN_PROGRESS or COMPLETED ## A value Value: required: - value type: object properties: value: type: string format: byte example: dGVzdA== ## A value of an property of an Device PropertyValue: allOf: - $ref: '#/components/schemas/Property' - $ref: '#/components/schemas/Value' ## An array of Property values PropertyValueArray: type: array items: $ref: '#/components/schemas/PropertyValue' ## Event Event: required: - event type: object properties: event: type: string description: |- percent-encoded JSON pointer to the SDF event object example: https://example.com/heartrate#/sdfObject/healthse\ Brinckman, et al. Expires 24 March 2026 [Page 82] Internet-Draft NIPC September 2025 \nsor/sdfEvent/fallDetected InstanceId: type: object properties: instanceId: type: string format: uuid description: |- A SCIM-generated UUID for the event instance example: 12345678-1234-5678-1234-56789abcdef4 ## A Connection Connection: type: object properties: retries: type: integer format: int32 example: 3 retryMultipleAPs: type: boolean example: true ## DataApp DataApp: oneOf: - $ref: '#/components/schemas/DataAppMqttClient' - $ref: '#/components/schemas/DataAppMqttBroker' - $ref: '#/components/schemas/DataAppWebhook' - $ref: '#/components/schemas/DataAppWebsocket' type: object properties: events: type: array items: $ref: '#/components/schemas/Event' DataAppMqttClient: type: object properties: mqttClient: type: boolean DataAppMqttBroker: type: object properties: Brinckman, et al. Expires 24 March 2026 [Page 83] Internet-Draft NIPC September 2025 mqttBroker: type: object required: - URI - username - password properties: URI: type: string example: mqtt.broker.com:8883 username: type: string example: user1 password: type: string example: password1 brokerCACert: description: PEM encoded CA certificate type: string customTopic: type: string description: custom MQTT topic to publish to example: custom/topic DataAppWebhook: type: object properties: webhook: type: object properties: URI: type: string example: webhook.com:443 headers: type: object additionalProperties: type: string example: x-api-key: fjelk-3dl33f-2wdsd serverCACert: type: string DataAppWebsocket: type: object properties: websocket: type: object properties: Brinckman, et al. Expires 24 March 2026 [Page 84] Internet-Draft NIPC September 2025 URI: type: string example: websocket.com:443 headers: type: object additionalProperties: type: string example: x-api-key: fjelk-3dl33f-2wdsd serverCACert: type: string ## sdfObject registration definition SdfReference: type: object description: SDF URL referring to the sdfobject properties: sdfName: type: string example: "https://example.com/heartrate#/sdfObject/healths\ \ensor" SdfModel: allOf: - type: object description: Sample SDF model properties: namespace: type: object additionalProperties: type: string example: heartrate: https://example.com/heartrate defaultNamespace: type: string example: heartrate - oneOf: - $ref: '#/components/schemas/SdfThing' - $ref: '#/components/schemas/SdfObject' SdfThing: type: object description: Sample SDF thing properties: sdfThing: additionalProperties: anyOf: - $ref: '#/components/schemas/SdfProperty' Brinckman, et al. Expires 24 March 2026 [Page 85] Internet-Draft NIPC September 2025 - $ref: '#/components/schemas/SdfEvent' - $ref: '#/components/schemas/SdfAction' - $ref: '#/components/schemas/SdfObject' example: multipleSensor: sdfEvent: isPresent: sdfOutputData: sdfProtocolMap: ble: type: advertisement sdfObject: healthsensor: sdfProperty: heartrate: sdfProtocolMap: ble: serviceID: 12345678-1234-5678-1234-56789ab\ \cdef4 characteristicID: 12345678-1234-5678-1234-\ \56789abcdef4 sdfEvent: fallDetected: sdfOutputData: sdfProtocolMap: ble: serviceID: 12345678-1234-5678-1234-56789\ \abcdef4 characteristicID: 12345678-1234-5678-123\ \4-56789abcdef4 sdfAction: start: sdfProtocolMap: ble: serviceID: 12345678-1234-5678-1234-56789ab\ \cdef4 characteristicID: 12345678-1234-5678-1234-\ \56789abcdef4 SdfObject: type: object description: Sample SDF object properties: sdfObject: additionalProperties: anyOf: - $ref: '#/components/schemas/SdfProperty' - $ref: '#/components/schemas/SdfEvent' Brinckman, et al. Expires 24 March 2026 [Page 86] Internet-Draft NIPC September 2025 - $ref: '#/components/schemas/SdfAction' example: healthsensor: sdfProperty: heartrate: sdfProtocolMap: ble: serviceID: 12345678-1234-5678-1234-56789abcdef4 characteristicID: 12345678-1234-5678-1234-5678\ \9abcdef4 sdfEvent: fallDetected: sdfOutputData: sdfProtocolMap: ble: serviceID: 12345678-1234-5678-1234-56789abcd\ \ef4 characteristicID: 12345678-1234-5678-1234-56\ \789abcdef4 sdfAction: start: sdfProtocolMap: ble: serviceID: 12345678-1234-5678-1234-56789abcdef4 characteristicID: 12345678-1234-5678-1234-5678\ \9abcdef4 SdfProperty: type: object description: Sample SDF property properties: sdfProperty: additionalProperties: allOf: - $ref: './protocolmaps/ProtocolMap.yaml#/components/s\ \chemas/ProtocolMap-Property' example: heartrate: sdfProtocolMap: ble: serviceID: 12345678-1234-5678-1234-56789abcdef4 characteristicID: 12345678-1234-5678-1234-56789abc\ \def4 SdfEvent: type: object description: Sample SDF property properties: Brinckman, et al. Expires 24 March 2026 [Page 87] Internet-Draft NIPC September 2025 sdfEvent: additionalProperties: #example, this will be the registere\ \d event type: object properties: sdfOutputData: allOf: - $ref: './protocolmaps/ProtocolMap.yaml#/componen\ \ts/schemas/ProtocolMap-Event' example: fallDetected: sdfOutputData: sdfProtocolMap: ble: serviceID: 12345678-1234-5678-1234-56789abcdef4 characteristicID: 12345678-1234-5678-1234-56789a\ \bcdef4 SdfAction: type: object description: Sample SDF property properties: sdfAction: additionalProperties: allOf: - $ref: './protocolmaps/ProtocolMap.yaml#/components/s\ \chemas/ProtocolMap-Property' example: start: sdfProtocolMap: ble: serviceID: 12345678-1234-5678-1234-56789abcdef4 characteristicID: 12345678-1234-5678-1234-56789abc\ \def4 # responses SuccessResponse: type: object properties: status: type: integer format: int32 example: 200 description: HTTP status code ## Error 500 application Failure response FailureResponse: Brinckman, et al. Expires 24 March 2026 [Page 88] Internet-Draft NIPC September 2025 type: object properties: type: type: string description: URI to the error type enum: - https://www.iana.org/assignments/nipc-problem-types#in\ \valid-id - https://www.iana.org/assignments/nipc-problem-types#in\ \valid-sdf-url - https://www.iana.org/assignments/nipc-problem-types#ex\ \tension-operation-not-executed - https://www.iana.org/assignments/nipc-problem-types#sd\ \f-model-already-registered - https://www.iana.org/assignments/nipc-problem-types#sd\ \f-model-in-use - https://www.iana.org/assignments/nipc-problem-types#pr\ \operty-not-readable - https://www.iana.org/assignments/nipc-problem-types#pr\ \operty-read-failed - https://www.iana.org/assignments/nipc-problem-types#pr\ \operty-not-writable - https://www.iana.org/assignments/nipc-problem-types#pr\ \operty-write-failed - https://www.iana.org/assignments/nipc-problem-types#ev\ \ent-already-enabled - https://www.iana.org/assignments/nipc-problem-types#ev\ \ent-not-enabled - https://www.iana.org/assignments/nipc-problem-types#ev\ \ent-not-registered - https://www.iana.org/assignments/nipc-problem-types#pr\ \otocolmap-ble-already-connected - https://www.iana.org/assignments/nipc-problem-types#pr\ \otocolmap-ble-no-connection - https://www.iana.org/assignments/nipc-problem-types#pr\ \otocolmap-ble-connection-timeout - https://www.iana.org/assignments/nipc-problem-types#pr\ \otocolmap-ble-bonding-failed - https://www.iana.org/assignments/nipc-problem-types#pr\ \otocolmap-ble-connection-failed - https://www.iana.org/assignments/nipc-problem-types#pr\ \otocolmap-ble-service-discovery-failed - https://www.iana.org/assignments/nipc-problem-types#pr\ \otocolmap-ble-invalid-service-or-characteristic - https://www.iana.org/assignments/nipc-problem-types#pr\ \otocolmap-zigbee-connection-timeout - https://www.iana.org/assignments/nipc-problem-types#pr\ \otocolmap-zigbee-invalid-endpoint-or-cluster Brinckman, et al. Expires 24 March 2026 [Page 89] Internet-Draft NIPC September 2025 - https://www.iana.org/assignments/nipc-problem-types#ex\ \tension-broadcast-invalid-data - https://www.iana.org/assignments/nipc-problem-types#ex\ \tension-firmware-rollback - https://www.iana.org/assignments/nipc-problem-types#ex\ \tension-firmware-update-failed - about:blank status: type: integer format: int32 example: 400 description: HTTP status code title: type: string example: Invalid Device ID description: Human-readable error title detail: type: string example: |- Device ID 12345678-1234-5678-1234-56789abcdef4 does not exist or is not a device description: Human-readable error message ## Property operations responses PropertyValueResponseArrayItem: oneOf: - $ref: '#/components/schemas/SuccessResponse' - $ref: '#/components/schemas/FailureResponse' PropertyValueResponseArray: type: array items: $ref: '#/components/schemas/PropertyValueResponseArrayItem' PropertyValueReadResponseArrayItem: oneOf: - $ref: '#/components/schemas/PropertyValue' - $ref: '#/components/schemas/FailureResponse' PropertyValueReadResponseArray: type: array items: allOf: - $ref: '#/components/schemas/PropertyValueReadResponseArr\ \ayItem' ## Event operations responses Brinckman, et al. Expires 24 March 2026 [Page 90] Internet-Draft NIPC September 2025 EventStatusResponseArrayItem: oneOf: - allOf: - $ref: '#/components/schemas/Event' - $ref: '#/components/schemas/InstanceId' - $ref: '#/components/schemas/FailureResponse' EventStatusResponseArray: type: array items: $ref: '#/components/schemas/EventStatusResponseArrayItem' Figure 31 Appendix B. Protocol mapping NIPC requires that a protocol mapping be provided as part of the SDF model for a device or have one provided using the NIPC action APIs with embedded protocol mapping. The protocol mapping is a JSON object that describes the underlying technology used to communicate with the device along with any additional information needed to communicate with the device. The JSON format of the protocol mapping is provided as a non- normative OpenAPI model for the convenience of the implementor. B.1. Protocol mapping OpenAPI model file "ProtocolMap.yaml" =============== NOTE: '\' line wrapping per RFC 8792 ================ openapi: 3.0.3 info: title: Non IP Device Control (NIPC) Protocol Mapping description: |- Non IP Device Control (NIPC) Protocol Mapping. When adding a new protocol mapping pls add a reference to the protocol map for all the schemas in this file. termsOfService: http://swagger.io/terms/ contact: email: bbrinckm@cisco.com license: name: TBD url: TBD version: 0.10.0 externalDocs: description: NIPC IETF draft Brinckman, et al. Expires 24 March 2026 [Page 91] Internet-Draft NIPC September 2025 url: https://datatracker.ietf.org/doc/draft-ietf-asdf-nipc/ components: schemas: # Protocol Mapping ## Protocol Map for Service Discovery ProtocolMap-ServiceList: type: object properties: sdfProtocolMap: oneOf: - $ref: './ProtocolMap-BLE.yaml#/components/schemas/Prot\ ocolMap-BLE-ServiceList' ## Protocol Map for Service Discovery result ProtocolMap-ServiceMap: type: object properties: sdfProtocolMap: oneOf: - $ref: './ProtocolMap-BLE.yaml#/components/schemas/Prot\ ocolMap-BLE-ServiceMap' - $ref: './ProtocolMap-Zigbee.yaml#/components/schemas/P\ rotocolMap-Zigbee-ServiceMap' ## Protocol Map for Broadcasts ProtocolMap-Broadcast: type: object properties: sdfProtocolMap: oneOf: - $ref: './ProtocolMap-BLE.yaml#/components/schemas/Prot\ ocolMap-BLE-Broadcast' - $ref: './ProtocolMap-Zigbee.yaml#/components/schemas/P\ rotocolMap-Zigbee-Broadcast' ## Protocol Map for a property ProtocolMap-Property: type: object properties: sdfProtocolMap: oneOf: - $ref: './ProtocolMap-BLE.yaml#/components/schemas/Prot\ ocolMap-BLE-Propmap' - $ref: './ProtocolMap-Zigbee.yaml#/components/schemas/P\ rotocolMap-Zigbee-Propmap' ## Protocol Map for an event Brinckman, et al. Expires 24 March 2026 [Page 92] Internet-Draft NIPC September 2025 ProtocolMap-Event: type: object properties: sdfProtocolMap: oneOf: - $ref: './ProtocolMap-BLE.yaml#/components/schemas/Prot\ ocolMap-BLE-Event' - $ref: './ProtocolMap-Zigbee.yaml#/components/schemas/P\ rotocolMap-Zigbee-Event' Figure 32 B.2. Protocol map for BLE file "ProtocolMap-BLE.yaml" =============== NOTE: '\' line wrapping per RFC 8792 ================ openapi: 3.0.3 info: title: Non IP Device Control (NIPC) BLE Protocol Mapping description: |- Non IP Device Control (NIPC) BLE Protocol Mapping. termsOfService: http://swagger.io/terms/ contact: email: bbrinckm@cisco.com license: name: TBD url: TBD version: 0.10.0 externalDocs: description: NIPC IETF draft url: https://datatracker.ietf.org/doc/draft-ietf-asdf-nipc/ components: schemas: # BLE Protocol Mapping ## A Service is a device with optional service IDs ProtocolMap-BLE-ServiceList: type: object properties: ble: type: object properties: services: type: array items: type: object Brinckman, et al. Expires 24 March 2026 [Page 93] Internet-Draft NIPC September 2025 properties: serviceID: type: string format: uuid example: 12345678-1234-5678-1234-56789abcdef4 cached: description: |- If we can cache information, then device doesn't need to be rediscovered before every connected. type: boolean default: false cacheIdlePurge: description: cache expiry period, when device allows type: integer example: 3600 # default 1 hour autoUpdate: description: |- autoupdate services if device supports it (default) type: boolean example: true bonding: #optional, by default defined in SCIM object type: string example: default enum: - default - none - justworks - passkey - oob ## Protocol Mapping for BLE Service Map ProtocolMap-BLE-ServiceMap: required: - services type: object properties: ble: type: array items: $ref: '#/components/schemas/ProtocolMap-BLE-Service' ProtocolMap-BLE-Service: required: - serviceID - characteristics type: object properties: serviceID: Brinckman, et al. Expires 24 March 2026 [Page 94] Internet-Draft NIPC September 2025 type: string format: uuid example: 12345678-1234-5678-1234-56789abcdef4 characteristics: type: array items: $ref: '#/components/schemas/ProtocolMap-BLE-Characterist\ ic' ProtocolMap-BLE-Characteristic: required: - characteristicID - flags - descriptors type: object properties: characteristicID: type: string format: uuid example: 12345678-1234-5678-1234-56789abcdef4 flags: type: array example: - read - write items: type: string enum: - read - write - notify descriptors: type: array items: $ref: '#/components/schemas/ProtocolMap-BLE-Descriptor' ProtocolMap-BLE-Descriptor: required: - descriptorID type: object properties: descriptorID: type: string format: uuid example: 12345678-1234-5678-1234-56789abcdef4 ## Protocol Mapping for BLE Broadcast ProtocolMap-BLE-Broadcast: Brinckman, et al. Expires 24 March 2026 [Page 95] Internet-Draft NIPC September 2025 required: - ble type: object properties: ble: type: object properties: connectable: type: boolean ## Protocol Mapping for BLE Property ProtocolMap-BLE-Propmap: required: - ble type: object properties: ble: required: - serviceID - characteristicID type: object properties: serviceID: type: string format: uuid example: 12345678-1234-5678-1234-56789abcdef4 characteristicID: type: string format: uuid example: 12345678-1234-5678-1234-56789abcdef4 ## Defines different types of BLE events ProtocolMap-BLE-Event: required: - ble type: object properties: ble: required: - type type: object properties: type: type: string example: gatt enum: - gatt - connection_events Brinckman, et al. Expires 24 March 2026 [Page 96] Internet-Draft NIPC September 2025 - advertisements serviceID: type: string example: 12345678-1234-5678-1234-56789abcdef0 characteristicID: type: string example: 12345678-1234-5678-1234-56789abcdef1 Figure 33 B.3. Protocol map for Zigbee file "ProtocolMap-Zigbee.yaml" openapi: 3.0.3 info: title: Non IP Device Control (NIPC) Zigbee Protocol Mapping description: |- Non IP Device Control (NIPC) Zigbee Protocol Mapping. termsOfService: http://swagger.io/terms/ contact: email: bbrinckm@cisco.com license: name: TBD url: TBD version: 0.10.0 externalDocs: description: NIPC IETF draft url: https://datatracker.ietf.org/doc/draft-ietf-asdf-nipc/ components: schemas: # Zigbee Protocol Mapping ## Protocol Mapping for Zigbee Service Map ProtocolMap-Zigbee-ServiceMap: required: - zigbee type: object properties: zigbee: type: array items: $ref: '#/components/schemas/ProtocolMap-Zigbee-Endpoint' ProtocolMap-Zigbee-Endpoint: required: - endpointID - clusters Brinckman, et al. Expires 24 March 2026 [Page 97] Internet-Draft NIPC September 2025 type: object properties: endpointID: type: integer format: int32 example: 10 clusters: type: array items: $ref: '#/components/schemas/ProtocolMap-Zigbee-Cluster' ProtocolMap-Zigbee-Cluster: required: - clusterID - properties type: object properties: clusterID: type: integer format: int32 example: 0 properties: type: array items: $ref: '#/components/schemas/ProtocolMap-Zigbee-Property' ProtocolMap-Zigbee-Property: required: - attributeID - propertyType type: object properties: attributeID: type: integer format: int32 example: 1 propertyType: type: integer format: int32 example: 32 ## Protocol Mapping for Zigbee broadcast ProtocolMap-Zigbee-Broadcast: required: - zigbee type: object properties: zigbee: Brinckman, et al. Expires 24 March 2026 [Page 98] Internet-Draft NIPC September 2025 type: object ## Protocol mapping for Zigbee property ProtocolMap-Zigbee-Propmap: required: - zigbee type: object properties: zigbee: required: - endpointID - clusterID - attributeID type: object properties: endpointID: type: integer format: int32 example: 1 clusterID: type: integer format: int32 example: 6 attributeID: type: integer format: int32 example: 16 type: type: integer format: int32 example: 1 ProtocolMap-Zigbee-Event: allOf: - $ref: '#/components/schemas/ProtocolMap-Zigbee-Propmap' Figure 34 Appendix C. NIPC API extensions The following OpenAPI models define a few example extensions to the NIPC API. C.1. NIPC API write binary blob extension Brinckman, et al. Expires 24 March 2026 [Page 99] Internet-Draft NIPC September 2025 file "Extension-Blob.yaml" =============== NOTE: '\' line wrapping per RFC 8792 ================ # yaml-language-server: $schema=https://json-schema.org/draft/2020-1\ 2/schema openapi: 3.0.3 info: title: Non IP Device Control (NIPC) API write binary blob extension description: |- Non IP Device Control (NIPC) API write binary blob extension termsOfService: http://swagger.io/terms/ contact: email: bbrinckm@cisco.com license: name: TBD url: TBD version: 0.13.0 externalDocs: description: NIPC IETF draft url: https://datatracker.ietf.org/doc/draft-ietf-asdf-nipc/ servers: - url: "{gw_host}/nipc/draft-13" variables: gw_host: default: localhost description: Gateway Host tags: - name: NIPC API extensions description: |- APIs that simplify application interaction by implementing one or more basic APIs into a single API call. paths: ### Extensions /extensions/{id}/properties/blob: put: tags: - NIPC API extensions summary: Write a binary blob to a property on a device description: |- Write a binary blob to a property on a device. Will chunk up the binary blob and perform multiple writes. If the underlying protocol requires a connection to be set up, this API call will perform the necessary connection management. If a connection is already active for this device, the existing connection will be leveraged without modifying it. ID cannot be a group-id. operationId: writeBlob Brinckman, et al. Expires 24 March 2026 [Page 100] Internet-Draft NIPC September 2025 parameters: - name: id in: path description: The ID of the device. Group ID is not allowed. required: true schema: type: string format: uuid example: 12345678-1234-5678-1234-56789abcdef4 - name: propertyName in: query description: |- The SDF property name that needs to be written to. required: true schema: type: string example: "https://example.com/heartrate#/sdfObject/thermos\ tat/sdfProperty/firmware" requestBody: content: application/json: schema: $ref: '#/components/schemas/Extension-Blob' required: true responses: '204': description: Success, no content 'default': description: Error response content: application/json: schema: $ref: '../NIPC.yaml#/components/schemas/FailureRespo\ nse' components: schemas: # Extensions ## A binary blob Extension Extension-Blob: required: - blob type: object properties: blob: type: string format: byte chunksize: Brinckman, et al. Expires 24 March 2026 [Page 101] Internet-Draft NIPC September 2025 type: integer C.2. NIPC API bulk operations extension file "Extension-Bulk.yaml" =============== NOTE: '\' line wrapping per RFC 8792 ================ # yaml-language-server: $schema=https://json-schema.org/draft/2020-1\ 2/schema openapi: 3.0.3 info: title: Non IP Device Control (NIPC) API bulk extension description: |- Non IP Device Control (NIPC) API bulk extension termsOfService: http://swagger.io/terms/ contact: email: bbrinckm@cisco.com license: name: TBD url: TBD version: 0.13.0 externalDocs: description: NIPC IETF draft url: https://datatracker.ietf.org/doc/draft-ietf-asdf-nipc/ servers: - url: "{gw_host}/nipc/draft-13" variables: gw_host: default: localhost description: Gateway Host tags: - name: NIPC API extensions description: |- APIs that simplify application interaction by implementing one or more basic APIs into a single API call. paths: ### Extensions /extensions/{id}/bulk: post: tags: - NIPC API extensions summary: Compound operations on a device description: Compound operations on a device operationId: Bulk parameters: - name: id Brinckman, et al. Expires 24 March 2026 [Page 102] Internet-Draft NIPC September 2025 in: path description: The ID of the device. Group ID is not allowed. required: true schema: type: string format: uuid example: 12345678-1234-5678-1234-56789abcdef4 requestBody: content: application/json: schema: $ref: "#/components/schemas/Extension-Bulk" examples: bulkRequest: $ref: "#/components/examples/bulkRequest" firmwareUpgradeRequest: $ref: "#/components/examples/firmwareUpgradeRequest" required: true responses: "202": description: Accepted headers: Location: schema: type: string example: /extensions/12345678-1234-5678-1234-56789ab\ cdef4/bulk/status?instanceId=12345678-1234-5678-1234-56789abcdef4 description: URL to get the bulk status response "401": description: Unauthorized "405": description: Invalid request "500": description: Server-side failure content: application/json: schema: $ref: "../NIPC.yaml#/components/schemas/FailureRespo\ nse" callbacks: bulkEvent: "{$request.body#/callback.url}": post: description: Callback for bulk response operationId: bulkCallback requestBody: content: application/json: Brinckman, et al. Expires 24 March 2026 [Page 103] Internet-Draft NIPC September 2025 schema: allOf: - $ref: "../NIPC.yaml#/components/schemas/Id" - $ref: "#/components/schemas/Extension-Bulk\ Response" responses: "200": description: OK "400": description: Bad request "401": description: Unauthorized "405": description: Invalid request "500": description: Server-side failure get: tags: - NIPC API extensions summary: Get Bulk response description: Get Bulk response operationId: getBulkResponse parameters: - name: id in: path description: The ID of the device. Group ID is not allowed. required: true schema: type: string format: uuid example: 12345678-1234-5678-1234-56789abcdef4 - name: instanceId in: query description: Instance ID of the bulk operation required: true schema: type: string format: uuid example: 12345678-1234-5678-1234-56789abcdef4 responses: "200": description: OK headers: content: application/json: schema: allOf: - $ref: "../NIPC.yaml#/components/schemas/Id" Brinckman, et al. Expires 24 March 2026 [Page 104] Internet-Draft NIPC September 2025 - $ref: "#/components/schemas/Extension-BulkRespon\ se" examples: bulkResponse: $ref: "#/components/examples/bulkResponse" firmwareUpgradeResponse: $ref: "#/components/examples/firmwareUpgradeRespon\ se" errorBulkResponse: $ref: "#/components/examples/errorBulkResponse" /extensions/{id}/bulk/status: get: tags: - NIPC API extensions summary: Get Bulk status description: Get Bulk status operationId: getBulkStatus parameters: - name: id in: path description: The ID of the device. Group ID is not allowed. required: true schema: type: string format: uuid example: 12345678-1234-5678-1234-56789abcdef4 - name: instanceId in: query description: Instance ID of the bulk operation required: true schema: type: string format: uuid example: 12345678-1234-5678-1234-56789abcdef4 responses: "200": description: OK headers: content: application/json: schema: allOf: - $ref: "./Extension-Async.yaml#/components/schema\ s/Extension-StatusResponse" "303": description: See Other headers: Brinckman, et al. Expires 24 March 2026 [Page 105] Internet-Draft NIPC September 2025 Location: schema: type: string example: /extensions/12345678-1234-5678-1234-56789ab\ cdef4/bulk?instanceId=12345678-1234-5678-1234-56789abcdef4 description: URL to get the bulk response content: application/json: schema: allOf: - $ref: "./Extension-Async.yaml#/components/schema\ s/Extension-StatusResponse" examples: successExample: summary: Success value: status: COMPLETED components: schemas: # Extensions ## Bulk schema Extension Extension-Bulk: allOf: - $ref: "./Extension-Async.yaml#/components/schemas/Extensio\ n-Callback" - type: object properties: operations: type: array items: $ref: "#/components/schemas/Extension-BulkOperation" trigger: type: string description: |- When to trigger the operations. If not specified, th\ e operations are triggered immediately. default: immediate enum: - immediate - advertisement ## Extension that defines an operation in a bulk API Extension-BulkOperation: required: - method - path allOf: Brinckman, et al. Expires 24 March 2026 [Page 106] Internet-Draft NIPC September 2025 - type: object properties: method: type: string enum: - POST - PUT - GET path: type: string enum: - /devices/{id}/properties?propertyName={propertyNam\ e} - /devices/{id}/actions/?actionName={actionName} - /extensions/{id}/properties/read/conditional?prope\ rtyName={propertyName} - /extensions/{id}/events/conditional?eventName={eve\ ntName} - /extensions/{id}/properties/file?propertyName={pro\ pertyName} example: /devices/12345678-1234-5678-1234-56789abcdef4\ /properties?propertyName=https%3A%2F%2Fexample.com%2Fthermometer%23%\ 2FsdfThing%2Fthermometer%2FsdfProperty%2Ftemperature data: type: object oneOf: - $ref: "../NIPC.yaml#/components/schemas/Value" - $ref: "./Extension-ReadConditional.yaml#/component\ s/schemas/Extension-ConditionalRead" ## Multiple returns for a bulk operation Extension-BulkResponse: type: object properties: operations: type: array items: $ref: "#/components/schemas/Extension-OperationResponse" ## Return for an operation Extension-OperationResponse: allOf: - type: object properties: method: type: string enum: - POST Brinckman, et al. Expires 24 March 2026 [Page 107] Internet-Draft NIPC September 2025 - PUT - GET path: type: string enum: - /devices/{id}/properties?propertyName={propertyNam\ e} - /devices/{id}/actions/?actionName={actionName} - /extensions/{id}/properties/read/conditional?prope\ rtyName={propertyName} - /extensions/{id}/events/conditional?eventName={eve\ ntName} example: /devices/12345678-1234-5678-1234-56789abcdef4\ /properties?propertyName=https%3A%2F%2Fexample.com%2Fthermometer%23%\ 2FsdfThing%2Fthermometer%2FsdfProperty%2Ftemperature response: anyOf: - $ref: "../NIPC.yaml#/components/schemas/Value" - $ref: "../NIPC.yaml#/components/schemas/SuccessRes\ ponse" - $ref: "../NIPC.yaml#/components/schemas/FailureRes\ ponse" examples: bulkRequest: summary: Bulk request example value: operations: - method: GET path: /devices/12345678-1234-5678-1234-56789abcdef4/prop\ erties?propertyName=https%3A%2F%2Fexample.com%2Fthermometer%23%2Fsdf\ Thing%2Fthermometer%2FsdfProperty%2Ftemperature - method: PUT path: /devices/12345678-1234-5678-1234-56789abcdef4/prop\ erties?propertyName=https%3A%2F%2Fexample.com%2Fthermometer%23%2Fsdf\ Thing%2Fthermometer%2FsdfProperty%2Ftemperature data: value: dGVzdA== - method: POST path: /extensions/12345678-1234-5678-1234-56789abcdef4/p\ roperties/read/conditional?propertyName=https%3A%2F%2Fexample.com%2F\ thermometer%23%2FsdfThing%2Fthermometer%2FsdfProperty%2Ftemperature data: value: dGVzdA== maxRepeat: 5 retryTime: 1 bulkResponse: summary: Bulk response example Brinckman, et al. Expires 24 March 2026 [Page 108] Internet-Draft NIPC September 2025 value: operations: - method: GET path: /devices/12345678-1234-5678-1234-56789abcdef4/prop\ erties?propertyName=https%3A%2F%2Fexample.com%2Fthermometer%23%2Fsdf\ Thing%2Fthermometer%2FsdfProperty%2Ftemperature response: value: dGVzdA== - method: PUT path: /devices/12345678-1234-5678-1234-56789abcdef4/prop\ erties?propertyName=https%3A%2F%2Fexample.com%2Fthermometer%23%2Fsdf\ Thing%2Fthermometer%2FsdfProperty%2Ftemperature response: status: 200 - method: POST path: /extensions/12345678-1234-5678-1234-56789abcdef4/p\ roperties/read/conditional?propertyName=https%3A%2F%2Fexample.com%2F\ thermometer%23%2FsdfThing%2Fthermometer%2FsdfProperty%2Ftemperature response: value: dGVzdA== errorBulkResponse: summary: Error Bulk response example value: operations: - method: GET path: /devices/12345678-1234-5678-1234-56789abcdef4/prop\ erties?propertyName=https%3A%2F%2Fexample.com%2Fthermometer%23%2Fsdf\ Thing%2Fthermometer%2FsdfProperty%2Ftemperature response: type: https://www.iana.org/assignments/nipc-problem-ty\ pes#property-not-readable status: 400 title: Property not readable detail: Property https://example.com/thermometer#/sdfT\ hing/thermometer/sdfProperty/temperature is not readable - method: PUT path: /devices/12345678-1234-5678-1234-56789abcdef4/prop\ erties?propertyName=https%3A%2F%2Fexample.com%2Fthermometer%23%2Fsdf\ Thing%2Fthermometer%2FsdfProperty%2Ftemperature response: type: https://www.iana.org/assignments/nipc-problem-ty\ pes#extension-operation-not-executed status: 400 title: Operation not executed detail: Operation was not executed since the previous \ operation failed - method: POST path: /extensions/12345678-1234-5678-1234-56789abcdef4/p\ Brinckman, et al. Expires 24 March 2026 [Page 109] Internet-Draft NIPC September 2025 roperties/read/conditional?propertyName=https%3A%2F%2Fexample.com%2F\ thermometer%23%2FsdfThing%2Fthermometer%2FsdfProperty%2Ftemperature response: type: https://www.iana.org/assignments/nipc-problem-ty\ pes#extension-operation-not-executed status: 400 title: Operation not executed detail: Operation was not executed since the previous \ operation failed firmwareUpgradeRequest: summary: Firmware upgrade request example value: operations: - method: PUT path: /devices/12345678-1234-5678-1234-56789abcdef4/prop\ erties?propertyName=https%3A%2F%2Fexample.com%2Fthermometer%23%2Fsdf\ Thing%2Fthermometer%2FsdfProperty%2FstartOTA data: value: dGVzdA== - method: POST path: /extensions/12345678-1234-5678-1234-56789abcdef4/e\ vents/conditional?eventName=https%3A%2F%2Fexample.com%2Fthermometer%\ 23%2FsdfThing%2Fthermometer%2FsdfEvent%2FotaStarted data: value: MQ== timeout: 5 - method: PUT path: /extensions/12345678-1234-5678-1234-56789abcdef4/p\ roperties/file?propertyName=https%3A%2F%2Fexample.com%2Fthermometer%\ 23%2FsdfThing%2Fthermometer%2FsdfProperty%2Ffirmware data: fileURL: https://example.com/firmware.bin chunkSize: 20 sha256Checksum: abcdef1234567890abcdef1234567890abcdef\ 1234567890abcdef1234567890 - method: PUT path: /devices/12345678-1234-5678-1234-56789abcdef4/prop\ erties?propertyName=https%3A%2F%2Fexample.com%2Fthermometer%23%2Fsdf\ Thing%2Fthermometer%2FsdfProperty%2FfinishOTA data: value: dGVzdA== - method: POST path: /extensions/12345678-1234-5678-1234-56789abcdef4/p\ roperties/read/conditional?propertyName=https%3A%2F%2Fexample.com%2F\ thermometer%23%2FsdfThing%2Fthermometer%2FsdfProperty%2FupdateStatus data: value: MQ== maxRepeat: 5 Brinckman, et al. Expires 24 March 2026 [Page 110] Internet-Draft NIPC September 2025 retryTime: 1 - method: PUT path: /devices/12345678-1234-5678-1234-56789abcdef4/prop\ erties?propertyName=https%3A%2F%2Fexample.com%2Fthermometer%23%2Fsdf\ Thing%2Fthermometer%2FsdfProperty%2FactivateOTA data: value: dGVzdA== firmwareUpgradeResponse: summary: Firmware upgrade response example value: operations: - method: PUT path: /devices/12345678-1234-5678-1234-56789abcdef4/prop\ erties?propertyName=https%3A%2F%2Fexample.com%2Fthermometer%23%2Fsdf\ Thing%2Fthermometer%2FsdfProperty%2FstartOTA response: status: 200 - method: POST path: /extensions/12345678-1234-5678-1234-56789abcdef4/e\ vents/conditional?eventName=https%3A%2F%2Fexample.com%2Fthermometer%\ 23%2FsdfThing%2Fthermometer%2FsdfEvent%2FotaStarted response: value: MQ== - method: PUT path: /extensions/12345678-1234-5678-1234-56789abcdef4/p\ roperties/file?propertyName=https%3A%2F%2Fexample.com%2Fthermometer%\ 23%2FsdfThing%2Fthermometer%2FsdfProperty%2Ffirmware response: status: 204 - method: PUT path: /devices/12345678-1234-5678-1234-56789abcdef4/prop\ erties?propertyName=https%3A%2F%2Fexample.com%2Fthermometer%23%2Fsdf\ Thing%2Fthermometer%2FsdfProperty%2FfinishOTA response: status: 200 - method: POST path: /extensions/12345678-1234-5678-1234-56789abcdef4/p\ roperties/read/conditional?propertyName=https%3A%2F%2Fexample.com%2F\ thermometer%23%2FsdfThing%2Fthermometer%2FsdfProperty%2FupdateStatus response: value: MQ== - method: PUT path: /devices/12345678-1234-5678-1234-56789abcdef4/prop\ erties?propertyName=https%3A%2F%2Fexample.com%2Fthermometer%23%2Fsdf\ Thing%2Fthermometer%2FsdfProperty%2FactivateOTA data: status: 200 Brinckman, et al. Expires 24 March 2026 [Page 111] Internet-Draft NIPC September 2025 C.3. NIPC API write file extension file "Extension-File.yaml" =============== NOTE: '\\' line wrapping per RFC 8792 =============== # yaml-language-server: $schema=https://json-schema.org/draft/2020-1\ \2/schema openapi: 3.0.3 info: title: Non IP Device Control (NIPC) API write file extension description: |- Non IP Device Control (NIPC) API write file extension termsOfService: http://swagger.io/terms/ contact: email: bbrinckm@cisco.com license: name: TBD url: TBD version: 0.13.0 externalDocs: description: NIPC IETF draft url: https://datatracker.ietf.org/doc/draft-ietf-asdf-nipc/ servers: - url: "{gw_host}/nipc/draft-13" variables: gw_host: default: localhost description: Gateway Host tags: - name: NIPC API extensions description: |- APIs that simplify application interaction by implementing one or more basic APIs into a single API call. paths: ### Extensions /extensions/{id}/properties/file: put: tags: - NIPC API extensions summary: Write a file to a property on a device description: |- Write a file to a property on a device. Will chunk up the file and perform multiple writes. If the underlying protocol requires a connection to be set up, this API call will perform the necessary connection management. If a connection is already active for this device, the existing connection will be leveraged without modifying it. ID cannot be a Brinckman, et al. Expires 24 March 2026 [Page 112] Internet-Draft NIPC September 2025 group-id. operationId: writeFile parameters: - name: id in: path description: The ID of the device. Group ID is not allowed. required: true schema: type: string format: uuid example: 12345678-1234-5678-1234-56789abcdef4 - name: propertyName in: query description: |- The SDF property name that needs to be written to. required: true schema: type: string example: "https://example.com/heartrate#/sdfObject/thermos\ \tat/sdfProperty/firmware" requestBody: content: application/json: schema: allOf: - $ref: '#/components/schemas/Extension-File' - $ref: './Extension-Async.yaml#/components/schemas/\ \Extension-Callback' required: true responses: '202': description: Accepted headers: Location: schema: type: string example: /extensions/12345678-1234-5678-1234-56789ab\ \cdef4/properties/file/status?propertyName=https%3A%2F%2Fexample.com\ \%2Fheartrate%23%2FsdfObject%2Fthermostat%2FsdfProperty%2Ffirmware&i\ \nstanceId=12345678-1234-5678-1234-56789abcdef4 description: |- URL to get the file write status Retry-After: schema: type: integer description: |- Time in seconds to wait before retrying 'default': Brinckman, et al. Expires 24 March 2026 [Page 113] Internet-Draft NIPC September 2025 description: Error response content: application/json: schema: $ref: '../NIPC.yaml#/components/schemas/FailureRespo\ \nse' callbacks: callbackEvent: "{$request.body#/callback.url}": post: requestBody: content: application/json: schema: anyOf: - allOf: - $ref: '../NIPC.yaml#/components/schemas/\ \Id' - $ref: '../NIPC.yaml#/components/schemas/\ \PropertyValue' - $ref: '../NIPC.yaml#/components/schemas/Fa\ \ilureResponse' examples: successExample: summary: Success value: id: 12345678-1234-5678-1234-56789abcdef4 property: https://example.com/heartrate#/s\ \dfObject/thermostat/sdfProperty/firmware failedResponse: summary: Failed value: id: 12345678-1234-5678-1234-56789abcdef4 status: 400 type: https://www.iana.org/assignments/nip\ \c-problem-types#invalid-id title: Invalid ID detail: "Invalid request" property: https://example.com/heartrate#/s\ \dfObject/thermostat/sdfProperty/firmware responses: '200': description: Success get: tags: - NIPC API extensions summary: Get the status of a file write operation description: |- Brinckman, et al. Expires 24 March 2026 [Page 114] Internet-Draft NIPC September 2025 Get the status of a file write operation. This will return the status of the file write operation, including any errors that may have occurred. operationId: getFileWriteStatus parameters: - name: id in: path description: The ID of the device. Group ID is not allowed. required: true schema: type: string format: uuid example: 12345678-1234-5678-1234-56789abcdef4 - name: propertyName in: query description: |- The SDF property name that needs to be written to. required: true schema: type: string example: "https://example.com/heartrate#/sdfObject/thermos\ \tat/sdfProperty/firmware" - name: instanceId in: query description: |- The Instance ID for the file write operation. required: true schema: type: string format: uuid example: 12345678-1234-5678-1234-56789abcdef4 responses: '204': description: Success, no content default: description: Error response content: application/json: schema: $ref: '../NIPC.yaml#/components/schemas/FailureRespo\ \nse' /extensions/{id}/properties/file/status: get: tags: - NIPC API extensions summary: Get the status of a file write operation description: |- Get the status of a file write operation. This will return Brinckman, et al. Expires 24 March 2026 [Page 115] Internet-Draft NIPC September 2025 the status of the file write operation, including any errors that may have occurred. operationId: getFileWriteStatus parameters: - name: id in: path description: The ID of the device. Group ID is not allowed. required: true schema: type: string format: uuid example: 12345678-1234-5678-1234-56789abcdef4 - name: propertyName in: query description: |- The SDF property name that needs to be written to. required: true schema: type: string example: "https://example.com/heartrate#/sdfObject/thermos\ \tat/sdfProperty/firmware" - name: instanceId in: query description: |- The Instance ID for the file write operation. required: true schema: type: string format: uuid example: 12345678-1234-5678-1234-56789abcdef4 responses: '200': description: Success, returns the status of the file write\ \ operation. content: application/json: schema: $ref: './Extension-Async.yaml#/components/schemas/Ex\ \tension-StatusResponse' '303': description: See Other headers: Location: schema: type: string example: /extensions/12345678-1234-5678-1234-56789ab\ \cdef4/properties/file?propertyName=https%3A%2F%2Fexample.com%2Fhear\ \trate%23%2FsdfObject%2Fthermostat%2FsdfProperty%2Ffirmware&instance\ Brinckman, et al. Expires 24 March 2026 [Page 116] Internet-Draft NIPC September 2025 \Id=12345678-1234-5678-1234-56789abcdef4 description: URL to get the file write response content: application/json: schema: $ref: './Extension-Async.yaml#/components/schemas/Ex\ \tension-StatusResponse' examples: successExample: summary: Completed value: id: 12345678-1234-5678-1234-56789abcdef4 status: COMPLETED components: schemas: # Extensions ## A File Extension Extension-File: required: - fileURL type: object properties: fileURL: type: string example: "https://domain.com/firmware.dat" description: |- URL to the firmware file. The HTTP method is assumed to be a GET. chunkSize: type: integer sha256Checksum: type: string description: firmware checksum headers: type: object additionalProperties: type: string example: x-api-key: fjelk-3dl33f-2wdsd C.4. NIPC API conditional read extension Brinckman, et al. Expires 24 March 2026 [Page 117] Internet-Draft NIPC September 2025 file "Extension-ReadConditional.yaml" =============== NOTE: '\' line wrapping per RFC 8792 ================ # yaml-language-server: $schema=https://json-schema.org/draft/2020-1\ 2/schema openapi: 3.0.3 info: title: Non IP Device Control (NIPC) API read conditional extension description: |- Non IP Device Control (NIPC) API read conditional extension termsOfService: http://swagger.io/terms/ contact: email: bbrinckm@cisco.com license: name: TBD url: TBD version: 0.13.0 externalDocs: description: NIPC IETF draft url: https://datatracker.ietf.org/doc/draft-ietf-asdf-nipc/ servers: - url: "{gw_host}/nipc/draft-13" variables: gw_host: default: localhost description: Gateway Host tags: - name: NIPC API extensions description: |- APIs that simplify application interaction by implementing one or more basic APIs into a single API call. paths: ### Extensions /extensions/{id}/properties/read/conditional: post: tags: - NIPC API extensions summary: Conditional read of a property description: Conditional read of a property operationId: conditionalRead parameters: - name: id in: path description: The ID of the device. Group ID is not allowed. required: true schema: type: string Brinckman, et al. Expires 24 March 2026 [Page 118] Internet-Draft NIPC September 2025 format: uuid example: 12345678-1234-5678-1234-56789abcdef4 - name: propertyName in: query description: |- The SDF property name that needs to be read conditionally. required: true allowReserved: true schema: type: string example: "#/sdfObject/thermostat/sdfProperty/temperature" requestBody: content: application/json: schema: $ref: '#/components/schemas/Extension-ConditionalRead' required: true responses: '202': description: Accepted headers: Location: schema: type: string example: /extensions/12345678-1234-5678-1234-56789ab\ cdef4/properties/read/conditional/status?propertyName=https%3A%2F%2F\ example.com%2Fheartrate%23%2FsdfObject%2Fthermostat%2FsdfProperty%2F\ temperature&instanceId=12345678-1234-5678-1234-56789abcdef4 description: |- URL to get the conditional read status Retry-After: schema: type: integer description: |- Time in seconds to wait before retrying 'default': description: Error response content: application/json: schema: $ref: '../NIPC.yaml#/components/schemas/FailureRespo\ nse' callbacks: callbackEvent: "{$request.body#/callback.url}": post: requestBody: content: Brinckman, et al. Expires 24 March 2026 [Page 119] Internet-Draft NIPC September 2025 application/json: schema: anyOf: - allOf: - $ref: '../NIPC.yaml#/components/schemas/\ Id' - $ref: '../NIPC.yaml#/components/schemas/\ PropertyValue' - $ref: '../NIPC.yaml#/components/schemas/Fa\ ilureResponse' examples: successExample: summary: Success value: id: 12345678-1234-5678-1234-56789abcdef4 property: https://example.com/heartrate#/s\ dfObject/thermostat/sdfProperty/temperature value: dGVzdA== failedResponse: summary: Failed value: id: 12345678-1234-5678-1234-56789abcdef4 status: 400 type: https://www.iana.org/assignments/nip\ c-problem-types#invalid-id title: Invalid ID detail: "Invalid request" property: https://example.com/heartrate#/s\ dfObject/thermostat/sdfProperty/temperature value: dGVzdA== responses: '200': description: Success get: tags: - NIPC API extensions summary: Get Conditional read response of a property description: Conditional read response of a property operationId: getConditionalRead parameters: - name: id in: path description: The ID of the device. Group ID is not allowed. required: true schema: type: string format: uuid Brinckman, et al. Expires 24 March 2026 [Page 120] Internet-Draft NIPC September 2025 example: 12345678-1234-5678-1234-56789abcdef4 - name: propertyName in: query description: |- The SDF property name that needs to be read conditionally. required: true allowReserved: true schema: type: string example: "#/sdfObject/thermostat/sdfProperty/temperature" - name: instanceId in: query description: |- Instance ID of the conditional read operation required: true schema: type: string format: uuid example: 12345678-1234-5678-1234-56789abcdef4 responses: '200': description: Success headers: content: application/json: schema: allOf: - $ref: '../NIPC.yaml#/components/schemas/Value' application/octet-stream: schema: type: string format: binary description: Binary data of the property value default: description: Error response content: application/problem+json: schema: allOf: - $ref: '../NIPC.yaml#/components/schemas/FailureR\ esponse' /extensions/{id}/properties/read/conditional/status: get: tags: - NIPC API extensions summary: Get Conditional read status of a property description: Conditional read status of a property operationId: getConditionalReadStatus Brinckman, et al. Expires 24 March 2026 [Page 121] Internet-Draft NIPC September 2025 parameters: - name: id in: path description: The ID of the device. Group ID is not allowed. required: true schema: type: string format: uuid example: 12345678-1234-5678-1234-56789abcdef4 - name: propertyName in: query description: |- The SDF property name that needs to be read conditionally. required: true allowReserved: true schema: type: string example: "#/sdfObject/thermostat/sdfProperty/temperature" - name: instanceId in: query description: Instance ID of the conditional read operation required: true schema: type: string format: uuid example: 12345678-1234-5678-1234-56789abcdef4 responses: '200': description: OK headers: content: application/json: schema: $ref: './Extension-Async.yaml#/components/schemas/Ex\ tension-StatusResponse' '303': description: See Other headers: Location: schema: type: string example: /extensions/12345678-1234-5678-1234-56789ab\ cdef4/properties/read/conditional?propertyName=https%3A%2F%2Fexample\ .com%2Fheartrate%23%2FsdfObject%2Fthermostat%2FsdfProperty%2Ftempera\ ture&instanceId=12345678-1234-5678-1234-56789abcdef4 description: URL to get the conditional read response content: application/json: Brinckman, et al. Expires 24 March 2026 [Page 122] Internet-Draft NIPC September 2025 schema: $ref: './Extension-Async.yaml#/components/schemas/Ex\ tension-StatusResponse' examples: successExample: summary: Completed value: id: 12345678-1234-5678-1234-56789abcdef4 status: COMPLETED components: schemas: # Extensions Extension-ConditionalRead: allOf: - $ref: '../NIPC.yaml#/components/schemas/Value' - $ref: './Extension-Async.yaml#/components/schemas/Extensio\ n-Callback' - type: object properties: maxRepeat: description: |- maximum time the conditional read should repeat (default 5, max 10) type: integer example: 5 retryTime: description: |- time between reads in seconds (default 1, max 10) type: integer example: 1 C.5. NIPC API conditional event extension file "Extension-EventConditional.yaml" =============== NOTE: '\' line wrapping per RFC 8792 ================ # yaml-language-server: $schema=https://json-schema.org/draft/2020-1\ 2/schema openapi: 3.0.3 info: title: Non IP Device Control (NIPC) API event conditional extension description: |- Non IP Device Control (NIPC) API event conditional extension termsOfService: http://swagger.io/terms/ contact: email: bbrinckm@cisco.com Brinckman, et al. Expires 24 March 2026 [Page 123] Internet-Draft NIPC September 2025 license: name: TBD url: TBD version: 0.13.0 externalDocs: description: NIPC IETF draft url: https://datatracker.ietf.org/doc/draft-ietf-asdf-nipc/ servers: - url: "{gw_host}/nipc/draft-13" variables: gw_host: default: localhost description: Gateway Host tags: - name: NIPC API extensions description: |- APIs that simplify application interaction by implementing one or more basic APIs into a single API call. paths: ### Extensions /extensions/{id}/events/conditional: post: tags: - NIPC API extensions summary: Enable an event until a condition is met description: Enable an event until a condition is met operationId: conditionalEvent parameters: - name: id in: path description: The ID of the device. Group ID is not allowed. required: true schema: type: string format: uuid example: 12345678-1234-5678-1234-56789abcdef4 - name: eventName in: query description: |- The SDF event name that needs to be enabled. required: true allowReserved: true schema: type: string example: "#/sdfObject/thermostat/sdfEvent/temperature" requestBody: content: Brinckman, et al. Expires 24 March 2026 [Page 124] Internet-Draft NIPC September 2025 application/json: schema: $ref: '#/components/schemas/Extension-ConditionalEvent' required: true responses: '202': description: Accepted headers: Location: schema: type: string example: /extensions/12345678-1234-5678-1234-56789ab\ cdef4/events/conditional/status?eventName=https%3A%2F%2Fexample.com%\ 2Fheartrate%23%2FsdfObject%2Fthermostat%2FsdfEvent%2Ftemperature&ins\ tanceId=12345678-1234-5678-1234-56789abcdef4 description: |- URL to get the conditional event status Retry-After: schema: type: integer description: |- Time in seconds to wait before retrying 'default': description: Error response content: application/json: schema: $ref: '../NIPC.yaml#/components/schemas/FailureRespo\ nse' callbacks: callbackEvent: "{$request.body#/callback.url}": post: requestBody: content: application/json: schema: anyOf: - allOf: - $ref: '../NIPC.yaml#/components/schemas/\ Id' - $ref: '../NIPC.yaml#/components/schemas/\ PropertyValue' - $ref: '../NIPC.yaml#/components/schemas/Fa\ ilureResponse' examples: successExample: summary: Success Brinckman, et al. Expires 24 March 2026 [Page 125] Internet-Draft NIPC September 2025 value: id: 12345678-1234-5678-1234-56789abcdef4 event: https://example.com/heartrate#/sdfO\ bject/thermostat/sdfEvent/temperature value: dGVzdA== failedResponse: summary: Failed value: id: 12345678-1234-5678-1234-56789abcdef4 status: 400 type: https://www.iana.org/assignments/nip\ c-problem-types#invalid-id title: Invalid ID detail: "Invalid request" event: https://example.com/heartrate#/sdfO\ bject/thermostat/sdfEvent/temperature value: dGVzdA== responses: '200': description: Success get: tags: - NIPC API extensions summary: Get Conditional event response description: Conditional event response operationId: getConditionalEvent parameters: - name: id in: path description: The ID of the device. Group ID is not allowed. required: true schema: type: string format: uuid example: 12345678-1234-5678-1234-56789abcdef4 - name: eventName in: query description: |- The name of the SDF event that is enabled. required: true allowReserved: true schema: type: string example: "#/sdfObject/thermostat/sdfEvent/temperature" - name: instanceId in: query description: |- Brinckman, et al. Expires 24 March 2026 [Page 126] Internet-Draft NIPC September 2025 Instance ID of the conditional event operation required: true schema: type: string format: uuid example: 12345678-1234-5678-1234-56789abcdef4 responses: '200': description: Success headers: content: application/json: schema: allOf: - $ref: '../NIPC.yaml#/components/schemas/Value' application/octet-stream: schema: type: string format: binary description: Binary data of the event value default: description: Error response content: application/problem+json: schema: allOf: - $ref: '../NIPC.yaml#/components/schemas/FailureR\ esponse' /extensions/{id}/events/conditional/status: get: tags: - NIPC API extensions summary: Get Conditional event status description: Conditional event status operationId: getConditionalEventStatus parameters: - name: id in: path description: The ID of the device. Group ID is not allowed. required: true schema: type: string format: uuid example: 12345678-1234-5678-1234-56789abcdef4 - name: eventName in: query description: |- The name of the SDF event that is enabled. Brinckman, et al. Expires 24 March 2026 [Page 127] Internet-Draft NIPC September 2025 required: true allowReserved: true schema: type: string example: "#/sdfObject/thermostat/sdfEvent/temperature" - name: instanceId in: query description: Instance ID of the conditional event operation required: true schema: type: string format: uuid example: 12345678-1234-5678-1234-56789abcdef4 responses: '200': description: OK headers: content: application/json: schema: $ref: './Extension-Async.yaml#/components/schemas/Ex\ tension-StatusResponse' '303': description: See Other headers: Location: schema: type: string example: /extensions/12345678-1234-5678-1234-56789ab\ cdef4/events/conditional?eventName=https%3A%2F%2Fexample.com%2Fheart\ rate%23%2FsdfObject%2Fthermostat%2FsdfEvent%2Ftemperature&instanceId\ =12345678-1234-5678-1234-56789abcdef4 description: URL to get the conditional event response content: application/json: schema: $ref: './Extension-Async.yaml#/components/schemas/Ex\ tension-StatusResponse' examples: successExample: summary: Completed value: id: 12345678-1234-5678-1234-56789abcdef4 status: COMPLETED components: schemas: # Extensions Brinckman, et al. Expires 24 March 2026 [Page 128] Internet-Draft NIPC September 2025 Extension-ConditionalEvent: allOf: - $ref: './Extension-Async.yaml#/components/schemas/Extensio\ n-Callback' - $ref: '../NIPC.yaml#/components/schemas/Value' - type: object properties: timeout: description: |- Time in seconds to keep the event enabled. If the event condition is not met within this time, the event will be disabled and marked as failed. type: integer example: 5 C.6. NIPC API property extensions file "Extension-Property.yaml" =============== NOTE: '\' line wrapping per RFC 8792 ================ # yaml-language-server: $schema=https://json-schema.org/draft/2020-1\ 2/schema openapi: 3.0.3 info: title: Non IP Device Control (NIPC) API read conditional extension description: |- Non IP Device Control (NIPC) API read conditional extension termsOfService: http://swagger.io/terms/ contact: email: bbrinckm@cisco.com license: name: TBD url: TBD version: 0.13.0 externalDocs: description: NIPC IETF draft url: https://datatracker.ietf.org/doc/draft-ietf-asdf-nipc/ servers: - url: "{gw_host}/nipc/draft-13" variables: gw_host: default: localhost description: Gateway Host tags: - name: NIPC API extensions description: |- APIs that simplify application interaction by implementing Brinckman, et al. Expires 24 March 2026 [Page 129] Internet-Draft NIPC September 2025 one or more basic APIs into a single API call. paths: ### Extensions /extensions/{id}/transmit: post: tags: - NIPC API extensions summary: Transmit to a device description: |- Transmit a payload to a device. The transmission is performe\ d on the AP where the device was last seen operationId: ActionTransmit parameters: - name: id in: path description: The ID of the device. Group ID is not allowed. required: true schema: type: string format: uuid example: 12345678-1234-5678-1234-56789abcdef4 requestBody: content: application/json: schema: $ref: '#/components/schemas/Transmit' required: true responses: '200': description: Success default: description: Error response content: application/problem+json: schema: $ref: '../NIPC.yaml#/components/schemas/FailureRespo\ nse' /extensions/{id}/properties/write: post: tags: - NIPC API extensions summary: Write a value to an property using protocol mapping description: |- Write a value to an unregistered property, embedding property protocol mapping in the API, this does not require property registration. You cannot write to a group id. Brinckman, et al. Expires 24 March 2026 [Page 130] Internet-Draft NIPC September 2025 operationId: ActionPropWrite parameters: - name: id in: path description: The ID of the device. Group ID is not allowed. required: true schema: type: string format: uuid example: 12345678-1234-5678-1234-56789abcdef4 requestBody: content: application/json: schema: allOf: - $ref: '../NIPC.yaml#/components/schemas/Value' - $ref: '../protocolmaps/ProtocolMap.yaml#/component\ s/schemas/ProtocolMap-Property' required: true responses: '204': description: Success, no content default: description: Error response content: application/problem+json: schema: $ref: '../NIPC.yaml#/components/schemas/FailureRespo\ nse' /extensions/{id}/properties/read: post: tags: - NIPC API extensions summary: Read a value to an property using protocol mapping description: |- Read a value from an unregistered property, embedding property protocol mapping in the API, this does not require property registration. You cannot read from a group id. operationId: ActionPropRead parameters: - name: id in: path description: The ID of the device. Group ID is not allowed. required: true schema: type: string format: uuid Brinckman, et al. Expires 24 March 2026 [Page 131] Internet-Draft NIPC September 2025 example: 12345678-1234-5678-1234-56789abcdef4 requestBody: content: application/json: schema: $ref: '../protocolmaps/ProtocolMap.yaml#/components/sc\ hemas/ProtocolMap-Property' required: true responses: '200': description: Success content: application/json: schema: allOf: - $ref: '../NIPC.yaml#/components/schemas/Value' default: description: Error response content: application/problem+json: schema: $ref: '../NIPC.yaml#/components/schemas/FailureRespo\ nse' components: schemas: Transmit: allOf: - $ref: '../protocolmaps/ProtocolMap.yaml#/components/schema\ s/ProtocolMap-Broadcast' required: - cycle type: object properties: cycle: type: string example: single enum: - single - repeat # transmit time in ms transmitTime: type: integer example: 3000 # interval between transmits in ms transmitInterval: type: integer example: 500 Brinckman, et al. Expires 24 March 2026 [Page 132] Internet-Draft NIPC September 2025 payload: type: string format: byte example: AgEaAgoMFv9MABAHch9BsDkgeA== Appendix D. Example SDF model with protocol mappings for BLE file "thermometer.sdf.json" { "namespace": { "thermometer": "https://example.com/thermometer" }, "defaultNamespace": "thermometer", "sdfThing": { "thermometer": { "sdfObject": { "health_thermometer": { "description": "Health Thermometer", "sdfProperty": { "temperature_type": { "description": "Temperature Type", "observable": false, "writable": false, "readable": true, "sdfProtocolMap": { "ble": { "serviceID": "1809", "characteristicID": "2A1D" } } }, "measurement_interval": { "description": "Measurement Interval", "observable": false, "writable": false, "readable": true, "sdfProtocolMap": { "ble": { "serviceID": "1809", "characteristicID": "2A21" } } } }, "sdfEvent": { "temperature_measurement": { "description": "Temperature Measurement", Brinckman, et al. Expires 24 March 2026 [Page 133] Internet-Draft NIPC September 2025 "sdfOutputData": { "sdfProtocolMap": { "ble": { "type": "gatt", "serviceID": "1809", "characteristicID": "2A1C" } } } }, "intermediate_temperature": { "description": "Intermediate Temperature", "sdfOutputData": { "sdfProtocolMap": { "ble": { "type": "gatt", "serviceID": "1809", "characteristicID": "2A1E" } } } } } } }, "description": "Generic Access, Device Information", "sdfProperty": { "device_name": { "description": "Device Name", "observable": false, "writable": true, "readable": true, "sdfProtocolMap": { "ble": { "serviceID": "1800", "characteristicID": "2A00" } } }, "appearance": { "description": "Appearance", "observable": false, "writable": false, "readable": true, "sdfProtocolMap": { "ble": { "serviceID": "1800", "characteristicID": "2A01" Brinckman, et al. Expires 24 March 2026 [Page 134] Internet-Draft NIPC September 2025 } } }, "manufacturer_name_string": { "description": "Manufacturer Name String", "observable": false, "writable": false, "readable": true, "sdfProtocolMap": { "ble": { "serviceID": "180A", "characteristicID": "2A29" } } }, "model_number_string": { "description": "Model Number String", "observable": false, "writable": false, "readable": true, "sdfProtocolMap": { "ble": { "serviceID": "180A", "characteristicID": "2A24" } } }, "hardware_revision_string": { "description": "Hardware Revision String", "observable": false, "writable": false, "readable": true, "sdfProtocolMap": { "ble": { "serviceID": "180A", "characteristicID": "2A27" } } }, "firmware_revision_string": { "description": "Firmware Revision String", "observable": false, "writable": false, "readable": true, "sdfProtocolMap": { "ble": { "serviceID": "180A", "characteristicID": "2A26" Brinckman, et al. Expires 24 March 2026 [Page 135] Internet-Draft NIPC September 2025 } } }, "system_id": { "description": "System ID", "observable": false, "writable": false, "readable": true, "sdfProtocolMap": { "ble": { "serviceID": "180A", "characteristicID": "2A23" } } } }, "sdfEvent": { "isPresent": { "description": "BLE advertisements", "sdfOutputData": { "sdfProtocolMap": { "ble": { "type": "advertisements" } } } }, "isConnected": { "description": "BLE connection events", "sdfOutputData": { "sdfProtocolMap": { "ble": { "type": "connection_events" } } } } } } } } Figure 35: Example SDF model with protocol mappings for BLE Authors' Addresses Brinckman, et al. Expires 24 March 2026 [Page 136] Internet-Draft NIPC September 2025 Bart Brinckman Cisco Systems Brussels Belgium Email: bbrinckm@cisco.com Rohit Mohan Cisco Systems 170 West Tasman Drive San Jose, 95134 United States of America Email: rohitmo@cisco.com Braeden Sanford Philips Cambridge, United States of America Email: braeden.sanford@philips.com Brinckman, et al. Expires 24 March 2026 [Page 137]