# Data Collaboration

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](/configuration-and-deployment/odd-platform.md#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](/features/active-platform-features/data-collaboration.md). The Slack integration here is a **full Slack app** (OAuth-token-driven; the [Slack Events API](https://docs.slack.dev/apis/events-api/) webhook reads replies back into the platform) — **distinct** from the [outgoing alert webhook](/configuration-and-deployment/odd-platform.md#enable-alert-notifications) 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](https://docs.slack.dev/apis/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

* [API Reference hub](/developer-guides/api-reference.md) — the full per-feature index.
* [Active platform features → Data Collaboration](/features/active-platform-features/data-collaboration.md) — feature description, Discussions tab, message-lifecycle model.
* [Configure ODD Platform → Enable Data Collaboration](/configuration-and-deployment/odd-platform.md#enable-data-collaboration) — `datacollaboration.*` configuration keys + Slack app manifest.


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.opendatadiscovery.org/developer-guides/api-reference/data-collaboration.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
