Architecture Overview#
Outeract is designed as a unified messaging infrastructure that abstracts the complexity of multiple messaging platforms into a single, consistent API.
System Architecture#
flowchart TB
subgraph App["Your Application"]
Send[Send Messages]
Query[Query Events]
Receive[Receive Webhooks]
end
subgraph Outeract["Outeract API"]
subgraph Gateway["API Gateway"]
Admin[Admin API<br/>JWT Auth]
Dev[Developer API<br/>API Key]
Router[Webhook Router]
end
subgraph Services["Service Layer"]
MsgSvc[Message Service]
EvtSvc[Event Service]
WebSvc[Webhook Service]
end
subgraph Adapters["Platform Adapters"]
WA[WhatsApp]
IG[Instagram]
TG[Telegram]
SL[Slack]
DC[Discord]
SMS[SMS/Email]
end
subgraph Data["Data Layer"]
DB[(PostgreSQL)]
Events[(Event Store)]
Files[(File Storage)]
end
end
subgraph Platforms["External Platform APIs"]
WAApi[WhatsApp Cloud API]
TGApi[Telegram Bot API]
SLApi[Slack Web API]
end
Send --> Dev
Query --> Dev
Receive --> Router
Gateway --> Services
Services --> Adapters
Adapters --> Data
WA --> WAApi
TG --> TGApi
SL --> SLApiAPI Layer#
Outeract exposes two primary APIs:
Admin API (/admin)#
- Authentication: JWT tokens
- Purpose: Organization management, application configuration, admin operations
- Users: Dashboard, admin applications
# Admin API Query Example
query {
organisation {
id
name
applications {
id
name
platformConnections {
id
platformName
status
}
}
}
}Developer API (/ and /v1)#
- Authentication: API keys with scopes
- Purpose: Message operations, event queries, user management
- Users: Your application backend
# Developer API Query Example
query {
events(
filters: { eventType: { contains: "message" } }
first: 10
) {
edges {
node {
id
eventType
payload
createdAt
}
}
}
}Webhook Architecture#
Outeract uses two webhook patterns depending on the platform:
Shared Webhooks#
Platforms: WhatsApp, Instagram, Facebook Messenger
Multiple platform connections share a single webhook URL. The platform sends all events to one endpoint, and Outeract routes them to the correct connection.
flowchart LR
Meta[Meta Platform] --> Webhook[Shared Webhook]
Webhook --> Router[Route by Account ID]
Router --> WA1[WhatsApp Connection 1<br/>Business Account A]
Router --> WA2[WhatsApp Connection 2<br/>Business Account B]
Router --> IG1[Instagram Connection 1<br/>Page C]Benefits:
- Single webhook URL to configure
- Automatic routing based on payload
- Simplified Meta app setup
Dedicated Webhooks#
Platforms: Telegram, Slack, Discord, SMS, Email
Each platform connection has its own unique webhook URL.
flowchart LR
TG[Telegram] --> TGW["/webhooks/{id}/{secret}"] --> TGC[Telegram Connection 1]
SL[Slack] --> SLW["/webhooks/{id}/{secret}"] --> SLC[Slack Connection 1]
DC[Discord] --> DCW["/webhooks/{id}/{secret}"] --> DCC[Discord Connection 1]Benefits:
- Direct routing (no payload inspection)
- Connection-specific secrets
- Independent configuration
Event Processing Pipeline#
flowchart TB
Msg[Inbound Message] --> WH[Webhook Handler]
WH -- Signature Verification --> PA[Platform Adapter]
PA -- Parse platform-specific payload --> EC[Event Creation]
EC -- Create Event + Edges --> DB[(Database)]
EC --> PS[Pub/Sub Topic]
PS --> Your[Your Webhook Subscription]Multi-Tenancy Model#
Outeract implements strict multi-tenancy at the application level:
flowchart TB
Org[Organisation - Tenant]
Org --> App1[Application 1 - Production]
Org --> App2[Application 2 - Staging]
App1 --> U1[Users - isolated]
App1 --> E1[Events - isolated]
App1 --> PC1[Platform Connections - isolated]
App1 --> K1[API Keys - scoped to this app]
App2 --> U2[Users - isolated]
App2 --> E2[Events - isolated]
App2 --> PC2[Platform Connections - isolated]
App2 --> K2[API Keys - scoped to this app]Isolation guarantees:
- All queries are automatically scoped to the application
- Cross-application data access is impossible
- API keys are bound to specific applications
- Webhooks include application context
Platform Adapters#
Each platform has a dedicated adapter that handles:
| Responsibility | Description |
|---|---|
| Authentication | OAuth flows, token refresh, API keys |
| Message Formatting | Convert to/from platform-specific formats |
| Webhook Processing | Parse inbound payloads, extract messages |
| Error Handling | Translate platform errors to Outeract errors |
| Health Checks | Verify credentials and connectivity |
| Rate Limiting | Platform-specific rate limit handling |
Adapter Interface#
class PlatformAdapter:
async def send_message(message: ExternalMessage) -> SendMessageResult
async def process_webhook(payload: dict) -> List[ExternalMessage]
async def verify_webhook(request: Request) -> Response
async def get_health() -> PlatformConnectionHealth
def validate_signature(request: Request, body: bytes, secret: str) -> boolData Model#
Outeract uses a graph-based data model:
flowchart TB
PU1[Platform User<br/>Sender] -- sent_by --> Event[Event<br/>Message]
Event -- sent_to --> PU2[Platform User<br/>Recipient]
PU1 -- belongs_to --> User[User<br/>Identity]
PU2 -- platform_user --> User
PU2 -- belongs_to --> PC[Platform Connection]Scalability#
Outeract is designed to scale horizontally:
| Component | Scaling Strategy |
|---|---|
| API Servers | Stateless, load balanced |
| Database | PostgreSQL with read replicas |
| Event Processing | Pub/Sub for async processing |
| File Storage | Google Cloud Storage |
| Webhook Delivery | Queue-based with retries |
Security#
Security is built into every layer:
- Transport: TLS 1.3 for all connections
- Authentication: API keys, JWT, OAuth 2.0
- Authorization: Scope-based access control
- Webhooks: HMAC-SHA256 signature verification
- Data: Encryption at rest, tenant isolation
- Secrets: Encrypted credential storage