Platform Integrations
Platform Integrations connect external services like Discord, Slack, and Microsoft Teams to LVNG workspaces. All endpoints enforce multi-tenant isolation -- integrations are scoped to the customer's workspaces via customer_id verification. Sensitive configuration data (tokens, webhook secrets) is masked in responses. Supported platforms are registered dynamically via the PlatformRegistry.
/api/v2/platform-integrations|Auth: JWT|Tenant isolation: customer_id / workspace ownershipList Integrations
/api/v2/platform-integrationsAuthenticatedReturns all platform integrations across all workspaces owned by the authenticated customer. Sensitive fields (config, webhook_secret) are masked -- config shows {configured: true|false} and webhook_secret shows '***' or null.
Request
400">curl -X 400">GET https:400">class="text-zinc-500">//api.lvng.ai/api/v2/platform-integrations \
-H 400">class="text-emerald-400">"Authorization: Bearer YOUR_API_KEY"Response 200
{
400">class="text-emerald-400">"integrations": [
{
400">class="text-emerald-400">"id": 400">class="text-emerald-400">"a1b2c3d4-e5f6-7890-abcd-ef1234567890",
400">class="text-emerald-400">"workspace_id": 400">class="text-emerald-400">"d4e5f6a7-b8c9-0d1e-2f3a-4b5c6d7e8f90",
400">class="text-emerald-400">"platform": 400">class="text-emerald-400">"discord",
400">class="text-emerald-400">"config": { 400">class="text-emerald-400">"configured": true },
400">class="text-emerald-400">"webhook_secret": 400">class="text-emerald-400">"***",
400">class="text-emerald-400">"enabled": true,
400">class="text-emerald-400">"connected": true,
400">class="text-emerald-400">"last_connected_at": 400">class="text-emerald-400">"2026-03-19T09:00:00.000Z",
400">class="text-emerald-400">"connection_error": null,
400">class="text-emerald-400">"api_key": null,
400">class="text-emerald-400">"api_key_created_at": null,
400">class="text-emerald-400">"created_at": 400">class="text-emerald-400">"2026-01-20T08:00:00.000Z",
400">class="text-emerald-400">"updated_at": 400">class="text-emerald-400">"2026-03-19T09:00:00.000Z"
},
{
400">class="text-emerald-400">"id": 400">class="text-emerald-400">"b2c3d4e5-f6a7-8901-bcde-f12345678901",
400">class="text-emerald-400">"workspace_id": 400">class="text-emerald-400">"d4e5f6a7-b8c9-0d1e-2f3a-4b5c6d7e8f90",
400">class="text-emerald-400">"platform": 400">class="text-emerald-400">"slack",
400">class="text-emerald-400">"config": { 400">class="text-emerald-400">"configured": true },
400">class="text-emerald-400">"webhook_secret": 400">class="text-emerald-400">"***",
400">class="text-emerald-400">"enabled": true,
400">class="text-emerald-400">"connected": true,
400">class="text-emerald-400">"last_connected_at": 400">class="text-emerald-400">"2026-03-18T22:00:00.000Z",
400">class="text-emerald-400">"connection_error": null,
400">class="text-emerald-400">"api_key": null,
400">class="text-emerald-400">"api_key_created_at": null,
400">class="text-emerald-400">"created_at": 400">class="text-emerald-400">"2026-02-10T14:30:00.000Z",
400">class="text-emerald-400">"updated_at": 400">class="text-emerald-400">"2026-03-18T22:00:00.000Z"
}
]
}Get Integration
/api/v2/platform-integrations/:idAuthenticatedReturns a single platform integration. Config and webhook_secret are masked. Returns 404 if the integration does not exist or does not belong to a workspace owned by the customer.
Path Parameters
idstring (UUID)requiredThe unique identifier of the integration.
Request
400">curl -X 400">GET https:400">class="text-zinc-500">//api.lvng.ai/api/v2/platform-integrations/a1b2c3d4-e5f6-7890-abcd-ef1234567890 \
-H 400">class="text-emerald-400">"Authorization: Bearer YOUR_API_KEY"Response 200
{
400">class="text-emerald-400">"integration": {
400">class="text-emerald-400">"id": 400">class="text-emerald-400">"a1b2c3d4-e5f6-7890-abcd-ef1234567890",
400">class="text-emerald-400">"workspace_id": 400">class="text-emerald-400">"d4e5f6a7-b8c9-0d1e-2f3a-4b5c6d7e8f90",
400">class="text-emerald-400">"platform": 400">class="text-emerald-400">"discord",
400">class="text-emerald-400">"config": { 400">class="text-emerald-400">"configured": true },
400">class="text-emerald-400">"webhook_secret": 400">class="text-emerald-400">"***",
400">class="text-emerald-400">"enabled": true,
400">class="text-emerald-400">"connected": true,
400">class="text-emerald-400">"last_connected_at": 400">class="text-emerald-400">"2026-03-19T09:00:00.000Z",
400">class="text-emerald-400">"connection_error": null,
400">class="text-emerald-400">"api_key": null,
400">class="text-emerald-400">"api_key_created_at": null,
400">class="text-emerald-400">"created_at": 400">class="text-emerald-400">"2026-01-20T08:00:00.000Z",
400">class="text-emerald-400">"updated_at": 400">class="text-emerald-400">"2026-03-19T09:00:00.000Z"
}
}Create Integration
/api/v2/platform-integrationsAuthenticatedCreates a new platform integration for a workspace. The workspace must belong to the authenticated customer. A webhook_secret is auto-generated. Returns 409 if the workspace already has an integration for that platform. Valid platforms are registered dynamically via PlatformRegistry.
Body Parameters
workspace_idstring (UUID)requiredThe workspace to attach this integration to. Must be owned by the authenticated customer.
platformstringrequiredPlatform identifier (e.g., discord, slack, teams). Validated against PlatformRegistry.
configobjectPlatform-specific configuration object (tokens, server IDs, etc.).
enabledbooleantrueWhether the integration is active.
Request
400">curl -X 400">POST https:400">class="text-zinc-500">//api.lvng.ai/api/v2/platform-integrations \
-H 400">class="text-emerald-400">"Authorization: Bearer YOUR_API_KEY" \
-H 400">class="text-emerald-400">"Content-Type: application/json" \
-d '{
400">class="text-emerald-400">"workspace_id": 400">class="text-emerald-400">"d4e5f6a7-b8c9-0d1e-2f3a-4b5c6d7e8f90",
400">class="text-emerald-400">"platform": 400">class="text-emerald-400">"slack",
400">class="text-emerald-400">"config": {
400">class="text-emerald-400">"bot_token": 400">class="text-emerald-400">"xoxb-xxxxxxxxxxxx-xxxxxxxxxxxx",
400">class="text-emerald-400">"team_id": 400">class="text-emerald-400">"T0123456789"
},
400">class="text-emerald-400">"enabled": true
}'Response 201
{
400">class="text-emerald-400">"integration": {
400">class="text-emerald-400">"id": 400">class="text-emerald-400">"c3d4e5f6-a7b8-9012-cdef-123456789012",
400">class="text-emerald-400">"workspace_id": 400">class="text-emerald-400">"d4e5f6a7-b8c9-0d1e-2f3a-4b5c6d7e8f90",
400">class="text-emerald-400">"platform": 400">class="text-emerald-400">"slack",
400">class="text-emerald-400">"config": { 400">class="text-emerald-400">"configured": true },
400">class="text-emerald-400">"webhook_secret": null,
400">class="text-emerald-400">"enabled": true,
400">class="text-emerald-400">"connected": null,
400">class="text-emerald-400">"last_connected_at": null,
400">class="text-emerald-400">"connection_error": null,
400">class="text-emerald-400">"api_key": null,
400">class="text-emerald-400">"api_key_created_at": null,
400">class="text-emerald-400">"created_at": 400">class="text-emerald-400">"2026-03-19T10:00:00.000Z",
400">class="text-emerald-400">"updated_at": 400">class="text-emerald-400">"2026-03-19T10:00:00.000Z"
}
}Update Integration
/api/v2/platform-integrations/:idAuthenticatedUpdates an integration's config or enabled status. If config is changed, the cached integration instance is cleared so the next operation uses the new configuration.
Path Parameters
idstring (UUID)requiredThe unique identifier of the integration.
Body Parameters
configobjectUpdated platform-specific configuration. Clears the cached instance when changed.
enabledbooleanEnable or disable the integration.
Request
400">curl -X 400">PATCH https:400">class="text-zinc-500">//api.lvng.ai/api/v2/platform-integrations/c3d4e5f6-a7b8-9012-cdef-123456789012 \
-H 400">class="text-emerald-400">"Authorization: Bearer YOUR_API_KEY" \
-H 400">class="text-emerald-400">"Content-Type: application/json" \
-d '{
400">class="text-emerald-400">"enabled": false
}'Response 200
{
400">class="text-emerald-400">"integration": {
400">class="text-emerald-400">"id": 400">class="text-emerald-400">"c3d4e5f6-a7b8-9012-cdef-123456789012",
400">class="text-emerald-400">"workspace_id": 400">class="text-emerald-400">"d4e5f6a7-b8c9-0d1e-2f3a-4b5c6d7e8f90",
400">class="text-emerald-400">"platform": 400">class="text-emerald-400">"slack",
400">class="text-emerald-400">"config": { 400">class="text-emerald-400">"configured": true },
400">class="text-emerald-400">"enabled": false,
400">class="text-emerald-400">"connected": null,
400">class="text-emerald-400">"created_at": 400">class="text-emerald-400">"2026-03-19T10:00:00.000Z",
400">class="text-emerald-400">"updated_at": 400">class="text-emerald-400">"2026-03-19T10:20:00.000Z"
}
}Delete Integration
/api/v2/platform-integrations/:idAuthenticatedPermanently deletes a platform integration and disconnects any active instance. The cached integration instance is removed. Returns 404 if the integration does not belong to the customer's workspaces.
Path Parameters
idstring (UUID)requiredThe unique identifier of the integration to delete.
Request
400">curl -X 400">DELETE https:400">class="text-zinc-500">//api.lvng.ai/api/v2/platform-integrations/c3d4e5f6-a7b8-9012-cdef-123456789012 \
-H 400">class="text-emerald-400">"Authorization: Bearer YOUR_API_KEY"Response 200
{
400">class="text-emerald-400">"success": true
}Test Connection
/api/v2/platform-integrations/:id/testAuthenticatedTests the connection to the external platform using the stored configuration. On success, updates the connected field to true and sets last_connected_at. On failure, stores the error message in connection_error.
Path Parameters
idstring (UUID)requiredThe unique identifier of the integration to test.
Request
400">curl -X 400">POST https:400">class="text-zinc-500">//api.lvng.ai/api/v2/platform-integrations/a1b2c3d4-e5f6-7890-abcd-ef1234567890/test \
-H 400">class="text-emerald-400">"Authorization: Bearer YOUR_API_KEY"Response 200
{
400">class="text-emerald-400">"success": true
}Sync Channels
/api/v2/platform-integrations/:id/sync-channelsAuthenticatedFetches all channels from the external platform and upserts them into the platform_channels table. Uses the integration instance's fetchChannels method. Existing channels are updated via upsert on integration_id + platform_channel_id.
Path Parameters
idstring (UUID)requiredThe unique identifier of the integration.
Request
400">curl -X 400">POST https:400">class="text-zinc-500">//api.lvng.ai/api/v2/platform-integrations/a1b2c3d4-e5f6-7890-abcd-ef1234567890/sync-channels \
-H 400">class="text-emerald-400">"Authorization: Bearer YOUR_API_KEY"Response 200
{
400">class="text-emerald-400">"success": true,
400">class="text-emerald-400">"channelCount": 5,
400">class="text-emerald-400">"channels": [
{
400">class="text-emerald-400">"id": 400">class="text-emerald-400">"1234567890123456789",
400">class="text-emerald-400">"name": 400">class="text-emerald-400">"general",
400">class="text-emerald-400">"400">type": 400">class="text-emerald-400">"text",
400">class="text-emerald-400">"topic": 400">class="text-emerald-400">"General discussion",
400">class="text-emerald-400">"serverId": 400">class="text-emerald-400">"9876543210987654321"
},
{
400">class="text-emerald-400">"id": 400">class="text-emerald-400">"2345678901234567890",
400">class="text-emerald-400">"name": 400">class="text-emerald-400">"engineering",
400">class="text-emerald-400">"400">type": 400">class="text-emerald-400">"text",
400">class="text-emerald-400">"topic": 400">class="text-emerald-400">"Engineering team discussions",
400">class="text-emerald-400">"serverId": 400">class="text-emerald-400">"9876543210987654321"
},
{
400">class="text-emerald-400">"id": 400">class="text-emerald-400">"3456789012345678901",
400">class="text-emerald-400">"name": 400">class="text-emerald-400">"product",
400">class="text-emerald-400">"400">type": 400">class="text-emerald-400">"text",
400">class="text-emerald-400">"topic": 400">class="text-emerald-400">"Product roadmap and feedback",
400">class="text-emerald-400">"serverId": 400">class="text-emerald-400">"9876543210987654321"
},
{
400">class="text-emerald-400">"id": 400">class="text-emerald-400">"4567890123456789012",
400">class="text-emerald-400">"name": 400">class="text-emerald-400">"design",
400">class="text-emerald-400">"400">type": 400">class="text-emerald-400">"text",
400">class="text-emerald-400">"topic": null,
400">class="text-emerald-400">"serverId": 400">class="text-emerald-400">"9876543210987654321"
},
{
400">class="text-emerald-400">"id": 400">class="text-emerald-400">"5678901234567890123",
400">class="text-emerald-400">"name": 400">class="text-emerald-400">"support",
400">class="text-emerald-400">"400">type": 400">class="text-emerald-400">"text",
400">class="text-emerald-400">"topic": 400">class="text-emerald-400">"Customer support escalations",
400">class="text-emerald-400">"serverId": 400">class="text-emerald-400">"9876543210987654321"
}
]
}List Synced Channels
/api/v2/platform-integrations/:id/channelsAuthenticatedReturns all channels previously synced for an integration from the platform_channels table. Channels are ordered alphabetically by name.
Path Parameters
idstring (UUID)requiredThe unique identifier of the integration.
Request
400">curl -X 400">GET https:400">class="text-zinc-500">//api.lvng.ai/api/v2/platform-integrations/a1b2c3d4-e5f6-7890-abcd-ef1234567890/channels \
-H 400">class="text-emerald-400">"Authorization: Bearer YOUR_API_KEY"Response 200
{
400">class="text-emerald-400">"channels": [
{
400">class="text-emerald-400">"id": 400">class="text-emerald-400">"7b8c9d0e-1f2a-3b4c-5d6e-7f8a9b0c1d2e",
400">class="text-emerald-400">"integration_id": 400">class="text-emerald-400">"a1b2c3d4-e5f6-7890-abcd-ef1234567890",
400">class="text-emerald-400">"platform_channel_id": 400">class="text-emerald-400">"1234567890123456789",
400">class="text-emerald-400">"platform_server_id": 400">class="text-emerald-400">"9876543210987654321",
400">class="text-emerald-400">"channel_name": 400">class="text-emerald-400">"engineering",
400">class="text-emerald-400">"channel_type": 400">class="text-emerald-400">"text",
400">class="text-emerald-400">"channel_topic": 400">class="text-emerald-400">"Engineering team discussions",
400">class="text-emerald-400">"auto_sync_messages": false,
400">class="text-emerald-400">"sync_direction": null,
400">class="text-emerald-400">"lvng_conversation_id": null,
400">class="text-emerald-400">"created_at": 400">class="text-emerald-400">"2026-03-19T09:35:00.000Z",
400">class="text-emerald-400">"updated_at": 400">class="text-emerald-400">"2026-03-19T09:35:00.000Z"
},
{
400">class="text-emerald-400">"id": 400">class="text-emerald-400">"2c3d4e5f-6a7b-8c9d-0e1f-2a3b4c5d6e7f",
400">class="text-emerald-400">"integration_id": 400">class="text-emerald-400">"a1b2c3d4-e5f6-7890-abcd-ef1234567890",
400">class="text-emerald-400">"platform_channel_id": 400">class="text-emerald-400">"2345678901234567890",
400">class="text-emerald-400">"platform_server_id": 400">class="text-emerald-400">"9876543210987654321",
400">class="text-emerald-400">"channel_name": 400">class="text-emerald-400">"general",
400">class="text-emerald-400">"channel_type": 400">class="text-emerald-400">"text",
400">class="text-emerald-400">"channel_topic": 400">class="text-emerald-400">"General discussion",
400">class="text-emerald-400">"auto_sync_messages": true,
400">class="text-emerald-400">"sync_direction": 400">class="text-emerald-400">"both",
400">class="text-emerald-400">"lvng_conversation_id": 400">class="text-emerald-400">"e5f6a7b8-c9d0-1e2f-3a4b-5c6d7e8f9a0b",
400">class="text-emerald-400">"created_at": 400">class="text-emerald-400">"2026-03-19T09:35:00.000Z",
400">class="text-emerald-400">"updated_at": 400">class="text-emerald-400">"2026-03-19T10:00:00.000Z"
}
]
}Update Channel Settings
/api/v2/platform-integrations/channels/:channelIdAuthenticatedUpdates sync settings for a platform channel. Verifies that the channel's integration belongs to a workspace owned by the authenticated customer.
Path Parameters
channelIdstring (UUID)requiredThe LVNG platform_channels table ID (not the external channel ID).
Body Parameters
auto_sync_messagesbooleanEnable or disable automatic message syncing for this channel.
sync_directionstringSync direction: inbound, outbound, or both.
lvng_conversation_idstring (UUID)Map this external channel to an LVNG conversation.
Request
400">curl -X 400">PATCH https:400">class="text-zinc-500">//api.lvng.ai/api/v2/platform-integrations/channels/7b8c9d0e-1f2a-3b4c-5d6e-7f8a9b0c1d2e \
-H 400">class="text-emerald-400">"Authorization: Bearer YOUR_API_KEY" \
-H 400">class="text-emerald-400">"Content-Type: application/json" \
-d '{
400">class="text-emerald-400">"auto_sync_messages": true,
400">class="text-emerald-400">"sync_direction": 400">class="text-emerald-400">"both",
400">class="text-emerald-400">"lvng_conversation_id": 400">class="text-emerald-400">"e5f6a7b8-c9d0-1e2f-3a4b-5c6d7e8f9a0b"
}'Response 200
{
400">class="text-emerald-400">"channel": {
400">class="text-emerald-400">"id": 400">class="text-emerald-400">"7b8c9d0e-1f2a-3b4c-5d6e-7f8a9b0c1d2e",
400">class="text-emerald-400">"integration_id": 400">class="text-emerald-400">"a1b2c3d4-e5f6-7890-abcd-ef1234567890",
400">class="text-emerald-400">"platform_channel_id": 400">class="text-emerald-400">"1234567890123456789",
400">class="text-emerald-400">"platform_server_id": 400">class="text-emerald-400">"9876543210987654321",
400">class="text-emerald-400">"channel_name": 400">class="text-emerald-400">"engineering",
400">class="text-emerald-400">"channel_type": 400">class="text-emerald-400">"text",
400">class="text-emerald-400">"channel_topic": 400">class="text-emerald-400">"Engineering team discussions",
400">class="text-emerald-400">"auto_sync_messages": true,
400">class="text-emerald-400">"sync_direction": 400">class="text-emerald-400">"both",
400">class="text-emerald-400">"lvng_conversation_id": 400">class="text-emerald-400">"e5f6a7b8-c9d0-1e2f-3a4b-5c6d7e8f9a0b",
400">class="text-emerald-400">"created_at": 400">class="text-emerald-400">"2026-03-19T09:35:00.000Z",
400">class="text-emerald-400">"updated_at": 400">class="text-emerald-400">"2026-03-19T10:45:00.000Z"
}
}Generate API Key
/api/v2/platform-integrations/:id/api-keyAuthenticatedGenerates a new API key for an integration in the format lvng_plat_{random_hex}. The key is only returned once in this response -- it cannot be retrieved again. Any existing API key for this integration is overwritten.
Path Parameters
idstring (UUID)requiredThe unique identifier of the integration.
Request
400">curl -X 400">POST https:400">class="text-zinc-500">//api.lvng.ai/api/v2/platform-integrations/a1b2c3d4-e5f6-7890-abcd-ef1234567890/api-key \
-H 400">class="text-emerald-400">"Authorization: Bearer YOUR_API_KEY"Response 201
{
400">class="text-emerald-400">"api_key": 400">class="text-emerald-400">"lvng_plat_a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0c1d2e3f4",
400">class="text-emerald-400">"api_key_created_at": 400">class="text-emerald-400">"2026-03-19T11:00:00.000Z",
400">class="text-emerald-400">"message": 400">class="text-emerald-400">"API key generated successfully. This key will only be shown once."
}Revoke API Key
/api/v2/platform-integrations/:id/api-keyAuthenticatedRevokes the API key for an integration by setting api_key and api_key_created_at to null. Any inbound requests using the old key will fail immediately.
Path Parameters
idstring (UUID)requiredThe unique identifier of the integration.
Request
400">curl -X 400">DELETE https:400">class="text-zinc-500">//api.lvng.ai/api/v2/platform-integrations/a1b2c3d4-e5f6-7890-abcd-ef1234567890/api-key \
-H 400">class="text-emerald-400">"Authorization: Bearer YOUR_API_KEY"Response 200
{
400">class="text-emerald-400">"success": true,
400">class="text-emerald-400">"message": 400">class="text-emerald-400">"API key revoked successfully"
}