# Datahose - Read Events

Creates and reads a real time feed of messages & events. The datahose API provides messages and events from all conversations in the pod, even the ones the service user is not part of. The types of events surfaced can be found in the [Real Time Events](https://docs.developers.symphony.com/building-bots-on-symphony/datafeed/real-time-events) list.

{% hint style="info" %}
**Add-on:** The Datahose API is an add-on to the Symphony Services, and is subject to additional charges. Prior to using Datahose in your Symphony environment(s), you will need to enter into a specific contract. Please reach out to <sales@symphony.com> to discuss the offering, its pricing or for any further information.
{% endhint %}

## Creates and Reads a real time feed of messages and events of your pod (Datahose)

> \_Available on Agent 22.5.1 and above.\_\
> \
> This API provides a real time feed of all the messages and events in the pod, \
> even from conversations where the calling service account is not a member. The types of events surfaced \
> can be found in the Real Time Events list.\
> In case you retrieving SOCIALMESSAGE events, the credentials of the ceservice \
> account must be properly configured in the Agent.\
> \
> The types of events returned can be found in the Real Time\
> Events list (see definition on top of the file). \
> \
> The ackId sent as parameter must be empty for the first call. In the response an ackId will be sent back\
> and it can be used for the next call: in this way you acknowledge that\
> you have received the events that came with that ackId.\
> \
> If you have several instances of the same bot, they must share the same feed so \
> that events are spread across all bot instances. To do so, you must: share the same \
> service account provide the same "tag" and same "filters" values.\
> \
> The Datahose API is an add-on to the Symphony Services, and is subject to additional charges. \
> Prior to using Datahose in your Symphony environment(s), you will need to enter into a specific contract.<br>

```json
{"openapi":"3.0.1","info":{"title":"Agent API","version":"25.8.1"},"servers":[{"url":"youragentURL.symphony.com/agent"}],"paths":{"/v5/events/read":{"post":{"tags":["Datahose"],"summary":"Creates and Reads a real time feed of messages and events of your pod (Datahose)","description":"_Available on Agent 22.5.1 and above._\n\nThis API provides a real time feed of all the messages and events in the pod, \neven from conversations where the calling service account is not a member. The types of events surfaced \ncan be found in the Real Time Events list.\nIn case you retrieving SOCIALMESSAGE events, the credentials of the ceservice \naccount must be properly configured in the Agent.\n\nThe types of events returned can be found in the Real Time\nEvents list (see definition on top of the file). \n\nThe ackId sent as parameter must be empty for the first call. In the response an ackId will be sent back\nand it can be used for the next call: in this way you acknowledge that\nyou have received the events that came with that ackId.\n\nIf you have several instances of the same bot, they must share the same feed so \nthat events are spread across all bot instances. To do so, you must: share the same \nservice account provide the same \"tag\" and same \"filters\" values.\n\nThe Datahose API is an add-on to the Symphony Services, and is subject to additional charges. \nPrior to using Datahose in your Symphony environment(s), you will need to enter into a specific contract.\n","operationId":"readEvents","parameters":[{"name":"sessionToken","in":"header","description":"Session authentication token.","required":true,"schema":{"type":"string"}},{"name":"keyManagerToken","in":"header","description":"Key Manager authentication token.","schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/V5EventsReadBody"}}},"required":true},"responses":{"200":{"description":"Datafeed successfully read.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/V5EventList"}}}},"400":{"description":"Bad request.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/V2Error"}}}},"401":{"description":"Unauthorized.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/V2Error"}}}},"403":{"description":"Forbidden.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/V2Error"}}}},"500":{"description":"Internal server error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/V2Error"}}}}}}}},"components":{"schemas":{"V5EventsReadBody":{"required":["tag","type"],"type":"object","properties":{"type":{"type":"string","description":"The type of feed. Only allowed value is \"datahose\"."},"tag":{"maxLength":80,"minLength":1,"type":"string","description":"A unique identifier to ensure uniqueness of the datafeed."},"eventTypes":{"type":"array","description":"At least one value is required. Values must be valid Real-Time Events, i.e. one of:\n* MESSAGESENT\n* MESSAGESUPPRESSED\n* SYMPHONYELEMENTSACTION\n* SHAREDPOST\n* INSTANTMESSAGECREATED\n* ROOMCREATED\n* ROOMUPDATED\n* ROOMDEACTIVATED\n* ROOMREACTIVATED\n* USERREQUESTEDTOJOINROOM\n* USERJOINEDROOM\n* USERLEFTROOM\n* ROOMMEMBERPROMOTEDTOOWNER\n* ROOMMEMBERDEMOTEDFROMOWNER\n* CONNECTIONREQUESTED\n* CONNECTIONACCEPTED\n","items":{"type":"string"}},"scopes":{"type":"array","description":"Allows to filter events by scope\nScopes supported:\n* INTERNAL: Only events related to chats that are Internal are received. Shared Wall posts are included\n* EXTERNAL: Only events related to chats that are External are received. Connection Requested/Accepted events are included\n* FEDERATED: Only events related to chats that are Federated are received. Events that are not related to streams (Shared Wall Post, Connection Requested/Accepted) are not included.\nIf more than one scope is set, then events included in the union of scopes will be received.\nIf not set, then all events will be received.\n","items":{"type":"string"}},"ackId":{"type":"string","description":"Must be omitted or set as an empty string for the first call. \nIn successive calls, it must be set to the last read ackId. \nIt acknowledges that the current batch of messages have been successfully received by the client.\n"},"updatePresence":{"type":"boolean","description":"Whether to update the presence status of the account to AVAILABLE \nwhen calling the endpoint. Default value is true.\n","default":true}}},"V5EventList":{"type":"object","properties":{"events":{"type":"array","default":[],"items":{"$ref":"#/components/schemas/V4Event"}},"ackId":{"type":"string","description":"The ackId which acknowledges that the current batch of messages \nhave been successfully received by the client\n"}}},"V4Event":{"type":"object","properties":{"id":{"type":"string","description":"Event ID"},"messageId":{"type":"string","description":"Message ID"},"timestamp":{"type":"integer","description":"Timestamp of event","format":"int64"},"type":{"type":"string","description":"Event type, possible events are:\n  - MESSAGESENT\n  - SHAREDPOST\n  - INSTANTMESSAGECREATED\n  - ROOMCREATED\n  - ROOMUPDATED\n  - ROOMDEACTIVATED\n  - ROOMREACTIVATED\n  - USERJOINEDROOM\n  - USERLEFTROOM\n  - ROOMMEMBERPROMOTEDTOOWNER\n  - ROOMMEMBERDEMOTEDFROMOWNER\n  - CONNECTIONREQUESTED\n  - CONNECTIONACCEPTED\n  - MESSAGESUPPRESSED\n  - SYMPHONYELEMENTSACTION\n  - USERREQUESTEDTOJOINROOM\n  - GENERICSYSTEMEVENT\n"},"diagnostic":{"type":"string","description":"Details if event failed to parse for any reason.  The contents of this field may not be useful,\ndepending on the nature of the error. Only present when error occurs.\n"},"initiator":{"$ref":"#/components/schemas/V4Initiator"},"payload":{"$ref":"#/components/schemas/V4Payload"}}},"V4Initiator":{"type":"object","properties":{"user":{"$ref":"#/components/schemas/V4User"}}},"V4User":{"type":"object","properties":{"userId":{"type":"integer","description":"Id of user","format":"int64"},"firstName":{"type":"string","description":"First name of user"},"lastName":{"type":"string","description":"Last name of user"},"displayName":{"type":"string","description":"User display name"},"email":{"type":"string","description":"Email of user"},"username":{"type":"string","description":"Applicable only to internal users"}}},"V4Payload":{"type":"object","properties":{"messageSent":{"$ref":"#/components/schemas/V4MessageSent"},"sharedPost":{"$ref":"#/components/schemas/V4SharedPost"},"instantMessageCreated":{"$ref":"#/components/schemas/V4InstantMessageCreated"},"roomCreated":{"$ref":"#/components/schemas/V4RoomCreated"},"roomUpdated":{"$ref":"#/components/schemas/V4RoomUpdated"},"roomDeactivated":{"$ref":"#/components/schemas/V4RoomDeactivated"},"roomReactivated":{"$ref":"#/components/schemas/V4RoomReactivated"},"userJoinedRoom":{"$ref":"#/components/schemas/V4UserJoinedRoom"},"userLeftRoom":{"$ref":"#/components/schemas/V4UserLeftRoom"},"roomMemberPromotedToOwner":{"$ref":"#/components/schemas/V4RoomMemberPromotedToOwner"},"roomMemberDemotedFromOwner":{"$ref":"#/components/schemas/V4RoomMemberDemotedFromOwner"},"connectionRequested":{"$ref":"#/components/schemas/V4ConnectionRequested"},"connectionAccepted":{"$ref":"#/components/schemas/V4ConnectionAccepted"},"messageSuppressed":{"$ref":"#/components/schemas/V4MessageSuppressed"},"symphonyElementsAction":{"$ref":"#/components/schemas/V4SymphonyElementsAction"},"userRequestedToJoinRoom":{"$ref":"#/components/schemas/V4UserRequestedToJoinRoom"},"genericSystemEvent":{"$ref":"#/components/schemas/V4GenericSystemEvent"}}},"V4MessageSent":{"type":"object","properties":{"message":{"$ref":"#/components/schemas/V4Message"}}},"V4Message":{"type":"object","properties":{"messageId":{"type":"string","description":"Id of the message"},"parentMessageId":{"type":"string","description":"Id of the parent message, set when the message is a reply to another message or a forwarded message. Since Agent 20.14."},"timestamp":{"type":"integer","description":"Timestamp of the message in milliseconds since Jan 1 1970","format":"int64"},"message":{"type":"string","description":"Message content in MessageMLV2","format":"MessageMLV2"},"sharedMessage":{"$ref":"#/components/schemas/V4Message"},"data":{"type":"string","description":"Message data in EntityJSON","format":"JSON"},"attachments":{"type":"array","default":[],"description":"Message attachments","items":{"$ref":"#/components/schemas/V4AttachmentInfo"}},"user":{"$ref":"#/components/schemas/V4User"},"stream":{"$ref":"#/components/schemas/V4Stream"},"externalRecipients":{"type":"boolean","description":"Indicates if the message have external recipients. Only present on real time messaging."},"diagnostic":{"type":"string","description":"Details if event failed to parse for any reason.  The contents of this field may not be useful,\ndepending on the nature of the error. Only present when error occurs.\n"},"userAgent":{"type":"string","description":"User agent string for client that sent the message.  Allows callers to identify which client sent the\norigin message (e.g. API Agent, SFE Client, mobile, etc)\n"},"originalFormat":{"type":"string","description":"Indicates the format in which the message was originally sent.  This could have been either:\n- com.symphony.markdown - Markdown OR Message ML V1\n- com.symphony.messageml.v2 - Message ML V2\n"},"disclaimer":{"type":"string","description":"Message that may be sent along with a regular message if configured for the POD,\nusually the first message sent in a room that day.\n"},"sid":{"type":"string","description":"Unique session identifier from where the message was created.\n"},"replacing":{"type":"string","description":"Id of the message that the current message is replacing (present only if set)"},"replacedBy":{"type":"string","description":"Id of the message that the current message is being replaced with (present only if set)"},"initialTimestamp":{"type":"integer","description":"Timestamp of when the initial message has been created in milliseconds since \nJan 1 1970 (present only if set)\n","format":"int64"},"initialMessageId":{"type":"string","description":"Id the the initial message that has been updated (present only if set)"},"silent":{"type":"boolean","description":"When false the user/s will receive the message update as unread (true by default)"}},"description":"A representation of a message sent by a user of Symphony"},"V4AttachmentInfo":{"required":["id","name","size","images"],"type":"object","properties":{"id":{"type":"string","description":"The attachment ID."},"name":{"type":"string","description":"The file name."},"size":{"type":"integer","description":"Size in bytes.","format":"int64"},"images":{"type":"array","items":{"$ref":"#/components/schemas/V4ThumbnailInfo"}}}},"V4ThumbnailInfo":{"type":"object","properties":{"id":{"type":"string","description":"The thumbnail ID."},"dimension":{"type":"string","description":"The thumbnail pixel size."}}},"V4Stream":{"type":"object","properties":{"streamId":{"type":"string","description":"Id of stream"},"streamType":{"type":"string","description":"Stream type, possible values are:\n  - IM\n  - MIM\n  - ROOM\n  - POST\n"},"roomName":{"type":"string","description":"Applicable only to rooms"},"members":{"type":"array","description":"Applicable only to IM Created","items":{"$ref":"#/components/schemas/V4User"}},"external":{"type":"boolean"},"crossPod":{"type":"boolean"},"recipientTenantIds":{"type":"array","description":"List of tenant identifiers (aka pod identifiers) involved in the conversation. It contains more than one\nitem if the conversation is external. Field is only present for real time messaging.\n","items":{"type":"integer","format":"int32"}}}},"V4SharedPost":{"type":"object","properties":{"message":{"$ref":"#/components/schemas/V4Message"},"sharedMessage":{"$ref":"#/components/schemas/V4Message"}}},"V4InstantMessageCreated":{"type":"object","properties":{"stream":{"$ref":"#/components/schemas/V4Stream"}}},"V4RoomCreated":{"type":"object","properties":{"stream":{"$ref":"#/components/schemas/V4Stream"},"roomProperties":{"$ref":"#/components/schemas/V4RoomProperties"}}},"V4RoomProperties":{"type":"object","properties":{"name":{"type":"string"},"description":{"type":"string"},"creatorUser":{"$ref":"#/components/schemas/V4User"},"createdDate":{"type":"integer","description":"Timestamp","format":"int64"},"external":{"type":"boolean"},"crossPod":{"type":"boolean"},"public":{"type":"boolean"},"copyProtected":{"type":"boolean"},"readOnly":{"type":"boolean"},"discoverable":{"type":"boolean"},"membersCanInvite":{"type":"boolean"},"keywords":{"type":"array","default":[],"items":{"$ref":"#/components/schemas/V4KeyValuePair"}},"canViewHistory":{"type":"boolean"}}},"V4KeyValuePair":{"type":"object","properties":{"key":{"type":"string"},"value":{"type":"string"}}},"V4RoomUpdated":{"type":"object","properties":{"stream":{"$ref":"#/components/schemas/V4Stream"},"newRoomProperties":{"$ref":"#/components/schemas/V4RoomProperties"}}},"V4RoomDeactivated":{"type":"object","properties":{"stream":{"$ref":"#/components/schemas/V4Stream"}}},"V4RoomReactivated":{"type":"object","properties":{"stream":{"$ref":"#/components/schemas/V4Stream"}}},"V4UserJoinedRoom":{"type":"object","properties":{"stream":{"$ref":"#/components/schemas/V4Stream"},"affectedUser":{"$ref":"#/components/schemas/V4User"}}},"V4UserLeftRoom":{"type":"object","properties":{"stream":{"$ref":"#/components/schemas/V4Stream"},"affectedUser":{"$ref":"#/components/schemas/V4User"}}},"V4RoomMemberPromotedToOwner":{"type":"object","properties":{"stream":{"$ref":"#/components/schemas/V4Stream"},"affectedUser":{"$ref":"#/components/schemas/V4User"}}},"V4RoomMemberDemotedFromOwner":{"type":"object","properties":{"stream":{"$ref":"#/components/schemas/V4Stream"},"affectedUser":{"$ref":"#/components/schemas/V4User"}}},"V4ConnectionRequested":{"type":"object","properties":{"toUser":{"$ref":"#/components/schemas/V4User"}}},"V4ConnectionAccepted":{"type":"object","properties":{"fromUser":{"$ref":"#/components/schemas/V4User"}}},"V4MessageSuppressed":{"type":"object","properties":{"messageId":{"type":"string"},"stream":{"$ref":"#/components/schemas/V4Stream"}}},"V4SymphonyElementsAction":{"type":"object","properties":{"stream":{"$ref":"#/components/schemas/V4Stream"},"formMessageId":{"type":"string","description":"The id of the message that contains the Form"},"formId":{"type":"string","description":"The id of the Form element"},"formValues":{"type":"object","description":"The values (in JSON format) answered on the Form"}}},"V4UserRequestedToJoinRoom":{"type":"object","properties":{"stream":{"$ref":"#/components/schemas/V4Stream"},"affectedUsers":{"type":"array","description":"List of affected users by the action (i.e. owners of the room)","items":{"$ref":"#/components/schemas/V4User"}}}},"V4GenericSystemEvent":{"type":"object","properties":{"stream":{"$ref":"#/components/schemas/V4Stream"},"eventTimestamp":{"type":"integer","description":"The timestamp when the event was emitted","format":"int64"},"sourceSystem":{"type":"string","description":"The name of the system that emitted the event"},"eventSubtype":{"type":"string","description":"The identifier of the type of generic event"},"parameters":{"type":"object","description":"Free-form properties that provide context about the event","additionalProperties":true}}},"V2Error":{"required":["code","message"],"type":"object","properties":{"code":{"type":"integer","format":"int32"},"message":{"type":"string"},"details":{"type":"object"}}}}}}
```

### Datahose flavors

Starting in August 2025, the datahose API has been improved with the ability to only capture messages sent and received by a set of users, instead of always capturing all messages. This user filter capability requires additional configuration steps, but allows finer grain access to sensitive information, improving the data confidentiality. It also enables further filtering capabilities, such as the new `scope` parameter.

### Datahose

#### Requirements

* Agent v22.6 (release date: June 2022) is required.

#### Entitlements

The service account needs to have both the **Can read from datahose feeds** and **Can create datahose feeds** entitlements enabled to call this endpoint.&#x20;

Please contact your Technical Account Manager or Symphony representative to get your chat Bot entitled.&#x20;

#### Configuration

The credentials of the Content Export service need to be setup in the Agent configuration for datahose to work.&#x20;

The description of the configuration fields for the Content Export service is available in the [Agent configuration guide](https://docs.developers.symphony.com/admin-guide/agent-guide/agent-configuration-fields#agent-configuration-fields) (look for `agent.privatekey.ceservice` and `agent.certificate.ceservice`).&#x20;

To check that the Content Export is correctly setup, you can test the Agent [health check extended endpoint](https://rest-api.symphony.com/main/info-health-check/health-check-extended-v3) (/agent /v3/health/extended).&#x20;

The value of `users.ceservice.status` should be "UP", see example of the Health check response below.

<details>

<summary>Health check response</summary>

```json
{
    "services": {
        "datafeed": {
            "status": "UP",
            "version": "2.11.2"
        },
        "key_manager": {
            "status": "UP",
            "version": "20.16.3"
        },
        "pod": {
            "status": "UP",
            "version": "20.16.74-216-100b3be"
        }
    },
    "status": "UP",
    "users": {
        "agentservice": {
            "authType": "RSA",
            "status": "UP"
        },
        "ceservice": {
            "authType": "RSA",
           
 "status": "UP"
Status of ceservice should be UP

        }
    },
    "version": "23.11.1-716"
}
```

</details>

### Datahose with user filter

#### Requirements&#x20;

* Agent v25.8 (release date: August 2025) is required.

#### Configuration

{% hint style="info" %}
Configuring the **user filter** also requires all the configuration steps of the normal datahose, listed above under [Datahose](#datahose).
{% endhint %}

The user filter is managed by **linking an app to the datahose service account**, and then **by entitling the monitored users to that app**. As a result, the Admin can dynamically add or remove a user from the monitored list by adding or removing an app entitlement.&#x20;

The configuration requires three steps:

1. **Configure the Service Account**
   1. Log into the Admin Portal and search the service account provisioned for the user of datahose.
   2. Select the service account, then in the **User Information** tab, add the role **App Service Account**, then select **Save.**
2. **Configure App in the Admin Portal**
   1. In the **Admin Portal,** select **App Management** from the left panel.
   2. Select **Add Custom App** from the top right of the screen.
   3. Add a **name**, publisher, description and appid. &#x20;
   4. **Domain**: Not used, but a valid url is required. For example you can use <https://symphony.com>.
   5. Permissions: Select **Get User Events.** A new field **App Service Account** should appear.
   6. In the new **App Service Account** field, press **Select.** A new modal will display that lists the Service Accounts eligible, and should include your datahose service account.
   7. Select the service account you provisioned earlier and save.
   8. From the left panel, select **App Settings.** Locate your new app, and change its **Global Status** to Enabled. **Visibility** should be Hidden, and **Installation** must be Manual.&#x20;
   9. Select **Save**.&#x20;
3. **Entitle Users to the new filtering app**
   1. In the **Admin Portal**, search the end users which conversations should be monitored through the datahose feed.
   2. For each end user, open its profile, then in the **Applications** tab, change the **Installation** property of your new app to **Installed**. Alternatively, entitling a user to an app can be automated using the App Management APIs, through the Bulk Manage feature, or using the Directory Bridge. Please refer to our Admin Guide for more information.

✅Now, when your Bot will start a datahose feed, only the events of the users that are entitled to your app will be received.&#x20;

### Using ackId

The endpoint returns the [Real Time Events](https://docs.developers.symphony.com/building-bots-on-symphony/datafeed/real-time-events) happening in the pod, either since the time the datahose feed was created or since the previous feed was read by the bot. The `ackId` has an essential role in retrieving the right events for the bot.

The `ackId` must be null or empty for the first call. Then, for subsequent requests, the `ackId` from the previous payload should be reused to confirm the reading of previous events already retrieved by the bot.\
\&#xNAN;*Please note that you can very easily access this API via our BDKs in Java and Python.*

*If a batch of messages is not confirmed by sending the `ackId`, the messages that are there will be returned in the subsequent readings and may blend into the newer messages.*

### Fair use policy

Datahose API is subject to a fair use policy of **5** active feeds.&#x20;

If your integration or workflow requires more than 5 feeds active at the same time, please contact Symphony.


---

# 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://rest-api.symphony.com/main/datahose/datahose-read-events.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.
