Pairing & connecting
Exchange a 6-digit code once to get a long-lived token. Everything except pairing and status requires it.
Why pairing exists
BrewPing lets a phone execute commands on your computer. To keep that channel from being open to anyone on the Wi-Fi, the desktop app issues a one-time 6-digit code. Entering that code on the phone exchanges it for a long-lived bearer token, which is then sent with every subsequent request.
Get the code on your computer
macOS — menu bar
Click the cup icon in the menu bar and choose Show pairing code (显示配对码). The main window opens on the Pairing section and shows the code plus a QR code.
Windows — tray or settings
Either click Show Pairing Code in the tray menu, or open Settings > Pairing. The section shows the code, a Copy button, a Refresh button and a QR code.
Share it
Type the 6 digits on your phone, or scan the QR code with the phone's camera.
Enter it on your phone
iOS — add the device
Tap + in the device bar, fill in Name, Host (IP or hostname), Port (defaults to 8787) and System, then enter the 6-digit code in the Pairing section of the same form. Alternatively tap Scan QR Code.
Android — pair dialog
Tap +, fill in Host / Port / Name and the system filter, then confirm. The Pair dialog asks for the 6-digit pairing code; Scan QR is available as well.
Confirm the result
On iOS the lock icon (key.slash) disappears from the device tab once paired. "Paired successfully." is shown after a successful exchange.
Code and token rules
| Property | Value |
|---|---|
| Code format | Exactly 6 digits, zero-padded (000000 – 999999) |
| Code lifetime | 600 seconds (10 minutes) |
| Code reuse | Single use — it is cleared immediately after a successful exchange |
| Token | 32 random bytes, stored as 64 hex characters |
| Token storage (desktop) | ~/.brewping/pairing.json, file mode 0600 |
| Token storage (iOS) | Keychain, not UserDefaults |
| Replay window | Timestamps must be within ±120 seconds |
| Nonce | Single-use per request; up to 2048 remembered |
Authenticated requests
Read requests (GET) only need the bearer token. Write requests additionally need a timestamp and a nonce header to prevent replay:
| Header | Required for | Rule |
|---|---|---|
| Authorization: Bearer <token> | Everything except POST /api/pair and GET /api/status | Compared in constant time |
| X-BrewPing-Timestamp | Write operations (POST / PATCH / DELETE) | Within ±120 seconds of server time |
| X-BrewPing-Nonce | Write operations (POST / PATCH / DELETE) | Must not have been used before |
# 1) Exchange the 6-digit code for a token
curl -X POST http://192.168.1.20:8787/api/pair \
-H 'Content-Type: application/json' \
-d '{"code":"123456"}'
# -> {"success":true,"token":"<64 hex chars>","deviceId":"...","deviceName":"..."}
# 2) Read: token only
curl http://192.168.1.20:8787/api/status \
-H 'Authorization: Bearer <token>'
# 3) Write: token + timestamp + nonce
curl -X POST http://192.168.1.20:8787/api/message \
-H 'Authorization: Bearer <token>' \
-H 'X-BrewPing-Timestamp: 1780000000' \
-H 'X-BrewPing-Nonce: 8f3c1a...' \
-H 'Content-Type: application/json' \
-d '{"text":"Refactor auth middleware, add rate limiting"}'QR code and deep link
The desktop QR code encodes a brewping://pair URL. Scanning it on the phone pre-fills the connection, so the code is the only thing left to confirm:
brewping://pair?host=192.168.1.20&port=8787&deviceId=...&name=Chenzk&osType=macDemo mode (iOS)
The iPhone app includes a Demo mode so the full flow can be exercised without a computer — useful for reviewers and for a first look. The demo device needs no pairing code.
- Empty-state card: Try the Demo (no Mac needed).
- Add Device form: Add Demo Device (no Mac needed).
- Help & About: Try it without a computer.
- Demo host is demo.brewping.local on port 8787; the device is named Demo Mac.