Install on your Pi
One-liner, no git required, downloads the release files, safe to re-run to update (config and logs are never touched):
# on the Pi
curl -fsSL https://raw.githubusercontent.com/ctrlpi/pi-gpio-api/main/install.sh | bashYou'll get instructions for autorun (systemd) setup printed at the end.
Set autorun or start with run.sh or venv/bin/python main.py
What it does
- Outputs: write
0/1/"on"/"off"/"toggle", pulse for a duration with automatic revert, clamp with a per-pinmax, invert relay logic withreversed - Inputs: pull-up/down/none, name aliases, and
watchedpins that fire a webhook on every state change - Sensors: named readings from a script in the agent's
scripts/folder, returned as JSON - surface a CPU temperature, a 1-Wire probe, or any tool's output over the same API - Persistence: pin config and last output values survive restarts and reboots (
init: "last") - Identity: every agent reports its name, IP, platform, OS, and CPU temperature; unauthenticated
/hellomakes LAN discovery trivial - Logging: request log with configurable retention (
log_days0 to 7), readable over the API
The REST API
All routes require the Api-Key header except /hello:
| Method | Path | Description |
|---|---|---|
GET | /hello | Discovery & health check, returns the agent's name, no auth |
GET | /gpio/read | Read 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/watched | List watched pins and the active webhook URL |
GET | /gpio/scan | Scan all BCM pins (Pi hardware), includes physical level, platform, CPU temp |
POST | /sensor/config/{name} | Configure a named sensor: a script to run from the agent's scripts/ folder |
GET | /sensor/read | Read all sensors (or /sensor/read/{name} for one) as JSON |
GET | /config/read | Agent identity + full config |
POST | /config/update | Update config fields (auto-backup first) |
POST | /config/load | Replace the whole config ({} resets) |
POST | /restart | Restart the server process, or reboot the device with {"reboot": true} |
POST | /upgrade | Upgrade in place - re-downloads the latest release (install.sh --upgrade) and restarts |
GET | /logs | Last 50 log lines as JSON |
main.py) can also serve interactive OpenAPI docs at /docs (Swagger UI) and /redoc, off by default, switched on with docs_enabled in the config. The Lite version (default install) does not serve them.Try it
# configure GPIO 17 as an output named "relay", active-low curl -X POST http://raspberrypi:8314/gpio/config/17 \ -H "Api-Key: your-secret-key" -H "Content-Type: application/json" \ -d '{"type": "output", "name": "relay", "reversed": true}' # pulse it for 2 seconds, reverts automatically curl -X POST http://raspberrypi:8314/gpio/write/relay \ -H "Api-Key: your-secret-key" -H "Content-Type: application/json" \ -d '{"value": 1, "duration": 2}'
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
This is the reference agent. pico-gpio-api and esp32-gpio-api speak the identical wire format on a Pico W and ESP32; homebridge-ctrlpi and mcp-bridge drive any mix of them interchangeably.
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 Pi over the network, pi-bay is coming soon.