Key points
- Wi-Fi provisioning gives a headless device the SSID and password of the network it should join. Bluetooth LE is the common transport because the phone keeps its own Wi-Fi connection and stays in contact with the device throughout.
- The exchange is a few GATT writes and reads: discover the device, optionally open an encrypted session using a code from its label, send the credentials, apply them, and read back the connection result.
- Improv Wi-Fi, ESP-IDF unified provisioning and Matter commissioning all do this, with different security and different phone apps. SoftAP setup still exists for devices with no Bluetooth LE.
- Most failures come from phone permissions, the wrong Wi-Fi band, or a device that believes it is already set up.
Wi-Fi provisioning for headless devices
Wi-Fi provisioning is getting a new device onto a Wi-Fi network by giving it the network’s name (SSID) and password, plus any settings the maker needs. Devices such as plugs, sensors and lights have no screen or keyboard to type a password on, so another device has to deliver it.
There are several ways to do it, and Espressif’s ESP-IDF lists most of them for its own chips:
- Bluetooth LE: a phone app connects to the device over Bluetooth LE and writes the credentials. This page is mostly about this method.
- SoftAP: the device starts its own temporary Wi-Fi access point, the phone joins it, and an app or web page sends the credentials over HTTP.
- Serial: a computer sends the credentials over USB or UART, which Improv Wi-Fi supports, including from a browser.
- SmartConfig: an Espressif method listed in ESP-IDF’s provisioning API.
- Wi-Fi Easy Connect (DPP): a QR code method for headless devices, which Android supports from Android 10 and which ESP-IDF supports on the device side.
Matter has its own version of this step inside commissioning, covered below.
Bluetooth LE vs SoftAP for device setup
IoT devices use Bluetooth LE for setup because it lets the phone talk to the device without leaving its own Wi-Fi network. Espressif’s provisioning guide gives the trade-offs directly:
- Bluetooth LE keeps an intact channel between device and phone for the whole process, so the phone gets reliable feedback on whether the device connected. Both Android and iOS apps can discover and connect to the device without sending the user out of the app. The cost is memory: Espressif says its BLE transport uses about 110 KB at runtime, most of which can be reclaimed after provisioning if the product no longer needs Bluetooth.
- SoftAP is highly interoperable and needs little extra memory, but the phone must disconnect from its own network to join the device’s, the device uses one radio for its access point and for the network it is joining, so status updates may not reach the phone, and Espressif says that on iOS the user has to go to Settings to join the device’s network. The Improv project adds that phones handle access points with no internet access badly, and that a wrong password or a dropped connection is hard to recover from.
That is why the common pattern today is Bluetooth LE where the chip has it, with SoftAP as the fallback for chips that do not, such as the ESP32-S2.
BLE Wi-Fi provisioning steps
BLE Wi-Fi provisioning is a short GATT conversation in which the device is the peripheral and the phone is the central. Espressif’s wifi_prov example shows each step, and the command-line tool esp_prov can run them by hand:
- The device advertises. It starts a GATT service and advertises a name or service UUID the app looks for. In Espressif’s example the name is
PROV_followed by part of the MAC address, such asPROV_01B1E8. - The phone discovers and connects. The app scans for that name or UUID, connects, and finds the provisioning service. Many products print a QR code that gives the app the device name and a code, so the user does not have to pick from a list. Espressif’s example QR code carries a JSON string with the version, device name, username, proof-of-possession code, transport and network type.
- Both sides check versions. The app reads the protocol version endpoint (
proto-ver) so it knows which features and security scheme to use. - They open a secure session. On the
prov-sessionendpoint, the app and device run a key exchange. With proof of possession, only an app that knows the code from the device’s label can complete it. - The device scans, if asked. On
prov-scan, the device lists the networks it can see, so the user picks one the device can actually hear. - The app sends the credentials. On
prov-config, it writes the SSID and password, encrypted with the session key, then sends an apply command. - The app polls for the result. It reads the connection state until the device reports connected or a failure reason, such as a wrong password.
- The device saves and cleans up. It stores the credentials in non-volatile storage and, in Espressif’s example, turns Bluetooth LE off to free its memory.
Each endpoint is a GATT characteristic with its own UUID, and the session and network messages are Protocol Buffers. What are GATT services and characteristics? explains the structure, and What is BLE advertising? covers step 1.
If you are building a device, the same steps give you a checklist: advertise something the app can filter on, put a unique code on the label, encrypt the session, let the device scan, report specific errors, and give users a way to reset provisioning.
Improv Wi-Fi, ESP-IDF and Matter provisioning
Improv Wi-Fi, ESP-IDF unified provisioning and Matter commissioning are three widely used ways to run that exchange, and SoftAP is the older alternative. As of October 2026:
| Improv Wi-Fi | ESP-IDF unified provisioning | Matter commissioning | SoftAP | |
|---|---|---|---|---|
| Transport | Bluetooth LE or serial | Bluetooth LE (GATT) or SoftAP with HTTP | Bluetooth LE, or the network, Wi-Fi USD or NFC on devices that support them | A temporary access point on the device, then HTTP |
| Security scheme | Optional physical authorization, such as a button; no encryption layer in the specification | Security 0 (none), Security 1 (Curve25519 key exchange, AES-256-CTR, optional proof of possession) or Security 2 (SRP6a, AES-256-GCM) | PASE with the setup passcode, then device attestation and operational certificates | WPA2 on the access point with a per-device passphrase, or none |
| Phone app | Home Assistant, ESP Web Tools in Chrome or Edge, or the maker’s own app | Espressif’s BLE and SoftAP Provisioning apps for Android and iOS, or esp_prov | The phone’s own Matter flow (Apple’s MatterSupport, Google Play services) or an ecosystem app | A browser or the maker’s app; Espressif’s iOS flow sends the user to Settings to join |
| Open spec or licence | Open standard; SDKs under Apache-2.0 | Apache-2.0 component; protocol tied to Espressif chips | CSA standard; open-source SDK under Apache-2.0; certification needs CSA membership | A pattern, not a standard |
| Best for | Hobby and open-source firmware (ESPHome, WLED, Tasmota) | Commercial products on Espressif chips that need an encrypted, branded setup | Smart home products that must work with Apple, Google, Amazon and others | Chips without Bluetooth LE, and setup from a laptop |
Improv Wi-Fi is an open standard from ESPHome and Home Assistant. Its BLE service exposes characteristics for capabilities, current state, error state, an RPC command and an RPC result. A device moves through four states, Authorization Required, Authorized, Provisioning and Provisioned, and can return a URL where the user finishes setup. The specification also defines commands to identify the device with a light or sound, report device information, scan for networks and set a hostname. Home Assistant’s Improv integration notes its limit: it only sends the Wi-Fi details, and does not add the device to Home Assistant.
ESP-IDF unified provisioning is Espressif’s framework, now shipped as the network_provisioning component. It provisions Wi-Fi over SoftAP or Bluetooth LE, and Thread over Bluetooth LE. The protocol is extensible, so a product can send its own configuration on custom endpoints in the same session.
Matter commissioning includes provisioning as one step: once the commissioner has a secure session, it sends the Wi-Fi or Thread credentials with the Network Commissioning cluster’s commands. Apple says iOS provisions a Matter accessory onto Wi-Fi or Thread itself, so the app never asks for credentials. Matter also checks that the device is certified and gives it an operational identity. How does Matter commissioning work? covers it.
Secure Wi-Fi provisioning
To keep provisioning secure, encrypt the session and tie it to something only the owner has. A provisioning exchange carries the home’s Wi-Fi password over the air, and anyone in Bluetooth LE range during setup can try to listen or to connect first. Concretely:
- Use an encrypted session. Espressif’s Security 1 and Security 2 schemes encrypt the credentials with a session key. Security 0 sends them in the clear and suits development only. Improv’s specification has no encryption layer, so it relies on the short setup window and physical access.
- Bind the session to the label. A unique per-device proof-of-possession code (Security 1) or username and password (Security 2), printed as a QR code, means only the person holding the device can provision it. Matter’s setup passcode does the same job in PASE.
- Require presence. Improv’s optional authorization asks for a button press and suggests revoking it after about a minute. A setup window that opens only after power-up or a button press limits who can try.
- Consider link encryption. ESP-IDF can require an encrypted Bluetooth LE link for writes to the provisioning characteristics, at the cost of a pairing dialog on the phone.
- Stop advertising when done. Turn the provisioning service off after success, and require a deliberate reset to start again.
- Treat the label as the trust anchor. A code printed on the device only proves you are talking to whichever device carries that label. When is trust on first use safe? covers the general problem.
BLE provisioning failures on phones
BLE provisioning fails on some phones because Android and iOS restrict Bluetooth and Wi-Fi information in different ways, and the device may not support the network the phone is on. Check these in order:
- Bluetooth permissions on Android. Android 12 and later need
BLUETOOTH_SCANandBLUETOOTH_CONNECT. Android 11 and lower need location permission to scan. DeclaringneverForLocationfilters some beacons out of scan results. Bluetooth permissions on Android explained has the details. - The app cannot read the current network name. Android’s
getSSID()returns an unknown SSID when the app lacks permission, so an app that pre-fills the network may show nothing. On iOS,NEHotspotNetwork.fetchCurrentreturns nothing unless the app meets one of Apple’s conditions, such as having precise location authorization, and holds the Access Wi-Fi Information entitlement. Let users type or pick the SSID from the device’s own scan. - The wrong band. The device may support only 2.4 GHz Wi-Fi. Home Assistant’s Matter guide says Matter devices often use 2.4 GHz and asks for the phone to be on the same 2.4 GHz network, and Matter’s Network Commissioning cluster has a status code for a band mismatch between 2.4 GHz and 5 GHz.
- The device thinks it is already provisioned. Espressif’s example warns that once credentials are applied, even wrong ones, the device will not re-enter provisioning mode on reboot until its stored settings are erased. Ship a factory reset.
- Long writes. Improv’s specification warns that a command over 20 bytes needs several Bluetooth LE packets, so client code has to handle that.
- Browser setup on iPhone. Improv’s in-browser setup runs in Chrome or Edge, and the Improv site says it does not work on iOS devices. Use a native app there.
- A pairing prompt. If the device forces link encryption, the phone shows a system pairing dialog, which users may dismiss.
Device setup with no internet
A device can be set up with no internet at all. Bluetooth LE provisioning runs entirely between the phone and the device, and the device only needs to join the access point, whether or not that network reaches the internet. Problems come from the apps around the protocol: a maker’s app that requires an account sign-in, or a phone that has to download components first, such as the Matter modules that Home Assistant says Android fetches through Google Play services. If a product must work on a site with no connectivity, test setup with the phone in airplane mode with Bluetooth and Wi-Fi turned back on, and make the maker’s app work without a sign-in. Can a smart home run without the cloud? covers what happens after setup.
Offline Protocol and device provisioning
Offline Protocol is not a provisioning protocol and does not hand out Wi-Fi credentials. What it covers starts after setup: devices that keep proving who they are to each other with their own keys, an Ed25519 identity per install and MLS-encrypted sessions, whether or not a network is up. Its documentation for constrained “leaf” devices faces the same security question as the section above. A device label carries only an address and a public key, firmware must decide when the radio accepts a pairing because “any address in radio range can complete a pairing”, and a swapped sticker is called out as a risk with no cryptographic fix, which an owner can detect by recording the device’s address at first pairing. The leaf crate compiles for microcontroller targets but has not yet been run on a board. Offline Protocol for embedded devices describes it.