Data Collaboration

Data Collaboration HTTP endpoints — outbound to the provider, per-entity threads & history, and the inbound Slack Events webhook. Gated by `@ConditionalOnDataCollaboration`.

The Data Collaboration HTTP surface is split across the data-collaboration controllers (DataCollaborationController, EventApiController) and a single Slack-events webhook. Every route below is gated by @ConditionalOnDataCollaboration (the Slack webhook controller is also conditional) — they return 404 Not Found when datacollaboration.enabled=false. For the configuration keys (datacollaboration.*), the Slack app manifest, and the operator setup flow, see Configure ODD Platform → Enable Data Collaboration; for the user-facing description (the per-entity Discussions tab, how a discussion flows, the message-lifecycle model), see Active platform features → Data Collaboration. The Slack integration here is a full Slack app (OAuth-token-driven; the Slack Events API webhook reads replies back into the platform) — distinct from the outgoing alert webhook used by alert notifications (notifications.receivers.slack.url, one-way write only).

Outbound to the provider — read & post

Method
Path
Operation ID
Purpose

GET

/api/datacollaboration/providers/slack/channels

getSlackChannels

List Slack channels the bot can write to, optionally filtered by channel_name. Used by the in-app channel autocomplete.

POST

/api/datacollaboration/providers/slack/messages

postMessageInSlack

Queue a message for delivery into Slack. Returns 202 Accepted once the message is enqueued; a background sender (DataCollaborationMessageSenderJob) drains the queue with up to datacollaboration.sending-messages-retry-count retries per message.

Per-entity threads & history

Method
Path
Operation ID
Purpose

GET

/api/dataentities/{data_entity_id}/messages

getDataEntityMessages

List thread-root messages attached to a data entity, paged by size and (optionally) filtered by channel_id.

GET

/api/dataentities/{data_entity_id}/messages/{message_id}

getMessages

List replies under a specific parent message, paged by size from last_message_id.

GET

/api/dataentities/{data_entity_id}/channels

getChannels

Top channels that already carry messages about the given entity (used to seed the channel picker).

GET

/api/messages/{message_id}/url

redirect

302 Found redirect to the provider's deep-link for the message — runtime returns HttpStatus.FOUND from DataCollaborationController.redirect(...) via DataCollaborationService.resolveMessageUrl(...). Spec / runtime drift: the OpenAPI spec declares 301 Moved Permanently for this route; the platform actually serves 302 Found. Operators relying on cache-cacheability semantics should treat the response as 302 for now (clients that follow redirects unconditionally are unaffected).

Inbound webhook from Slack

Method
Path
Purpose

POST

/api/slack/events

Slack Events API webhook. Handles three event types in SlackEventParser: url_verification (Slack handshake — returns the challenge token), event_callback (a thread reply — enqueued via DataCollaborationService.enqueueMessageEvent(...) and translated to a platform message by DataCollaborationMessageEventProcessor), and filter / error events (logged, acknowledged with 200 / 400). The path is fixed in EventApiController.java:22, so the manifest line https://<ODD_PLATFORM_BASE_URL>/api/slack/events matches the platform's route exactly.

See also

Last updated