← All packages

esp32-gpio-api

The ESP32 port of pi-gpio-api: same endpoints, same wire format, same API-key auth, on an ESP32, ESP32-C3, or ESP32-S3 with MicroPython 1.29. Clients, testers, and bridges target a Pi, Pico, or ESP32 interchangeably.

platformESP32 / ESP32-C3 / ESP32-S3 version0.9.27 runtimeMicroPython authApi-Key licenseMIT statusBeta

Install on your ESP32

Flash MicroPython 1.29, connect the ESP32 to your Mac/PC over USB, and run this command. It downloads release files, asks for your agent name, API key, and Wi-Fi credentials, and deploys everything to the board:

# on your Mac/PC
curl -fsSL https://raw.githubusercontent.com/ctrlpi/esp32-gpio-api/main/install.sh | bash

Pre-compiled bytecode, zero extra dependencies

app.mpy is pre-compiled into bytecode for fast boot times and reduced RAM usage. boot.py connects to Wi-Fi at startup and launches the server automatically.

Wi-Fi credentials live in wifi.txt on the board (install.sh writes it from a prompt):

SSID = "YourNetwork"
PASSWORD = "YourPassword"

What it does

Interchangeable by design: the ctrlPi integration test suite runs the same REST tests against a Pi, a Pico, and an ESP32, only the physical pin numbers differ.

The REST API

All routes require the Api-Key header except /hello:

MethodPathDescription
GET/helloDiscovery & health check, returns the agent's name, no auth
GET/gpio/readRead all configured pins
GET/gpio/read/{name_or_gpio}Read one pin by GPIO number or name alias
POST/gpio/write/{name_or_gpio}Write a value, supports "on"/"off"/"toggle" and timed duration pulses
POST/gpio/config/{name_or_gpio}Configure a pin: type, name, init, pullup, max, reversed, watched
GET/gpio/watchedList watched pins and the active webhook URL
GET/gpio/scanScan all usable GPIO pins, includes physical level, platform, CPU temp
POST/sensor/config/{name}Configure a named sensor: a script (.py) to run from the agent's scripts/ folder
GET/sensor/readRead all sensors (or /sensor/read/{name} for one) as JSON
GET/config/readAgent identity + full config
POST/config/updateUpdate config fields (auto-backup first)
POST/config/loadReplace the whole config ({} resets)
POST/restartRestart the device - resets microcontroller into clean state
POST/upgradeUpgrade in place - downloads latest release files and resets
GET/logsLast 30 log lines as JSON (in-memory, cleared on reboot)

Try it

# configure GPIO 18 as an output named "led"
curl -X POST http://<esp32-ip>:8314/gpio/config/18 \
  -H "Api-Key: your-secret-key" -H "Content-Type: application/json" \
  -d '{"type": "output", "name": "led"}'

# pulse it for 1.5 seconds, reverts automatically
curl -X POST http://<esp32-ip>:8314/gpio/write/led \
  -H "Api-Key: your-secret-key" -H "Content-Type: application/json" \
  -d '{"value": 1, "duration": 1.5}'

Webhooks

Mark any pin watched and the agent POSTs its state to your configured webhook URL on every change, that's how homebridge-ctrlpi gets real-time input events. While setting up, point webhook_url at ctrlPi's public test endpoint and watch your events live while wiring.

In the family

Everything that drives a Pi or Pico agent drives an ESP32 agent unchanged: homebridge-ctrlpi, mcp-bridge, ctrlpi-cli, and ctrlpi-lab. Watch live webhooks at ctrlpi.com.

To test endpoints, watch webhook events and tail logs in the browser, open ctrlpi-lab, and to find and drive agents from a terminal, use ctrlpi-cli.

To get an agent onto a board over USB, use pico-bay. It can install MicroPython, manage the board's files and run code on a Pico and an ESP32.