Protocol — open-wire / 1
Every message between Open-Wire and an agent is a JSON envelope with protocol: "open-wire/1".
Inbound (channel → agent)
When Slack delivers an event, Open-Wire POSTs this to the installation webhook_url:
{
"protocol": "open-wire/1",
"type": "message.inbound",
"id": "msg_…",
"channel": "slack",
"installation_id": "inst_…",
"thread": { "id": "C123:1710000000.000100" },
"from": { "id": "U123", "kind": "user" },
"to": { "id": "C123", "kind": "channel" },
"body": { "text": "hello" },
"created_at": "2026-07-30T00:00:00.000Z"
}Headers: X-Open-Wire-Protocol, X-Open-Wire-Installation, optional X-Open-Wire-Secret.
Outbound (agent → channel)
Agents (or Rails Agent Cloud) call POST /api/v1/messages:
{
"protocol": "open-wire/1",
"type": "message.send",
"installation_id": "inst_…",
"to": { "id": "C123", "kind": "channel" },
"thread": { "id": "C123:1710000000.000100" },
"body": { "text": "hi from the agent", "blocks": null }
}Identity fields
installation_id— which workspace / grant to usethread.id— provider thread key (Slack:channel:ts)channel— adapter name (slack, …)
Rails Agent reverse path
Rails Agent depends on the open-wire Ruby gem (path-sourced until RubyGems publish). Inbound webhooks hit the existing engine — no second mount:
POST /agents/open_wire/inbound/:agent_slug Headers: X-Open-Wire-Secret, X-Open-Wire-Protocol, X-Open-Wire-Installation
Cloud Connect uses /api/v1/agents/:id/open-wire/inbound which verifies the secret, starts/resumes an agent run, and replies on the same thread.