Library / SDK
Azure/azure-iot-sdk-c avatar
Azure/azure-iot-sdk-c

azure-iot-sdk-c connects C devices to IoT Hub, with per-platform packaging

A C99 SDK for connecting devices to Microsoft Azure IoT services

619 stars752 forksCNOASSERTION

At a glance

What is it?
The Azure IoT C SDK lets C99 and C++ applications talk to Azure IoT Hub, IoT Central and Device Provisioning, with the protocol chosen when the client connection is created. Getting it is easy on Windows, iOS and Arduino, and on Linux it comes down to cloning and building the tree, while constrained hardware belongs to the Embedded C SDK instead.
Who is it for?
azure-iot-sdk-c fits C and C++ teams building devices with enough memory for a full SDK, and it is the wrong choice for kilobyte-class hardware, where the Embedded C SDK with bring your own MQTT, TLS and sockets is the documented path.
Can I use it commercially?
Check first. The repository uses a licence we do not classify automatically, so read its LICENSE file before any commercial use.
Is it still maintained?
Yes. The repository last received commits 1 day ago.
What is it written in?
Mainly C, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 22, 2026, and from our analysis. They are not legal advice.

Editorial analysis

One repository for the device side and the service side of Azure IoT

The repository holds the source of the Azure IoT Hub Device SDK, which lets applications written in C99 or later, or in C++, communicate with Azure IoT Hub, Azure IoT Central and Azure IoT Device Provisioning. Along with the source it includes setup instructions and samples demonstrating use cases.

The folder layout shows the scope more clearly than the prose does. There is an iothub_client directory for the device side and an iothub_service_client directory for the service side, plus separate provisioning_client and provisioning_service_client directories. Around them sit the supporting pieces you would expect in a C SDK of this size: a serializer directory, a certs directory, a deps directory that holds third-party code, uamqp and umqtt for the AMQP and MQTT transports, c-utility, compat_stubs, configs, tools, testtools, build and build_all directories, and samples.

Two things stand out for an engineer reading the tree. The presence of uamqp and umqtt means the protocol stacks are vendored into the build rather than taken from the system, which matters for reproducibility on devices. And the samples directory contains dockerbuilds and a solutions directory, so the reference code is meant to be built in containers as well as on a host.

The target audience is explicit: device-side applications in C. Anything that manages a fleet of devices rather than a fleet member belongs to the service client.

Packaging differs sharply by platform, and iOS is the awkward one

The README is direct about how you obtain the SDK: on supported platforms the simplest route is a package, and on other platforms, including Linux, you clone and build the SDK directly. You may also build it from source for the platforms that do have packages.

The package list is short and each entry points at a specific mechanism:

bash
- Arduino:                                   [Device SDK library in the Arduino IDE](https://aka.ms/arduino)
- Windows:                                   [Device SDK on Vcpkg](./doc/setting_up_vcpkg.md#setup-c-sdk-vcpkg-for-windows-development-environment)
- iOS:                                       [Device SDK on CocoaPod](https://cocoapods.org/pods/AzureIoTHubClient)

Three different packaging ecosystems, one library. Arduino ships it inside the IDE, Windows uses Vcpkg with a setup guide in the doc directory, and iOS uses CocoaPods. If you are on Linux, none of these apply, and the README points to a compile guide in the iothub_client directory instead.

The iOS entry carries explicit limitations. Authentication on iOS is limited to SAS keys, with no officially supported certificate-based authentication, and the Device Provisioning Client is not supported on iOS at all, only the IoT Hub device client. The README routes people who need those two features to a native Swift library sample built on top of the Embedded C SDK. If your device needs X.509 device certificates and hardware provisioning, iOS is not a viable target for this particular SDK.

The protocol is chosen when the connection is created

IoT Hub speaks more than one wire protocol, and the Device Client SDK lets you pick at connection creation time rather than compiling in a choice. The README lists MQTT, AMQP and HTTPS, and notes that MQTT and AMQP can optionally run over WebSockets.

That single design point covers most of the operational decisions you would otherwise make at the transport layer. WebSockets matter when the device sits behind a proxy that only permits HTTP traffic, since both MQTT and AMQP can be tunnelled through it. HTTPS is there for the constrained case where you want a request-response style connection with no persistent session. MQTT is the usual choice for telemetry, AMQP for device-side features that need a session.

The SDK also carries a serializer directory and a serial_pp.i preprocessing file, indicating that the message model is generated rather than hand-written for each payload type, and the topics list includes serializer and service-sdk, which matches the presence of the iothub_service_client and provisioning_service_client directories.

One thing the README does not spell out in this excerpt is how the choice maps to concrete API calls, since the detail lives in the API reference documentation and in the per-directory readme linked for Linux. Expect to read those before writing the first connection.

Linux means building the tree yourself

For Linux the README gives no package. The instruction is that you need to clone and build the SDK directly, and the linked device SDK readme in the iothub_client directory carries the compile steps. The repository itself gives you the build machinery to do that: a top-level CMakeLists.txt, a build directory and a build_all directory, a deps directory for external dependencies, and a .gitmodules file, which is the hint that some of those dependencies arrive as submodules rather than as vendored files.

There are also samples to build against, with a samples readme and dockerbuilds directories, so the practical first step is to compile the library and one sample before wiring the SDK into a product.

The docs directory holds the Vcpkg setup guide referenced from the Windows package, and the API reference for the C SDKs is published separately from the README. For a library this size, that separation is normal: the README is a map of the options, and the per-directory readmes carry the build details.

The tools and jenkins directories indicate the build is driven by internal CI rather than only by hand, which is relevant when you want to know whether a given commit has been exercised on the platforms you care about.

The honest alternative for small devices is the Embedded C SDK

The README twice points constrained hardware elsewhere, and it is worth repeating the guidance rather than treating it as a footnote. For constrained devices, where memory is measured in kilobytes rather than megabytes, the README says there are lighter weight SDK options and refers to the Other Azure IoT SDKs page.

Those alternatives are named, and their differences are real. The Azure IoT SDK for Embedded C enables a bring your own network approach, where you choose the MQTT client, TLS implementation and sockets yourself and assemble the device solution from them. The Azure IoT middleware for Azure RTOS builds on the embedded SDK and tightly couples with the Azure RTOS family of networking and operating system products, which the README says gives very performant and small applications for real-time constrained devices. The Azure IoT middleware for FreeRTOS also builds on the embedded SDK, takes care of the MQTT stack while integrating with FreeRTOS, and gives a distilled Azure IoT feature set while keeping flexibility in the networking stack.

The choice, then, is architectural rather than a matter of version numbers. This C SDK is the full stack with vendored transports and the broadest feature surface. The embedded SDK is a set of interfaces you fill with your own networking stack. The two middlewares trade some of that flexibility for a ready-made MQTT and OS integration.

LTS tags, a dated TLS notice, and a custom license

Three maintenance facts belong in any adoption decision here.

The first is the release scheme. The published tags are LTS_10_2026, LTS_03_2025 and LTS_08_2024, and the README has a Long Term Support section with its own LTS schedule and a release example. So releases are dated and named by support window, not by semantic version, and choosing an LTS line rather than the newest commit is how you get a predictable patch stream for a fleet of devices. The last push was on 2026-10-22, three days after the LTS_10_2026 tag.

The second is a security notice that has not been updated. The README warns about a TLS root certificate migration for IoT Hub and Device Provisioning from the Baltimore CyberTrust CA Root to the DigiCert Global G2 CA root, described as happening in October 2022, with a transition period in which devices must carry both public certificates, whether hardcoded in the application or flashed onto the WiFi module. Devices holding only the Baltimore root would lose the ability to connect. The advice itself, configure both roots in the device TLS stack, is still the safe configuration to verify; the dates in the notice are from 2022 and say nothing about the current state of the fleet, which is exactly why you should check the certificate store on the devices rather than trust the notice to be current.

The third is licensing. The repository carries a LICENSE file, a thirdpartynotice.txt and a SECURITY.md, and the license is the custom one that GitHub cannot classify rather than a standard MIT or Apache text. Any organisation that runs a license scanner or has an approved-license list needs to read that file, and the third-party notice matters because uamqp, umqtt and the deps directory pull in external code.

Folder deprecation is the quiet upgrade risk

The table of contents includes a section on deprecated folders and a deprecation notes section, and the top-level tree shows why that matters. Directories such as build and build_all, iothub_service_client, provisioning_service_client, c-utility, compat_stubs, testtools, jenkins and tools sit side by side with the core client directories.

In a repository that has been public for years and is still publishing dated LTS lines, older organizational layouts tend to linger. The README's own structure section groups some of those directories under deprecated folders, which is the sort of arrangement that produces a mildly confusing first read for a new contributor: you are not sure whether iothub_service_client is part of the supported surface or a leftover.

Two practical consequences follow. First, read the folder structure section of the README before you wire your build system to a specific directory, since deprecated directories may still be present and still compile. Second, treat the deprecation notes as part of your upgrade checklist, together with the LTS schedule, rather than as historical documentation.

The same caution applies to the samples. There are many of them, in a samples directory with its own readme, and a sample that still uses a deprecated folder will not tell you the intended path; the readme is the place to check. For device fleets, the LTS tag is the safer upgrade unit because it corresponds to the support schedule the maintainers publish rather than to whatever the main branch happens to contain.

Editorial conclusion

azure-iot-sdk-c fits C and C++ teams building devices with enough memory for a full SDK, and it is the wrong choice for kilobyte-class hardware, where the Embedded C SDK with bring your own MQTT, TLS and sockets is the documented path. Before you start, check that your device can hold a TLS stack with both root certificates the README asks for, pick your platform route from the package list rather than building from source on a platform that already has a supported package, and read the deprecation notes and the LTS schedule in the README, since the release tags follow a dated LTS scheme and the last push was on 2026-10-22 with a LTS_10_2026 tag.

Frequently asked questions

Which protocols can the Azure IoT C SDK device client use?

The README states that IoT Hub supports MQTT, AMQP and HTTPS for device connections, that MQTT and AMQP can optionally run over WebSockets, and that the Device Client SDK lets the protocol be chosen at connection creation time.

How do I install the Azure IoT C SDK on Linux?

The README says that for platforms including Linux you need to clone and build the SDK directly, and points to the compile section of the device SDK readme in the iothub_client directory. The repository ships a top-level CMakeLists.txt, a deps directory and a .gitmodules file for that build.

Can I use the Azure IoT C SDK on iOS with certificate authentication?

No. The README lists the iOS limitations: authentication is limited to SAS keys with no officially supported certificate-based authentication, and the Device Provisioning Client is not supported on iOS. It points to a native Swift library sample built on the Embedded C SDK for those two features.

Which Azure IoT SDK should I use for a device with only kilobytes of memory?

The README says that for constrained devices, where memory is measured in kilobytes rather than megabytes, there are lighter weight SDK options, and it names the Azure IoT SDK for Embedded C with a bring your own network approach, plus middleware layers for Azure RTOS and FreeRTOS built on top of it.

Official sources

  1. Azure/azure-iot-sdk-c on GitHub
  2. Issues
  3. Project website
  4. README
  5. Releases
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/azure-azure-iot-sdk-c.svg)](https://hysenlabs.com/projects/azure-azure-iot-sdk-c)

Was this useful?