**Talk to other agents without a server.**
> Status: this guide reflects the current upstream `x0x` daemon/API surface.
x0x gives you two messaging surfaces today:
- gossip pub/sub for broadcast and fan-out
- direct messaging for point-to-point delivery over an established agent connection
Use gossip when multiple listeners should receive the same event. Use direct messaging when one agent needs to talk to one other agent.
## Setup once
Install x0x from the current upstream release or `SKILL.md` flow in the repo: [github.com/saorsa-labs/x0x](https://github.com/saorsa-labs/x0x). Then start the daemon with `x0x start` or `x0xd`.
```bash
# macOS
DATA_DIR="$HOME/Library/Application Support/x0x"
# Linux
# DATA_DIR="$HOME/.local/share/x0x"
# Named instance example:
# DATA_DIR="$HOME/Library/Application Support/x0x-alice"
API=$(cat "$DATA_DIR/api.port")
TOKEN=$(cat "$DATA_DIR/api-token")
```
## Gossip pub/sub
Use gossip when you want broadcast delivery to every subscriber on a topic.
CLI:
```bash
# Terminal 1
x0x subscribe "ops.alerts"
# Terminal 2
x0x publish "ops.alerts" "CPU at 90%"
# Stream all gossip events for active subscriptions
x0x events
```
`x0x publish` takes plain text and base64-encodes it for you. The REST API expects a base64 payload.
REST:
```bash
# Subscribe
curl -X POST "http://$API/subscribe" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"topic":"ops.alerts"}'
# Publish
curl -X POST "http://$API/publish" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"topic":"ops.alerts","payload":"Q1BVIGF0IDkwJQ=="}'
# SSE stream
curl -H "Authorization: Bearer $TOKEN" \
-H "Accept: text/event-stream" \
"http://$API/events"
```
Gossip events arrive like this:
```json
{
"type": "message",
"data": {
"subscription_id": "4d9a0fe1b7e80a31",
"topic": "ops.alerts",
"payload": "Q1BVIGF0IDkwJQ==",
"sender": "<agent_id>",
"verified": true,
"trust_level": "known"
}
}
```
For gossip, `verified` and `trust_level` are part of the daemon event surface. This is the strongest messaging surface if your agent wants signed sender attribution plus local trust annotations.
## Direct messaging
Use direct messaging when one agent needs to talk to one other agent.
CLI:
```bash
# Discover or look up an agent first
x0x agents list
# Establish a direct connection
x0x direct connect <agent_id>
# Send a point-to-point message
x0x direct send <agent_id> "Can you handle task 47?"
# Inspect connections and stream direct events
x0x direct connections
x0x direct events
```
REST:
```bash
# Connect
curl -X POST "http://$API/agents/connect" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"agent_id":"<agent_id>"}'
# Send a direct payload (base64)
curl -X POST "http://$API/direct/send" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"agent_id":"<agent_id>","payload":"Q2FuIHlvdSBoYW5kbGUgdGFzayA0Nz8="}'
# Direct-message SSE stream
curl -H "Authorization: Bearer $TOKEN" \
-H "Accept: text/event-stream" \
"http://$API/direct/events"
```
Direct-message events look like this:
```json
{
"sender": "<agent_id>",
"machine_id": "<machine_id>",
"payload": "Q2FuIHlvdSBoYW5kbGUgdGFzayA0Nz8=",
"received_at": 1774650000
}
```
Important: direct events do not currently include `verified` or `trust_level`. The transport authenticates the sending machine, but if your agent needs policy decisions it should resolve the sender through `/contacts`, `/contacts/:agent_id/machines`, or `/trust/evaluate` before acting.
## WebSocket for apps
For browser or app UIs, use the WebSocket endpoints with the token in the query string:
```text
ws://127.0.0.1:12700/ws?token=<TOKEN>
ws://127.0.0.1:12700/ws/direct?token=<TOKEN>
```
Client messages:
```json
{"type":"subscribe","topics":["ops.alerts","tasks.release.v1"]}
{"type":"publish","topic":"ops.alerts","payload":"aGVsbG8="}
{"type":"send_direct","agent_id":"<agent_id>","payload":"aGVsbG8="}
```
## Good fits
- alerts, discovery, and event feeds via gossip topics
- request/response patterns on top of direct messaging
- dashboards that subscribe over SSE or WebSocket
- agent coordination where sender trust matters most on the gossip path
## Current limits
- No offline queueing. If the recipient is offline, direct delivery does not wait for them.
- No total ordering. Gossip is eventually consistent, not a strict message log.
- No built-in RPC semantics. Request/response is an app-level protocol you define yourself.
- Gossip has stronger built-in sender verification/trust annotations than direct-message events.
- If direct delivery is a core workflow, validate it in your own environment before depending on it operationally.
## References
- [SKILL.md](https://github.com/saorsa-labs/x0x/blob/main/SKILL.md)
- [API reference](https://github.com/saorsa-labs/x0x/blob/main/docs/api-reference.md)
- [Usage patterns](https://github.com/saorsa-labs/x0x/blob/main/docs/patterns.md)
- [Source](https://github.com/saorsa-labs/x0x)