Skip to main content

Quick Start

This guide walks you through setting up your first app and agent on Relay. By the end, you'll have an app sending events and an agent receiving and replying to them.

Estimated time: 5 minutes


Step 1: Sign Up

Head to relay.ckgworks.com and click Sign Up.

Complete your account registration. You'll land on the Dashboard.


Step 2: Create an Organization

On the dashboard, click Create Organization (or New Organization if you already have one).

An organization is your workspace. It's where you register apps, agents, and set allowlists.

Give it a name like "My First Relay" and click Create.

You're now in your organization. Note the Organization ID — you'll need it for configuration.


Who Manages What?

TokenCreated inStored byUsed by
App token (rlk_)Relay DashboardYour app's .envYour app's WebSocket connection
Agent token (rla_)Relay DashboardAgent's .envAgent's WebSocket connection

Your app never needs to see or store agent tokens. You only need the agent_id (a plain string like athena_k9p2m3) to route events.


Step 3: Register Your App

In the organization sidebar, click AppsRegister New App.

Enter a name like "Portal Test App" and click Register.

Relay generates an app token that looks like: rlk_portal_x8k2m9p...

Copy this token. You'll use it to authenticate your app's WebSocket connection.

note

Keep this token secret. Anyone with it can send events as your app. Store it in your .env file, never in version control.


Step 4: Register an Agent

In the organization sidebar, click AgentsRegister New Agent.

Enter a name like "Athena" and click Register.

Relay auto-generates a unique agent ID (e.g., athena_k9p2m3) and an agent token like: rla_athena_k9p2m3_x8k2...

Copy both. The agent ID is what your app uses to route events. The token is what the agent uses to connect.

Copy this token. You'll use it to authenticate your agent's WebSocket connection.

note

One agent token works across all allowlisted apps. Store it securely in your plugin or agent server config.


Step 5: Set Up Allowlisting

By default, apps can't send to agents. You need to explicitly allowlist them.

In the Allowlist section of your organization:

  1. Select your app (Portal Test App)
  2. Select the agent (athena)
  3. Click Allow

Now your app can send events to this agent.


Step 6: Connect Your App (WebSocket)

Create a simple Python script to connect your app to Relay:

import asyncio
import websockets
import json
import uuid

APP_TOKEN = "rlk_portal_x8k2m9p..." # From Step 3
RELAY_URL = "wss://api.relay.ckgworks.com/v1/ws/app"

async def connect_app():
headers = {
"Authorization": f"Bearer {APP_TOKEN}"
}

async with websockets.connect(
RELAY_URL,
subprotocols=["relay-app"],
extra_headers=headers
) as ws:
print("✓ App connected to Relay")

# Listen for messages
while True:
try:
message = await ws.recv()
data = json.loads(message)
print(f"← {data['type']}: {data}")
except websockets.exceptions.ConnectionClosed:
print("✗ Connection closed. Reconnecting...")
await asyncio.sleep(2)
break

asyncio.run(connect_app())

Run this script:

pip install websockets
python app.py

You should see:

✓ App connected to Relay

Leave this running. You'll use it in the next step.


Step 7: Connect Your Agent (WebSocket)

In another terminal, create a Node.js script to connect your agent:

const WebSocket = require("ws");

const AGENT_TOKEN = "rla_athena_k9x2p..."; // From Step 4
const RELAY_URL = "wss://api.relay.ckgworks.com/v1/ws/agent";

const ws = new WebSocket(RELAY_URL, ["relay-agent"], {
headers: {
Authorization: `Bearer ${AGENT_TOKEN}`,
},
});

ws.on("open", () => {
console.log("✓ Agent connected to Relay");
});

ws.on("message", (data) => {
const message = JSON.parse(data);
console.log(`${message.type}: ${JSON.stringify(message)}`);
});

ws.on("close", () => {
console.log("✗ Connection closed");
});

ws.on("error", (err) => {
console.error("Error:", err);
});

Set up Node.js if you haven't:

npm init -y
npm install ws
node agent.js

You should see:

✓ Agent connected to Relay

Now both your app and agent are connected to Relay.


Step 8: Send Your First Event

Back in the Python script, add a function to send an event. Replace the connect_app() function:

import asyncio
import websockets
import json
import uuid

APP_TOKEN = "rlk_portal_x8k2m9p..."
AGENT_ID = "athena"
RELAY_URL = "wss://api.relay.ckgworks.com/v1/ws/app"

async def connect_app():
headers = {
"Authorization": f"Bearer {APP_TOKEN}"
}

async with websockets.connect(
RELAY_URL,
subprotocols=["relay-app"],
extra_headers=headers
) as ws:
print("✓ App connected to Relay\n")

# Send an event
event = {
"type": "event",
"agent_id": AGENT_ID,
"thread_id": f"thread-{uuid.uuid4().hex[:8]}",
"payload": {
"event": "comment.mention",
"message": "@athena summarize this task",
"sender": {
"id": "user-456",
"name": "Developer"
},
"task_id": "task-123",
"task_title": "Q2 Roadmap Review",
"project": "Test Project"
}
}

print(f"→ Sending event:\n{json.dumps(event, indent=2)}\n")
await ws.send(json.dumps(event))

# Listen for replies
while True:
try:
message = await ws.recv()
data = json.loads(message)
print(f"← {data['type']}: {json.dumps(data, indent=2)}\n")
except websockets.exceptions.ConnectionClosed:
print("✗ Connection closed")
break

asyncio.run(connect_app())

Run the app script again:

python app.py

You should see the event being sent to Relay.


Step 9: See the Agent Receive and Reply

In your agent terminal, you should see:

← event: {
"type": "event",
"event_id": "evt_k9p2m",
"agent_id": "athena",
"session_key": "relay:athena:portal:thread-abc123",
"payload": {
"event": "comment.mention",
"message": "@athena summarize this task",
...
}
}

Now the agent can respond. Add this to the Node.js script:

ws.on("message", (data) => {
const message = JSON.parse(data);

if (message.type === "event") {
console.log(`← Event received: ${message.event_id}`);

// Send a reply
const reply = {
type: "reply",
event_id: message.event_id,
payload: message.payload, // Echo back the original payload
content: "This task involves reviewing the Q2 roadmap and priorities.",
finish_reason: "stop"
};

console.log(`→ Sending reply:\n${JSON.stringify(reply, indent=2)}\n`);
ws.send(JSON.stringify(reply));
}
});

Now when the agent receives an event, it will automatically send back a reply.


Step 10: See Your App Receive the Reply

Back in your app terminal, you should now see:

← type: accepted
← type: token (streaming tokens from the agent)
← type: token
← type: token
← type: reply (final assembled response)

Here's what each message means:

  • accepted: Relay received your event and is routing it to the agent.
  • token: A single token from the agent's response (useful for "typing..." UI).
  • reply: The complete final response, with the agent's full message.

Congratulations!

You've just: ✓ Signed up for Relay ✓ Created an organization ✓ Registered an app and an agent ✓ Set up allowlisting ✓ Connected both to Relay via WebSocket ✓ Sent your first event ✓ Received a streaming reply


What's Next?

Now that you understand the flow, explore the deeper topics:

Or check out the API Reference for complete message schemas.