[フレーム] Skip to main content
Javascript disabled? Like other modern websites, the IETF Datatracker relies on Javascript. Please enable Javascript for full functionality.

An Application Layer Interface for Non-Internet-Connected Physical Components (NIPC)
draft-ietf-asdf-nipc-15

Document Type Active Internet-Draft (asdf WG)
Authors Bart Brinckman , Rohit Mohan , Braeden Sanford
Last updated 2025年12月03日 (Latest revision 2025年12月02日)
Replaces draft-brinckman-nipc
RFC stream Internet Engineering Task Force (IETF)
Intended RFC status (None)
Formats
Additional resources Mailing list discussion
Stream WG state WG Document
Document shepherd Niklas Widell
IESG IESG state I-D Exists
Consensus boilerplate Unknown
Telechat date (None)
Responsible AD (None)
Send notices to niklas.widell@ericsson.com
Email authors Email WG IPR References Referenced by Nits Search email archive
draft-ietf-asdf-nipc-15
Network Working Group B. Brinckman
Internet-Draft R. Mohan
Intended status: Standards Track Cisco Systems
Expires: 5 June 2026 B. Sanford
 Philips
 2 December 2025
 An Application Layer Interface for Non-Internet-Connected Physical
 Components (NIPC)
 draft-ietf-asdf-nipc-15
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 a 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 5 June 2026.
Copyright Notice
 Copyright (c) 2025 IETF Trust and the persons identified as the
 document authors. All rights reserved.
Brinckman, et al. Expires 5 June 2026 [Page 1]
Internet-Draft NIPC December 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. Motivation . . . . . . . . . . . . . . . . . . . . . . . 4
 1.2. Non-IP Gateway . . . . . . . . . . . . . . . . . . . . . 5
 1.3. Terminology . . . . . . . . . . . . . . . . . . . . . . . 7
 1.4. Glossary . . . . . . . . . . . . . . . . . . . . . . . . 7
 2. Architecture . . . . . . . . . . . . . . . . . . . . . . . . 9
 2.1. Overview . . . . . . . . . . . . . . . . . . . . . . . . 9
 2.2. Onboarding . . . . . . . . . . . . . . . . . . . . . . . 10
 2.3. Registrations . . . . . . . . . . . . . . . . . . . . . . 10
 2.3.1. SDF model registrations . . . . . . . . . . . . . . . 11
 2.3.2. Data application registrations . . . . . . . . . . . 11
 2.4. NIPC Operations . . . . . . . . . . . . . . . . . . . . . 11
 2.4.1. Overview . . . . . . . . . . . . . . . . . . . . . . 11
 2.4.2. Properties . . . . . . . . . . . . . . . . . . . . . 12
 2.4.3. Actions . . . . . . . . . . . . . . . . . . . . . . . 12
 2.4.4. Events . . . . . . . . . . . . . . . . . . . . . . . 12
 2.4.5. Groups . . . . . . . . . . . . . . . . . . . . . . . 13
 2.4.6. Connection management for NIPC Operations . . . . . . 13
 2.4.7. Extensions . . . . . . . . . . . . . . . . . . . . . 13
 2.5. Events publish subscribe interface . . . . . . . . . . . 13
 2.6. Paths . . . . . . . . . . . . . . . . . . . . . . . . . . 14
 2.6.1. General . . . . . . . . . . . . . . . . . . . . . . . 14
 2.6.2. NIPC Registrations . . . . . . . . . . . . . . . . . 15
 2.6.3. NIPC Operations . . . . . . . . . . . . . . . . . . . 15
 2.7. Schema . . . . . . . . . . . . . . . . . . . . . . . . . 16
 2.7.1. SDF model registrations . . . . . . . . . . . . . . . 16
 2.7.2. NIPC Operations . . . . . . . . . . . . . . . . . . . 16
 2.7.3. SDF Name . . . . . . . . . . . . . . . . . . . . . . 17
 2.7.4. Parameters . . . . . . . . . . . . . . . . . . . . . 17
 2.7.5. Responses . . . . . . . . . . . . . . . . . . . . . . 18
 3. NIPC Registrations . . . . . . . . . . . . . . . . . . . . . 20
 3.1. SDF model registrations APIs . . . . . . . . . . . . . . 20
 3.1.1. Register an SDF model . . . . . . . . . . . . . . . . 20
 3.1.2. Get all SDF models . . . . . . . . . . . . . . . . . 21
 3.1.3. Get an SDF model . . . . . . . . . . . . . . . . . . 22
 3.1.4. Delete an SDF model . . . . . . . . . . . . . . . . . 22
 3.1.5. Update an SDF model . . . . . . . . . . . . . . . . . 23
Brinckman, et al. Expires 5 June 2026 [Page 2]
Internet-Draft NIPC December 2025
 3.2. Data application registrations APIs . . . . . . . . . . . 24
 3.2.1. Register a data application . . . . . . . . . . . . . 25
 3.2.2. Update a data application . . . . . . . . . . . . . . 28
 3.2.3. Get a data application . . . . . . . . . . . . . . . 29
 3.2.4. Delete a data application . . . . . . . . . . . . . . 29
 4. NIPC Operation APIs . . . . . . . . . . . . . . . . . . . . . 29
 4.1. NIPC Property APIs . . . . . . . . . . . . . . . . . . . 30
 4.1.1. Update one or multiple values . . . . . . . . . . . . 30
 4.1.2. Read one or multiple values . . . . . . . . . . . . . 33
 4.2. NIPC Event APIs . . . . . . . . . . . . . . . . . . . . . 34
 4.2.1. Enable event reporting . . . . . . . . . . . . . . . 35
 4.2.2. Disable event reporting . . . . . . . . . . . . . . . 36
 4.2.3. Get status of one or more events . . . . . . . . . . 36
 4.2.4. Enable event reporting on a group of devices . . . . 37
 4.2.5. Disable event reporting on a group of devices . . . . 38
 4.2.6. Get event status on a group of devices . . . . . . . 40
 4.3. NIPC Action APIs . . . . . . . . . . . . . . . . . . . . 41
 4.3.1. Perform an action . . . . . . . . . . . . . . . . . . 41
 4.3.2. Check action status . . . . . . . . . . . . . . . . . 42
 4.4. NIPC explicit connections management APIs . . . . . . . . 43
 4.4.1. Connect to a device . . . . . . . . . . . . . . . . . 43
 4.4.2. Update a connection . . . . . . . . . . . . . . . . . 46
 4.4.3. Disconnect from a device . . . . . . . . . . . . . . 49
 4.4.4. Get connection status . . . . . . . . . . . . . . . . 49
 5. NIPC Extensibility . . . . . . . . . . . . . . . . . . . . . 50
 5.1. Protocol mappings . . . . . . . . . . . . . . . . . . . . 51
 5.2. API extensions . . . . . . . . . . . . . . . . . . . . . 51
 6. NIPC Error Handling . . . . . . . . . . . . . . . . . . . . . 52
 7. Publish/Subscribe Interface . . . . . . . . . . . . . . . . . 54
 7.1. CDDL Definition . . . . . . . . . . . . . . . . . . . . . 54
 7.2. CBOR Examples . . . . . . . . . . . . . . . . . . . . . . 56
 8. Examples . . . . . . . . . . . . . . . . . . . . . . . . . . 57
 8.1. Property Read/Write . . . . . . . . . . . . . . . . . . . 57
 8.2. Enabling an Event on a Device . . . . . . . . . . . . . . 59
 8.3. Enabling an Event on a Group of Devices . . . . . . . . . 62
 9. Implementation Status . . . . . . . . . . . . . . . . . . . . 64
 9.1. TieDie IoT . . . . . . . . . . . . . . . . . . . . . . . 65
 9.2. Cisco Sensor Connect for IoT Services (Catalyst) . . . . 65
 9.3. Cisco Sensor Connect for IoT Services (Meraki) . . . . . 66
 9.4. NIPC Prototype . . . . . . . . . . . . . . . . . . . . . 66
 10. Security Considerations . . . . . . . . . . . . . . . . . . . 66
 10.1. Payload Encryption Considerations . . . . . . . . . . . 66
 10.2. TLS Support Considerations . . . . . . . . . . . . . . . 67
 10.3. HTTP Considerations . . . . . . . . . . . . . . . . . . 67
 10.4. Authorization Considerations . . . . . . . . . . . . . . 67
 10.4.1. API authorization Considerations . . . . . . . . . . 67
 10.4.2. Authorization Token/Bearer Token/Cookie
 Considerations . . . . . . . . . . . . . . . . . . . 67
Brinckman, et al. Expires 5 June 2026 [Page 3]
Internet-Draft NIPC December 2025
 10.5. Other Security Considerations . . . . . . . . . . . . . 68
 11. IANA Considerations . . . . . . . . . . . . . . . . . . . . . 68
 11.1. Media Type Registration . . . . . . . . . . . . . . . . 69
 11.2. API extensions . . . . . . . . . . . . . . . . . . . . . 70
 11.3. Well-known URIs . . . . . . . . . . . . . . . . . . . . 71
 11.4. Problem Details for NIPC APIs . . . . . . . . . . . . . 72
 12. References . . . . . . . . . . . . . . . . . . . . . . . . . 74
 12.1. Normative References . . . . . . . . . . . . . . . . . . 75
 12.2. Informative References . . . . . . . . . . . . . . . . . 78
 Appendix A. OpenAPI definition . . . . . . . . . . . . . . . . . 78
 Appendix B. Protocol mapping . . . . . . . . . . . . . . . . . . 109
 Appendix C. NIPC API extensions . . . . . . . . . . . . . . . . 109
 C.1. NIPC API write binary blob extension . . . . . . . . . . 109
 C.2. NIPC API bulk operations extension . . . . . . . . . . . 111
 C.3. NIPC API write file extension . . . . . . . . . . . . . . 121
 C.4. NIPC API conditional read extension . . . . . . . . . . . 127
 C.5. NIPC API conditional event extension . . . . . . . . . . 133
 C.6. NIPC API property extensions . . . . . . . . . . . . . . 138
 Appendix D. NIPC API CDDL Definition . . . . . . . . . . . . . . 142
 Appendix E. Example SDF model with protocol mappings for BLE . . 147
 Authors' Addresses . . . . . . . . . . . . . . . . . . . . . . . 150
1. Introduction
1.1. Motivation
 Low-power sensors, actuators, and other connected devices deployed
 for building management, healthcare, workplace, manufacturing,
 logistics, and hospitality use cases are often resource and battery
 constrained. Many lack native IP connectivity and instead attach via
 heterogeneous non-IP operational networks. Common non-IP protocols
 include BLE [BLE53] and Zigbee [Zigbee22]. When IP is available,
 constrained application protocols such as CoAP [RFC7252] may be used.
 These devices still need to exchange data with IP-based applications.
 Accordingly, applications on the IP network obtain telemetry from and
 issue operations to such devices through an application-layer
 gateway. This gateway bridges the application network and one or
 more separate operational networks where devices are connected,
 allowing applications on the IP network to perform operations on
 devices connected to these other operational networks.
 +-------------+ +---------+ +--------+
 | Application |<------------>| Gateway |<------------>| Device |
 | | Application | | Device | |
 +-------------+ network +---------+ network +--------+
 Figure 1: Gateway for non-Internet-Connected Devices
Brinckman, et al. Expires 5 June 2026 [Page 4]
Internet-Draft NIPC December 2025
 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 devices on other operational networks, bespoke and vendor-
 specific implementations have proliferated. Each deployment then
 requires: (1) defining or adapting yet another API, and (2) deploying
 additional gateway functions, increasing operational and integration
 cost. This specification defines a single, extensible application
 layer interface for cross-network and cross-protocol device
 interaction through a network gateway. The intent is to support
 multiple network and network protocols (and versions) concurrently,
 allow incremental addition of new protocols via mapping, and reduce
 redundant infrastructure by enabling multiple applications to share
 one standardized gateway function.
 A standardized Application Layer Gateway interface has the following
 benefits:
 1. Eliminates repeated bespoke integration effort across
 deployments.
 2. Avoids deploying multiple overlapping gateway functions for
 different networks, protocols or use cases.
 3. Reduces time and operational cost to integrate new networks and
 devices.
1.2. Non-IP Gateway
 A Non-Internet-Connected Physical Components (NIPC) gateway is an
 application layer gateway (ALG) that implements APIs for applications
 to communicate with devices on different networks, leveraging
 different protocols. These NIPC APIs consist of reading or writing
 properties of devices, invoking actions on devices, as well as
 enabling or disabling events on devices.
 In order to perform NIPC operations on a device, 2 prerequisites must
 be fulfilled:
 * The device is onboarded (its identity and any credentials/trust
 material are provisioned). Onboarding is out of scope of this
 document. It may be performed via SCIM [RFC7644] with
 [I-D.ietf-scim-device-model].
Brinckman, et al. Expires 5 June 2026 [Page 5]
Internet-Draft NIPC December 2025
 * An interaction model for the class of devices must be registered
 with the gateway. This allows the gateway to understand how to
 interact with the device in a protocol-neutral way. The
 interaction model is provided to the gateway by means of an SDF
 model, described in [I-D.ietf-asdf-sdf].
 Once these prerequisites are met, the gateway can resolve a
 referenced SDF affordance into the protocol-specific operations
 required for that device.
 A NIPC gateway provides the following functions:
 * Authentication and authorization of application clients that will
 leverage the NIPC APIs.
 * Maintain a repository of onboarded device objects.
 * Accept and validate SDF interaction model registrations.
 * Expose APIs for property, action, and event operations.
 * Perform implicit connection management to devices where required;
 optionally support explicit connection management.
 * Stream events (publish/subscribe) to authorized data applications.
 * Proxy payloads between networks without interpreting or modifying
 application data.
 * Operate one or more channels to supported wired or wireless
 networks.
 * Optionally provide a bridge between devices on one or more device
 networks connected to the NIPC-Gateway. This may include
 translating between different protocols, if multiple protocols are
 supported on the device network(s).
 The gateway’s role is to proxy traffic between application and device
 networks; it is not intended to be middleware that inspects, decodes,
 or transforms device payloads.
Brinckman, et al. Expires 5 June 2026 [Page 6]
Internet-Draft NIPC December 2025
 +------------------------------------------+
 | |
 +-----------+ 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 illustrates the basic components: applications, the NIPC
 application-layer gateway (ALG), an access point (AP), and a device
 (D). The applications, ALG, and AP reside on an IP network; the AP
 provides a wireless or wired interface to the device. Applications
 often operate in a different administrative domain than the ALG and
 AP, so the ALG will have to support authorization. The ALG bridges
 the IP application domain and the device network, be it an IP-based
 or non-IP device network. This enables applications to perform
 operations on devices attached to those device networks.
 Applications use a JSON-based [RFC8259] RESTful NIPC APIs for
 property, action, and event operations, and a CBOR-based [RFC8949]
 publish/subscribe interface for event streaming.
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.
1.4. Glossary
 * NIPC: Non-IP Control, the application layer interface defined in
 this document.
 * NIPC Gateway: An application layer gateway that implements the
 NIPC interface.
Brinckman, et al. Expires 5 June 2026 [Page 7]
Internet-Draft NIPC December 2025
 * SDF: Semantic Device Format, a standardized format to describe
 devices and their interaction models, as defined in
 [I-D.ietf-asdf-sdf].
 * SDF Affordance: An interaction point on a device as defined in an
 SDF model. Examples of affordances are properties, actions &
 events.
 * SDF Global Name: Absolute URI (with fragment) identifying an SDF
 affordance.
 * SCIM: System for Cross-domain Identity Management, a standardized
 protocol to manage identity information, as defined in [RFC7644].
 * ALG: Application Layer Gateway.
 * IoT: Internet of Things.
 * Protocol Mapping / sdfProtocolMap: Mapping from protocol-neutral
 SDF affordances to protocol-specific operations.
 * BLE: Bluetooth Low Energy protocol.
 * Zigbee: Low-power mesh networking protocol.
 * GATT: Generic Attribute Profile used in BLE for
 services/characteristics/descriptors.
 * Service (BLE): Top-level GATT grouping of characteristics.
 * Characteristic (BLE): GATT data element supporting read/write/
 notify.
 * Descriptor (BLE): Metadata element attached to a characteristic.
 * Bonding (BLE): Procedure to establish trusted, reusable security
 keys.
 * Service Discovery (BLE): Procedure to enumerate GATT
 services/characteristics/descriptors.
 * Device Onboarding: Registration of a device identity and metadata
 before NIPC operations.
 * Device ID / Group ID: UUID identifying a device or a group of
 devices.
 * UUID: Universally unique identifier (128-bit).
Brinckman, et al. Expires 5 June 2026 [Page 8]
Internet-Draft NIPC December 2025
 * Data Application / Data App: Registered application receiving
 streamed event data.
 * MQTT: Publish/subscribe messaging protocol used for streaming.
 * Webhook: HTTP callback endpoint for push delivery.
 * Websocket: Bidirectional TCP-based message channel over HTTP.
 * Publish/Subscribe Interface: Streaming channel for events (CBOR-
 encoded payloads).
 * CBOR: Concise Binary Object Representation; compact binary data
 format.
 * CDDL: Concise Data Definition Language; schema language for CBOR
 data.
 * JSON: JavaScript Object Notation; text encoding used for API
 payloads.
 * Access Point (AP): Network element with a radio interface
 communicating with devices.
2. Architecture
2.1. Overview
 A Non-Internet-Connected Physical Components (NIPC) gateway is an
 application-layer gateway (ALG) that exposes APIs enabling
 applications to perform operations on devices attached to networks
 connected to the gateway. NIPC defines two API categories:
 * Registrations: register SDF models for classes of devices and
 register data applications that receive streaming event data.
 * Operations: perform protocol-neutral device interactions (read/
 write properties, invoke actions, enable/disable events) across
 heterogeneous networks and protocols.
 To execute NIPC operations on a device, both prerequisites MUST be
 met:
 1. Device onboarding: The device identity and required trust
 material are provisioned (e.g., via SCIM [RFC7644] with
 [I-D.ietf-scim-device-model]). This yields the device ID
 referenced in NIPC API paths.
Brinckman, et al. Expires 5 June 2026 [Page 9]
Internet-Draft NIPC December 2025
 2. Interaction model: An SDF model [I-D.ietf-asdf-sdf] is
 registered, providing protocol-neutral affordances and mappings
 to protocol-specific operations.
 +------------+
 | SCIM |
 | object | +----------------+
 | {ID} +---------->| |
 +------------+ | NIPC Operation |
 | - Property |
 | - Action |
 +------------+ | - Event |
 | SDF +---------->| |
 | model | +----------------+
 +------------+
 Figure 3: NIPC prerequisites
 Once both prerequisites are met, authorized applications can perform
 NIPC operations on devices identified by their IDs. See Section 10
 for authorization details. NIPC operations act on SDF
 affordances—properties, actions, and events—defined in the registered
 SDF model. Certain NIPC operations may also be performed on groups
 of devices identified by a group ID.
2.2. Onboarding
 Onboarding is the process of declaring a device’s identity to the
 NIPC gateway and provisioning the trust material required to
 communicate with the device. The device object MUST include
 sufficient information to bootstrap trust and establish connectivity,
 as NIPC operations assume connectivity can be established without
 separate API calls. While onboarding can be performed in various
 ways, it is RECOMMENDED to use SCIM [RFC7644] with the device schema
 [I-D.ietf-scim-device-model], which defines the necessary attributes
 and extensions to support NIPC. As per Section 4.2 of [RFC7643],
 group objects may also be declared, and leveraged in NIPC operations.
2.3. Registrations
 NIPC registration APIs allow applications to declare information
 about a device class or authorize a data application. These APIs do
 not operate on specific devices or groups of devices.
 NIPC supports two registration types:
 1. SDF model registration: Registers an SDF interaction model for a
 class of devices.
Brinckman, et al. Expires 5 June 2026 [Page 10]
Internet-Draft NIPC December 2025
 2. Data application authorization: Authorizes an application to
 receive streaming event data. Optionally, the SDF model
 reference and/or data-app registration MAY be included in the
 device's SCIM object. See [I-D.ietf-scim-device-model] and
 [I-D.ietf-asdf-sdf-protocol-mapping] for details.
2.3.1. SDF model registrations
 The SDF model for a class of devices determines how a gateway can
 interact with these devices in a protocol-neutral way. To enable
 this, the SDF model must contain protocol mappings, mapping protocol-
 neutral SDF affordances to protocol-specific operations as defined in
 [I-D.ietf-asdf-sdf-protocol-mapping]. The SDF affordances supported
 by the device, as well as its protocol-mappings, are provided to the
 gateway by means of SDF model registration. SDF models are described
 in [I-D.ietf-asdf-sdf].
2.3.2. Data application registrations
 NIPC operations can enable or disable event reporting on a device.
 Events are reported through a publish-subscribe interface.
 Applications that are authorized to perform NIPC operations on
 devices can define which applications are permitted to receive
 streaming event data for that device. The data-app registrations API
 maps an event to an application that is authorized to receive that
 data. The registration also defines what protocol will be used to
 deliver the data (e.g., MQTT, webhook, websocket). This registration
 basically allows applications to determine which data-streams are
 consumed by which data-applications.
2.4. NIPC Operations
2.4.1. Overview
 NIPC APIs are exposed over HTTP [RFC9110]. Requests and responses
 use JSON [RFC8259] unless another media type is negotiated via
 Content-Type and Accept. A media type for an SDF affordance can also
 be stipulated in the SDF ContentFormat data quality, as described in
 Section 4.7 of [I-D.ietf-asdf-sdf]. The default media type is
 "application/nipc+json" (see Section 11.1). SDF model registrations
 use "application/sdf+json". Property APIs MAY use other media types
 appropriate to the property payload.
 Failures use Problem Details [RFC9457] with application/problem+json.
 NIPC operations are protocol-neutral operations on SDF affordances,
 more specifically properties, actions & events. NIPC operations can
 happen against affordances registered in an SDF model. Operations
Brinckman, et al. Expires 5 June 2026 [Page 11]
Internet-Draft NIPC December 2025
 reference affordances by their SDF global name. If the underlying
 protocol requires a connection, the gateway establishes and tears
 down the connection implicitly unless an explicit connection is
 already in place.
 NIPC exposes three operation groups:
 * Properties APIs: These APIs allow applications to perform
 operations on properties, such as to read or write values to them.
 * Actions APIs: These APIs perform actions on devices, such as
 enabling or disabling a feature on a device.
 * Events APIs: These APIs allow apps to enable or disable event
 reporting on devices. Events are reported over the events
 publish/subscribe interface.
2.4.2. Properties
 Property operations allow clients to read and write values for SDF
 properties.
 Requests and responses use application/nipc+json unless another media
 type is negotiated via Content-Type and Accept. When using JSON,
 binary property values are base64-encoded with padding per Section 5
 of [RFC4648]. Multiple properties MAY be read or written in a single
 request. When a single property is addressed via a query parameter,
 non-JSON media types MAY be used for the payload. On success, the
 response returns either 200 with per-property status (JSON) or 204 No
 Content for single, non-JSON writes.
2.4.3. Actions
 Action operations invoke SDF actions on devices.
 A successful action request returns 202 Accepted with a Location
 header referencing the action instance. Clients poll the instance
 URI to obtain status (e.g., IN_PROGRESS, COMPLETED). Request bodies
 are optional and MAY carry action input in a media type appropriate
 to the underlying protocol (e.g., octet-stream).
2.4.4. Events
 Event operations enable and disable device event reporting.
 Enabling an event returns 201 Created with a Location header
 referencing the event instance. Disabling an event uses the instance
 identifier and returns 204 No Content on success (for a single
Brinckman, et al. Expires 5 June 2026 [Page 12]
Internet-Draft NIPC December 2025
 device) or a per-device status list (for a group). Event payloads
 are delivered via the publish/subscribe interface encoded in CBOR
 [RFC8949].
2.4.5. Groups
 Where supported by the underlying protocol, operations MAY target a
 group of devices identified by a group ID. Responses for group
 operations return per-device results; failures for individual devices
 are reported using Problem Details entries within the array.
2.4.6. Connection management for NIPC Operations
 For protocols that require connection setup, the gateway performs
 implicit connection management during an operation (establish on
 demand; tear down on completion). Gateways MAY support explicit
 connection management; when an explicit connection is active,
 operations reuse it and do not tear it down. Explicit connection
 management is described in Section 4.4.
2.4.7. Extensions
 NIPC supports API extensions for compound or specialized operations.
 Extensions can execute a set of NIPC operations in a single request
 or provide more efficient mechanisms for specific use cases (e.g., a
 bulk operation).
 Extensions MUST use the "/extensions" path element. To ensure
 interoperability, extensions MUST be registered with IANA as defined
 in Section 11.2.
2.5. Events publish subscribe interface
 Events are delivered via a publish/subscribe interface. NIPC events
 are encoded in CBOR ([RFC8949]) and can be transported over MQTT,
 Webhook or Websocket.
 CBOR is used for the publish/subscribe interface as Non-IP payloads
 are typically binary. CBOR encodes binary payloads efficiently, and
 is more compact than JSON, therefore reducing the amount of data that
 needs to be transmitted to the application.
 Event types include:
 * Streaming data from devices: Streaming data is activated/
 deactivated with the NIPC events API
 * Broadcasts from devices (e.g., advertisements in BLE)
Brinckman, et al. Expires 5 June 2026 [Page 13]
Internet-Draft NIPC December 2025
 * Connection events: Devices connecting & disconnecting
2.6. Paths
2.6.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
 * /groups: for NIPC operations on groups of devices
 * /extensions: for NIPC extension APIs
 The well-known URI /.well-known/nipc defined in Section 11.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.
Brinckman, et al. Expires 5 June 2026 [Page 14]
Internet-Draft NIPC December 2025
 {
 "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
 A formal CBOR definition of the well-known response is as follows:
 NipcWellKnown = {
 base_path: text,
 ? versions: [* uri / text],
 ? extensions: [* uri / text]
 }
2.6.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.6.3. NIPC Operations
 Every NIPC Operations API pertains to either a device or group of
 devices, identified by an ID, hence the ID must be reflected as the
 first parameter in the path. For example:
 "https://example.com/nipc/v1/{id}"
 The second parameter in the path refers to the NIPC operation that
 the API will perform on the device. This can be:
 * properties
Brinckman, et al. Expires 5 June 2026 [Page 15]
Internet-Draft NIPC December 2025
 * events
 * actions
 * extensions
 These are described in Section 2.4.
2.7. 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.7.1. SDF model registrations
 To execute NIPC operations, an SDF interaction model for the device
 class MUST be registered. The model MUST include protocol mappings
 that relate protocol-neutral SDF affordances to protocol-specific
 operations.
 Registration is performed via POST /registrations/models with the SDF
 model in the request body. A registered model can be retrieved via
 GET /registrations/models using the model identifier (sdfName).
2.7.2. NIPC Operations
 NIPC operations require two parameters:
 1. Device ID: the UUID identifying the target device (or group).
 2. sdfName: the SDF global name (absolute URI with fragment) of the
 affordance (property, action, or event) on which the operation
 acts.
2.7.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, adhering to [RFC9562].
 +===========+======+======================================+
 | Attribute | Type | Example |
 +===========+======+======================================+
 | id | uuid | 1d3b2c36-8a65-45a6-87c1-bcdbe0a32e30 |
 +-----------+------+--------------------------------------+
 Table 1: Definition of a device or group of devices
Brinckman, et al. Expires 5 June 2026 [Page 16]
Internet-Draft NIPC December 2025
 ID is a UUID assigned during onboarding (e.g., by a SCIM server).
 The identifier is returned when the device object is created and is
 used by both the application and the NIPC gateway. The application
 must store this UUID in order to use it to identify the device on
 which it wants to perform NIPC operations. If the NIPC gateway is
 not co-located with the SCIM server, it retrieves the device object
 from SCIM using this ID.
2.7.3. SDF Name
 Operations act on SDF affordances and reference them by SDF global
 name—an absolute URI with fragment that includes the namespace. The
 affordance referenced MAY be a property, action, or event; the
 reference is carried as a string.
 For example:
 +================+================================================+
 | NIPC Operation | Example SDF Name used in the API |
 +================+================================================+
 | Property | https://example.com/heartrate#/ |
 | | sdfObject/thermostat/sdfProperty/temperature |
 +----------------+------------------------------------------------+
 | Event | https://example.com/heartrate# |
 | | /sdfObject/healthsensor/sdfEvent/fallDetected |
 +----------------+------------------------------------------------+
 | Action | https://example.com/heartrate#/ |
 | | sdfObject/thermostat/sdfAction/resetThermostat |
 +----------------+------------------------------------------------+
 Table 2: Example SDF names for NIPC operations
2.7.4. Parameters
 To minimize deployment risk arising from inconsistent URI path
 normalization and handling of percent-encoded reserved characters in
 path elements (notably "/" encoded as "%2F") across common HTTP
 servers and intermediaries (e.g., Jetty, Tomcat, Apache httpd,
 NGINX), NIPC uses query parameters (except the primary {id} path
 segment) rather than additional path segments for values that can
 legitimately contain reserved characters (such as SDF global names).
 Although [RFC3986] and [RFC9110] require that reserved characters not
 be normalized or decoded in ways that alter semantics,
 misinterpretation of these rules has led to security vulnerabilities
 (path confusion, cache poisoning, authorization bypass) and to
 conservative default configurations that reject encoded slashes. In
 proxy deployments, relaxing these defaults often triggers security
 review friction. Representing such values in the query component
Brinckman, et al. Expires 5 June 2026 [Page 17]
Internet-Draft NIPC December 2025
 avoids reliance on tolerant path normalization behavior, reduces
 ambiguity for intermediaries, and aligns with prevailing "safe"
 operational profiles; a malformed or unsupported parameter can be
 rejected with a 4xx status without exposing downstream services to
 traversal or normalization discrepancies.
2.7.5. Responses
 A NIPC Gateway must respond to a NIPC operation request
 synchronously, and provide the result of the completed operation in
 the HTTP response.
 Exceptions to this are the following:
 1. Extensions: Extension APIs (see Section 5.2) execute compound
 operations and thus require the gateway to execute multiple NIPC
 operations. On acceptance, the gateway returns 202 Accepted.
 Clients poll the extension URI (GET) for execution status. If a
 callback URI was supplied in the request, the gateway MAY send
 the final result upon completion.
 2. Actions: Action requests return 202 Accepted with a Location
 header pointing to the action instance used for status tracking.
 A failure response must contain an HTTP status code of 4xx or 5xx,
 and use [RFC9457] Problem Details with application/problem+json media
 type.
 All NIPC failure responses must include the following attributes:
 * type: a URI identifying the error (see Section 6)
 * status: the 4xx or 5xx HTTP status code
 * title: a brief, human-readable summary
 * detail: a human-readable explanation specific to this occurrence
 Additional attributes MAY be included as permitted by [RFC9457].
 =============== NOTE: '\' line wrapping per RFC 8792 ================
 FailureResponse = {
 ? type: FailureTypeURI,
 ? status: uint,
 ? title: text,
 ? detail: text
 }
Brinckman, et al. Expires 5 June 2026 [Page 18]
Internet-Draft NIPC December 2025
 ; Enumerated problem type URIs registered for NIPC
 FailureTypeURI = (
 "https://www.iana.org/assignments/nipc-problem-types#invalid-id" /
 "https://www.iana.org/assignments/nipc-problem-types#invalid-sdf-u\
 rl" /
 "https://www.iana.org/assignments/nipc-problem-types#extension-ope\
 ration-not-executed" /
 "https://www.iana.org/assignments/nipc-problem-types#sdf-model-alr\
 eady-registered" /
 "https://www.iana.org/assignments/nipc-problem-types#sdf-model-in-\
 use" /
 "https://www.iana.org/assignments/nipc-problem-types#property-not-\
 readable" /
 "https://www.iana.org/assignments/nipc-problem-types#property-read\
 -failed" /
 "https://www.iana.org/assignments/nipc-problem-types#property-not-\
 writable" /
 "https://www.iana.org/assignments/nipc-problem-types#property-writ\
 e-failed" /
 "https://www.iana.org/assignments/nipc-problem-types#event-already\
 -enabled" /
 "https://www.iana.org/assignments/nipc-problem-types#event-not-ena\
 bled" /
 "https://www.iana.org/assignments/nipc-problem-types#event-not-reg\
 istered" /
 "https://www.iana.org/assignments/nipc-problem-types#protocolmap-b\
 le-already-connected" /
 "https://www.iana.org/assignments/nipc-problem-types#protocolmap-b\
 le-no-connection" /
 "https://www.iana.org/assignments/nipc-problem-types#protocolmap-b\
 le-connection-timeout" /
 "https://www.iana.org/assignments/nipc-problem-types#protocolmap-b\
 le-bonding-failed" /
 "https://www.iana.org/assignments/nipc-problem-types#protocolmap-b\
 le-connection-failed" /
 "https://www.iana.org/assignments/nipc-problem-types#protocolmap-b\
 le-service-discovery-failed" /
 "https://www.iana.org/assignments/nipc-problem-types#protocolmap-b\
 le-invalid-service-or-characteristic" /
 "https://www.iana.org/assignments/nipc-problem-types#protocolmap-z\
 igbee-connection-timeout" /
 "https://www.iana.org/assignments/nipc-problem-types#protocolmap-z\
 igbee-invalid-endpoint-or-cluster" /
 "https://www.iana.org/assignments/nipc-problem-types#extension-bro\
 adcast-invalid-data" /
 "https://www.iana.org/assignments/nipc-problem-types#extension-fir\
 mware-rollback" /
 "https://www.iana.org/assignments/nipc-problem-types#extension-fir\
Brinckman, et al. Expires 5 June 2026 [Page 19]
Internet-Draft NIPC December 2025
 mware-update-failed" /
 "about:blank"
 )
 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 1d3b2c36-8a65-45a6-87c1-bcdbe0a32e30 does not\
 \ exist or is not a device"
 }
 Figure 5: Example failure response
3. NIPC Registrations
3.1. SDF model registrations APIs
 SDF model registration 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].
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:
 * The SDF document in JSON format containing one or more sdfThings
 or sdfObjects, similar to the example in Figure 33.
 * The SDF document MUST contain protocol mappings, as described in
 [I-D.ietf-asdf-sdf-protocol-mapping].
 Response:
 A list containing objects where each object has an "sdfName" which is
 the global name of the top-level sdfThing or sdfObject in the SDF
 model.
Brinckman, et al. Expires 5 June 2026 [Page 20]
Internet-Draft NIPC December 2025
 =============== NOTE: '\' line wrapping per RFC 8792 ================
 SdfGlobalName = text ; absolute URI with fragment referencing an \
 sdfThing or sdfObject
 SdfReference = {
 sdfName: SdfGlobalName
 }
 SdfReferenceArray = [* SdfReference]
 Example of a response:
 [
 {
 "sdfName": "https://example.com/heartrate#/sdfObject/healthsensor"
 }
 ]
 Figure 6: Example of a response to an SDF model registration
3.1.2. Get all SDF models
 Method: GET /registrations/models
 Description: Gets all SDF models registered with the gateway.
 Response:
 A list containing objects where each object has an "sdfName" which is
 the global name of the top-level sdfThing or sdfObject in the SDF
 model.
 =============== NOTE: '\' line wrapping per RFC 8792 ================
 SdfGlobalName = text ; absolute URI with fragment referencing an \
 sdfThing or sdfObject
 SdfReference = {
 sdfName: SdfGlobalName
 }
 SdfReferenceArray = [* SdfReference]
 Example of a response:
Brinckman, et al. Expires 5 June 2026 [Page 21]
Internet-Draft NIPC December 2025
 [
 {
 "sdfName": "https://example.com/heartrate#/sdfObject/healthsensor"
 },
 {
 "sdfName": "https://example.com/thermometer#/sdfObject/thermometer"
 }
 ]
 Figure 7: Example of a response to get all SDF models
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 Figure 33.
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:
 * A list containing objects where each object has an "sdfName" which
 is the global name of the top-level sdfThing or sdfObject in the
 SDF model
Brinckman, et al. Expires 5 June 2026 [Page 22]
Internet-Draft NIPC December 2025
 =============== NOTE: '\' line wrapping per RFC 8792 ================
 SdfGlobalName = text ; absolute URI with fragment referencing an \
 sdfThing or sdfObject
 SdfReference = {
 sdfName: SdfGlobalName
 }
 SdfReferenceArray = [* SdfReference]
 Example of a response:
 {
 "sdfName": "https://example.com/heartrate#/sdfObject/healthsensor"
 }
 Figure 8: Example of a response to an SDF model registration
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 Figure 33.
 Response:
 * A list containing objects where each object has an "sdfName" which
 is the global name of the top-level sdfThing or sdfObject in the
 SDF model
Brinckman, et al. Expires 5 June 2026 [Page 23]
Internet-Draft NIPC December 2025
 =============== NOTE: '\' line wrapping per RFC 8792 ================
 SdfGlobalName = text ; absolute URI with fragment referencing an \
 sdfThing or sdfObject
 SdfReference = {
 sdfName: SdfGlobalName
 }
 SdfReferenceArray = [* SdfReference]
 Example of a response:
 {
 "sdfName": "https://example.com/heartrate#/sdfObject/healthsensor"
 }
 Figure 9: Example of a response to an SDF model registration
3.2. Data application registrations APIs
 Data-app registration 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 as an authorized endpoint that can receive data for a device.
 The endpoint app is defined in Section 6 of
 [I-D.ietf-scim-device-model].
 Apart from the endpoint app ID, the API also configures the protocol
 the data-app supports. These should be one of the following:
 * mqttClient: The data-app is an MQTT client, which means that the
 NIPC gateway must act as an MQTT broker.
 * mqttBroker: The data-app is an MQTT broker, which means that the
 NIPC gateway must act as an MQTT client. The MQTT broker
 configuration data, such as the URI, credentials and MQTT topic
 must also be provided in the registration API.
 * webhook: The data-app supports a webhook the gateway can publish
 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.
Brinckman, et al. Expires 5 June 2026 [Page 24]
Internet-Draft NIPC December 2025
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 is authorized
 for.
 * mqttClient: a boolean that denotes that the data application is an
 MQTT client.
 * mqttBroker: The data app is an MQTT broker. This object contains
 the MQTT broker information:
 - 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/<dataAppId>/<namespace>/<json_pointer_to_sdf_event>, as
 described in Section 4.2. In this attribute, a custom topic
 can be configured (optional).
 * webhook: The data app supports a webhook. This object contains a
 webhook URL along with any credentials that are required to
 authenticate the webhook.
 - URI: the webhook URI. The URI MUST include the scheme used by
 the webhook server (e.g., "https://"). It is up to the
 implementation to support different schemes. If a scheme is
 not supported, the NIPC gateway MUST return an error response
 with type "https://www.iana.org/assignments/nipc-problem-
 types#unsupported-uri-scheme".
Brinckman, et al. Expires 5 June 2026 [Page 25]
Internet-Draft NIPC December 2025
 - 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.
 Each header is represented as a key-value pair in the object.
 - serverCACert: the CA certificate of the webhook server, encoded
 as per [RFC7468] and newlines encoded as '\n' (optional)
 * websocket: The data app supports a websocket. This object
 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 URI. The URI MUST include the scheme used
 by the websocket server (e.g., "wss://"). It is up to the
 implementation to support different schemes. If a scheme is
 not supported, the NIPC gateway MUST return an error response
 with type "https://www.iana.org/assignments/nipc-problem-
 types#unsupported-uri-scheme".
 - 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.
 Each header is represented as a key-value pair in the object.
 - serverCACert: the CA certificate of the websocket server,
 encoded as per [RFC7468] and newlines encoded as '\n'
 (optional)
Brinckman, et al. Expires 5 June 2026 [Page 26]
Internet-Draft NIPC December 2025
 DataApp = {
 events: [* EventRef],
 ( DataAppMqttClient //
 DataAppMqttBroker //
 DataAppWebhook //
 DataAppWebsocket )
 }
 EventRef = {
 event: text ; SDF global name (absolute URI with fragment)
 }
 DataAppMqttClient = {
 mqttClient: bool
 }
 DataAppMqttBroker = {
 mqttBroker: {
 URI: text,
 username: text,
 password: text,
 ? brokerCACert: text, ; PEM-encoded CA certificate
 ? customTopic: text ; optional custom MQTT topic
 }
 }
 DataAppWebhook = {
 webhook: {
 URI: text,
 ? headers: { * text => text }, ; key/value headers
 ? serverCACert: text
 }
 }
 DataAppWebsocket = {
 websocket: {
 URI: text,
 ? headers: { * text => text }, ; key/value headers
 ? serverCACert: text
 }
 }
 Example of a request body:
Brinckman, et al. Expires 5 June 2026 [Page 27]
Internet-Draft NIPC December 2025
 =============== 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:
 =============== 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 registration.
 Query Parameters:
Brinckman, et al. Expires 5 June 2026 [Page 28]
Internet-Draft NIPC December 2025
 * dataAppId: the ID of the data application
 Request Body:
 * The request body is identical to the request body for the register
 data application API Section 3.2.1.
 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 object 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 Section 3.2.1.
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:
 * If successful, the response will be identical to the request body
 for the register data application API Section 3.2.1.
4. NIPC Operation APIs
 The NIPC operation APIs perform protocol-neutral interactions on SDF
 affordances, properties, events, and actions. This allows
 applications to read & update device properties, invoke actions, and
 consume events.
Brinckman, et al. Expires 5 June 2026 [Page 29]
Internet-Draft NIPC December 2025
 NIPC defines three API collections aligned with the SDF Affordances
 defined in Section 1.2 of [I-D.ietf-asdf-sdf]:
 * Properties: read and write device properties.
 * Events: enable and disable device event reporting.
 * Actions: invoke device actions.
 To invoke NIPC operations APIs on a device, one or more SDF models
 MUST be registered for that device. The SDF model MAY have a
 top-level sdfThing (with multiple sdfObjects) or a top-level
 sdfObject. Operations depend on affordances (sdfProperty, sdfEvent,
 sdfAction) defined in the registered SDF model and on a device ID
 (see [I-D.ietf-scim-device-model]). Affordances are referenced by
 their SDF global name (absolute URI with fragment) as described in
 Section 4 of [I-D.ietf-asdf-sdf].
 The NIPC Gateway must match the SDF global name against the
 registered SDF model to resolve the protocol mapping (protocolmap)
 the gateway will execute. When carried in a URI, the SDF global name
 MUST be percent-encoded per Section 2.1 of [RFC3986].
4.1. NIPC Property APIs
 These APIs allow applications to read and update device properties.
 If the underlying protocol requires a connection, the gateway
 establishes it implicitly for the operation; when an explicit
 connection is already active, operations reuse it without
 modification.
 Requests and responses support content negotiation via Content-Type
 and Accept. When using "application/nipc+json", payloads must follow
 the examples above. Binary property values must be base64-encoded
 with padding per Section 5 of [RFC4648] in the "value" field. For
 other media types, payload semantics must follow the selected media
 type.
4.1.1. Update one or 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
Brinckman, et al. Expires 5 June 2026 [Page 30]
Internet-Draft NIPC December 2025
 Query Parameters:
 * propertyName: Identifies a single property to update. If present,
 the request body MAY use any media type appropriate to the
 property payload. -or-
 * If absent, the request body MUST be application/nipc+json and
 contain an array of update items, each with a property and a
 value.
 Request Body:
 * If the query parameter propertyName is provided, the request body
 MAY use any media type appropriate to the property payload. The
 value is encoded as per the content type of the payload. -or-
 * If the query parameter propertyName is NOT provided, the request
 body must be an array of properties to update, each containing a
 property and a value. The value attribute contains the raw binary
 data, which must be encoded in base64 with padding as per
 Section 5 of [RFC4648].
 PropertyValueArray = [* PropertyValue]
 ; Minimal PropertyValue shape (matches allOf of Property + Value)
 PropertyValue = {
 property: text, ; SDF global name of the property
 value: b64text ; base64-encoded bytes (RFC 4648 Section 5)
 }
 ; Helper type for base64-with-padding encoded text
 b64text = text
 Example body for updating multiple properties:
Brinckman, et al. Expires 5 June 2026 [Page 31]
Internet-Draft NIPC December 2025
 =============== 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
 must 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. The "properties" array must be an array of
 properties that were updated, each containing a property and a
 value. -or-
 * If the Accept header is set to any other media type and the
 propertyName query parameter is provided, the response must be 204
 No Content with no body.
 =============== NOTE: '\' line wrapping per RFC 8792 ================
 PropertyValueResponseArray = [* PropertyValueResponseArrayItem]
 PropertyValueResponseArrayItem = ( SuccessResponse // FailureRespons\
 e )
 ; Minimal success shape (may be extended)
 SuccessResponse = {
 ? status: uint
 }
 Example of a response:
Brinckman, et al. Expires 5 June 2026 [Page 32]
Internet-Draft NIPC December 2025
 =============== 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
4.1.2. Read one or 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.
 Response:
 * If the Accept header is set to application/nipc+json, the response
 must be an array of properties, each containing a property and a
 value. The value must be the raw binary data read from the
 property, encoded in base64 with padding as per Section 5 of
 [RFC4648]. The array must contain objects with 2 attributes: -
 property: The property that was read. - value: The bytes that
 were read in base64 encoding -or-
Brinckman, et al. Expires 5 June 2026 [Page 33]
Internet-Draft NIPC December 2025
 * If the Accept header is set to any other media type and a single
 propertyName query parameter is provided, the request body MAY use
 any media type appropriate to the property payload. The value is
 encoded as per the content type of the payload.
 =============== NOTE: '\' line wrapping per RFC 8792 ================
 PropertyValueReadResponseArray = [* PropertyValueReadResponseArrayIt\
 em]
 PropertyValueReadResponseArrayItem = ( PropertyValue // FailureRespo\
 nse )
 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
4.2. NIPC Event APIs
 Event APIs enable or disable reporting of device events. For certain
 protocols, a connection may be required. If the underlying protocol
 requires a connection, the gateway establishes it implicitly for the
 operation. If an explicitly created connection is already active, it
 is reused without modification.
 Events are referenced by the SDF global name of an sdfEvent. The
 {id} path segment identifies a device or a group of devices. A group
 event MAY be enabled only if the underlying protocol supports group
 activation (e.g., BLE advertisement or connection status events).
 If the data application registered for this event is an MQTT broker
 or client, the event SDF global name may be used to construct the
 MQTT topic for the event. The topic is constructed using the data
Brinckman, et al. Expires 5 June 2026 [Page 34]
Internet-Draft NIPC December 2025
 application ID, the default namespace for the event, and the event
 itself. For example, if the data application ID is "0927ce7c-b258-
 4bfa-a345-bcc9f74385b4" and the event is
 "https://example.com/thermometer#/sdfThing/thermometer/sdfEvent/
 isPresent", the topic will be:
 =============== NOTE: '\' line wrapping per RFC 8792 ================
 data-app/<dataAppId>/<namespace>/<json_pointer_to_sdf_event>
 data-app/0927ce7c-b258-4bfa-a345-bcc9f74385b4/thermometer/sdfThing/\
 thermometer/sdfEvent/isPresent
 A data application may subscribe to this topic using the topic or it
 may use MQTT wildcards to subscribe to data-app/+/temperature/# to
 receive all events for the temperature namespace.
 If a customTopic was supplied in the data-app registration
 (mqttBroker case), that topic MUST be used instead of the constructed
 default.
4.2.1. Enable event reporting
 Method: POST /devices/{id}/events{?eventName}
 Description: Enables an event on a device
 Parameters:
 * id: the ID of the device
 Query Parameters:
 * eventName: the event to enable. The eventName must be 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:
Brinckman, et al. Expires 5 June 2026 [Page 35]
Internet-Draft NIPC December 2025
 =============== NOTE: '\' line wrapping per RFC 8792 ================
 HTTP/1.1 201 Created
 Location: /devices/1d3b2c36-8a65-45a6-87c1-bcdbe0a32e30/events?insta\
 nceId=02ee282c-8915-4b2e-bbd2-88966773134a
 The Location header must contain the URI for the created event
 instance, which may be used to check status or disable the event.
4.2.2. Disable event reporting
 Method: DELETE /devices/{id}/events{?instanceId}
 Description: Disables an event on a 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
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
 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)
Brinckman, et al. Expires 5 June 2026 [Page 36]
Internet-Draft NIPC December 2025
 Response: The response must be an array of events, each containing an
 instanceID and an event. - instanceId: must be the unique instance
 ID for each enabled event. - event: must be the event URI for each
 enabled event.
 =============== NOTE: '\' line wrapping per RFC 8792 ================
 EventStatusResponseArray = [* EventStatusResponseArrayItem]
 EventStatusResponseArrayItem = ( EventInstanceSuccess // FailureResp\
 onse )
 ; Success item = { event, instanceId }
 EventInstanceSuccess = {
 event: text, ; SDF global name of the event (absolute URI w\
 ith fragment)
 instanceId: text ; UUID (as text)
 }
 Example of a response:
 =============== NOTE: '\' line wrapping per RFC 8792 ================
 [
 {
 "instanceId": "02ee282c-8915-4b2e-bbd2-88966773134a",
 "event": "https://example.com/heartrate#/sdfObject/healthsensor/\
 sdfEvent/fallDetected"
 }
 ]
 Figure 15: Example get multiple events status 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. The eventName is a URL encoded
 string that is the absolute URI that is the global name of an
 sdfEvent.
Brinckman, et al. Expires 5 June 2026 [Page 37]
Internet-Draft NIPC December 2025
 Response:
 * The response must return HTTP status code 201 Created with a
 Location header pointing to the created event instance. The
 Location header must contain the URI for the created event
 instance, which can be used to check status or disable the event.
 Example of a successful response:
 =============== NOTE: '\' line wrapping per RFC 8792 ================
 HTTP/1.1 201 Created
 Location: /groups/0dc729d7-f6c3-491d-9b9d-e7176d2be243/events?instan\
 ceId=f1b9f26b-21ce-4deb-9d57-289ba7e17cce
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: MUST return 200 OK with an array of per-device event status
 entries. For each device where the event was successfully disabled,
 the entry MUST include deviceId and event (SDF global name). For
 each device where disabling failed, the entry MUST be a Problem
 Details error object for that device.
Brinckman, et al. Expires 5 June 2026 [Page 38]
Internet-Draft NIPC December 2025
 =============== NOTE: '\' line wrapping per RFC 8792 ================
 GroupEventStatusResponseArray = [* GroupEventStatusResponse]
 GroupEventSuccessResponse = { event: text, deviceId: text }
 ; Each item is either an event+deviceId success or a FailureResponse
 GroupEventStatusResponse = (GroupEventSuccessResponse // FailureResp\
 onse)
 ; FailureResponse (Problem Details subset; align with your existing \
 definition if present)
 GroupFailureResponse = {
 FailureResponse,
 ? deviceId: text
 }
 Example of a response:
 =============== NOTE: '\' line wrapping per RFC 8792 ================
 [
 {
 "event": "https://example.com/heartrate#/sdfObject/healthsensor/\
 sdfEvent/fallDetected",
 "deviceId": "1d3b2c36-8a65-45a6-87c1-bcdbe0a32e30"
 },
 {
 "event": "https://example.com/heartrate#/sdfObject/healthsensor/\
 sdfEvent/fallDetected",
 "deviceId": "d62c7fb2-a216-4811-a388-053b17fdbedc"
 },
 {
 "event": "https://example.com/heartrate#/sdfObject/healthsensor/\
 sdfEvent/fallDetected",
 "deviceId": "01b52a23-b98c-454c-ba9e-086a43bdfd79"
 },
 {
 "type": "https://www.iana.org/assignments/nipc-problem-types#eve\
 nt-not-enabled",
 "status": 400,
 "title": "Event Not Enabled",
 "deviceId": "9171ec16-e3c1-4ccf-ad23-b92a1a3f069d",
 "detail": "Failed to disable the event for device 9171ec16-e3c1-\
 4ccf-ad23-b92a1a3f069d"
 }
 ]
Brinckman, et al. Expires 5 June 2026 [Page 39]
Internet-Draft NIPC December 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 for 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: MUST return 200 OK with an array of per-device event status
 entries. For each device where the event was successfully enabled,
 the entry MUST include deviceId and event (SDF global name). For
 each device where enabling failed, the entry MUST be a Problem
 Details error object for that device.
 =============== NOTE: '\' line wrapping per RFC 8792 ================
 GroupEventStatusResponseArray = [* GroupEventStatusResponse]
 GroupEventSuccessResponse = { event: text, deviceId: text }
 ; Each item is either an event+deviceId success or a FailureResponse
 GroupEventStatusResponse = (GroupEventSuccessResponse // FailureResp\
 onse)
 ; FailureResponse (Problem Details subset; align with your existing \
 definition if present)
 GroupFailureResponse = {
 FailureResponse,
 ? deviceId: text
 }
 Example of a response:
Brinckman, et al. Expires 5 June 2026 [Page 40]
Internet-Draft NIPC December 2025
 =============== NOTE: '\' line wrapping per RFC 8792 ================
 [
 {
 "event": "https://example.com/heartrate#/sdfObject/healthsensor/\
 sdfEvent/fallDetected",
 "deviceId": "1d3b2c36-8a65-45a6-87c1-bcdbe0a32e30"
 },
 {
 "event": "https://example.com/heartrate#/sdfObject/healthsensor/\
 sdfEvent/fallDetected",
 "deviceId": "d62c7fb2-a216-4811-a388-053b17fdbedc"
 },
 {
 "event": "https://example.com/heartrate#/sdfObject/healthsensor/\
 sdfEvent/fallDetected",
 "deviceId": "01b52a23-b98c-454c-ba9e-086a43bdfd79"
 },
 {
 "type": "https://www.iana.org/assignments/nipc-problem-types#eve\
 nt-not-enabled",
 "status": 400,
 "title": "Event Not Enabled",
 "deviceId": "9171ec16-e3c1-4ccf-ad23-b92a1a3f069d",
 "detail": "Failed to disable the event for device 9171ec16-e3c1-\
 4ccf-ad23-b92a1a3f069d"
 }
 ]
 Figure 16: Example get multiple group events status response
4.3. NIPC Action APIs
 NIPC Action APIs invoke device actions. If the underlying protocol
 requires a connection, the gateway establishes it implicitly for the
 operation. If an explicitly established connection is already
 active, the operation MUST reuse it without modification.
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
Brinckman, et al. Expires 5 June 2026 [Page 41]
Internet-Draft NIPC December 2025
 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. The Location header
 contains the URI for the action instance, which can be used to check
 the action status.
 Example of a successful response:
 =============== NOTE: '\' line wrapping per RFC 8792 ================
 HTTP/1.1 202 Accepted
 Location: /devices/1d3b2c36-8a65-45a6-87c1-bcdbe0a32e30/actions?inst\
 anceId=02ee282c-8915-4b2e-bbd2-88966773134a
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:
 * instanceId: the instance ID of the action (obtained from the
 Location header)
 Response: MUST return 200 OK with an action status, which may be "in
 progress" or "completed".
 ActionResponse = {
 status: ActionStatus
 }
 ActionStatus = (
 "IN_PROGRESS" /
 "COMPLETED"
 )
Brinckman, et al. Expires 5 June 2026 [Page 42]
Internet-Draft NIPC December 2025
 Example of a response:
 {
 "status": "COMPLETED"
 }
 Figure 17: Example action status response
4.4. NIPC explicit connections management APIs
 Many 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 connection 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
 * 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 discovery can be buffered across connections,
 so the API also supports caching parameters.
 Example body of a connection without specific discovery of
 properties:
Brinckman, et al. Expires 5 June 2026 [Page 43]
Internet-Draft NIPC December 2025
 {
 "retries": 3,
 "retryMultipleAPs": true
 }
 Figure 18: Example connection
 where-
 * "retries" defines the number of retries in case the operation 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:
 {
 "retries": 3,
 "retryMultipleAPs": true,
 "sdfProtocolMap": {
 "ble": {
 "services": [
 {
 "serviceID": "00001809-0000-1000-8000-00805f9b34fb"
 }
 ],
 "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.
Brinckman, et al. Expires 5 June 2026 [Page 44]
Internet-Draft NIPC December 2025
 * "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 characteristics, which in turn contains an
 array of descriptors, as shown in Figure 20.
 services
 - serviceID
 |
 |> characteristics
 - characteristicID
 - flags
 |
 |> Descriptors
 - descriptorID
 Figure 20: BLE Services
 Example of a response:
Brinckman, et al. Expires 5 June 2026 [Page 45]
Internet-Draft NIPC December 2025
 {
 "id": "1d3b2c36-8a65-45a6-87c1-bcdbe0a32e30",
 "sdfProtocolMap": {
 "ble": [
 {
 "serviceID": "00001809-0000-1000-8000-00805f9b34fb",
 "characteristics": [
 {
 "characteristicID":
 "00002a1c-0000-1000-8000-00805f9b34fb",
 "flags": [
 "read",
 "write"
 ],
 "descriptors": [
 {
 "descriptorID":
 "00002902-0000-1000-8000-00805f9b34fb"
 }
 ]
 }
 ]
 }
 ]
 }
 }
 Figure 21: 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.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:
Brinckman, et al. Expires 5 June 2026 [Page 46]
Internet-Draft NIPC December 2025
 * 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 discovery can be buffered across connections,
 so the API also supports caching parameters.
 Example body of an update connection:
 {
 "sdfProtocolMap": {
 "ble": {
 "services": [
 {
 "serviceID": "00001809-0000-1000-8000-00805f9b34fb"
 }
 ],
 "cached": false,
 "cacheIdlePurge": 3600,
 "autoUpdate": true
 }
 }
 }
 Figure 22: Example service discovery response
 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 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:
Brinckman, et al. Expires 5 June 2026 [Page 47]
Internet-Draft NIPC December 2025
 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 characteristics, which in turn contains an
 array of descriptors, as shown in Figure 20.
 Example of a response:
 {
 "id": "1d3b2c36-8a65-45a6-87c1-bcdbe0a32e30",
 "sdfProtocolMap": {
 "ble": [
 {
 "serviceID": "00001809-0000-1000-8000-00805f9b34fb",
 "characteristics": [
 {
 "characteristicID":
 "00002a1c-0000-1000-8000-00805f9b34fb",
 "flags": [
 "read",
 "write"
 ],
 "descriptors": [
 {
 "descriptorID":
 "00002902-0000-1000-8000-00805f9b34fb"
 }
 ]
 }
 ]
 }
 ]
 }
 }
 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.
Brinckman, et al. Expires 5 June 2026 [Page 48]
Internet-Draft NIPC December 2025
4.4.3. Disconnect from a device
 Method: DELETE /devices/{id}/connections
 Description: Disconnect from a device
 Parameters:
 * id: the ID of the device
 Response:
 Returns HTTP status code 200 OK with device ID on successful
 disconnect.
 Example of a response:
 {
 "id": "1d3b2c36-8a65-45a6-87c1-bcdbe0a32e30"
 }
 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 5 June 2026 [Page 49]
Internet-Draft NIPC December 2025
 {
 "id": "1d3b2c36-8a65-45a6-87c1-bcdbe0a32e30",
 "sdfProtocolMap": {
 "ble": [
 {
 "serviceID": "00001809-0000-1000-8000-00805f9b34fb",
 "characteristics": [
 {
 "characteristicID":
 "00002a1c-0000-1000-8000-00805f9b34fb",
 "flags": [
 "read",
 "write"
 ],
 "descriptors": [
 {
 "descriptorID":
 "00002902-0000-1000-8000-00805f9b34fb"
 }
 ]
 }
 ]
 }
 ]
 }
 }
 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 designed to be extensible in two complementary ways:
 * Protocol mappings: NIPC relies on SDF protocol mappings to relate
 protocol-neutral affordances to protocol-specific operations.
 Adding a new mapping enables support for additional device
 protocols (or versions) without the need to change the NIPC API
 itself. This allows deployments to evolve as device ecosystems
Brinckman, et al. Expires 5 June 2026 [Page 50]
Internet-Draft NIPC December 2025
 change, while preserving application portability and gateway
 interoperability. Protocol mapping is an extension to SDF and
 described in [I-D.ietf-asdf-sdf-protocol-mapping].
 * API extensions: Extensions compose multiple NIPC operations into a
 single request or introduce specialized flows optimized for common
 scenarios (e.g., bulk property updates, conditional reads,
 firmware operations). Extensions MUST use the "/extensions" path
 element and SHOULD focus on efficiency, latency reduction, and
 operational simplicity (fewer round trips, reduced state
 management). To ensure interoperability and consistent security
 review, extensions MUST be registered with IANA as defined in
 Section 11.2.
5.1. Protocol mappings
 NIPC relies on SDF protocol mappings
 [I-D.ietf-asdf-sdf-protocol-mapping] to relate protocol-neutral
 affordances to protocol-specific operations. In
 [I-D.ietf-asdf-sdf-protocol-mapping] BLE and Zigbee are used as
 examples, however the mapping mechanism is extensible; so support for
 additional protocols (or versions) can be added without changing the
 NIPC schema or API.
5.2. API extensions
 The extension APIs allow for extensibility of the APIs. Extension
 APIs may leverage the basic NIPC defined APIs and combine them in
 compound statements in order to streamline application operation
 against devices, make operations more expedient and convenient in one
 API call. An example of this is the bulk API extension. They may
 also introduce new functionality that is specific to a use case or
 protocol, such as the BLE transmit API.
 Extensions must be defined under the /extensions path element. The
 extension name is defined as a path parameter after the /extensions
 path element. Extensions may define their own request and response
 payloads, as well as their own query parameters. Extensions must be
 IANA registered as defined in Section 11.2.
Brinckman, et al. Expires 5 June 2026 [Page 51]
Internet-Draft NIPC December 2025
 Extensions MAY implement long-running operations (e.g., firmware
 updates, bulk actions). For such operations, the server SHOULD
 respond with 202 Accepted and a Location header referencing a status
 URI. Clients MAY poll the status URI (GET) to obtain progress.
 While the operation is in progress, the status endpoint SHOULD return
 200 OK with status information; upon completion, the server MAY
 redirect with 303 See Other to the final result resource, or return
 200 OK with the completed result from the status endpoint. This
 pattern minimizes client state, supports retry, and provides a
 uniform mechanism for tracking asynchronous execution.
 In the appendix Appendix C, we have defined a few example extensions.
6. NIPC Error Handling
 Error types in NIPC APIs must use URI-based error type identifiers as
 defined in Section 11.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.
 NIPC 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 | | |
Brinckman, et al. Expires 5 June 2026 [Page 52]
Internet-Draft NIPC December 2025
 +----------------------+------------------------------+-----------+
 | sdf-model-in-use | SDF model in use | Generic |
 +----------------------+------------------------------+-----------+
 | unsupported-uri- | Unsupported URI scheme | Generic |
 | scheme | | |
 +----------------------+------------------------------+-----------+
 | property-not- | Property not readable | Property |
 | 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 |
Brinckman, et al. Expires 5 June 2026 [Page 53]
Internet-Draft NIPC December 2025
 | invalid-endpoint-or- | cluster ID | specific |
 | cluster | | |
 +----------------------+------------------------------+-----------+
 | extension-transmit- | Invalid transmit data | Transmit |
 | invalid-data | | APIs |
 +----------------------+------------------------------+-----------+
 | extension-firmware- | Firmware rollback | Extension |
 | rollback | | APIs |
 +----------------------+------------------------------+-----------+
 | extension-firmware- | Firmware update failed | Extension |
 | update-failed | | APIs |
 +----------------------+------------------------------+-----------+
 Table 3: Error Codes
 The appropriate HTTP status code is returned in the response.
7. Publish/Subscribe Interface
 Events are delivered via a publish/subscribe interface. Event types
 include: (1) streaming data (enabled/disabled via the NIPC Events
 API), (2) broadcasts (e.g., advertisements), and (3) connection
 status (device link up/down). Event payloads are encoded in CBOR
 [RFC8949] and MAY be transported over MQTT, webhook, or websocket.
 CBOR is used because non-IP device payloads are typically binary; it
 encodes such data efficiently and is more compact than JSON, reducing
 bandwidth.
7.1. CDDL Definition
 The event streaming format is defined here in CDDL [RFC8610]. A
 DataSubscription is a CBOR map containing the raw payload (bytes) and
 a timestamp (epoch seconds). It MAY include deviceID (the SCIM
 device identifier) when the payload is associated with a known
 onboarded device. Optional members (e.g., apMacAddress, rssi) MAY be
 present but can reveal deployment topology and SHOULD be omitted
 unless required. A choice group within DataSubscription indicates
 the event type (e.g., advertisement, subscription notification,
 connection status). An event publication MAY carry one or more
 DataSubscription entries in an array. Such an array is represented
 as DataBatch.
Brinckman, et al. Expires 5 June 2026 [Page 54]
Internet-Draft NIPC December 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 5 June 2026 [Page 55]
Internet-Draft NIPC December 2025
7.2. CBOR Examples
 This section contains a few examples of the DataSubscription struct
 in CBOR diagnostic notation.
 [
 {
 "data": h'02011A020A0C16FF4C001007721F41B0392078',
 "deviceID": "1d3b2c36-8a65-45a6-87c1-bcdbe0a32e30",
 "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": "1d3b2c36-8a65-45a6-87c1-bcdbe0a32e30",
 "timestamp": 1727484393,
 "bleSubscription": {
 "serviceID": "a4e649f4-4be5-11e5-885d-feff819cdc9f",
 "characteristicID": "c4c1f6e2-4be5-11e5-885d-feff819cdc9f"
 }
 }
 ]
 Figure 28: BLE GATT Notification
Brinckman, et al. Expires 5 June 2026 [Page 56]
Internet-Draft NIPC December 2025
 [
 {
 "deviceID": "1d3b2c36-8a65-45a6-87c1-bcdbe0a32e30",
 "timestamp": 1727484393,
 "bleConnectionStatus": {
 "macAddress": "C1:5C:00:00:00:01",
 "connected": true
 }
 }
 ]
 Figure 29: BLE Connection status event
 [
 {
 "data": h'434630374346303739453036',
 "deviceID": "1d3b2c36-8a65-45a6-87c1-bcdbe0a32e30",
 "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 5 June 2026 [Page 57]
Internet-Draft NIPC December 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 Figure 33
 * Read a property from the BLE device
 ============== NOTE: '\' line wrapping per RFC 8792 ==============
 GET /devices/1d3b2c36-8a65-45a6-87c1-bcdbe0a32e30/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 5 June 2026 [Page 58]
Internet-Draft NIPC December 2025
 ============== NOTE: '\' line wrapping per RFC 8792 ==============
 PUT /devices/1d3b2c36-8a65-45a6-87c1-bcdbe0a32e30/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 on a Device
 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 5 June 2026 [Page 59]
Internet-Draft NIPC December 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 Figure 33
 * Register the data app with the event
Brinckman, et al. Expires 5 June 2026 [Page 60]
Internet-Draft NIPC December 2025
 ============== NOTE: '\' line wrapping per RFC 8792 ==============
 POST /registrations/data-apps?dataAppId=0927ce7c-b258-4bfa-a345-\
 bcc9f74385b4
 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/1d3b2c36-8a65-45a6-87c1-bcdbe0a32e30/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/1d3b2c36-8a65-45a6-87c1-bcdbe0a32e30/events?in\
 stanceId=02ee282c-8915-4b2e-bbd2-88966773134a
 * Check the status of the event
Brinckman, et al. Expires 5 June 2026 [Page 61]
Internet-Draft NIPC December 2025
 ============== NOTE: '\' line wrapping per RFC 8792 ==============
 GET /devices/1d3b2c36-8a65-45a6-87c1-bcdbe0a32e30/events?instance\
 Id=02ee282c-8915-4b2e-bbd2-88966773134a
 Host: localhost
 HTTP/1.1 200 OK
 content-type: application/nipc+json
 {
 "event": "https://example.com/thermometer#/sdfThing/thermometer\
 /sdfEvent/isPresent"
 }
8.3. Enabling an Event on a Group of Devices
 In this example, we will enable an advertisement subscription event
 for a group of devices.
 The sequence of operations for this are:
 * Onboard devices and endpoint app using the SCIM Interface (out of
 scope of this memo)
 * Register an SDF model for the devices
 ============== 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 Figure 33
 * Register the data app with the event
Brinckman, et al. Expires 5 June 2026 [Page 62]
Internet-Draft NIPC December 2025
 ============== NOTE: '\' line wrapping per RFC 8792 ==============
 POST /registrations/data-apps?dataAppId=0927ce7c-b258-4bfa-a345-\
 bcc9f74385b4
 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 on a group of devices
 ============== NOTE: '\' line wrapping per RFC 8792 ==============
 POST /groups/0dc729d7-f6c3-491d-9b9d-e7176d2be243/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: /groups/0dc729d7-f6c3-491d-9b9d-e7176d2be243/events?in\
 stanceId=f1b9f26b-21ce-4deb-9d57-289ba7e17cce
 * Check the status of the event
Brinckman, et al. Expires 5 June 2026 [Page 63]
Internet-Draft NIPC December 2025
 ============== NOTE: '\' line wrapping per RFC 8792 ==============
 GET /groups/0dc729d7-f6c3-491d-9b9d-e7176d2be243/events?instance\
 Id=f1b9f26b-21ce-4deb-9d57-289ba7e17cce
 Host: localhost
 HTTP/1.1 200 OK
 content-type: application/nipc+json
 [
 {
 "event": "https://example.com/heartrate#/sdfObject/healthsen\
 sor/sdfEvent/fallDetected",
 "deviceId": "1d3b2c36-8a65-45a6-87c1-bcdbe0a32e30"
 },
 {
 "event": "https://example.com/heartrate#/sdfObject/healthsen\
 sor/sdfEvent/fallDetected",
 "deviceId": "d62c7fb2-a216-4811-a388-053b17fdbedc"
 },
 {
 "event": "https://example.com/heartrate#/sdfObject/healthsen\
 sor/sdfEvent/fallDetected",
 "deviceId": "01b52a23-b98c-454c-ba9e-086a43bdfd79"
 },
 {
 "type": "https://www.iana.org/assignments/nipc-problem-types\
 #event-not-enabled",
 "status": 400,
 "title": "Event Not Enabled",
 "deviceId": "9171ec16-e3c1-4ccf-ad23-b92a1a3f069d",
 "detail": "Failed to disable the event for device 9171ec16-e\
 3c1-4ccf-ad23-b92a1a3f069d"
 }
 ]
9. Implementation Status
 This section is to be removed before publishing as an RFC.
 This section records the status of known implementations of the
 protocol defined by this specification at the time of posting of this
 Internet-Draft, and is based on a proposal described in [RFC7942].
 The description of implementations in this section is intended to
 assist the IETF in its decision processes in progressing drafts to
 RFCs. Please note that the listing of any individual implementation
 here does not imply endorsement by the IETF. Furthermore, no effort
 has been spent to verify the information presented here that was
Brinckman, et al. Expires 5 June 2026 [Page 64]
Internet-Draft NIPC December 2025
 supplied by IETF contributors. This is not intended as, and must not
 be construed to be, a catalog of available implementations or their
 features. Readers are advised to note that other implementations may
 exist.
 According to [RFC7942], "this will allow reviewers and working groups
 to assign due consideration to documents that have the benefit of
 running code, which may serve as evidence of valuable experimentation
 and feedback that have made the implemented protocols more mature.
 It is up to the individual working groups to use this information as
 they see fit".
9.1. TieDie IoT
 Organization: Cisco Systems, North Carolina State University
 Description: Open-source implementation of the NIPC APIs and gateway
 functionality for BLE. Client libraries and sample application
 functions for Python and Java are also provided.
 Level of maturity: Open-source prototype
 Coverage: All NIPC APIs for BLE protocol mapping
 Version compatibility: All versions up to draft-15
 Licensing: Apache License, Version 2.0
 URL: https://github.com/iot-onboarding/tiedie
9.2. Cisco Sensor Connect for IoT Services (Catalyst)
 Organization: Cisco Systems
 Description: Commercial solution that delivers advanced BLE
 capabilities over Cisco Wireless infrastructure.
 Level of maturity: Production
 Coverage: All NIPC APIs for BLE protocol mapping
 Version compatibility: draft-00
 Licensing: Proprietary
 URL: https://developer.cisco.com/docs/spaces-connect-for-iot-
 services/
Brinckman, et al. Expires 5 June 2026 [Page 65]
Internet-Draft NIPC December 2025
9.3. Cisco Sensor Connect for IoT Services (Meraki)
 Organization: Cisco Systems
 Description: Commercial solution that delivers advanced BLE
 capabilities over Cisco Wireless infrastructure.
 Level of maturity: Beta
 Coverage: All NIPC APIs for BLE protocol mapping
 Version compatibility: draft-15
 Licensing: Proprietary
9.4. NIPC Prototype
 Organization: Ericsson Research
 Description: Prototype implementation in C of the NIPC API.
 Level of maturity: Research prototype
 Coverage: Registration and NIPC operations
 Version compatibility: Draft-04
 Licensing: Proprietary
 Contact: Lorenzo Corneo lorenzo.corneo@ericsson.com
 (mailto:lorenzo.corneo@ericsson.com)
10. Security Considerations
10.1. Payload Encryption Considerations
 Responses to NIPC operations requests may contain sensitive or
 confidential information. Therefore, application and device
 implementations should consider payload encryption. NIPC does not
 provide any payload encryption mechanism. If payload encryption is
 required, it MUST be provided by the underlying device protocol
 (e.g., BLE security modes) or by the transport-layer security
 mechanism (e.g., TLS).
Brinckman, et al. Expires 5 June 2026 [Page 66]
Internet-Draft NIPC December 2025
10.2. TLS Support Considerations
 NIPC MUST run on top of a transport-layer security mechanism such as
 TLS. When leveraging TLS, the NIPC gateway MUST support TLS 1.2
 [RFC5246] and TLS 1.3 [RFC8446] and MAY support additional transport-
 layer mechanisms. When using TLS, the client MUST perform a TLS/SSL
 server identity check, per [RFC6125]. Implementation security
 considerations for TLS can be found in [RFC7525].
10.3. HTTP Considerations
 NIPC runs on top of HTTP and is thus subject to the security
 considerations of HTTP Section 9 of [RFC7230].
10.4. Authorization Considerations
10.4.1. API authorization Considerations
 To enable NIPC gateway functions, the network administrator MUST
 authorize applications (e.g., via exchange of tokens or public keys).
 Authorization MAY be role-based. The following baseline roles are
 RECOMMENDED:
 * Onboarding: permitted to create and manage device and endpoint-app
 identities via SCIM (typically co-located with the gateway).
 * Control: permitted to invoke NIPC property, action, and event
 APIs.
 * Data: permitted to receive streamed event data. Deployments MAY
 further refine authorization at per-API or per-affordance
 granularity.
10.4.2. Authorization Token/Bearer Token/Cookie Considerations
 When using authorization tokens such as those issued by OAuth 2.0
 [RFC6749], implementers MUST take into account threats and
 countermeasures as documented in Section 8 of [RFC7521].
 Since the possession of a bearer token, Authorization token, or
 cookie MAY authorize the holder to perform NIPC Operations on
 devices, tokens and cookies MUST contain sufficient entropy to
 prevent random guessing attack; for example, see Section 5.2 of
 [RFC6750] and Section 5.1.4.2.2 of [RFC6819].
 As with all NIPC communications, bearer tokens and HTTP cookies MUST
 be exchanged using transport-layer security mechanism such as TLS.
Brinckman, et al. Expires 5 June 2026 [Page 67]
Internet-Draft NIPC December 2025
 Bearer tokens MUST have a limited lifetime that can be determined
 directly or indirectly (e.g., by checking with a validation service)
 by the application. By expiring tokens, applications are forced to
 obtain a new token (which usually involves re-authentication) for
 continued authorized access. For example, in OAuth 2.0, an
 application MAY use OAuth token refresh to obtain a new bearer token
 after authenticating to an authorization server. See Section 6 of
 [RFC6749]. As with bearer tokens, an HTTP cookie SHOULD last no
 longer than the lifetime of a browser session. An expiry time should
 be set that limits session cookie lifetime as per Section 5.2.1 of
 [RFC6265].
 Implementations supporting OAuth bearer tokens need to factor in
 security considerations of this authorization method [RFC7521].
 Implementers also need to consider authentication choices coupled
 with OAuth bearer tokens. For example, when using OAuth bearer
 tokens with client authentication via client credentials Section 4.4
 of [RFC6749], implementers need to consider the security
 considerations of client authentication via client credentials as
 described in Section 3.2 of [RFC6819].
10.5. Other Security Considerations
 * Preventing automated attacks: It is recommended to limit the
 number of requests that any particular application MAY make in a
 period of time.
 * Logging and monitoring: It is recommended to log and monitor API
 usage to detect potential abuse or attacks.
 * Input validation: It is recommended to validate all inputs to
 prevent injection attacks.
 * Error handling: It is recommended to handle errors gracefully
 without exposing sensitive information.
 * Least privilege: It is recommended to follow the principle of
 least privilege when granting access to resources.
 * Storage and handling of sensitive data: Credentials MUST NOT be
 stored in clear-text, but MUST be stored using an encrypted
 protection mechanism (e.g., hashing).
11. IANA Considerations
 This section provides guidance to the Internet Assigned Numbers
 Authority (IANA) regarding registration of values related to NIPC, in
 accordance with [RFC8126].
Brinckman, et al. Expires 5 June 2026 [Page 68]
Internet-Draft NIPC December 2025
11.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
 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 10 section of this document.
 Interoperability considerations: none
 Published specification: This document, the NIPC API specification.
 Applications that use this media type: Applications implementing NIPC
 APIs for IoT device management.
 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
Brinckman, et al. Expires 5 June 2026 [Page 69]
Internet-Draft NIPC December 2025
11.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
 * 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 5 June 2026 [Page 70]
Internet-Draft NIPC December 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 4
11.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 5 June 2026 [Page 71]
Internet-Draft NIPC December 2025
 +============+===================+==============================+
 | URI Suffix | Change Controller | Specification Document |
 +============+===================+==============================+
 | nipc | IETF | This document, Section 2.6.1 |
 +------------+-------------------+------------------------------+
 Table 5
 The well-known URI for NIPC is:
 /.well-known/nipc
11.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 5 June 2026 [Page 72]
Internet-Draft NIPC December 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/ | Unsupported URI | This |
 | nipc-problem-types#unsupported- | scheme | document |
 | uri-scheme | | |
 +-----------------------------------+-------------------+-----------+
 | 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 |
Brinckman, et al. Expires 5 June 2026 [Page 73]
Internet-Draft NIPC December 2025
 | nipc-problem-types#protocolmap- | timeout | document |
 | ble-connection-timeout | | |
 +-----------------------------------+-------------------+-----------+
 | https://www.iana.org/assignments/ | BLE bonding | This |
 | 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 6
 Each Problem Type URI is intended for use as the "type" member in
 Problem Details responses as described.
12. References
Brinckman, et al. Expires 5 June 2026 [Page 74]
Internet-Draft NIPC December 2025
12.1. Normative References
 [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-25, 13 October 2025,
 <https://datatracker.ietf.org/doc/html/draft-ietf-asdf-
 sdf-25>.
 [I-D.ietf-asdf-sdf-protocol-mapping]
 Mohan, R., Brinckman, B., and L. Corneo, "Protocol Mapping
 for SDF", Work in Progress, Internet-Draft, draft-ietf-
 asdf-sdf-protocol-mapping-02, 2 December 2025,
 <https://datatracker.ietf.org/doc/html/draft-ietf-asdf-
 sdf-protocol-mapping-02>.
 [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,
 <https://datatracker.ietf.org/doc/html/draft-ietf-scim-
 device-model-18>.
 [RFC2119] Bradner, S., "Key words for use in RFCs to Indicate
 Requirement Levels", BCP 14, RFC 2119,
 DOI 10.17487/RFC2119, March 1997,
 <https://www.rfc-editor.org/info/rfc2119>.
 [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,
 <https://www.rfc-editor.org/info/rfc3986>.
 [RFC4648] Josefsson, S., "The Base16, Base32, and Base64 Data
 Encodings", RFC 4648, DOI 10.17487/RFC4648, October 2006,
 <https://www.rfc-editor.org/info/rfc4648>.
 [RFC5246] Dierks, T. and E. Rescorla, "The Transport Layer Security
 (TLS) Protocol Version 1.2", RFC 5246,
 DOI 10.17487/RFC5246, August 2008,
 <https://www.rfc-editor.org/info/rfc5246>.
Brinckman, et al. Expires 5 June 2026 [Page 75]
Internet-Draft NIPC December 2025
 [RFC6125] Saint-Andre, P. and J. Hodges, "Representation and
 Verification of Domain-Based Application Service Identity
 within Internet Public Key Infrastructure Using X.509
 (PKIX) Certificates in the Context of Transport Layer
 Security (TLS)", RFC 6125, DOI 10.17487/RFC6125, March
 2011, <https://www.rfc-editor.org/info/rfc6125>.
 [RFC6265] Barth, A., "HTTP State Management Mechanism", RFC 6265,
 DOI 10.17487/RFC6265, April 2011,
 <https://www.rfc-editor.org/info/rfc6265>.
 [RFC6570] Gregorio, J., Fielding, R., Hadley, M., Nottingham, M.,
 and D. Orchard, "URI Template", RFC 6570,
 DOI 10.17487/RFC6570, March 2012,
 <https://www.rfc-editor.org/info/rfc6570>.
 [RFC6749] Hardt, D., Ed., "The OAuth 2.0 Authorization Framework",
 RFC 6749, DOI 10.17487/RFC6749, October 2012,
 <https://www.rfc-editor.org/info/rfc6749>.
 [RFC6750] Jones, M. and D. Hardt, "The OAuth 2.0 Authorization
 Framework: Bearer Token Usage", RFC 6750,
 DOI 10.17487/RFC6750, October 2012,
 <https://www.rfc-editor.org/info/rfc6750>.
 [RFC6819] Lodderstedt, T., Ed., McGloin, M., and P. Hunt, "OAuth 2.0
 Threat Model and Security Considerations", RFC 6819,
 DOI 10.17487/RFC6819, January 2013,
 <https://www.rfc-editor.org/info/rfc6819>.
 [RFC7230] Fielding, R., Ed. and J. Reschke, Ed., "Hypertext Transfer
 Protocol (HTTP/1.1): Message Syntax and Routing",
 RFC 7230, DOI 10.17487/RFC7230, June 2014,
 <https://www.rfc-editor.org/info/rfc7230>.
 [RFC7468] Josefsson, S. and S. Leonard, "Textual Encodings of PKIX,
 PKCS, and CMS Structures", RFC 7468, DOI 10.17487/RFC7468,
 April 2015, <https://www.rfc-editor.org/info/rfc7468>.
 [RFC7521] Campbell, B., Mortimore, C., Jones, M., and Y. Goland,
 "Assertion Framework for OAuth 2.0 Client Authentication
 and Authorization Grants", RFC 7521, DOI 10.17487/RFC7521,
 May 2015, <https://www.rfc-editor.org/info/rfc7521>.
Brinckman, et al. Expires 5 June 2026 [Page 76]
Internet-Draft NIPC December 2025
 [RFC7525] Sheffer, Y., Holz, R., and P. Saint-Andre,
 "Recommendations for Secure Use of Transport Layer
 Security (TLS) and Datagram Transport Layer Security
 (DTLS)", RFC 7525, DOI 10.17487/RFC7525, May 2015,
 <https://www.rfc-editor.org/info/rfc7525>.
 [RFC7643] Hunt, P., Ed., Grizzle, K., Wahlstroem, E., and C.
 Mortimore, "System for Cross-domain Identity Management:
 Core Schema", RFC 7643, DOI 10.17487/RFC7643, September
 2015, <https://www.rfc-editor.org/info/rfc7643>.
 [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, <https://www.rfc-editor.org/info/rfc7644>.
 [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,
 <https://www.rfc-editor.org/info/rfc8126>.
 [RFC8174] Leiba, B., "Ambiguity of Uppercase vs Lowercase in RFC
 2119 Key Words", BCP 14, RFC 8174, DOI 10.17487/RFC8174,
 May 2017, <https://www.rfc-editor.org/info/rfc8174>.
 [RFC8259] Bray, T., Ed., "The JavaScript Object Notation (JSON) Data
 Interchange Format", STD 90, RFC 8259,
 DOI 10.17487/RFC8259, December 2017,
 <https://www.rfc-editor.org/info/rfc8259>.
 [RFC8446] Rescorla, E., "The Transport Layer Security (TLS) Protocol
 Version 1.3", RFC 8446, DOI 10.17487/RFC8446, August 2018,
 <https://www.rfc-editor.org/info/rfc8446>.
 [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, <https://www.rfc-editor.org/info/rfc8610>.
 [RFC8615] Nottingham, M., "Well-Known Uniform Resource Identifiers
 (URIs)", RFC 8615, DOI 10.17487/RFC8615, May 2019,
 <https://www.rfc-editor.org/info/rfc8615>.
 [RFC8949] Bormann, C. and P. Hoffman, "Concise Binary Object
 Representation (CBOR)", STD 94, RFC 8949,
 DOI 10.17487/RFC8949, December 2020,
 <https://www.rfc-editor.org/info/rfc8949>.
Brinckman, et al. Expires 5 June 2026 [Page 77]
Internet-Draft NIPC December 2025
 [RFC9110] Fielding, R., Ed., Nottingham, M., Ed., and J. Reschke,
 Ed., "HTTP Semantics", STD 97, RFC 9110,
 DOI 10.17487/RFC9110, June 2022,
 <https://www.rfc-editor.org/info/rfc9110>.
 [RFC9457] Nottingham, M., Wilde, E., and S. Dalal, "Problem Details
 for HTTP APIs", RFC 9457, DOI 10.17487/RFC9457, July 2023,
 <https://www.rfc-editor.org/info/rfc9457>.
 [RFC9562] Davis, K., Peabody, B., and P. Leach, "Universally Unique
 IDentifiers (UUIDs)", RFC 9562, DOI 10.17487/RFC9562, May
 2024, <https://www.rfc-editor.org/info/rfc9562>.
12.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, <https://www.bluetooth.com/bluetooth-
 resources/gatt-rest-api/>.
 [RFC7252] Shelby, Z., Hartke, K., and C. Bormann, "The Constrained
 Application Protocol (CoAP)", RFC 7252,
 DOI 10.17487/RFC7252, June 2014,
 <https://www.rfc-editor.org/info/rfc7252>.
 [RFC7942] Sheffer, Y. and A. Farrel, "Improving Awareness of Running
 Code: The Implementation Status Section", BCP 205,
 RFC 7942, DOI 10.17487/RFC7942, July 2016,
 <https://www.rfc-editor.org/info/rfc7942>.
 [Zigbee22] Connectivity Standards Alliance, "Zigbee Specification,
 Version 22 1.0", 2017.
Appendix A. OpenAPI definition
 The following non-normative model is provided for convenience of the
 implementor.
 <CODE BEGINS> 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
Brinckman, et al. Expires 5 June 2026 [Page 78]
Internet-Draft NIPC December 2025
 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.15.0
 externalDocs:
 description: NIPC IETF draft
 url: https://datatracker.ietf.org/doc/draft-ietf-asdf-nipc/
 servers:
 - url: "{gw_host}/nipc/draft-15"
 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
 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:
Brinckman, et al. Expires 5 June 2026 [Page 79]
Internet-Draft NIPC December 2025
 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: 1d3b2c36-8a65-45a6-87c1-bcdbe0a32e30
 - 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.
 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:
Brinckman, et al. Expires 5 June 2026 [Page 80]
Internet-Draft NIPC December 2025
 '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
 description: The ID of the device. Group ID is not allowed.
 required: true
 schema:
 type: string
 format: uuid
 example: 1d3b2c36-8a65-45a6-87c1-bcdbe0a32e30
 - name: propertyName
 in: query
 description: Properties to be read
 required: true
 allowReserved: true
 schema:
 type: array
 items:
Brinckman, et al. Expires 5 June 2026 [Page 81]
Internet-Draft NIPC December 2025
 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: |-
 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: The ID of the device.
 required: true
 schema:
 type: string
Brinckman, et al. Expires 5 June 2026 [Page 82]
Internet-Draft NIPC December 2025
 format: uuid
 example: 1d3b2c36-8a65-45a6-87c1-bcdbe0a32e30
 - 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: |-
 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: The ID of the device.
 required: true
 schema:
 type: string
Brinckman, et al. Expires 5 June 2026 [Page 83]
Internet-Draft NIPC December 2025
 format: uuid
 example: 1d3b2c36-8a65-45a6-87c1-bcdbe0a32e30
 - name: instanceId
 in: query
 description: instance id of the event that needs to be disab\
 \led
 required: true
 schema:
 type: string
 format: uuid
 example: 02ee282c-8915-4b2e-bbd2-88966773134a
 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
 schema:
 type: string
 format: uuid
 example: 1d3b2c36-8a65-45a6-87c1-bcdbe0a32e30
 - 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
Brinckman, et al. Expires 5 June 2026 [Page 84]
Internet-Draft NIPC December 2025
 example: 02ee282c-8915-4b2e-bbd2-88966773134a
 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
 schema:
 type: string
 format: uuid
 example: 0dc729d7-f6c3-491d-9b9d-e7176d2be243
 - 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:
Brinckman, et al. Expires 5 June 2026 [Page 85]
Internet-Draft NIPC December 2025
 '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:
 type: string
 format: uuid
 example: 0dc729d7-f6c3-491d-9b9d-e7176d2be243
 - name: instanceId
 in: query
 description: instance id of the event that needs to be disab\
 \led
 required: true
 schema:
 type: string
 format: uuid
 example: f1b9f26b-21ce-4deb-9d57-289ba7e17cce
 responses:
 '200':
Brinckman, et al. Expires 5 June 2026 [Page 86]
Internet-Draft NIPC December 2025
 description: Success, event disabled
 content:
 application/nipc+json:
 schema:
 $ref: '#/components/schemas/GroupEventStatusResponse\
 \Array'
 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: 0dc729d7-f6c3-491d-9b9d-e7176d2be243
 - name: instanceId
 in: query
 description: |-
 Instance IDs of the events that need to be filtered
 required: false
 schema:
 type: string
 format: uuid
 example: f1b9f26b-21ce-4deb-9d57-289ba7e17cce
 responses:
 '200':
 description: Success, events retrieved
 content:
 application/nipc+json:
 schema:
 $ref: '#/components/schemas/GroupEventStatusResponse\
 \Array'
 default:
 description: Error response
Brinckman, et al. Expires 5 June 2026 [Page 87]
Internet-Draft NIPC December 2025
 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: 1d3b2c36-8a65-45a6-87c1-bcdbe0a32e30
 - 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:
 content:
 application/octet-stream:
 schema:
 type: string
 format: binary
 required: false
 responses:
 '202':
 description: Accepted, action is being performed
 headers:
Brinckman, et al. Expires 5 June 2026 [Page 88]
Internet-Draft NIPC December 2025
 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: 1d3b2c36-8a65-45a6-87c1-bcdbe0a32e30
 - name: instanceId
 in: query
 description: |-
 instance id of the action that needs to be checked
 required: true
 schema:
 type: string
 format: uuid
 example: 02ee282c-8915-4b2e-bbd2-88966773134a
 responses:
 '200':
 description: Success, action is active
 content:
 application/nipc+json:
 schema:
 $ref: '#/components/schemas/ActionResponse'
 default:
Brinckman, et al. Expires 5 June 2026 [Page 89]
Internet-Draft NIPC December 2025
 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: 1d3b2c36-8a65-45a6-87c1-bcdbe0a32e30
 requestBody:
 content:
 application/nipc+json:
 schema:
 anyOf:
 - $ref: '#/components/schemas/Connection'
 - $ref: './protocolmaps/ProtocolMap.yaml#/components\
 \/schemas/ProtocolMap-ServiceList'
 required: false
 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
Brinckman, et al. Expires 5 June 2026 [Page 90]
Internet-Draft NIPC December 2025
 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: 1d3b2c36-8a65-45a6-87c1-bcdbe0a32e30
 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'
 - $ref: './protocolmaps/ProtocolMap.yaml#/componen\
 \ts/schemas/ProtocolMap-ServiceMap'
 default:
 description: Error response
 content:
 application/problem+json:
 schema:
 $ref: '#/components/schemas/FailureResponse'
 delete:
Brinckman, et al. Expires 5 June 2026 [Page 91]
Internet-Draft NIPC December 2025
 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: 1d3b2c36-8a65-45a6-87c1-bcdbe0a32e30
 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
 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: 1d3b2c36-8a65-45a6-87c1-bcdbe0a32e30
Brinckman, et al. Expires 5 June 2026 [Page 92]
Internet-Draft NIPC December 2025
 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:
 application/nipc+json:
 schema:
 type: array
 items:
 allOf:
 - $ref: '#/components/schemas/SdfReference'
 default:
 description: Error response
 content:
 application/problem+json:
Brinckman, et al. Expires 5 June 2026 [Page 93]
Internet-Draft NIPC December 2025
 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:
 - 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: |-
Brinckman, et al. Expires 5 June 2026 [Page 94]
Internet-Draft NIPC December 2025
 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:
 - name: sdfName
 in: query
 description: sdfObject name
 required: true
 schema:
 type: string
 example: "https://example.com/heartrate#/sdfObject/healt\
 \hsensor"
 responses:
 '200':
Brinckman, et al. Expires 5 June 2026 [Page 95]
Internet-Draft NIPC December 2025
 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: 0927ce7c-b258-4bfa-a345-bcc9f74385b4
 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
 content:
Brinckman, et al. Expires 5 June 2026 [Page 96]
Internet-Draft NIPC December 2025
 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: 0927ce7c-b258-4bfa-a345-bcc9f74385b4
 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
 content:
 application/problem+json:
 schema:
 allOf:
 - $ref: '#/components/schemas/FailureResponse'
 delete:
 tags:
 - NIPC registration APIs
 summary: Delete registration of a dataApp
Brinckman, et al. Expires 5 June 2026 [Page 97]
Internet-Draft NIPC December 2025
 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: 0927ce7c-b258-4bfa-a345-bcc9f74385b4
 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:
 - name: dataAppId
 in: query
 description: id of the data app that will be updated
 required: true
 schema:
 type: string
 format: uuid
 example: 0927ce7c-b258-4bfa-a345-bcc9f74385b4
 responses:
 '200':
Brinckman, et al. Expires 5 June 2026 [Page 98]
Internet-Draft NIPC December 2025
 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: 1d3b2c36-8a65-45a6-87c1-bcdbe0a32e30
 ## A property
 Property:
 required:
 - property
 type: object
 properties:
 property:
 type: string
 example: "https://example.com/heartrate#/sdfObject/thermos\
 \tat/sdfProperty/temperature"
 ActionResponse:
 required:
 - action
 type: object
 properties:
 status:
 type: string
Brinckman, et al. Expires 5 June 2026 [Page 99]
Internet-Draft NIPC December 2025
 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\
 \nsor/sdfEvent/fallDetected
 InstanceId:
 type: object
 properties:
 instanceId:
 type: string
 format: uuid
 description: |-
 A SCIM-generated UUID for the event instance
Brinckman, et al. Expires 5 June 2026 [Page 100]
Internet-Draft NIPC December 2025
 example: 02ee282c-8915-4b2e-bbd2-88966773134a
 ## 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:
 mqttBroker:
 type: object
 required:
 - URI
 - username
 - password
 properties:
 URI:
 type: string
 example: mqtt.broker.com:8883
Brinckman, et al. Expires 5 June 2026 [Page 101]
Internet-Draft NIPC December 2025
 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:
 URI:
 type: string
 example: websocket.com:443
 headers:
 type: object
 additionalProperties:
 type: string
 example:
 x-api-key: fjelk-3dl33f-2wdsd
 serverCACert:
Brinckman, et al. Expires 5 June 2026 [Page 102]
Internet-Draft NIPC December 2025
 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'
 - $ref: '#/components/schemas/SdfEvent'
 - $ref: '#/components/schemas/SdfAction'
 - $ref: '#/components/schemas/SdfObject'
 example:
 multipleSensor:
 sdfEvent:
 isPresent:
 sdfOutputData:
 sdfProtocolMap:
 ble:
Brinckman, et al. Expires 5 June 2026 [Page 103]
Internet-Draft NIPC December 2025
 type: advertisement
 sdfObject:
 healthsensor:
 sdfProperty:
 heartrate:
 sdfProtocolMap:
 ble:
 serviceID: 00001809-0000-1000-8000-00805f9\
 \b34fb
 characteristicID: 00002a1c-0000-1000-8000-\
 00805円f9b34fb
 sdfEvent:
 fallDetected:
 sdfOutputData:
 sdfProtocolMap:
 ble:
 serviceID: 00001809-0000-1000-8000-00805\
 \f9b34fb
 characteristicID: 00002a1c-0000-1000-800\
 0円-00805f9b34fb
 sdfAction:
 start:
 sdfProtocolMap:
 ble:
 serviceID: 00001809-0000-1000-8000-00805f9\
 \b34fb
 characteristicID: 00002a1c-0000-1000-8000-\
 00805円f9b34fb
 SdfObject:
 type: object
 description: Sample SDF object
 properties:
 sdfObject:
 additionalProperties:
 anyOf:
 - $ref: '#/components/schemas/SdfProperty'
 - $ref: '#/components/schemas/SdfEvent'
 - $ref: '#/components/schemas/SdfAction'
 example:
 healthsensor:
 sdfProperty:
 heartrate:
 sdfProtocolMap:
 ble:
 serviceID: 00001809-0000-1000-8000-00805f9b34fb
 characteristicID: 00002a1c-0000-1000-8000-0080\
 5円f9b34fb
Brinckman, et al. Expires 5 June 2026 [Page 104]
Internet-Draft NIPC December 2025
 sdfEvent:
 fallDetected:
 sdfOutputData:
 sdfProtocolMap:
 ble:
 type: advertisements
 sdfAction:
 start:
 sdfProtocolMap:
 ble:
 serviceID: 00001809-0000-1000-8000-00805f9b34fb
 characteristicID: 00002a1c-0000-1000-8000-0080\
 5円f9b34fb
 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: 00001809-0000-1000-8000-00805f9b34fb
 characteristicID: 00002a1c-0000-1000-8000-00805f9b\
 34円fb
 SdfEvent:
 type: object
 description: Sample SDF property
 properties:
 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:
Brinckman, et al. Expires 5 June 2026 [Page 105]
Internet-Draft NIPC December 2025
 ble:
 serviceID: 00001809-0000-1000-8000-00805f9b34fb
 characteristicID: 00002a1c-0000-1000-8000-00805f\
 9円b34fb
 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: 00001809-0000-1000-8000-00805f9b34fb
 characteristicID: 00002a1c-0000-1000-8000-00805f9b\
 34円fb
 # responses
 SuccessResponse:
 type: object
 properties:
 status:
 type: integer
 format: int32
 example: 200
 description: HTTP status code
 ## Error 500 application Failure response
 FailureResponse:
 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\
Brinckman, et al. Expires 5 June 2026 [Page 106]
Internet-Draft NIPC December 2025
 \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
 - 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:
Brinckman, et al. Expires 5 June 2026 [Page 107]
Internet-Draft NIPC December 2025
 type: string
 example: Invalid Device ID
 description: Human-readable error title
 detail:
 type: string
 example: |-
 Device ID 1d3b2c36-8a65-45a6-87c1-bcdbe0a32e30 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
 EventStatusResponseArrayItem:
 oneOf:
 - allOf:
 - $ref: '#/components/schemas/Event'
 - $ref: '#/components/schemas/InstanceId'
 - $ref: '#/components/schemas/FailureResponse'
 EventStatusResponseArray:
 type: array
 items:
 $ref: '#/components/schemas/EventStatusResponseArrayItem'
 GroupEventStatusResponse:
Brinckman, et al. Expires 5 June 2026 [Page 108]
Internet-Draft NIPC December 2025
 type: object
 oneOf:
 - allOf:
 - $ref: '#/components/schemas/Event'
 - type: object
 properties:
 deviceId:
 type: string
 format: uuid
 example: 0dc729d7-f6c3-491d-9b9d-e7176d2be243
 - $ref: '#/components/schemas/FailureResponse'
 GroupEventStatusResponseArray:
 type: array
 items:
 $ref: '#/components/schemas/GroupEventStatusResponse'
 <CODE ENDS>
 Figure 31
Appendix B. Protocol mapping
 The OpenAPI model for SDF protocol mapping is provided in Appendix B
 of [I-D.ietf-asdf-sdf-protocol-mapping].
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
 <CODE BEGINS> 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
Brinckman, et al. Expires 5 June 2026 [Page 109]
Internet-Draft NIPC December 2025
 version: 0.15.0
 externalDocs:
 description: NIPC IETF draft
 url: https://datatracker.ietf.org/doc/draft-ietf-asdf-nipc/
 servers:
 - url: "{gw_host}/nipc/draft-15"
 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
 parameters:
 - name: id
 in: path
 description: The ID of the device. Group ID is not allowed.
 required: true
 schema:
 type: string
 format: uuid
 example: 1d3b2c36-8a65-45a6-87c1-bcdbe0a32e30
 - name: propertyName
 in: query
 description: |-
 The SDF property name that needs to be written to.
 required: true
 schema:
 type: string
Brinckman, et al. Expires 5 June 2026 [Page 110]
Internet-Draft NIPC December 2025
 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:
 type: integer
 <CODE ENDS>
C.2. NIPC API bulk operations extension
 <CODE BEGINS> 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/
Brinckman, et al. Expires 5 June 2026 [Page 111]
Internet-Draft NIPC December 2025
 contact:
 email: bbrinckm@cisco.com
 license:
 name: TBD
 url: TBD
 version: 0.15.0
 externalDocs:
 description: NIPC IETF draft
 url: https://datatracker.ietf.org/doc/draft-ietf-asdf-nipc/
 servers:
 - url: "{gw_host}/nipc/draft-15"
 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
 in: path
 description: The ID of the device. Group ID is not allowed.
 required: true
 schema:
 type: string
 format: uuid
 example: 1d3b2c36-8a65-45a6-87c1-bcdbe0a32e30
 requestBody:
 content:
 application/json:
 schema:
 $ref: "#/components/schemas/Extension-Bulk"
 examples:
 bulkRequest:
 $ref: "#/components/examples/bulkRequest"
 firmwareUpgradeRequest:
Brinckman, et al. Expires 5 June 2026 [Page 112]
Internet-Draft NIPC December 2025
 $ref: "#/components/examples/firmwareUpgradeRequest"
 required: true
 responses:
 "202":
 description: Accepted
 headers:
 Location:
 schema:
 type: string
 example: /extensions/1d3b2c36-8a65-45a6-87c1-bcdbe0a\
 32e30/bulk/status?instanceId=02ee282c-8915-4b2e-bbd2-88966773134a
 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:
 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
Brinckman, et al. Expires 5 June 2026 [Page 113]
Internet-Draft NIPC December 2025
 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: 1d3b2c36-8a65-45a6-87c1-bcdbe0a32e30
 - name: instanceId
 in: query
 description: Instance ID of the bulk operation
 required: true
 schema:
 type: string
 format: uuid
 example: 1d3b2c36-8a65-45a6-87c1-bcdbe0a32e30
 responses:
 "200":
 description: OK
 headers:
 content:
 application/json:
 schema:
 allOf:
 - $ref: "../NIPC.yaml#/components/schemas/Id"
 - $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
Brinckman, et al. Expires 5 June 2026 [Page 114]
Internet-Draft NIPC December 2025
 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: 1d3b2c36-8a65-45a6-87c1-bcdbe0a32e30
 - name: instanceId
 in: query
 description: Instance ID of the bulk operation
 required: true
 schema:
 type: string
 format: uuid
 example: 1d3b2c36-8a65-45a6-87c1-bcdbe0a32e30
 responses:
 "200":
 description: OK
 headers:
 content:
 application/json:
 schema:
 allOf:
 - $ref: "./Extension-Async.yaml#/components/schema\
 s/Extension-StatusResponse"
 "303":
 description: See Other
 headers:
 Location:
 schema:
 type: string
 example: /extensions/1d3b2c36-8a65-45a6-87c1-bcdbe0a\
 32e30/bulk?instanceId=02ee282c-8915-4b2e-bbd2-88966773134a
 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:
Brinckman, et al. Expires 5 June 2026 [Page 115]
Internet-Draft NIPC December 2025
 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:
 - 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}
Brinckman, et al. Expires 5 June 2026 [Page 116]
Internet-Draft NIPC December 2025
 - /extensions/{id}/events/conditional?eventName={eve\
 ntName}
 - /extensions/{id}/properties/file?propertyName={pro\
 pertyName}
 example: /devices/1d3b2c36-8a65-45a6-87c1-bcdbe0a32e30\
 /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
 - 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/1d3b2c36-8a65-45a6-87c1-bcdbe0a32e30\
 /properties?propertyName=https%3A%2F%2Fexample.com%2Fthermometer%23%\
 2FsdfThing%2Fthermometer%2FsdfProperty%2Ftemperature
 response:
Brinckman, et al. Expires 5 June 2026 [Page 117]
Internet-Draft NIPC December 2025
 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/1d3b2c36-8a65-45a6-87c1-bcdbe0a32e30/prop\
 erties?propertyName=https%3A%2F%2Fexample.com%2Fthermometer%23%2Fsdf\
 Thing%2Fthermometer%2FsdfProperty%2Ftemperature
 - method: PUT
 path: /devices/1d3b2c36-8a65-45a6-87c1-bcdbe0a32e30/prop\
 erties?propertyName=https%3A%2F%2Fexample.com%2Fthermometer%23%2Fsdf\
 Thing%2Fthermometer%2FsdfProperty%2Ftemperature
 data:
 value: dGVzdA==
 - method: POST
 path: /extensions/1d3b2c36-8a65-45a6-87c1-bcdbe0a32e30/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
 value:
 operations:
 - method: GET
 path: /devices/1d3b2c36-8a65-45a6-87c1-bcdbe0a32e30/prop\
 erties?propertyName=https%3A%2F%2Fexample.com%2Fthermometer%23%2Fsdf\
 Thing%2Fthermometer%2FsdfProperty%2Ftemperature
 response:
 value: dGVzdA==
 - method: PUT
 path: /devices/1d3b2c36-8a65-45a6-87c1-bcdbe0a32e30/prop\
 erties?propertyName=https%3A%2F%2Fexample.com%2Fthermometer%23%2Fsdf\
 Thing%2Fthermometer%2FsdfProperty%2Ftemperature
 response:
 status: 200
 - method: POST
 path: /extensions/1d3b2c36-8a65-45a6-87c1-bcdbe0a32e30/p\
Brinckman, et al. Expires 5 June 2026 [Page 118]
Internet-Draft NIPC December 2025
 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/1d3b2c36-8a65-45a6-87c1-bcdbe0a32e30/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/1d3b2c36-8a65-45a6-87c1-bcdbe0a32e30/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/1d3b2c36-8a65-45a6-87c1-bcdbe0a32e30/p\
 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/1d3b2c36-8a65-45a6-87c1-bcdbe0a32e30/prop\
 erties?propertyName=https%3A%2F%2Fexample.com%2Fthermometer%23%2Fsdf\
Brinckman, et al. Expires 5 June 2026 [Page 119]
Internet-Draft NIPC December 2025
 Thing%2Fthermometer%2FsdfProperty%2FstartOTA
 data:
 value: dGVzdA==
 - method: POST
 path: /extensions/1d3b2c36-8a65-45a6-87c1-bcdbe0a32e30/e\
 vents/conditional?eventName=https%3A%2F%2Fexample.com%2Fthermometer%\
 23%2FsdfThing%2Fthermometer%2FsdfEvent%2FotaStarted
 data:
 value: MQ==
 timeout: 5
 - method: PUT
 path: /extensions/1d3b2c36-8a65-45a6-87c1-bcdbe0a32e30/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/1d3b2c36-8a65-45a6-87c1-bcdbe0a32e30/prop\
 erties?propertyName=https%3A%2F%2Fexample.com%2Fthermometer%23%2Fsdf\
 Thing%2Fthermometer%2FsdfProperty%2FfinishOTA
 data:
 value: dGVzdA==
 - method: POST
 path: /extensions/1d3b2c36-8a65-45a6-87c1-bcdbe0a32e30/p\
 roperties/read/conditional?propertyName=https%3A%2F%2Fexample.com%2F\
 thermometer%23%2FsdfThing%2Fthermometer%2FsdfProperty%2FupdateStatus
 data:
 value: MQ==
 maxRepeat: 5
 retryTime: 1
 - method: PUT
 path: /devices/1d3b2c36-8a65-45a6-87c1-bcdbe0a32e30/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/1d3b2c36-8a65-45a6-87c1-bcdbe0a32e30/prop\
 erties?propertyName=https%3A%2F%2Fexample.com%2Fthermometer%23%2Fsdf\
 Thing%2Fthermometer%2FsdfProperty%2FstartOTA
 response:
Brinckman, et al. Expires 5 June 2026 [Page 120]
Internet-Draft NIPC December 2025
 status: 200
 - method: POST
 path: /extensions/1d3b2c36-8a65-45a6-87c1-bcdbe0a32e30/e\
 vents/conditional?eventName=https%3A%2F%2Fexample.com%2Fthermometer%\
 23%2FsdfThing%2Fthermometer%2FsdfEvent%2FotaStarted
 response:
 value: MQ==
 - method: PUT
 path: /extensions/1d3b2c36-8a65-45a6-87c1-bcdbe0a32e30/p\
 roperties/file?propertyName=https%3A%2F%2Fexample.com%2Fthermometer%\
 23%2FsdfThing%2Fthermometer%2FsdfProperty%2Ffirmware
 response:
 status: 204
 - method: PUT
 path: /devices/1d3b2c36-8a65-45a6-87c1-bcdbe0a32e30/prop\
 erties?propertyName=https%3A%2F%2Fexample.com%2Fthermometer%23%2Fsdf\
 Thing%2Fthermometer%2FsdfProperty%2FfinishOTA
 response:
 status: 200
 - method: POST
 path: /extensions/1d3b2c36-8a65-45a6-87c1-bcdbe0a32e30/p\
 roperties/read/conditional?propertyName=https%3A%2F%2Fexample.com%2F\
 thermometer%23%2FsdfThing%2Fthermometer%2FsdfProperty%2FupdateStatus
 response:
 value: MQ==
 - method: PUT
 path: /devices/1d3b2c36-8a65-45a6-87c1-bcdbe0a32e30/prop\
 erties?propertyName=https%3A%2F%2Fexample.com%2Fthermometer%23%2Fsdf\
 Thing%2Fthermometer%2FsdfProperty%2FactivateOTA
 data:
 status: 200
 <CODE ENDS>
C.3. NIPC API write file extension
 <CODE BEGINS> 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
Brinckman, et al. Expires 5 June 2026 [Page 121]
Internet-Draft NIPC December 2025
 license:
 name: TBD
 url: TBD
 version: 0.15.0
 externalDocs:
 description: NIPC IETF draft
 url: https://datatracker.ietf.org/doc/draft-ietf-asdf-nipc/
 servers:
 - url: "{gw_host}/nipc/draft-15"
 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
 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: 1d3b2c36-8a65-45a6-87c1-bcdbe0a32e30
 - name: propertyName
 in: query
 description: |-
 The SDF property name that needs to be written to.
Brinckman, et al. Expires 5 June 2026 [Page 122]
Internet-Draft NIPC December 2025
 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/1d3b2c36-8a65-45a6-87c1-bcdbe0a\
 32円e30/properties/file/status?propertyName=https%3A%2F%2Fexample.com\
 \%2Fheartrate%23%2FsdfObject%2Fthermostat%2FsdfProperty%2Ffirmware&i\
 \nstanceId=02ee282c-8915-4b2e-bbd2-88966773134a
 description: |-
 URL to get the file write 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:
Brinckman, et al. Expires 5 June 2026 [Page 123]
Internet-Draft NIPC December 2025
 - 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: 02ee282c-8915-4b2e-bbd2-88966773134a
 property: https://example.com/heartrate#/s\
 \dfObject/thermostat/sdfProperty/firmware
 failedResponse:
 summary: Failed
 value:
 id: 02ee282c-8915-4b2e-bbd2-88966773134a
 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: |-
 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: 1d3b2c36-8a65-45a6-87c1-bcdbe0a32e30
 - name: propertyName
 in: query
Brinckman, et al. Expires 5 June 2026 [Page 124]
Internet-Draft NIPC December 2025
 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: 1d3b2c36-8a65-45a6-87c1-bcdbe0a32e30
 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
 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: 1d3b2c36-8a65-45a6-87c1-bcdbe0a32e30
 - name: propertyName
 in: query
 description: |-
Brinckman, et al. Expires 5 June 2026 [Page 125]
Internet-Draft NIPC December 2025
 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: 1d3b2c36-8a65-45a6-87c1-bcdbe0a32e30
 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/1d3b2c36-8a65-45a6-87c1-bcdbe0a\
 32円e30/properties/file?propertyName=https%3A%2F%2Fexample.com%2Fhear\
 \trate%23%2FsdfObject%2Fthermostat%2FsdfProperty%2Ffirmware&instance\
 \Id=02ee282c-8915-4b2e-bbd2-88966773134a
 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: 02ee282c-8915-4b2e-bbd2-88966773134a
 status: COMPLETED
 components:
Brinckman, et al. Expires 5 June 2026 [Page 126]
Internet-Draft NIPC December 2025
 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
 <CODE ENDS>
C.4. NIPC API conditional read extension
 <CODE BEGINS> 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.15.0
 externalDocs:
 description: NIPC IETF draft
Brinckman, et al. Expires 5 June 2026 [Page 127]
Internet-Draft NIPC December 2025
 url: https://datatracker.ietf.org/doc/draft-ietf-asdf-nipc/
 servers:
 - url: "{gw_host}/nipc/draft-15"
 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
 format: uuid
 example: 1d3b2c36-8a65-45a6-87c1-bcdbe0a32e30
 - 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':
Brinckman, et al. Expires 5 June 2026 [Page 128]
Internet-Draft NIPC December 2025
 description: Accepted
 headers:
 Location:
 schema:
 type: string
 example: /extensions/1d3b2c36-8a65-45a6-87c1-bcdbe0a\
 32e30/properties/read/conditional/status?propertyName=https%3A%2F%2F\
 example.com%2Fheartrate%23%2FsdfObject%2Fthermostat%2FsdfProperty%2F\
 temperature&instanceId=02ee282c-8915-4b2e-bbd2-88966773134a
 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:
 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: 1d3b2c36-8a65-45a6-87c1-bcdbe0a32e30
 property: https://example.com/heartrate#/s\
 dfObject/thermostat/sdfProperty/temperature
 value: dGVzdA==
 failedResponse:
Brinckman, et al. Expires 5 June 2026 [Page 129]
Internet-Draft NIPC December 2025
 summary: Failed
 value:
 id: 1d3b2c36-8a65-45a6-87c1-bcdbe0a32e30
 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
 example: 1d3b2c36-8a65-45a6-87c1-bcdbe0a32e30
 - 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: 1d3b2c36-8a65-45a6-87c1-bcdbe0a32e30
Brinckman, et al. Expires 5 June 2026 [Page 130]
Internet-Draft NIPC December 2025
 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
 parameters:
 - name: id
 in: path
 description: The ID of the device. Group ID is not allowed.
 required: true
 schema:
 type: string
 format: uuid
 example: 1d3b2c36-8a65-45a6-87c1-bcdbe0a32e30
 - 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
Brinckman, et al. Expires 5 June 2026 [Page 131]
Internet-Draft NIPC December 2025
 in: query
 description: Instance ID of the conditional read operation
 required: true
 schema:
 type: string
 format: uuid
 example: 1d3b2c36-8a65-45a6-87c1-bcdbe0a32e30
 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/1d3b2c36-8a65-45a6-87c1-bcdbe0a\
 32e30/properties/read/conditional?propertyName=https%3A%2F%2Fexample\
 .com%2Fheartrate%23%2FsdfObject%2Fthermostat%2FsdfProperty%2Ftempera\
 ture&instanceId=02ee282c-8915-4b2e-bbd2-88966773134a
 description: URL to get the conditional read response
 content:
 application/json:
 schema:
 $ref: './Extension-Async.yaml#/components/schemas/Ex\
 tension-StatusResponse'
 examples:
 successExample:
 summary: Completed
 value:
 id: 1d3b2c36-8a65-45a6-87c1-bcdbe0a32e30
 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
Brinckman, et al. Expires 5 June 2026 [Page 132]
Internet-Draft NIPC December 2025
 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
 <CODE ENDS>
C.5. NIPC API conditional event extension
 <CODE BEGINS> 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
 license:
 name: TBD
 url: TBD
 version: 0.15.0
 externalDocs:
 description: NIPC IETF draft
 url: https://datatracker.ietf.org/doc/draft-ietf-asdf-nipc/
 servers:
 - url: "{gw_host}/nipc/draft-15"
 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.
Brinckman, et al. Expires 5 June 2026 [Page 133]
Internet-Draft NIPC December 2025
 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: 1d3b2c36-8a65-45a6-87c1-bcdbe0a32e30
 - 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:
 application/json:
 schema:
 $ref: '#/components/schemas/Extension-ConditionalEvent'
 required: true
 responses:
 '202':
 description: Accepted
 headers:
 Location:
 schema:
 type: string
 example: /extensions/1d3b2c36-8a65-45a6-87c1-bcdbe0a\
 32e30/events/conditional/status?eventName=https%3A%2F%2Fexample.com%\
 2Fheartrate%23%2FsdfObject%2Fthermostat%2FsdfEvent%2Ftemperature&ins\
 tanceId=02ee282c-8915-4b2e-bbd2-88966773134a
 description: |-
 URL to get the conditional event status
 Retry-After:
 schema:
Brinckman, et al. Expires 5 June 2026 [Page 134]
Internet-Draft NIPC December 2025
 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
 value:
 id: 02ee282c-8915-4b2e-bbd2-88966773134a
 event: https://example.com/heartrate#/sdfO\
 bject/thermostat/sdfEvent/temperature
 value: dGVzdA==
 failedResponse:
 summary: Failed
 value:
 id: 02ee282c-8915-4b2e-bbd2-88966773134a
 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:
Brinckman, et al. Expires 5 June 2026 [Page 135]
Internet-Draft NIPC December 2025
 '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: 1d3b2c36-8a65-45a6-87c1-bcdbe0a32e30
 - 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: |-
 Instance ID of the conditional event operation
 required: true
 schema:
 type: string
 format: uuid
 example: 1d3b2c36-8a65-45a6-87c1-bcdbe0a32e30
 responses:
 '200':
 description: Success
 headers:
 content:
 application/json:
 schema:
 allOf:
 - $ref: '../NIPC.yaml#/components/schemas/Value'
 application/octet-stream:
 schema:
 type: string
 format: binary
Brinckman, et al. Expires 5 June 2026 [Page 136]
Internet-Draft NIPC December 2025
 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: 1d3b2c36-8a65-45a6-87c1-bcdbe0a32e30
 - 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: Instance ID of the conditional event operation
 required: true
 schema:
 type: string
 format: uuid
 example: 1d3b2c36-8a65-45a6-87c1-bcdbe0a32e30
 responses:
 '200':
 description: OK
 headers:
 content:
 application/json:
Brinckman, et al. Expires 5 June 2026 [Page 137]
Internet-Draft NIPC December 2025
 schema:
 $ref: './Extension-Async.yaml#/components/schemas/Ex\
 tension-StatusResponse'
 '303':
 description: See Other
 headers:
 Location:
 schema:
 type: string
 example: /extensions/1d3b2c36-8a65-45a6-87c1-bcdbe0a\
 32e30/events/conditional?eventName=https%3A%2F%2Fexample.com%2Fheart\
 rate%23%2FsdfObject%2Fthermostat%2FsdfEvent%2Ftemperature&instanceId\
 =02ee282c-8915-4b2e-bbd2-88966773134a
 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: 02ee282c-8915-4b2e-bbd2-88966773134a
 status: COMPLETED
 components:
 schemas:
 # Extensions
 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
 <CODE ENDS>
C.6. NIPC API property extensions
Brinckman, et al. Expires 5 June 2026 [Page 138]
Internet-Draft NIPC December 2025
 <CODE BEGINS> 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.15.0
 externalDocs:
 description: NIPC IETF draft
 url: https://datatracker.ietf.org/doc/draft-ietf-asdf-nipc/
 servers:
 - url: "{gw_host}/nipc/draft-15"
 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}/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
Brinckman, et al. Expires 5 June 2026 [Page 139]
Internet-Draft NIPC December 2025
 schema:
 type: string
 format: uuid
 example: 1d3b2c36-8a65-45a6-87c1-bcdbe0a32e30
 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.
 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: 1d3b2c36-8a65-45a6-87c1-bcdbe0a32e30
 requestBody:
 content:
 application/json:
 schema:
 allOf:
 - $ref: '../NIPC.yaml#/components/schemas/Value'
 - $ref: '../protocolmaps/ProtocolMap.yaml#/component\
 s/schemas/ProtocolMap-Property'
Brinckman, et al. Expires 5 June 2026 [Page 140]
Internet-Draft NIPC December 2025
 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
 example: 1d3b2c36-8a65-45a6-87c1-bcdbe0a32e30
 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
Brinckman, et al. Expires 5 June 2026 [Page 141]
Internet-Draft NIPC December 2025
 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
 payload:
 type: string
 format: byte
 example: AgEaAgoMFv9MABAHch9BsDkgeA==
 <CODE ENDS>
Appendix D. NIPC API CDDL Definition
 The following is a combined reference of all NIPC API CDDL
 definitions used in this document.
 <CODE BEGINS> file "combined.cddl"
 =============== NOTE: '\' line wrapping per RFC 8792 ================
 ; This file is auto-generated from individual NIPC API CDDL files
 ; ============================================
 ; From: cddl/api/action_response.cddl
Brinckman, et al. Expires 5 June 2026 [Page 142]
Internet-Draft NIPC December 2025
 ; ============================================
 ActionResponse = {
 status: ActionStatus
 }
 ActionStatus = (
 "IN_PROGRESS" /
 "COMPLETED"
 )
 ; ============================================
 ; From: cddl/api/data_app.cddl
 ; ============================================
 DataApp = {
 events: [* EventRef],
 ( DataAppMqttClient //
 DataAppMqttBroker //
 DataAppWebhook //
 DataAppWebsocket )
 }
 EventRef = {
 event: text ; SDF global name (absolute URI with fragment)
 }
 DataAppMqttClient = {
 mqttClient: bool
 }
 DataAppMqttBroker = {
 mqttBroker: {
 URI: text,
 username: text,
 password: text,
 ? brokerCACert: text, ; PEM-encoded CA certificate
 ? customTopic: text ; optional custom MQTT topic
 }
 }
 DataAppWebhook = {
 webhook: {
 URI: text,
 ? headers: { * text => text }, ; key/value headers
 ? serverCACert: text
 }
 }
 DataAppWebsocket = {
 websocket: {
Brinckman, et al. Expires 5 June 2026 [Page 143]
Internet-Draft NIPC December 2025
 URI: text,
 ? headers: { * text => text }, ; key/value headers
 ? serverCACert: text
 }
 }
 ; ============================================
 ; From: cddl/api/event_status_array.cddl
 ; ============================================
 EventStatusResponseArray = [* EventStatusResponseArrayItem]
 EventStatusResponseArrayItem = ( EventInstanceSuccess // FailureResp\
 onse )
 ; Success item = { event, instanceId }
 EventInstanceSuccess = {
 event: text, ; SDF global name of the event (absolute URI w\
 ith fragment)
 instanceId: text ; UUID (as text)
 }
 ; ============================================
 ; From: cddl/api/failure_response.cddl
 ; ============================================
 FailureResponse = {
 ? type: FailureTypeURI,
 ? status: uint,
 ? title: text,
 ? detail: text
 }
 ; Enumerated problem type URIs registered for NIPC
 FailureTypeURI = (
 "https://www.iana.org/assignments/nipc-problem-types#invalid-id" /
 "https://www.iana.org/assignments/nipc-problem-types#invalid-sdf-u\
 rl" /
 "https://www.iana.org/assignments/nipc-problem-types#extension-ope\
 ration-not-executed" /
 "https://www.iana.org/assignments/nipc-problem-types#sdf-model-alr\
 eady-registered" /
 "https://www.iana.org/assignments/nipc-problem-types#sdf-model-in-\
 use" /
 "https://www.iana.org/assignments/nipc-problem-types#property-not-\
 readable" /
 "https://www.iana.org/assignments/nipc-problem-types#property-read\
 -failed" /
 "https://www.iana.org/assignments/nipc-problem-types#property-not-\
 writable" /
 "https://www.iana.org/assignments/nipc-problem-types#property-writ\
Brinckman, et al. Expires 5 June 2026 [Page 144]
Internet-Draft NIPC December 2025
 e-failed" /
 "https://www.iana.org/assignments/nipc-problem-types#event-already\
 -enabled" /
 "https://www.iana.org/assignments/nipc-problem-types#event-not-ena\
 bled" /
 "https://www.iana.org/assignments/nipc-problem-types#event-not-reg\
 istered" /
 "https://www.iana.org/assignments/nipc-problem-types#protocolmap-b\
 le-already-connected" /
 "https://www.iana.org/assignments/nipc-problem-types#protocolmap-b\
 le-no-connection" /
 "https://www.iana.org/assignments/nipc-problem-types#protocolmap-b\
 le-connection-timeout" /
 "https://www.iana.org/assignments/nipc-problem-types#protocolmap-b\
 le-bonding-failed" /
 "https://www.iana.org/assignments/nipc-problem-types#protocolmap-b\
 le-connection-failed" /
 "https://www.iana.org/assignments/nipc-problem-types#protocolmap-b\
 le-service-discovery-failed" /
 "https://www.iana.org/assignments/nipc-problem-types#protocolmap-b\
 le-invalid-service-or-characteristic" /
 "https://www.iana.org/assignments/nipc-problem-types#protocolmap-z\
 igbee-connection-timeout" /
 "https://www.iana.org/assignments/nipc-problem-types#protocolmap-z\
 igbee-invalid-endpoint-or-cluster" /
 "https://www.iana.org/assignments/nipc-problem-types#extension-bro\
 adcast-invalid-data" /
 "https://www.iana.org/assignments/nipc-problem-types#extension-fir\
 mware-rollback" /
 "https://www.iana.org/assignments/nipc-problem-types#extension-fir\
 mware-update-failed" /
 "about:blank"
 )
 ; ============================================
 ; From: cddl/api/group_event_status_response_array.cddl
 ; ============================================
 GroupEventStatusResponseArray = [* GroupEventStatusResponse]
 GroupEventSuccessResponse = { event: text, deviceId: text }
 ; Each item is either an event+deviceId success or a FailureResponse
 GroupEventStatusResponse = (GroupEventSuccessResponse // FailureResp\
 onse)
 ; FailureResponse (Problem Details subset; align with your existing \
 definition if present)
 GroupFailureResponse = {
 FailureResponse,
Brinckman, et al. Expires 5 June 2026 [Page 145]
Internet-Draft NIPC December 2025
 ? deviceId: text
 }
 ; ============================================
 ; From: cddl/api/property_value_array.cddl
 ; ============================================
 PropertyValueArray = [* PropertyValue]
 ; Minimal PropertyValue shape (matches allOf of Property + Value)
 PropertyValue = {
 property: text, ; SDF global name of the property
 value: b64text ; base64-encoded bytes (RFC 4648 Section 5)
 }
 ; Helper type for base64-with-padding encoded text
 b64text = text
 ; ============================================
 ; From: cddl/api/property_value_read_response_array.cddl
 ; ============================================
 PropertyValueReadResponseArray = [* PropertyValueReadResponseArrayIt\
 em]
 PropertyValueReadResponseArrayItem = ( PropertyValue // FailureRespo\
 nse )
 ; ============================================
 ; From: cddl/api/property_value_response_array.cddl
 ; ============================================
 PropertyValueResponseArray = [* PropertyValueResponseArrayItem]
 PropertyValueResponseArrayItem = ( SuccessResponse // FailureRespons\
 e )
 ; Minimal success shape (may be extended)
 SuccessResponse = {
 ? status: uint
 }
 ; ============================================
 ; From: cddl/api/sdf_reference.cddl
 ; ============================================
 SdfGlobalName = text ; absolute URI with fragment referencing an \
 sdfThing or sdfObject
 SdfReference = {
 sdfName: SdfGlobalName
 }
 SdfReferenceArray = [* SdfReference]
Brinckman, et al. Expires 5 June 2026 [Page 146]
Internet-Draft NIPC December 2025
 <CODE ENDS>
 Figure 32: NIPC API CDDL Definitions
Appendix E. Example SDF model with protocol mappings for BLE
 <CODE BEGINS> 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",
 "sdfOutputData": {
 "sdfProtocolMap": {
Brinckman, et al. Expires 5 June 2026 [Page 147]
Internet-Draft NIPC December 2025
 "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 5 June 2026 [Page 148]
Internet-Draft NIPC December 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 5 June 2026 [Page 149]
Internet-Draft NIPC December 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"
 }
 }
 }
 }
 }
 }
 }
 }
 <CODE ENDS>
 Figure 33: Example SDF model with protocol mappings for BLE
Authors' Addresses
Brinckman, et al. Expires 5 June 2026 [Page 150]
Internet-Draft NIPC December 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 5 June 2026 [Page 151]

AltStyle によって変換されたページ (->オリジナル) /