📡TetherClaw Docs

API Reference

The TetherClaw relay WebSocket protocol for developers building custom integrations.

Client Connection

Connect to the relay as a mobile client or custom app:

wss://relay.tetherclaw.app?key=<apiKey>&role=client

Query parameters:

ParameterRequiredValue
keyYesYour TetherClaw API key
roleYesclient

After connecting, the relay immediately sends a gateway status event so you know whether the gateway is online before sending any messages.

Bridge Registration Protocol

A bridge (gateway) connects to the relay with role=gateway:

wss://relay.tetherclaw.app?key=<apiKey>&role=gateway

After connecting, the relay sends a registered event:

json
{ "event": "registered", "apiKey": "tc-xxx", "clients": 0 }

The bridge should maintain this connection with auto-reconnect. If a second gateway registers for the same key, the first is evicted. Rate limiting applies: more than 10 reconnect attempts per minute will result in a rate_limited response.

Message Types (Client → Relay)

connect

Initial handshake. Send once after connecting.

json
{
  "type": "req",
  "method": "connect",
  "id": "connect-1"
}

The relay responds with:

json
{
  "type": "res",
  "id": "connect-1",
  "ok": true,
  "payload": {
    "type": "hello-ok",
    "protocol": 3,
    "auth": { "mode": "token" }
  }
}

chat.send

Send a message to an agent.

json
{
  "type": "req",
  "method": "chat.send",
  "id": "msg-001",
  "payload": {
    "sessionKey": "agent:midas:tetherclaw:mobile",
    "message": "What's the store revenue today?"
  }
}

sessionKey format: agent:<agentId>:<context>. For standard TetherClaw use, the format is agent:<agentId>:tetherclaw:mobile.

The relay forwards this to the connected gateway. Responses come back as chat events (see Event Types below).

agents.list

Request the list of available agents from the gateway.

json
{
  "type": "req",
  "method": "agents.list",
  "id": "list-001"
}

The gateway responds with the list of configured agents. The exact response format depends on your platform.

warroom.broadcast

Send a message to multiple agents simultaneously (Pro tier and above).

json
{
  "type": "req",
  "method": "warroom.broadcast",
  "id": "wr-001",
  "params": {
    "message": "Morning standup — what are your priorities today?",
    "agents": ["midas", "gecko", "martha"]
  }
}

The relay fans out a chat.send to each agent listed and responds with:

json
{
  "type": "res",
  "id": "wr-001",
  "ok": true,
  "payload": { "queued": 3 }
}

Each agent's response comes back as a separate chat event stream.

Event Types (Relay → Client)

gateway_online

The gateway is connected and ready to receive messages.

json
{ "event": "gateway_online", "apiKey": "tc-xxx" }

gateway_offline

The gateway has been disconnected for more than 60 seconds. Messages sent while the gateway is offline are queued (up to 100 messages) and delivered when the gateway reconnects.

json
{ "event": "gateway_offline", "apiKey": "tc-xxx" }

gateway_reconnecting

The gateway just disconnected. The relay is holding the session for up to 60 seconds waiting for it to reconnect. Don't show an error yet.

json
{ "event": "gateway_reconnecting", "apiKey": "tc-xxx" }

gateway_reconnected

The gateway came back within the hold window. The session has resumed.

json
{ "event": "gateway_reconnected", "apiKey": "tc-xxx" }

chat

An agent response. Arrives in two phases: streaming deltas as the agent types, then a final message.

Delta (streaming):

json
{
  "event": "chat",
  "state": "delta",
  "runId": "run-abc123",
  "sessionKey": "agent:midas:tetherclaw:mobile",
  "message": {
    "role": "assistant",
    "content": [{ "type": "text", "text": "Revenue today is " }]
  }
}

Final:

json
{
  "event": "chat",
  "state": "final",
  "runId": "run-abc123",
  "sessionKey": "agent:midas:tetherclaw:mobile",
  "message": {
    "role": "assistant",
    "content": [{ "type": "text", "text": "Revenue today is $4,200 — up 12% from yesterday." }]
  }
}

Error:

json
{
  "event": "chat",
  "state": "error",
  "sessionKey": "agent:midas:tetherclaw:mobile",
  "error": { "message": "Agent is offline." }
}

approval_request

An agent is requesting your approval before taking an action. This is triggered when the agent's response contains the [APPROVAL REQUIRED] sentinel.

json
{
  "type": "event",
  "event": "approval_request",
  "payload": {
    "id": "apr-1234567890-abc123",
    "agentId": "midas",
    "action": "Place order for 500 units of SKU-4421 at $12.50 each — total $6,250",
    "timestamp": 1745000000000
  }
}

Respond with approval_response:

json
{
  "type": "approval_response",
  "id": "apr-1234567890-abc123",
  "approved": true
}