A channel adapter is the bridge between an external messaging platform and Curia’s internal message bus. Every channel — CLI, HTTP, Email, Signal — follows the same pattern: receive platform messages, normalize them into bus events, and deliver outbound responses back through the platform API.Documentation Index
Fetch the complete documentation index at: https://docs.meetcuria.com/llms.txt
Use this file to discover all available pages before exploring further.
The channel adapter pattern
Every channel adapter:- Registers with the bus as
layer: "channel"— this limits it to publishing onlyinbound.messageandinbound.eventtypes (the hard security boundary) - Subscribes to
outbound.messageevents — to deliver responses back through the platform - Normalizes inbound messages into the standard
inbound.messageevent payload - Declares a trust level — high, medium, or low — based on the identity guarantees of the platform
Implementation steps
Create the adapter directory
Create a new directory under
src/channels/<name>/ with an adapter file:Register with the bus
Register your adapter as a channel-layer module. The bus will enforce that you can only publish channel-allowed event types.
Handle inbound messages
When your platform delivers a message, normalize it into an The
inbound.message event and publish it on the bus:channelTrust field declares your channel’s trust level. Choose based on the identity guarantees your platform provides:| Trust level | When to use |
|---|---|
high | Strong identity verification (local access, E2E encryption with phone verification) |
medium | Token-based or OAuth authentication |
low | Weak identity guarantees (email addresses can be spoofed) |
Handle outbound messages
Subscribe to Filter by channel name so you only handle messages destined for your channel.
outbound.message events and deliver them through your platform’s API:Add configuration
Add a config section to
config/default.yaml for any channel-specific settings (API keys, polling intervals, etc.). Use env:VAR_NAME references for secrets.What the dispatch layer handles for you
You don’t need to implement any of these in your adapter — they’re handled by the dispatch layer after yourinbound.message is published:
- Contact resolution — the dispatcher resolves the sender to a contact record
- Trust scoring — your
channelTrustvalue is combined with contact confidence and injection risk - Rate limiting — global and per-sender limits are enforced
- Prompt injection scanning — inbound text is checked against detection patterns
- PII redaction — outbound messages are redacted based on channel-specific policies
Testing
Write tests for your adapter covering:- Inbound message normalization (platform format → bus event)
- Outbound message delivery (bus event → platform API call)
- Authentication and connection handling
- Error recovery (platform API failures, connection drops)
How channels work
Channel routing, trust levels, and the dispatch pipeline in detail.
Architecture
How channel adapters fit into the five-layer bus architecture.