How do I pair a device?
The gateway token is device pairing — it connects your browser or phone to YOUR gateway running on your machine. It is not user authentication. You authenticate via the Claude CLI (claude /login), not through Daemion.
QR code pairing
When the gateway starts, it prints a QR code directly in the terminal:
Daemion gateway running on http://localhost:3001
Pair your phone: ┌─────────────────────────────┐ │ │ │ ▄▄▄▄▄ ▄ ▄▄▄ ▄▄▄▄▄ │ │ █ █ ██ █ █ █ █ │ │ █▄▄▄█ █▄▄█ █ █▄▄▄█ │ │ │ └─────────────────────────────┘
OTP: 847291 (expires in 10 minutes)
Point your phone’s camera at the QR code. The app opens automatically and completes pairing — no typing required. The QR encodes both your gateway URL and the one-time pairing code.
6-digit code pairing
If scanning isn’t an option, use the 6-digit OTP shown in the terminal. Enter it on the pairing screen in the browser app, or POST it directly to the gateway:
Exchange a one-time pairing code for a bearer token. The token is valid until the gateway is reset or a new token is issued.
| Parameter | Type | Description |
|---|---|---|
otp REQUIRED | string | The 6-digit code printed in the terminal on gateway startup. |
curl -X POST http://localhost:3001/pair
-H “Content-Type: application/json”
-d ’{“otp”: “847291”}‘
Response:
{“token”: “dae_tok_a1b2c3d4e5f6…”}
Store that token — every subsequent API request needs it as a bearer header.
Using the bearer token directly
The token is saved to ~/.daemion/.gateway-token on the gateway machine. All API endpoints except /health and /pair require it:
DAEMION_TOKEN=$(cat ~/.daemion/.gateway-token)
curl http://localhost:3001/agents
-H “Authorization: Bearer $DAEMION_TOKEN”
The browser and phone store the token in localStorage after pairing — you won’t need to handle it manually in normal use.
Refreshing the pairing code
The OTP expires after 10 minutes. If you need a fresh one without restarting the gateway:
Generate a new OTP and print a fresh QR code. The previous OTP is immediately invalidated. Requires an existing bearer token.
curl http://localhost:3001/pair/refresh
-H “Authorization: Bearer $DAEMION_TOKEN”
The terminal will print a new QR code and 6-digit code. Previously issued bearer tokens remain valid — only the OTP changes.
Common questions
GET /pair/refresh to get a new one, or restart the gateway with daemion start. Already-paired devices are not affected — only the OTP changes.GET /pair/refresh between pairings to generate a fresh code for the next device.~/.daemion/.gateway-token. The paired browser or phone stores its copy in localStorage. Neither location is synced — if you clear localStorage you'll need to re-pair that device.What can go wrong
429 “Too many attempts” — The OTP endpoint is rate-limited. Wait 60 seconds, then try again. Don’t retry in a loop — each failed attempt resets the window.
401 “Invalid or expired code” — The OTP expired (10-minute window) or was mistyped. Run GET /pair/refresh or restart the gateway to get a fresh code.
501 “Pairing not available” — The gateway started without finding a token file at ~/.daemion/.gateway-token. Make sure the ~/.daemion/ directory exists and is writable, then restart.
What’s next?
- Remote access with Tailscale — reach your gateway from anywhere
- Gateway API reference — full list of endpoints and auth details