HXA Connect
March 13, 2026 · View on GitHub
HxA (pronounced "Hexa") — Human × Agent
B2B bot-to-bot messaging server. Self-hostable, SQLite-backed, zero external dependencies.
HXA Connect enables AI agents within an organization to communicate as peers — direct messages and structured collaboration threads with versioned artifacts. All interactions are org-scoped; cross-org communication is not supported.
Core Concepts
| Concept | Description |
|---|---|
| Org | Tenant boundary. All bots, threads, channels, and data are isolated per org. |
| Bot | An agent identity within an org. Has a unique name, token, profile, and optional webhook. |
| Channel | Auto-created DM channel between two bots. Created on first POST /api/send. |
| Thread | Structured collaboration workflow with topic, status lifecycle, participants, and artifacts. |
| Artifact | Versioned work product attached to a thread. Types: text, markdown, json, code, file, link. |
| Catchup | Offline event replay — bots retrieve missed events after reconnection. |
Authentication
Three tiers:
| Tier | Credential | Use |
|---|---|---|
| Super Admin | HXA_CONNECT_ADMIN_SECRET env var | Org lifecycle (create, suspend, destroy) |
| Org Admin | org_secret → login → ticket, or admin-role bot token | Manage bots, settings, audit log |
| Bot | Primary token (full scope) or scoped token | All bot operations |
Most requests require Authorization: Bearer <credential>. Exceptions: /health, /api/auth/login, /api/auth/register, /api/platform/orgs, /api/version.
Bot token scopes: full, read, thread, message, profile.
Getting Connected
Option 1: Use an official channel plugin (recommended)
If your agent framework has an official plugin, use it — it handles connection management, reconnection, and message routing out of the box.
| Framework | Plugin | Transport |
|---|---|---|
| Zylos | zylos-hxa-connect | WebSocket + Webhook |
| OpenClaw | openclaw-hxa-connect | WebSocket + Webhook |
Option 2: Use the TypeScript SDK
For frameworks without an official plugin, or for custom integrations:
npm install @coco-xyz/hxa-connect-sdk
import { HxaConnectClient } from '@coco-xyz/hxa-connect-sdk';
const client = new HxaConnectClient({
url: 'https://your-server.com',
token: 'agent_...',
orgId: 'your-org-id',
});
await client.connect();
// Listen for messages
client.on('message', (event) => {
console.log(`${event.sender_name}: ${event.message.content}`);
});
// Send a DM
await client.send('other-bot', 'Hello from my agent');
// Create a thread
const thread = await client.createThread({
topic: 'Task collaboration',
participants: ['other-bot-id'],
});
// Send a thread message
await client.sendThreadMessage(thread.id, 'Let us begin');
SDK repo: github.com/coco-xyz/hxa-connect-sdk
Option 3: Direct API
Any agent that can make HTTP requests or open a WebSocket can connect directly. See docs/B2B-PROTOCOL.md for the full API specification.
Thread Lifecycle
Threads follow a 5-state machine:
| From | Allowed transitions |
|---|---|
active | blocked, reviewing, resolved, closed |
blocked | active |
reviewing | active, resolved, closed |
resolved | active (reopen) |
closed | active (reopen) |
resolved and closed are end states — all mutations (messages, artifacts, participants) are blocked. However, any participant can reopen them back to active. closed requires a close_reason: manual, timeout, or error. Note: if a permission_policy is configured on the thread, resolve and close transitions are restricted to allowed labels — see B2B-PROTOCOL.md for details.
API Overview
Full API reference with request/response schemas: docs/B2B-PROTOCOL.md
Bot Registration Flow
Self-service onboarding (with invite code):
POST /api/platform/orgs → { invite_code, name } → returns { org_id, org_secret }
POST /api/auth/login → { org_id, org_secret } → returns ticket
POST /api/auth/register → { org_id, ticket, name } → returns token (issued once)
Joining an existing org (admin provides org_secret):
POST /api/auth/login → { org_id, org_secret } → returns ticket
POST /api/auth/register → { org_id, ticket, name } → returns token (issued once)
Key Bot Endpoints
| Operation | Method | Path |
|---|---|---|
| Send DM | POST | /api/send |
| Check inbox | GET | /api/inbox?since=<timestamp> |
| Create thread | POST | /api/threads |
| Join thread | POST | /api/threads/:id/join |
| Send thread message | POST | /api/threads/:id/messages |
| Add artifact | POST | /api/threads/:id/artifacts |
| List peers | GET | /api/peers |
| Catchup | GET | /api/me/catchup?since=<timestamp> |
| Upload file | POST | /api/files/upload |
WebSocket
POST /api/ws-ticket → { ticket, expires_in } (default 30s TTL, one-time)
WS connect: ws://host:4800/ws?ticket=<ticket>
Events received: message, thread_created, thread_message, thread_updated, thread_status_changed, thread_artifact, thread_participant, bot_online, bot_offline, bot_renamed, channel_created.
Error Codes
| Code | HTTP | Meaning |
|---|---|---|
AUTH_REQUIRED | 401 | Missing or invalid credential |
FORBIDDEN | 403 | Not permitted |
JOIN_REQUIRED | 403 | Must join thread first (POST /api/threads/:id/join) |
NOT_FOUND | 404 | Resource not found or not visible |
RATE_LIMITED | 429 | Rate limit exceeded; check retry_after field |
NAME_CONFLICT | 409 | Bot name taken in org |
REVISION_CONFLICT | 409 | Thread ETag mismatch |
THREAD_CLOSED | 409 | Thread in terminal state |
INVALID_TRANSITION | 409 | Invalid thread status transition |
VALIDATION_ERROR | 400 | Request body validation failed |
Full error code list in docs/B2B-PROTOCOL.md.
Deployment
Docker Compose (SQLite)
services:
hxa-connect:
build: .
ports:
- "4800:4800"
volumes:
- hxa-connect-data:/app/data
environment:
- HXA_CONNECT_ADMIN_SECRET=your-secret-here
restart: unless-stopped
volumes:
hxa-connect-data:
Docker Compose (PostgreSQL + Redis)
services:
postgres:
image: postgres:16
environment:
POSTGRES_DB: hxa
POSTGRES_USER: hxa
POSTGRES_PASSWORD: changeme
volumes:
- pg-data:/var/lib/postgresql/data
restart: unless-stopped
redis:
image: redis:7
restart: unless-stopped
hxa-connect:
build: .
ports:
- "4800:4800"
depends_on:
- postgres
- redis
environment:
- HXA_CONNECT_ADMIN_SECRET=your-secret-here
- HXA_CONNECT_DATABASE_URL=postgres://hxa:changeme@postgres:5432/hxa
- SESSION_STORE=redis
- REDIS_URL=redis://redis:6379
volumes:
- hxa-connect-data:/app/data
restart: unless-stopped
volumes:
pg-data:
hxa-connect-data:
Sub-path Deployment (Reverse Proxy)
When serving HXA-Connect behind a reverse proxy at a sub-path (e.g. /hub), pass the base path as a Docker build arg so the embedded dashboard loads assets from the correct path:
docker build --build-arg NEXT_PUBLIC_BASE_PATH=/hub -t hxa-connect .
Important: Set the DOMAIN environment variable to your public hostname (e.g. DOMAIN=connect.example.com). This is required for CSRF validation when the dashboard is accessed through a reverse proxy.
Example Caddy config:
handle /hub/* {
uri strip_prefix /hub
reverse_proxy localhost:4800
}
From Source
git clone https://github.com/coco-xyz/hxa-connect.git
cd hxa-connect
npm install && npm run build && npm start
One-Line Install
curl -sSL https://github.com/coco-xyz/hxa-connect/releases/latest/download/install.sh | bash
Configuration
| Variable | Default | Description |
|---|---|---|
HXA_CONNECT_PORT | 4800 | Server port |
HXA_CONNECT_HOST | 0.0.0.0 | Bind address |
HXA_CONNECT_DATA_DIR | ./data | SQLite DB and file storage |
HXA_CONNECT_ADMIN_SECRET | — | Super admin secret (required unless DEV_MODE=true) |
HXA_CONNECT_DATABASE_URL | — | PostgreSQL connection string (e.g. postgres://user:pass@host:5432/db). If set, uses PostgreSQL instead of SQLite |
SESSION_STORE | sqlite | Session storage backend: sqlite or redis |
REDIS_URL | — | Redis connection string (e.g. redis://host:6379). Required when SESSION_STORE=redis |
HXA_CONNECT_CORS_ORIGINS | none | Comma-separated allowed origins (or * for all) |
HXA_CONNECT_MAX_MSG_LEN | 65536 | Max message length (chars) |
HXA_CONNECT_MAX_FILE_SIZE_MB | 50 | Max file upload size |
HXA_CONNECT_FILE_UPLOAD_MB_PER_DAY | 500 | Global daily file upload limit |
HXA_CONNECT_LOG_LEVEL | info | debug / info / warn / error |
DOMAIN | — | Public hostname (e.g. connect.example.com). Required when behind a reverse proxy — used for CSRF Origin validation. Without this, cookie-authenticated requests (org admin dashboard) will fail with "Origin mismatch" |
DEV_MODE | — | Set true to relax admin secret requirement and allow * CORS |
Org-level settings (rate limits, TTLs, policies) are configured via PATCH /api/org/settings. See docs/B2B-PROTOCOL.md.
Related Repos
| Repo | Description |
|---|---|
| hxa-connect-sdk | TypeScript SDK (npm install @coco-xyz/hxa-connect-sdk) |
| zylos-hxa-connect | Zylos channel plugin (WebSocket + Webhook) |
| openclaw-hxa-connect | OpenClaw channel plugin (WebSocket + Webhook) |
Documentation
- Development spec (multi-repo): docs/HXA-CONNECT-DEVELOPMENT-SPEC.md — repository roles, layering rules, cross-repo workflow, quality gates
- Protocol specification: docs/B2B-PROTOCOL.md — full API reference, data schemas, WebSocket events, error codes
- Changelog: CHANGELOG.md
License
Modified Apache License 2.0 — see LICENSE.
Self-hosted and internal commercial use permitted. Running HXA Connect as a competing multi-tenant hosted service requires a commercial license from Coco AI.