BridgeThe companion bridge

What your phone talks to. The bridge passes /api/companion/* through to the runtime behind a token, and nothing else.

macOS 1.1.4127.0.0.1:381112 min read
On this page

Address and tokens

  • Where: 127.0.0.1:38111 by default. The bridge listens on the Mac's loopback address; a phone reaches it through your tailnet or an HTTPS relay you run, set with ROACHTAIL_RELAY_HOST.
  • Auth: authorization: Bearer <token>, with either the companion token or a paired device's rtp_ token.
  • Scope: only /api/companion/* and GET /health. Anything else gets a 404 from the bridge, so a phone's token can't reach the rest of the API. The same routes also answer on the loopback API.

The companion token is in the installer settings. Treat it like a password, because it is one:

Terminal
BRIDGE=http://127.0.0.1:38111
TOKEN=$(sed -n 's/.*"companionToken" *: *"\([^"]*\)".*/\1/p' ~/Library/Application\ Support/roachnet/roachnet-installer.json)
curl -s "$BRIDGE/api/companion/runtime" -H "authorization: Bearer $TOKEN"

Device tokens

A phone pairs with POST /api/companion/roachtail/pair, trading a RoachTail join code for its own rtp_ token. That route needs no token itself.

  • A join code pairs once, expires after 10 minutes, and retires after five wrong guesses.
  • The Mac keeps only a hash of each device token and compares tokens in constant time.
  • A device token that goes unused for 90 days stops working (ROACHTAIL_PEER_IDLE_DAYS; 0 turns that off).
  • Linked devices on the Mac removes one device without touching the others.

Pairing answers 409 while RoachTail is off, and 401 for a wrong, expired or used code.

Every route

MethodPathWhat it does
GET/healthBridge health

The one bridge path that needs no token.

GET/api/companion/bootstrapPhone bootstrap

Everything the phone’s first screen needs, in one call.

GET/api/companion/runtimeRuntime snapshot

The phone’s Runtime tab: system, models, services, downloads.

GET/api/companion/vaultVault summary

Where the vault is and what is in it.

GET/api/companion/accountAccount link

The account metadata this Mac holds.

POST/api/companion/account/affectLink or unlink the account

Updates the account metadata on this Mac.

GET/api/companion/roachtailRoachTail state

Pairing, peers and routes for the private device lane.

POST/api/companion/roachtail/pairPair a device

Trades a join code for a device token, so it needs no token itself.

POST/api/companion/roachtail/affectChange RoachTail

Turn the lane on or off, refresh the code, manage peers.

GET/api/companion/roachsyncRoachSync state

Sync settings for this Mac.

POST/api/companion/roachsync/affectChange RoachSync

Enable, disable, refresh, set the folder or clear peers.

POST/api/companion/installQueue an install

The RoachNet Apps install lane, for the phone and the Mac.

GET/api/companion/chat/sessionsChat sessions

Your RoachClaw chats from the phone, newest first.

POST/api/companion/chat/sessionsNew chat session

Creates an empty session.

GET/api/companion/chat/sessions/:idOne chat session

A session with its messages.

POST/api/companion/chat/sendSend a chat message

Records your message, asks the local model, records the reply.

POST/api/companion/services/affectControl a service

Start, stop or restart a service from the phone.

POST/api/companion/*Any other companion action

Every other POST under /api/companion/ gets the same success reply.

GET/api/companion/themeActive theme

New in 1.1. The Mac’s resolved theme, so the phone can wear it.

19 routes, from the route data the route browser uses, checked against Router.swift at tag v1.1.4.

Checked against v1.1.4 · 5 November 2026
esc
↑ ↓ move↵ openesc closeSearches on your device. Nothing is sent anywhere.