relay

Quickstart

Get relay running and create your first conversation — via WhatsApp, Telegram, or phone call.

1. Connect WhatsApp

Authenticate with WhatsApp by scanning a QR code:

relay whatsapp login

A QR code appears in your terminal. Scan it with your WhatsApp app. Auth state is saved locally in .relay-agent/whatsapp-auth/ and reconnects automatically on restart.

You can verify the connection at any time:

relay whatsapp status

2. Start the Daemon

Launch the persistent background process:

relay start

The daemon runs on localhost:3214 and maintains channel connections (WhatsApp, Telegram, phone). All CLI commands communicate with the daemon via HTTP.

3. Configure API Credentials

Set up the model provider for agent sessions:

relay init --api-key sk-ant-... --provider anthropic

You can also use --provider openai with an OpenAI key. If you omit the flags, the command prompts interactively. Alternatively, set the ANTHROPIC_API_KEY or OPENAI_API_KEY environment variable.

4. Create a Conversation

Create a new conversation instance with an objective and todo list:

relay create \
  --contact="+56912345678" \
  --objective="confirm delivery time for order #4421" \
  --todos="ask preferred time,confirm address,get signature name" \
  --heartbeat-interval=1800000 \
  --max-followups=5

Returns a unique instance ID. The agent sends an initial message via WhatsApp and the conversation begins.

5. Monitor Progress

Check the state of your conversation:

relay get <instance-id>

List all active instances:

relay list

Read the full transcript:

relay transcript <instance-id>

6. Control the Conversation

Pause, resume, or cancel at any time:

relay pause <instance-id>
relay resume <instance-id>
relay cancel <instance-id>

Inject a message manually when needed:

relay send <instance-id> "Sorry for the delay, checking now"

7. Stop the Daemon

When you're done:

relay stop

All state is flushed to disk and persists for the next session.

Telegram

relay supports Telegram as a conversation channel via a bot powered by the grammY framework.

Prerequisites

Connect the bot

relay telegram login --token <BOT_TOKEN>

The token is verified against the Telegram API and saved locally in .relay-agent/telegram-auth/. The daemon auto-reconnects on restart.

Check the bot status at any time:

relay telegram status

Create a Telegram conversation

relay create \
  --contact="+56912345678" \
  --objective="confirm delivery time for order #4421" \
  --todos="ask preferred time,confirm address" \
  --channel=telegram

The contact must message the bot on Telegram to start receiving replies. When the user sends a message, relay maps their chat ID to the instance and routes replies through the bot.

You can also provide a known chat ID directly:

relay create \
  --contact="+56912345678" \
  --objective="confirm delivery time" \
  --todos="ask ETA,confirm address" \
  --channel=telegram \
  --telegram-chat-id=123456789

Disconnect

relay telegram logout

Phone Calls (ElevenLabs)

relay also supports outbound phone calls via ElevenLabs Conversational AI. Calls use Twilio for telephony and ElevenLabs for the voice agent.

Prerequisites

  • An ElevenLabs account with Conversational AI enabled
  • A Twilio phone number connected to your ElevenLabs account
  • Set your API key:
export ELEVENLABS_API_KEY=your-key-here

Quick call (standalone)

Place a one-off call without instance tracking:

relay call "+56912345678" \
  --phone-number-id=PN123abc \
  --prompt="Confirm the delivery window for order #4421" \
  --first-message="Hi, I'm calling from Acme Co about your delivery."

Managed call (with instance tracking)

Create a full conversation instance on the phone channel — with objectives, todos, and transcript storage:

relay create \
  --contact="+56912345678" \
  --objective="confirm delivery time for order #4421" \
  --todos="ask preferred time,confirm address" \
  --channel=phone \
  --phone-number-id=PN123abc \
  --first-message="Hi, I'm calling about your recent order."

The daemon polls ElevenLabs for call status. When the call ends, the transcript is stored and the instance transitions to COMPLETED or FAILED.

On this page