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
    App["Your Application<br/>Send messages · Query events · Receive webhooks"]
    Gateway["API Gateway<br/>Developer API (key) · Console API · Webhook Router"]
    Services["Service Layer<br/>Message · Event · Webhook services"]
    Adapters["Platform Adapters<br/>WhatsApp · Telegram · Slack · + 7 more"]
    Data["Data Layer<br/>PostgreSQL · Event Store · File Storage"]
    Ext["External Platform APIs<br/>WhatsApp Cloud · Telegram Bot · Slack Web"]

    App --> Gateway
    Gateway --> Services
    Services --> Adapters
    Adapters --> Data
    Adapters --> Ext

API Layer#

Developer API (/)#

  • Authentication: API keys with scopes
  • Purpose: Message operations, event queries, user management
  • Users: Your application backend

This is the API you integrate against. A second, internal GraphQL schema backs the console. It handles account-level operations such as organisations, applications, platform connections, API keys and webhook subscriptions, and authenticates console sessions rather than API keys. It isn’t a public integration surface; anything it manages is configured through the console.

# Developer API Query Example
query {
  events(
    eventTypes: ["message.inbound", "message.outbound"]
    first: 10
  ) {
    edges {
      node {
        id
        eventTypeName
        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:

ResponsibilityDescription
AuthenticationOAuth flows, token refresh, API keys
Message FormattingConvert to/from platform-specific formats
Webhook ProcessingParse inbound payloads, extract messages
Error HandlingTranslate platform errors to Outeract errors
Health ChecksVerify credentials and connectivity
Rate LimitingPlatform-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) -> bool

Data 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 -- identity --> User
    PU2 -- belongs_to --> PC[Platform Connection]

Scalability#

Outeract is designed to scale horizontally:

ComponentScaling Strategy
API ServersStateless, load balanced
DatabasePostgreSQL with read replicas
Event ProcessingPub/Sub for async processing
File StorageGoogle Cloud Storage
Webhook DeliveryQueue-based with retries

Security#

Security is built into every layer:

  • Transport: TLS 1.3 for all connections
  • Authentication: API keys, console sessions, OAuth 2.0
  • Authorization: Scope-based access control
  • Webhooks: HMAC-SHA256 signature verification
  • Data: Encryption at rest, tenant isolation
  • Secrets: Encrypted credential storage