Integrations
Overview
The integrations module provides a generic configuration framework for platform-specific integrations (e.g., OBS, Discord bots). Each integration is scoped to an account with a platform identifier, a human-readable label, an enable/disable toggle, and a flexible JSONB config field for platform-specific settings.
The generic integration surface exposes read, update and toggle only — it has no create or delete operation. Rows in integration_configs are written by the feature that owns the integration: system connections (db::system_connections), the Kick worker, and the OBS integration all insert and delete their own row. OBS additionally has its own dedicated REST and GraphQL surface with full create/delete semantics; see OBS.
Architecture
Dashboard UI
|
v
Next.js API Proxy (/api/integrations)
|
v
GraphQL (IntegrationQuery / IntegrationMutation)
|
v
db::integrations (PostgreSQL)
The config JSONB field stores platform-specific configuration. For example, an OBS integration might store WebSocket connection details, scene mappings, or source configurations. The API layer is agnostic to the config structure -- validation is handled by the consuming service.
API
GraphQL Queries
All four operations are gated by FeatureGuard::new("feature:integrations").and(PermissionGuard::new(<permission>)), so an account whose plan lacks feature:integrations gets FEATURE_DISABLED before the permission is even considered.
| Query | Args | Returns | Feature | Permission |
|---|---|---|---|---|
integrations | -- | [Integration!]! | feature:integrations | settings:read |
integration | id: UUID! | Integration | feature:integrations | settings:read |
integrationsreturns all configs for the active account, ordered by platform.integrationreturns a single config by ID, filtered by account ownership.
GraphQL Mutations
| Mutation | Args | Returns | Feature | Permission |
|---|---|---|---|---|
updateIntegration | input: UpdateIntegrationInput! | Integration! | feature:integrations | settings:edit |
toggleIntegration | id: UUID! | Integration! | feature:integrations | settings:edit |
updateIntegrationsupports partial updates viaCOALESCE-- only provided fields are changed.toggleIntegrationflips theenabledboolean without requiring the caller to know the current state.
Both mutations verify account ownership before proceeding.
REST Endpoints
The generic integration surface is GraphQL-only — there is no /v1/integrations
REST resource for listing, updating or toggling an arbitrary integration. The
paths that do exist under /v1/integrations/ all belong to the OBS integration
and are documented in OBS:
| Method | Path |
|---|---|
GET / PUT / DELETE | /v1/integrations/obs |
GET | /v1/integrations/obs/credentials |
GET | /v1/integrations/obs/status |
POST | /v1/integrations/obs/test |
The web dashboard reaches the generic surface through its Next.js proxy routes
(/api/integrations, /api/integrations/[id]), which execute the GraphQL
operations server-side.
WebSocket
There is no integration channel. channel_gate_for in
crates/lo-websocket/src/gate.rs maps no integrations channel type, so a
subscription attempt is rejected as Unknown. Integrations that stream data do
so on their own channels — OBS through its status polling, Discord through
events:{account_id}.
GraphQL Types
type Integration {
id: UUID!
accountId: UUID!
platform: String!
label: String!
enabled: Boolean!
config: JSON!
createdAt: String!
updatedAt: String!
}
input UpdateIntegrationInput {
id: UUID!
label: String
enabled: Boolean
config: JSON
}
Permissions
| Permission | Description |
|---|---|
settings:read | View integration configurations |
settings:edit | Update integration configurations |
Integrations share the settings:* permission namespace. Included in: Owner, Administrator roles.
Beyond the permission, every operation requires the feature:integrations flag on the account's plan.
Database
Table: integration_configs
| Column | Type | Description |
|---|---|---|
id | UUID (PK) | Integration config ID |
account_id | UUID (FK) | Owning account |
platform | TEXT | Platform identifier (e.g., obs, discord) |
label | TEXT | Human-readable label |
enabled | BOOLEAN | Whether the integration is active |
config | JSONB | Platform-specific configuration |
created_at | TIMESTAMPTZ | Creation timestamp |
updated_at | TIMESTAMPTZ | Last update timestamp |
DB Functions
| Function | Description |
|---|---|
list_integrations | List all configs for an account, ordered by platform ASC |
get_integration | Get a single config by ID |
update_integration | Partial update using COALESCE for label, enabled, config |
toggle_integration | Flip enabled to NOT enabled |
Key Files
| File | Purpose |
|---|---|
apps/api/src/graphql/integrations.rs | GraphQL queries, mutations, input/output types |
apps/api/src/db/integrations.rs | Database CRUD operations |
crates/lo-auth/src/rbac.rs | Permission constants (settings:read, settings:edit) |