Self-Hosted Private Server

Private Server

Run the Phone Agent relay on your own machine. Your phone connects to your server, your apps send messages to your server, and nothing leaves your network. This page shows you exactly how to download it, run it, and send your first message — in about three commands.

1. Download the Docker server

Private Server is a paid add-on. After you sign in with a paid account that includes Private Server, download the saved Docker image from your account page. One file works on Linux, macOS, and Windows with Docker Desktop.

Paid account required: Free accounts can use the hosted Phone Agent flow within free caps, but Business Hub and Private Server downloads are paid-only.
File name
phoneagent-private-server-v0.1.1.tar
Format
Docker image archive from docker save

After download, put the .tar file in a folder where you can run terminal commands.

Optional: verify the file
# Linux / macOS
sha256sum phoneagent-private-server-v0.1.1.tar

# Windows PowerShell
Get-FileHash .\phoneagent-private-server-v0.1.1.tar -Algorithm SHA256
Load the Docker image
docker load -i phoneagent-private-server-v0.1.1.tar
Why Docker: one image runs identically on every OS. The image contains the relay, dependencies, and runtime defaults. Nothing to pip install, nothing to compile on your machine.

2. Get your license credentials

The Private Server validates against the central license server on startup. Sign in to your account page and click Generate server credentials under Private Server. You will get a .env-style block to paste into the container's environment:

PHONE_AGENT_LICENSE_SERVER_URL=https://phonerelay.dev
PHONE_AGENT_API_KEY=...
PHONE_AGENT_ACTIVATION_TOKEN=...
PHONE_AGENT_LICENSE_BEARER=...
PHONE_AGENT_LICENSE_BEARER_EXPIRES_AT=...
Save the bearer when shown — it is not displayed again. Click Generate again any time to rotate (this revokes the previous bearer; any running container stops validating until you update its env vars and restart).

3. Run the server

One docker run — the container listens on 0.0.0.0:8443 inside, mapped to your host port. Save the license env block from step 2 as phoneagent.env first, then:

docker run -d \
  --name phoneagent-server \
  -p 8443:8443 \
  -v phoneagent-data:/data \
  --env-file phoneagent.env \
  -e AUTH_SECRET_KEY="replace-with-random-secret" \
  -e MIDDLE_ADMIN_TOKEN="replace-with-random-admin-token" \
  -e GTS_DEVICE_PEPPER_RING="v1:replace-with-private-pepper-32chars-min" \
  phonerelay/private-server:v0.1.1

Or with docker-compose:

# docker-compose.yml
services:
  phoneagent:
    image: phonerelay/private-server:v0.1.1
    container_name: phoneagent-server
    restart: unless-stopped
    ports:
      - "8443:8443"
    volumes:
      - phoneagent-data:/data
    env_file:
      - phoneagent.env       # contains PHONE_AGENT_LICENSE_* from your account page
    environment:
      - PHONEAGENT_PUBLIC_HOST=your-ip-or-domain
      - AUTH_SECRET_KEY=replace-with-random-secret
      - MIDDLE_ADMIN_TOKEN=replace-with-random-admin-token
      - GTS_DEVICE_PEPPER_RING=v1:replace-with-private-pepper-32chars-min

volumes:
  phoneagent-data:
If startup fails with private-server license: ...: the container is refusing to boot because the license check failed (missing env vars, expired bearer, cancelled subscription). Re-generate credentials from your account page, update the env, and restart.

On first run, get the API key + pairing QR from the container logs:

docker logs phoneagent-server

Phone Agent Server v1.0.0
Listening on https://0.0.0.0:8443
API key:   pa_live_8f3c…  ← use this as Bearer token
Phone QR:  open https://<your-ip>:8443/qr in the Android app
Open https://<your-ip>:8443/qr in a browser and scan it with the Phone Agent Android app to pair the phone with this server.

4. Optional helper aliases

If you prefer short commands, download the helper file next to the Docker tar and load it into your shell:

source ./phoneagent-private-server-aliases.sh
pa-init-env
pa-load phoneagent-private-server-v0.1.1.tar
pa-start
pa-health
pa-webchat

To keep the commands available in every new terminal:

echo 'source ~/Downloads/phoneagent-private-server-aliases.sh' >> ~/.bashrc
source ~/.bashrc

Useful commands after it is loaded:

The helper stores secrets in .phoneagent-private.env. Keep that file private and do not commit it.

5. Send your first message

Once the phone is paired, send a message via the HTTP API:

curl
curl -X POST https://<your-ip>:8443/api/v1/messages \
  -H "Authorization: Bearer pa_live_8f3c…" \
  -H "Content-Type: application/json" \
  -d '{
    "channel": "sms",
    "to": "+15551234567",
    "text": "Hello from my private server!"
  }'
Python
import requests

requests.post(
    "https://your-ip:8443/api/v1/messages",
    headers={"Authorization": "Bearer pa_live_8f3c…"},
    json={"channel": "sms", "to": "+15551234567", "text": "Hello!"},
    verify=False,  # set to your cert path in prod
)

Full request/response reference: HTTPS API.

6. Configuration

Configure via environment variables on the docker run (or environment: in docker-compose). The common knobs:

Generate production secrets before first boot:

python3 -c "import secrets; print(secrets.token_urlsafe(48))"
docker run -d --name phoneagent-server \
  -p 8443:8443 \
  -v phoneagent-data:/data \
  -e AUTH_SECRET_KEY="replace-with-random-secret" \
  -e MIDDLE_ADMIN_TOKEN="replace-with-random-admin-token" \
  -e GTS_DEVICE_PEPPER_RING="v1:replace-with-private-pepper-32chars-min" \
  -e PHONEAGENT_API_KEYS=pa_live_8f3c,pa_live_other \
  -e PHONEAGENT_IP_ALLOWLIST=10.0.0.0/8 \
  -e PHONEAGENT_RATE_PER_MINUTE=60 \
  -e PHONEAGENT_QUEUE_MAX=1000 \
  -e PHONEAGENT_TLS_CERT=/data/cert.pem \
  -e PHONEAGENT_TLS_KEY=/data/key.pem \
  phonerelay/private-server:v0.1.1

All variables:

State (DB, generated certs, queued messages) lives in the /data volume inside the container. Mount it to a persistent volume (-v phoneagent-data:/data) so restarts don't wipe pairings.

7. Operations & security

Recommended for production deployments:

Building an "AI notifications gateway" for many users? Put a thin server in front of Phone Agent that owns the API key and applies your per-user policy before forwarding.

Next

Day-to-day API usage: HTTP API Examples. Web UI for sending: WebChat.