# Symphony Messaging API Reference documentation

Welcome, Symphony Developer!

This is the API reference documentation page for the following Symphony APIs: Pod, Agent, Key Manager, DLP, Audit Trail, Malware Scanner and Groups.&#x20;

An overview of the API is available [here](https://docs.developers.symphony.com/bots/overview-of-rest-api) on our developer doc website.

{% hint style="info" %}
**New API portal.** Please note that we migrated our documentation to a different provider to provide a better service and improve the overall quality of the documentation. In this transition period you may notice missing information or an inconsistent look and feel. Please reach out to the Symphony support or your usual point of contact at Symphony if you encounter any issue. \
Thank you for your understanding.
{% endhint %}

### URL paths

The URLs paths are specific to your company. They also depend on the type of deployment (in-cloud vs. on premise).

Please get in touch with your Symphony point of contact to know more.

#### In-Cloud deployments

In-cloud deployments of Symphony use the following formats as both the Agent URL and the Key Auth URL are the same as your pod subdomain:

* Session Auth URL: YOUR-POD-SUBDOMAIN-api.symphony.com
* Key Auth URL: YOUR-POD-SUBDOMAIN-api.symphony.com
* Pod Url: YOUR-POD-SUBDOMAIN.symphony.com
* Agent Url: YOUR-POD-SUBDOMAIN.symphony.com

#### On-Premise deployments

For enterprise deployments of Symphony, the Agent URL and the Key Auth URL may differ from your pod subdomain because the Symphony software is deployed on premise. Therefore, enterprise deployments use the following formats:

* Session Auth URL: YOUR-POD-SUBDOMAIN-api.symphony.com
* Key Auth URL: YOUR-KEYAUTH-URL-api.symphony.com
* Pod Url: YOUR-POD-SUBDOMAIN.symphony.com
* Agent Url: YOUR-AGENT-URL.symphony.com

Contact your Symphony point of contact for details.


# Bots Authentication

When a bot process (API caller) starts, it must perform both session authentication and key manager authentication to obtain session tokens. These two tokens, which should be treated as opaque data by the bot, must be presented in custom headers with each subsequent REST API request. This authentication process can be performed using client certificates or a JSON Web Token (JWT) signed and verified using an [RSA public/private key pair](https://docs.developers.symphony.com/building-bots-on-symphony/authentication/rsa-authentication).

### Authentication Using an RSA Public/Private Key Pair

When a bot process (API caller) starts, it must first call the [RSA Session Authenticate](/main/bot-authentication/rsa-session-authenticate) endpoint for authenticating on the Symphony servers (pod). This endpoint will examine the JWT provided to identify the bot user and return a session token.

The bot must then call the analogous [RSA Key Manager Authenticate](/main/bot-authentication/rsa-key-manager-authenticate) endpoint for authenticating on the key manager. This endpoint will return another session token.

For more information, refer to [RSA Bot Authentication Workflow](https://docs.developers.symphony.com/building-bots-on-symphony/authentication/rsa-authentication).

### Authentication Using Client Certificates

When a bot process (API caller) starts, it must first call the [Session Authenticate](/main/bot-authentication/rsa-session-authenticate) endpoint for authenticating on the Symphony servers (pod). This endpoint will examine the client certificate provided in the TLS session to identify the bot user and return a session token.

The bot must then call the analogous [Key Manager Authenticate](/main/bot-authentication/rsa-key-manager-authenticate) endpoint for authenticating on the key manager. This endpoint will return another session token.

This approach provides a cryptographically secure authentication mechanism for callers of the API, without requiring the bot process to perform any cryptographic operations. The secure authentication is implemented in the TLS layer and handled for the client by the SSL Socket library used to establish the network connection.

For more information, refer to [Certificate Authentication Workflow](https://docs.developers.symphony.com/building-bots-on-symphony/authentication/certificate-authentication).


# Session Authenticate

Authenticates the API caller on the Symphony servers (pod) using a JWT.

## Authenticate with public key

> Based on an authentication request token signed by the caller's RSA private key,\
> authenticate the API caller and return a session token.\
> \
> A HTTP 401 Unauthorized error is returned on errors during authentication (e.g. invalid user,\
> malformed authentication token, user's public key not imported in the pod, invalid token signature etc.).<br>

```json
{"openapi":"3.1.1","info":{"title":"Login API","version":"20.14.1"},"paths":{"/pubkey/authenticate":{"post":{"summary":"Authenticate with public key","description":"Based on an authentication request token signed by the caller's RSA private key,\nauthenticate the API caller and return a session token.\n\nA HTTP 401 Unauthorized error is returned on errors during authentication (e.g. invalid user,\nmalformed authentication token, user's public key not imported in the pod, invalid token signature etc.).\n","tags":["Authentication"],"responses":{"200":{"description":"OK.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Token"}}}},"401":{"description":"Client is unauthorized to access this resource","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Forbidden to access this endpoint .","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Server error, see response body for further details.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AuthenticateRequest"}}},"required":true}}}},"components":{"schemas":{"Token":{"type":"object","properties":{"name":{"description":"The name of the header in which the token should be presented on subsequent API calls.\n","type":"string"},"token":{"type":"string","description":"Authentication token that should be passed as header in each API rest calls.\nThis should be considered opaque data by the client. It is not intended to contain any data interpretable by the\nclient. The format is secret and subject to change without notice.\n"},"authorizationToken":{"type":"string","description":"(Beta) Short lived access token built from a user session. This field is still on Beta, please continue using \nthe returned \"token\" instead.\n"}}},"Error":{"type":"object","properties":{"code":{"type":"integer","format":"int32"},"message":{"type":"string"}}},"AuthenticateRequest":{"type":"object","description":"Request body for pubkey authentication","properties":{"token":{"type":"string","description":"a JWT containing the caller's username or application appGroupId and an expiration date, signed by the caller's private key."}}}}}}
```

> #### ❗️ Session Token Management
>
> The token you receive is valid for the lifetime of a session that is defined by your pod's administration team. This ranges from 1 hour to 2 weeks.
>
> You should keep using the same token until you receive a HTTP 401, at which you should re-authenticate and get a new token for a new session.
>
> [Datafeeds](/main/datafeed) survive session expiration, you do not need to re-create your datafeed if your session expires.

> #### 🚧 Important
>
> * The following restrictions apply:
>   * The JWT must have an expiration date between the current time and five minutes from the current time.
>   * The JWT must be signed by a private key matching the public key saved for its subject ("sub").
> * For more information on creating and using an RSA session token, refer to [RSA Bot Authentication Workflow](https://docs.developers.symphony.com/building-bots-on-symphony/authentication/rsa-authentication).

*Note that the Session Authenticate endpoint may return an authorizationToken (short lived access token built from a user session) in addition to the session token. Please note this has been introduced as beta and should not be used until further notice; please continue using the returned "token" instead.*


# Key Manager Authenticate

Authenticates the API caller on the key manager using a JWT.

{% openapi src="/files/XuRHNWZSuwS5aAMRzawl" path="/pubkey/authenticate" method="post" %}
[km-api-public.yaml](https://544392450-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F909t04Fk8FiEI7fBcmlw%2Fuploads%2Fgit-blob-b6d63f640faf8ffd4c3cb7d5da4b3f6866387e25%2Fkm-api-public.yaml?alt=media)
{% endopenapi %}

To know more about RSA authentication process, refer to [RSA Bot Authentication Workflow](https://docs.developers.symphony.com/building-bots-on-symphony/authentication/rsa-authentication).

For more information on creating and using an RSA key manager token, refer to [RSA Bot Authentication Workflow](https://docs.developers.symphony.com/building-bots-on-symphony/authentication/rsa-authentication).

> #### ❗️ Key Manager Token Management
>
> The token you receive is valid for the lifetime of a session that is defined by your pod's administration team. This ranges from 1 hour to 2 weeks.
>
> You should keep using the same token until you receive a HTTP 401, at which you should re-authenticate and get a new token for a new session.
>
> [Datafeeds](/main/datafeed) survive session expiration, you do not need to re-create your datafeed if your session expires.

> #### 🚧 Important
>
> * The following restrictions apply:
>   * The JWT must have an expiration date between the current time and five minutes from the current time.
>   * The JWT must be signed by a private key matching the public key saved for its subject ("sub").
> * For more information on creating and using an RSA session token, refer to [RSA Bot Authentication Workflow](https://docs.developers.symphony.com/building-bots-on-symphony/authentication/rsa-authentication).


# Session Authenticate (Cert)

Authenticates the API caller on the Symphony servers (pod) using the client certificate provided in the TLS session, returning a session token.

{% hint style="warning" %}
**Backward compatibility breaking notice**: Starting in **March 2025**, the request's Content-type header must be empty, and its body must be null.
{% endhint %}

{% openapi src="/files/T41DVTovUhrKgc4uLHrd" path="/v1/authenticate" method="post" expanded="true" fullWidth="true" %}
[authenticator-api-public.yaml](https://544392450-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F909t04Fk8FiEI7fBcmlw%2Fuploads%2Fgit-blob-fbac22e6de11bb95e3f2243769875c33684b49d8%2Fauthenticator-api-public.yaml?alt=media)
{% endopenapi %}

> #### ❗️ Session Token Management
>
> The token you receive is valid for the lifetime of a session that is defined by your pod's administration team. This ranges from 1 hour to 2 weeks.
>
> You should keep using the same token until you receive a HTTP 401, at which you should re-authenticate and get a new token for a new session.
>
> [Datafeeds](/main/datafeed) survive session expiration, you do not need to re-create your datafeed if your session expires.

To call the Session Authenticate endpoint, you must provide a certificate where the Common Name of the certificate matches the username of an active Service User account on your pod.

> #### 🚧 Important
>
> * Before calling any of the Pod or Agent API endpoints, the caller must be authenticated on both the pod and key manager by calling this endpoint, followed by the [Key Manager Authenticate](/main/bot-authentication/rsa-key-manager-authenticate) endpoint.
> * The certificate used for authentication (and therefore the Root certification) must have a strength of 4096 bits, or the cert will be rejected
> * Symphony prevents bots from calling this endpoint when the following conditions are true:
>   * An application and a bot have the same name.
>   * The application specifies a [valid certificate in its manifest file](https://docs.developers.symphony.com/building-extension-applications-on-symphony/app-configuration/application-manifest-bundle-file-reference).
>   * The application is enabled and not marked for deletion. For more information about enabling and deleting applications, see the *Symphony Administration Guide*.
> * The request's Content-type header must be empty, and its body must be null.

*Note that the Session Authenticate endpoint may return an authorizationToken (short lived access token built from a user session) in addition to the session token. Please note this has been introduced as beta and should not be used until further notice; please continue using the returned "token" instead.*


# Key Manager Authenticate (Cert)

Authenticates the API caller on the key manager using the client certificate provided in the TLS session, returning a key manager token.

{% openapi src="/files/bJvxCRcpQFWL9QXqSE5x" path="/v1/authenticate" method="post" %}
[km-cert-api-public.yaml](https://544392450-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F909t04Fk8FiEI7fBcmlw%2Fuploads%2Fgit-blob-419162d50a87f510738956b4563b2497b773594d%2Fkm-cert-api-public.yaml?alt=media)
{% endopenapi %}

> #### ❗️ Key Manager Token Management
>
> The token you receive is valid for the lifetime of a session that is defined by your pod's administration team. This ranges from 1 hour to 2 weeks.
>
> You should keep using the same token until you receive a HTTP 401, at which you should re-authenticate and get a new token for a new session.
>
> [Datafeeds](/main/datafeed) survive session expiration, you do not need to re-create your datafeed if your session expires.

> #### 🚧
>
> Before calling the Pod endpoints, the caller must be authenticated with the pod (the dedicated Symphony cloud service) by calling the [Session Authenticate](/main/bot-authentication/rsa-session-authenticate) endpoint, followed by this one.

To call the Key Manager Authenticate endpoint, you must provide a certificate where the Common Name of the certificate matches the username of an active Service User account on your pod.


# Session Logout

Log out a user’s session.

{% openapi src="/files/T41DVTovUhrKgc4uLHrd" path="/v1/logout" method="post" expanded="true" fullWidth="true" %}
[authenticator-api-public.yaml](https://544392450-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F909t04Fk8FiEI7fBcmlw%2Fuploads%2Fgit-blob-fbac22e6de11bb95e3f2243769875c33684b49d8%2Fauthenticator-api-public.yaml?alt=media)
{% endopenapi %}

> #### 📘 Note
>
> You must provide a certificate where the Common Name of the certificate matches the username of an active Service User account on your pod.\
> To call the Logout endpoint for a user, you must have a valid sessionToken for the user.

Example call sequence:

1. Call [Session Authenticate](/main/bot-authentication/rsa-session-authenticate) to get a `sessionToken`.
2. Call [Logout](/main/bot-authentication/logout) with the `sessionToken`.

To call the Logout endpoint for an app, you must have a valid session token for an app that's been installed for the user whom you intend to log out.

Example call sequences:

1. Call [App Authenticate](/main/apps-on-behalf-of-obo/obo-rsa-app-authentication) to get a `sessionToken`.
2. Call [Logout](/main/bot-authentication/logout) with the `sessionToken`.
3. Call [App Authenticate](/main/apps-on-behalf-of-obo/obo-rsa-app-authentication) to get a `sessionToken`.
4. Call [User Authenticate](/main/apps-on-behalf-of-obo/obo-rsa-user-authentication-by-user-id) with the `sessionToken`.
5. Call [Logout](/main/bot-authentication/logout) with the `sessionToken`.


# Key Manager Logout

Log out a user’s key manager session.

{% openapi src="/files/bJvxCRcpQFWL9QXqSE5x" path="/v1/logout" method="post" %}
[km-cert-api-public.yaml](https://544392450-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F909t04Fk8FiEI7fBcmlw%2Fuploads%2Fgit-blob-419162d50a87f510738956b4563b2497b773594d%2Fkm-cert-api-public.yaml?alt=media)
{% endopenapi %}

To call the Key Manager Logout endpoint for a user, you must have a valid keyManagerToken for the user.

Example call sequence:

1. Call [Key Manager Authenticate](/main/bot-authentication/rsa-key-manager-authenticate) to get a `keyManagerToken`.
2. Call [Key Manager Logout](/main/bot-authentication/key-manager-logout) with the `keyManagerToken`.


# Apps Authentication


# Authenticate App

Authenticate extension app with a public key. See also: Application Authentication in the Client Extension API documentation.

{% openapi src="/files/QTYCdVMbKdCr4AG0pr4r" path="/v1/pubkey/app/authenticate/extensionApp" method="post" expanded="true" fullWidth="true" %}
[login-api-public.yaml](https://544392450-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F909t04Fk8FiEI7fBcmlw%2Fuploads%2Fgit-blob-0a6a293d0a6cdb3b172f2d2f3cb550af3be41315%2Flogin-api-public.yaml?alt=media)
{% endopenapi %}


# Pod Certificate

Retrieve the certificate that can be used to validate the JWT token obtained through the extension application authentication flow.

{% openapi src="/files/T41DVTovUhrKgc4uLHrd" path="/v1/app/pod/certificate" method="get" expanded="true" %}
[authenticator-api-public.yaml](https://544392450-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F909t04Fk8FiEI7fBcmlw%2Fuploads%2Fgit-blob-fbac22e6de11bb95e3f2243769875c33684b49d8%2Fauthenticator-api-public.yaml?alt=media)
{% endopenapi %}


# Apps On Behalf Of (OBO)


# API Endpoints for Apps

### Get Started with OBO

OBO or On-Behalf-Of authentication allows an extension application to be able to call REST API endpoints to perform operations on behalf of an application end-user.

Such operations include:

* List the streams of a given user
* Initiate connection requests to and determine connection status with other users
* Get the presence state of other connected users
* Initiate IMs with other users
* Send messages and attachments
* Set the context user's own presence

> #### 📘 More information on OBO
>
> For more information, please refer to [OBO Authentication](https://docs.developers.symphony.com/building-extension-applications-on-symphony/app-authentication/obo-authentication).

## API endpoints enabled for OBO

The following table describes which of our REST API endpoints are OBO-enabled, and for each the application permission that must be granted to the app.

{% hint style="info" %}
Premium APIs are an add-on to the Symphony Services, and are subject to additional charges. Prior to using them, you will need to enter into a specific contract. Please reach out to <sales@symphony.com> to discuss the offering, its pricing, or any further information.
{% endhint %}

<table><thead><tr><th width="261.45703125">OBO-enabled endpoint</th><th width="176.36328125">Permission</th><th width="152.91015625">Endpoint documentation</th><th width="127.20703125" data-type="checkbox">Premium APIs</th></tr></thead><tbody><tr><td>GET /pod/v1/connection/list</td><td>GET_USER_CONNECTIONS</td><td><a data-mention href="/pages/mIozaSn9HaKKBMF72SbQ">/pages/mIozaSn9HaKKBMF72SbQ</a></td><td>false</td></tr><tr><td>GET /pod/v1/admin/system/protocols/list</td><td>SEND_MESSAGES</td><td><p><em>Deprecated documentation. For more information, refer to:</em></p><p><a data-mention href="/pages/rrW0dxqJ0XALRyQUEI3b">/pages/rrW0dxqJ0XALRyQUEI3b</a></p></td><td>false</td></tr><tr><td>GET /pod/v1/connection/user/{userId}/info</td><td>GET_USER_CONNECTIONS</td><td><a data-mention href="/pages/1skpI0wNR2ouSnWJcJoU">/pages/1skpI0wNR2ouSnWJcJoU</a></td><td>false</td></tr><tr><td>GET /pod/v1/files/allowedTypes</td><td>SEND_MESSAGES</td><td><a data-mention href="/pages/lVq6rByF9MGbEhL1GGmi">/pages/lVq6rByF9MGbEhL1GGmi</a></td><td>false</td></tr><tr><td>GET /pod/v1/presence/feed/{feedId}/read</td><td>GET_PRESENCE</td><td><a data-mention href="/pages/U7OxQkFF5VQletQPFMes">/pages/U7OxQkFF5VQletQPFMes</a></td><td>false</td></tr><tr><td>GET /pod/v1/sessioninfo</td><td>GET_BASIC_USER_INFO</td><td><em>Deprecated documentation. For more information, refer to:</em><br><a data-mention href="/pages/yYK763uCdGWxeyw0cKYQ">/pages/yYK763uCdGWxeyw0cKYQ</a></td><td>false</td></tr><tr><td>GET /pod/v1/streams/{streamId}/info</td><td>SEND_MESSAGES</td><td><em>Deprecated documentation. For more information, refer to:</em><br><a data-mention href="/pages/f1lkRncUJmnoka8J69gC">/pages/f1lkRncUJmnoka8J69gC</a></td><td>false</td></tr><tr><td>GET /pod/v1/user</td><td>GET_BASIC_CONTACT_INFO</td><td><em>Deprecated documentation. For more information, refer to:</em><br><a data-mention href="/pages/eKBGHqOjwe6iaz62HWEA">/pages/eKBGHqOjwe6iaz62HWEA</a></td><td>false</td></tr><tr><td>GET /pod/v1/user/presence</td><td>GET_PRESENCE</td><td><em>Deprecated documentation. For more information, refer to:</em><br><a data-mention href="/pages/L8Abr3Wf0n6N23pxk9vI">/pages/L8Abr3Wf0n6N23pxk9vI</a></td><td>false</td></tr><tr><td>GET /pod/v1/user/{userId}/presence</td><td>GET_PRESENCE</td><td><em>Deprecated documentation. For more information, refer to:</em><br><a data-mention href="/pages/PoFcOW1wge8cBui4jD19">/pages/PoFcOW1wge8cBui4jD19</a></td><td>false</td></tr><tr><td>GET /pod/v2/sessioninfo</td><td>GET_BASIC_USER_INFO</td><td><a data-mention href="/pages/yYK763uCdGWxeyw0cKYQ">/pages/yYK763uCdGWxeyw0cKYQ</a></td><td>false</td></tr><tr><td>GET /pod/v2/user</td><td>GET_BASIC_CONTACT_INFO  SEND_MESSAGES</td><td><em>Deprecated documentation. For more information, refer to:</em><br><a data-mention href="/pages/eKBGHqOjwe6iaz62HWEA">/pages/eKBGHqOjwe6iaz62HWEA</a></td><td>false</td></tr><tr><td>GET /pod/v2/user/presence</td><td>GET_PRESENCE</td><td><a data-mention href="/pages/L8Abr3Wf0n6N23pxk9vI">/pages/L8Abr3Wf0n6N23pxk9vI</a></td><td>false</td></tr><tr><td>GET /pod/v2/user/{userId}/presence</td><td>GET_PRESENCE</td><td><em>Deprecated documentation. For more information, refer to:</em><br><a data-mention href="/pages/PoFcOW1wge8cBui4jD19">/pages/PoFcOW1wge8cBui4jD19</a></td><td>false</td></tr><tr><td>GET /pod/v3/room/{roomId}/info</td><td>MANAGE_ROOMS</td><td><a data-mention href="/pages/lB8KolMLiQkIQOJNSxBQ">/pages/lB8KolMLiQkIQOJNSxBQ</a></td><td>false</td></tr><tr><td>GET /pod/v3/user/{userId}/presence</td><td>GET_PRESENCE</td><td><a data-mention href="/pages/PoFcOW1wge8cBui4jD19">/pages/PoFcOW1wge8cBui4jD19</a></td><td>false</td></tr><tr><td>GET /pod/v3/users</td><td>GET_BASIC_CONTACT_INFO</td><td><a data-mention href="/pages/eKBGHqOjwe6iaz62HWEA">/pages/eKBGHqOjwe6iaz62HWEA</a></td><td>false</td></tr><tr><td>POST /v1/user/{uid}/follow</td><td>MANAGE_USER_FOLLOWING</td><td><a data-mention href="/pages/7IPrcdfnQWmuEHqyA19I">/pages/7IPrcdfnQWmuEHqyA19I</a></td><td>false</td></tr><tr><td>POST /v1/user/{uid}/unfollow</td><td>MANAGE_USER_FOLLOWING</td><td><a data-mention href="/pages/i9GnDKrzeGPGHMPJqOvs">/pages/i9GnDKrzeGPGHMPJqOvs</a></td><td>false</td></tr><tr><td>GET /agent/v1/signals/{signalId}/get</td><td>MANAGE_SIGNALS</td><td><a data-mention href="/pages/wd0koxucO0LwcL5LbNKm">/pages/wd0koxucO0LwcL5LbNKm</a></td><td>false</td></tr><tr><td>GET  /agent/v1/signals/{signalId}/subscribers</td><td>MANAGE_SIGNALS</td><td><a data-mention href="/pages/ACeKPqEUkOa8WiLZHqRL">/pages/ACeKPqEUkOa8WiLZHqRL</a></td><td>false</td></tr><tr><td>GET  /agent/v1/signals/list</td><td>MANAGE_SIGNALS</td><td><a data-mention href="/pages/H9BvxfGCH7GIRUnuc7HY">/pages/H9BvxfGCH7GIRUnuc7HY</a></td><td>false</td></tr><tr><td>POST /agent/v1/signals/create</td><td>MANAGE_SIGNALS</td><td><a data-mention href="/pages/bDLu6q1eZJCk0CgfoHza">/pages/bDLu6q1eZJCk0CgfoHza</a></td><td>false</td></tr><tr><td>POST /agent/v1/signals/{signalId}/update</td><td>MANAGE_SIGNALS</td><td><a data-mention href="/pages/0D9fLyAUb20gPeupPnpd">/pages/0D9fLyAUb20gPeupPnpd</a></td><td>false</td></tr><tr><td>POST /agent/v1/signals/{signalId}/delete</td><td>MANAGE_SIGNALS</td><td><a data-mention href="/pages/HP0Z4uMWBwUbn8TTi2cT">/pages/HP0Z4uMWBwUbn8TTi2cT</a></td><td>false</td></tr><tr><td>POST /agent/v1/signals/{signalId}/subscribe</td><td>MANAGE_SIGNALS</td><td><a data-mention href="/pages/AC5L5WAKnTLTNtajzJ1G">/pages/AC5L5WAKnTLTNtajzJ1G</a></td><td>false</td></tr><tr><td>POST /agent/v1/signals/{signalId}/unsubscribe</td><td>MANAGE_SIGNALS</td><td><a data-mention href="/pages/gdJs5kQkbHSb5i7sfsAf">/pages/gdJs5kQkbHSb5i7sfsAf</a></td><td>false</td></tr><tr><td>POST /agent/v3/stream/{streamId}/share</td><td>SEND_MESSAGES</td><td><a data-mention href="/pages/SU7Ch6IObT1Z0cLmDiMh">/pages/SU7Ch6IObT1Z0cLmDiMh</a></td><td>false</td></tr><tr><td>POST /agent/v4/stream/{streamId}/message/create</td><td>SEND_MESSAGES</td><td><a data-mention href="/pages/ehGwBvwaMIEWzlStKYOx">/pages/ehGwBvwaMIEWzlStKYOx</a></td><td>false</td></tr><tr><td>POST /agent/v4/message/blast</td><td>SEND_MESSAGES</td><td><a data-mention href="/pages/UHXORS6Dz7xn35s62W5L">/pages/UHXORS6Dz7xn35s62W5L</a></td><td>false</td></tr><tr><td>POST /agent/v4/stream/{:sid}/message/{:mid}/update</td><td>SEND_MESSAGES</td><td><a data-mention href="/pages/vucA2sPJHQ9PMcFGrqbU">/pages/vucA2sPJHQ9PMcFGrqbU</a></td><td>false</td></tr><tr><td>POST /v1/admin/messagesuppression/{messageId}/suppress</td><td>SUPPRESS_MESSAGES</td><td><a data-mention href="/pages/uRcJWMyZEK8dyh7FIwhO">/pages/uRcJWMyZEK8dyh7FIwhO</a></td><td>false</td></tr><tr><td>POST /pod/v1/connection/create</td><td>REQUEST_USER_CONNECTIONS</td><td><a data-mention href="/pages/FbG9fRDvI4qT8YOLkcN9">/pages/FbG9fRDvI4qT8YOLkcN9</a></td><td>false</td></tr><tr><td>POST /pod/v1/im/create</td><td>SEND_MESSAGES</td><td><a data-mention href="/pages/q9CAqiK7ruQK9t16OuyH">/pages/q9CAqiK7ruQK9t16OuyH</a></td><td>false</td></tr><tr><td>POST /pod/v1/presence/feed/create</td><td>GET_PRESENCE</td><td><a data-mention href="/pages/xDWny0kWxp7DnrXu7OMk">/pages/xDWny0kWxp7DnrXu7OMk</a></td><td>false</td></tr><tr><td>POST /pod/v1/presence/feed/{feedId}/delete</td><td>GET_PRESENCE</td><td><a data-mention href="/pages/vombKpIS3y8MXmk11DJX">/pages/vombKpIS3y8MXmk11DJX</a></td><td>false</td></tr><tr><td>POST /pod/v2/room/{roomId}/membership/list</td><td>MANAGE_ROOMS<br>LIST_USER_STREAMS</td><td>Since SBE 20.16<br><a data-mention href="/pages/7ILYTDxOcojZDuIR9H6T">/pages/7ILYTDxOcojZDuIR9H6T</a></td><td>false</td></tr><tr><td>POST /pod/v1/room/{roomId}/membership/add</td><td>MANAGE_ROOMS</td><td><a data-mention href="/pages/QC1Rsg9M3CyEPEbVTJtM">/pages/QC1Rsg9M3CyEPEbVTJtM</a></td><td>false</td></tr><tr><td>POST /pod/v1/room/{roomId}/membership/demoteOwner</td><td>MANAGE_ROOMS</td><td><a data-mention href="/pages/S86t6XTphY6Jg7byPXeU">/pages/S86t6XTphY6Jg7byPXeU</a></td><td>false</td></tr><tr><td>"POST" /pod/v1/room/{roomId}/membership/promoteOwner</td><td>MANAGE_ROOMS</td><td><a data-mention href="/pages/2Kss9VcbVjVwnplgwMxh">/pages/2Kss9VcbVjVwnplgwMxh</a></td><td>false</td></tr><tr><td>POST /pod/v1/room/{roomId}/membership/remove</td><td>MANAGE_ROOMS</td><td><a data-mention href="/pages/nYnj8ov8uEvfC6WUSsOm">/pages/nYnj8ov8uEvfC6WUSsOm</a></td><td>false</td></tr><tr><td>POST /pod/v1/room/{roomId}/setActive</td><td>MANAGE_ROOMS</td><td><a data-mention href="/pages/xpY7Pl9GOoeGsprbEfu5">/pages/xpY7Pl9GOoeGsprbEfu5</a></td><td>false</td></tr><tr><td>POST /pod/v1/streams/list</td><td>LIST_USER_STREAMS</td><td><a data-mention href="/pages/E1u41UHYesTLGJSg3jRz">/pages/E1u41UHYesTLGJSg3jRz</a></td><td>false</td></tr><tr><td>POST /pod/v2/user/presence</td><td>SET_PRESENCE</td><td><a data-mention href="/pages/PiOGmxBF6g96fY6B9r4K">/pages/PiOGmxBF6g96fY6B9r4K</a></td><td>false</td></tr><tr><td>POST /pod/v1/user/presence/register</td><td>GET_PRESENCE</td><td><a data-mention href="/pages/tuIPEwbfPA0dFdw4VkqR">/pages/tuIPEwbfPA0dFdw4VkqR</a></td><td>false</td></tr><tr><td>POST /pod/v1/user/search</td><td>GET_BASIC_CONTACT_INFO</td><td><a data-mention href="/pages/pBbBmSNvNOqlRJtTaaKa">/pages/pBbBmSNvNOqlRJtTaaKa</a></td><td>false</td></tr><tr><td>POST /pod/v2/user/presence</td><td>SET_PRESENCE</td><td><a data-mention href="/pages/PiOGmxBF6g96fY6B9r4K">/pages/PiOGmxBF6g96fY6B9r4K</a></td><td>false</td></tr><tr><td>POST /pod/v3/room/create</td><td>MANAGE_ROOMS  CREATE_USER_STREAM</td><td><a data-mention href="/pages/yCsXZPy2jssQzEh8R4ew">/pages/yCsXZPy2jssQzEh8R4ew</a></td><td>false</td></tr><tr><td>POST /pod/v3/room/search</td><td>MANAGE_ROOMS</td><td><a data-mention href="/pages/WcJCaaZLaDd0de0bT5pK">/pages/WcJCaaZLaDd0de0bT5pK</a></td><td>false</td></tr><tr><td>POST /pod/v3/room/{roomId}/update</td><td>MANAGE_ROOMS</td><td><a data-mention href="/pages/MRgt7FVE43dWvZAxgGhG">/pages/MRgt7FVE43dWvZAxgGhG</a></td><td>false</td></tr><tr><td>POST /pod/v3/user/presence</td><td>SET_PRESENCE</td><td><a data-mention href="/pages/afTlLFjj3ICA2an5Dkdw">/pages/afTlLFjj3ICA2an5Dkdw</a></td><td>false</td></tr><tr><td>GET /agent/v4/stream/{sid}/message</td><td>GET_MESSAGES</td><td><a data-mention href="/pages/lsG4JJVCpAwMIkgbKJ1W">/pages/lsG4JJVCpAwMIkgbKJ1W</a></td><td>true</td></tr><tr><td>POST /agent<br>/v1/message/search</td><td>GET_MESSAGES</td><td><a data-mention href="/pages/I2VvZUQKB517cJgyA7FD">/pages/I2VvZUQKB517cJgyA7FD</a></td><td>true</td></tr></tbody></table>

### The following table describes the use of permissions:

<table><thead><tr><th width="288">Permission</th><th>Usage</th></tr></thead><tbody><tr><td>GET_BASIC_CONTACT_INFO</td><td>An app can get basic contact info.</td></tr><tr><td>GET_BASIC_USER_INFO</td><td>An app can get basic contact info.</td></tr><tr><td>SEND_MESSAGES</td><td>An app can send messages on behalf of a user. Creates IM for users.</td></tr><tr><td>SUPPRESS_MESSAGES</td><td>An app can suppress a user's messages on behalf of that user.</td></tr><tr><td>CREATE_USER_STREAM</td><td>An app can create streams on behalf of a user.</td></tr><tr><td>MANAGE_ROOMS</td><td>An app can manage streams on behalf of a user.</td></tr><tr><td>MANAGE_SIGNALS</td><td>An app can list, create, edit, and delete signals on behalf of a user.</td></tr><tr><td>LIST_USER_STREAMS</td><td>An app can get a list of user streams on behalf of users.</td></tr><tr><td>GET_USER_CONNECTIONS</td><td>An app can get an <code>appinfo</code> of all user connections on behalf of users.</td></tr><tr><td>REQUEST_USER_CONNECTIONS</td><td>An app can send connection requests on behalf of users.</td></tr><tr><td>GET_PRESENCE</td><td>An app can get a user presence on behalf of users.</td></tr><tr><td>SET_PRESENCE</td><td>An app can set presence on behalf of users.</td></tr><tr><td>MANAGE_USER_FOLLOWING</td><td>An app can make a list of users follow or unfollow a considered user, identified by his uid.</td></tr><tr><td>GET_MESSAGES</td><td>Retrieve messages on the user behalf.</td></tr></tbody></table>

> 🚧 All "On-Behalf-Of" (OBO) endpoints strictly adhere to the existing entitlements or state of the user in session.
>
> For example, an app cannot send a message on behalf of a user if that user is not already connected to the intended recipient. Similarly, if a user lacks the "Can Send Files" entitlement in Symphony Messaging, the app is restricted from sending messages with attachments on their behalf.
>
> This principle also applies to data retrieval use cases, where the app cannot retrieve more data than the user is permitted to see. Consequently, all relevant communication controls, such as history logs, room membership, and information barriers, are automatically applied.


# App Authentication

Authenticates an OBO app using the application saved RSA public key.

{% openapi src="/files/QTYCdVMbKdCr4AG0pr4r" path="/pubkey/app/authenticate" method="post" expanded="true" fullWidth="true" %}
[login-api-public.yaml](https://544392450-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F909t04Fk8FiEI7fBcmlw%2Fuploads%2Fgit-blob-0a6a293d0a6cdb3b172f2d2f3cb550af3be41315%2Flogin-api-public.yaml?alt=media)
{% endopenapi %}

> #### 📘 Requirements
>
> This authentication requires the app to be enabled and to have at least one RSA Public key registered. For more information, refer to [Create an RSA Key Pair](https://docs.developers.symphony.com/building-bots-on-symphony/authentication/rsa-authentication#1-create-an-rsa-key-pair).


# User Authentication by User ID

Enables an RSA application to authenticate on behalf of a particular user.

{% openapi src="/files/QTYCdVMbKdCr4AG0pr4r" path="/pubkey/app/user/{userId}/authenticate" method="post" expanded="true" fullWidth="true" %}
[login-api-public.yaml](https://544392450-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F909t04Fk8FiEI7fBcmlw%2Fuploads%2Fgit-blob-0a6a293d0a6cdb3b172f2d2f3cb550af3be41315%2Flogin-api-public.yaml?alt=media)
{% endopenapi %}

> #### 📘 Requirements
>
> The app must have been created on the pod.\
> The app must be enabled.\
> The user must exist and have the app installed. For more information, refer to [Update user Apps](/main/apps-entitlements/partial-update-user-apps).


# User Authentication by User Name

Enables an RSA application to authenticate on behalf of a particular user.

{% openapi src="/files/QTYCdVMbKdCr4AG0pr4r" path="/pubkey/app/username/{username}/authenticate" method="post" expanded="true" fullWidth="true" %}
[login-api-public.yaml](https://544392450-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F909t04Fk8FiEI7fBcmlw%2Fuploads%2Fgit-blob-0a6a293d0a6cdb3b172f2d2f3cb550af3be41315%2Flogin-api-public.yaml?alt=media)
{% endopenapi %}

> #### 📘 Requirements
>
> The app must have been created on the pod.\
> The app must be enabled.\
> The user must exist and have the app installed. For more information, refer to [Update user Apps](/main/apps-entitlements/partial-update-user-apps).


# Info - Health Check


# Health Check

Returns the connectivity status of your Agent service.

If your Agent service is started and running properly, the status value will be `UP`.

`Available on Agent 2.57.0 and above.`&#x20;

## Checks health status

> \_Available on Agent 2.57.0 and above.\_\
> \
> Returns the connectivity status of your Agent server. If your Agent server is started and running, the status value will be \`UP\`<br>

```json
{"openapi":"3.0.1","info":{"title":"Agent API","version":"25.8.1"},"servers":[{"url":"youragentURL.symphony.com/agent"}],"paths":{"/v3/health":{"get":{"tags":["System"],"summary":"Checks health status","description":"_Available on Agent 2.57.0 and above._\n\nReturns the connectivity status of your Agent server. If your Agent server is started and running, the status value will be `UP`\n","operationId":"v3Health","responses":{"200":{"description":"Agent application is alive.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/V3Health"}}}}}}}},"components":{"schemas":{"V3Health":{"type":"object","properties":{"services":{"type":"object","additionalProperties":{"$ref":"#/components/schemas/V3HealthComponent"}},"status":{"$ref":"#/components/schemas/V3HealthStatus"},"users":{"type":"object","additionalProperties":{"$ref":"#/components/schemas/V3HealthComponent"}},"version":{"type":"string","description":"Required Agent verison"}}},"V3HealthComponent":{"type":"object","properties":{"authType":{"$ref":"#/components/schemas/V3HealthAuthType"},"message":{"type":"string","description":"An error message, if the component status is DOWN"},"status":{"$ref":"#/components/schemas/V3HealthStatus"},"version":{"type":"string","description":"Optional component version"}}},"V3HealthAuthType":{"type":"string","description":"Type of authentication","enum":["RSA","CERT"]},"V3HealthStatus":{"type":"string","description":"Application health status.","enum":["UP","DOWN"]}}}}
```


# Health Check Extended

Returns the connectivity status of the Agent services as well as users connectivity.

`Available on Agent 2.57.0 and above.`&#x20;

## Checks health status of services and users

> \_Available on Agent 2.57.0 and above.\_\
> \
> Returns the connectivity status of the Agent services (\*\*pod\*\*, \*\*key manager\*\* and \*\*datafeed\*\*) as well as users\
> connectivity (\*\*agentservice\*\* and \*\*ceservice\*\*).\
> \
> The global status will be set to \`DOWN\` if at least one of the sub-status is also \`DOWN\`.<br>

```json
{"openapi":"3.0.1","info":{"title":"Agent API","version":"25.8.1"},"servers":[{"url":"youragentURL.symphony.com/agent"}],"paths":{"/v3/health/extended":{"get":{"tags":["System"],"summary":"Checks health status of services and users","description":"_Available on Agent 2.57.0 and above._\n\nReturns the connectivity status of the Agent services (**pod**, **key manager** and **datafeed**) as well as users\nconnectivity (**agentservice** and **ceservice**).\n\nThe global status will be set to `DOWN` if at least one of the sub-status is also `DOWN`.\n","operationId":"v3ExtendedHealth","responses":{"200":{"description":"Agent is healthy, all components are `UP`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/V3Health"}}}},"503":{"description":"Agent is unhealthy, some components are `DOWN`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/V3Health"}}}}}}}},"components":{"schemas":{"V3Health":{"type":"object","properties":{"services":{"type":"object","additionalProperties":{"$ref":"#/components/schemas/V3HealthComponent"}},"status":{"$ref":"#/components/schemas/V3HealthStatus"},"users":{"type":"object","additionalProperties":{"$ref":"#/components/schemas/V3HealthComponent"}},"version":{"type":"string","description":"Required Agent verison"}}},"V3HealthComponent":{"type":"object","properties":{"authType":{"$ref":"#/components/schemas/V3HealthAuthType"},"message":{"type":"string","description":"An error message, if the component status is DOWN"},"status":{"$ref":"#/components/schemas/V3HealthStatus"},"version":{"type":"string","description":"Optional component version"}}},"V3HealthAuthType":{"type":"string","description":"Type of authentication","enum":["RSA","CERT"]},"V3HealthStatus":{"type":"string","description":"Application health status.","enum":["UP","DOWN"]}}}}
```

{% hint style="info" %}
📘 **Result Fields**

This API returns the connectivity status of the Agent services as well as users connectivity. The global status will be set to `DOWN` if at least one of the sub-status is also `DOWN`.\
\
**Agent services**: pod, key manager and datafeed.\
**User connectivity**: agentservice and ceservice
{% endhint %}


# Session User

Returns the userId of the calling user.

## GET /v2/sessioninfo

> Get information about the current user's session.

```json
{"openapi":"3.1.1","info":{"title":"Pod API","version":"20.17.1"},"servers":[{"url":"http://yourpodURL.symphony.com/pod"}],"paths":{"/v2/sessioninfo":{"get":{"summary":"Get information about the current user's session.","parameters":[{"schema":{"type":"string"},"name":"sessionToken","description":"Session authentication token.","in":"header","required":true}],"tags":["Session"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserV2"}}}},"400":{"description":"Client error, see response body for further details.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Unauthorized: Invalid session token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Forbidden: Caller lacks necessary entitlement.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Server error, see response body for further details.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}}},"components":{"schemas":{"UserV2":{"description":"User record version 2","type":"object","properties":{"id":{"type":"integer","format":"int64"},"emailAddress":{"type":"string","format":"email"},"firstName":{"type":"string"},"lastName":{"type":"string"},"displayName":{"type":"string"},"title":{"type":"string"},"company":{"type":"string"},"username":{"type":"string"},"location":{"type":"string"},"accountType":{"type":"string","enum":["NORMAL","SYSTEM","SDL"]},"avatars":{"$ref":"#/components/schemas/AvatarList"},"workPhoneNumber":{"type":"string","description":"Note: only available if the application has the extended user or contact permission"},"mobilePhoneNumber":{"type":"string","description":"Note: only available if the application has the extended user or contact permission"},"jobFunction":{"type":"string","description":"Note: only available if the application has the extended user or contact permission"},"department":{"type":"string","description":"Note: only available if the application has the extended user or contact permission"},"division":{"type":"string","description":"Note: only available if the application has the extended user or contact permission"},"roles":{"$ref":"#/components/schemas/StringList"},"userMetadata":{"type":"object","description":"Metadata map of key/values","additionalProperties":{"type":"object"}}}},"AvatarList":{"type":"array","items":{"$ref":"#/components/schemas/Avatar"}},"Avatar":{"type":"object","properties":{"size":{"description":"The Avatar Size","type":"string"},"url":{"description":"Url of the image","type":"string"}}},"StringList":{"type":"array","items":{"type":"string"}},"Error":{"type":"object","properties":{"code":{"type":"integer","format":"int32"},"message":{"type":"string"}}}}}}
```

When calling this as an [OBO-enabled endpoint](/main/apps-on-behalf-of-obo/obo-enabled-endpoints#api-endpoints-enabled-for-obo):

* Use the [OBO User Authenticate](/main/apps-on-behalf-of-obo/obo-rsa-user-authentication-by-user-id) token for `sessionToken`.
* An OBO application must include the Primary User Identity (GET\_BASIC\_USER\_INFO) permission, along with all other required authentication and permissions. See [App Authenticate](/main/apps-on-behalf-of-obo/obo-rsa-app-authentication) and [OBO-Enabled Endpoints](/main/apps-on-behalf-of-obo/obo-enabled-endpoints#api-endpoints-enabled-for-obo).

See [Bot Permissions](https://docs.developers.symphony.com/building-bots-on-symphony/configuration/bot-permissions) for a list of roles and associated privileges.


# Agent Info

Gets configuration and deployment information about the Agent service.

## GET /v1/info

> Get information about the Agent

```json
{"openapi":"3.0.1","info":{"title":"Agent API","version":"25.8.1"},"servers":[{"url":"youragentURL.symphony.com/agent"}],"paths":{"/v1/info":{"get":{"tags":["Signals"],"summary":"Get information about the Agent","responses":{"200":{"description":"Agent info.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentInfo"}}}},"400":{"description":"Client error, see response body for further details.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/V2Error"}}}},"401":{"description":"Unauthorized: Session tokens invalid.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/V2Error"}}}},"403":{"description":"Forbidden: Caller lacks necessary entitlement.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/V2Error"}}}},"500":{"description":"Server error, see response body for further details.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/V2Error"}}}}}}}},"components":{"schemas":{"AgentInfo":{"type":"object","properties":{"ipAddress":{"type":"string","description":"The IP address of the Agent server."},"hostname":{"type":"string","description":"The hostname of the Agent server."},"serverFqdn":{"type":"string","description":"The fully-qualified domain name of the Agent server. Must be set by the user at startup."},"version":{"type":"string","description":"The version of the Agent."},"url":{"type":"string","description":"The URL under which the Agent is available."},"onPrem":{"type":"boolean","description":"Whether this is an on-prem or cloud installation."},"mt":{"type":"boolean","description":"Whether this is a multi tenant instance."},"commitId":{"type":"string","description":"The Git commit ID of the running revision."}}},"V2Error":{"required":["code","message"],"type":"object","properties":{"code":{"type":"integer","format":"int32"},"message":{"type":"string"},"details":{"type":"object"}}}}}}
```


# Echo

A test endpoint, which simply returns the input provided.

## POST /v1/util/echo

> Test endpoint, returns input.

```json
{"openapi":"3.0.1","info":{"title":"Agent API","version":"25.8.1"},"servers":[{"url":"youragentURL.symphony.com/agent"}],"paths":{"/v1/util/echo":{"post":{"tags":["Util"],"summary":"Test endpoint, returns input.","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":{"description":"Message in plain text","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SimpleMessage"}}},"required":true},"responses":{"200":{"description":"Message sent.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SimpleMessage"}}}},"400":{"description":"Client error, see response body for further details.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Unauthorized: Session tokens invalid.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Forbidden: Caller lacks necessary entitlement.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Server error, see response body for further details.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}}},"components":{"schemas":{"SimpleMessage":{"type":"object","properties":{"message":{"type":"string"}},"description":"A string wrapped in a JSON object."},"Error":{"type":"object","properties":{"code":{"type":"integer","format":"int32"},"message":{"type":"string"}}}}}}
```


# Messages


# Get Messages

## Get messages from an existing stream.

> A caller can fetch all unseen messages by passing the timestamp of\
> the last message seen as the since parameter and the number of messages\
> with the same timestamp value already seen as the skip parameter. This\
> means that every message will be seen exactly once even in the case that\
> an additional message is processed with the same timestamp as the last\
> message returned by the previous call, and the case where there are\
> more than maxMessages with the same timestamp value.\
> \
> This method is intended for historic queries and is generally reliable\
> but if guaranteed delivery of every message in real time is required\
> then the equivilent firehose method should be called.<br>

```json
{"openapi":"3.0.1","info":{"title":"Agent API","version":"25.8.1"},"servers":[{"url":"youragentURL.symphony.com/agent"}],"paths":{"/v4/stream/{sid}/message":{"get":{"tags":["Messages"],"summary":"Get messages from an existing stream.","description":"A caller can fetch all unseen messages by passing the timestamp of\nthe last message seen as the since parameter and the number of messages\nwith the same timestamp value already seen as the skip parameter. This\nmeans that every message will be seen exactly once even in the case that\nan additional message is processed with the same timestamp as the last\nmessage returned by the previous call, and the case where there are\nmore than maxMessages with the same timestamp value.\n\nThis method is intended for historic queries and is generally reliable\nbut if guaranteed delivery of every message in real time is required\nthen the equivilent firehose method should be called.\n","parameters":[{"name":"sid","in":"path","description":"Stream ID","required":true,"schema":{"type":"string"}},{"name":"since","in":"query","description":"Timestamp of first required message.\n\nThis is a long integer value representing milliseconds since\nJan 1 1970\n","required":true,"schema":{"type":"integer","format":"int64"}},{"name":"until","in":"query","description":"Timestamp of last required message.\n\nThis is a long integer value representing milliseconds since\nJan 1 1970\n","schema":{"type":"integer","format":"int64"}},{"name":"skip","in":"query","description":"No. of messages to skip.","schema":{"type":"integer"}},{"name":"limit","in":"query","description":"Max No. of messages to return. If no value is provided, 50 is the default. The maximum supported value is 500.\n","schema":{"type":"integer"}},{"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"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/V4MessageList"}}}},"204":{"description":"No Messages.","content":{}},"400":{"description":"Client error, see response body for further details.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/V2Error"}}}},"401":{"description":"Unauthorized: Session tokens invalid.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/V2Error"}}}},"403":{"description":"Forbidden: Caller lacks necessary entitlement.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/V2Error"}}}},"500":{"description":"Server error, see response body for further details.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/V2Error"}}}}}}}},"components":{"schemas":{"V4MessageList":{"type":"array","items":{"$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."}}},"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"}}},"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"}}}},"V2Error":{"required":["code","message"],"type":"object","properties":{"code":{"type":"integer","format":"int32"},"message":{"type":"string"},"details":{"type":"object"}}}}}}
```

> #### 📘 Optional attributes returned
>
> Note that some attributes are returned in the payload only under specific conditions:
>
> * `sharedMessage` only when the message represented by this class is a wall post sharing another message;
> * `initialMessageId`, `initialTimestamp`, and `replacing` only when the corresponding message is sent as an update to another message thanks to [Update Message](/main/messages/update-message-v4) endpoint. Note that the first two attributes relate to the original (and therefore first) message sent, whereas the `replacing` attribute relates to the message that has been updated by this message;
> * `replacedBy` only when this message has been updated by a new message. It contains the id of the replacing message.
> * `parentMessageId` only when this message is a reply or a forward of another message which id is returned in this attribute.

## Pagination usage

• The `skip` parameter is supposed to be used to skip messages that have the same timestamp as the one specified on `since`.

• Pagination is supposed to use the `since` parameter instead of `skip` and `limit`.

Examples:

If you want to get two messages at a time skipping the ones you have already seen, the calls should be the following:

1. First call\
   `https://acme.symphony.com/agent/v4/stream/sid/message?since=0&limit=2`
2. Second call\
   Let's assume here that the timestamp from the message returned on the first call was 1551052800000 and there was no other message with that same timestamp returned.

`https://acme.symphony.com/agent/v4/stream/sid/message?since=1551052800000&limit=2&skip=1`

It returns the two messages received after or on the timestamp 1551052800000, skipping one message from that same timestamp (which is the one you have already seen).

Note that you can keep doing this process with subsequent calls.

> #### 📘 Supported stream types
>
> In addition to conversation streams such as IM, Chat rooms and Wall posts, Symphony also supports other types of streams, some of them reserved for internal use. These other stream types (ACTION, POST, PRIVATE\_CHANNEL, MEETING, SUPPRESS\_JUSTIFICATION) are not supported by the Get Messages endpoint.

> #### 📘 See also:
>
> [Message](https://docs.developers.symphony.com/building-bots-on-symphony/messages)\
> [MessageML](https://docs.developers.symphony.com/building-bots-on-symphony/messages/overview-of-messageml)\
> [Message ID](https://docs.developers.symphony.com/bots/messages#message-identifiers)\
> [Message Format - MessageML](https://docs.developers.symphony.com/building-bots-on-symphony/messages/overview-of-messageml/message-format-messageml)\
> [PresentationML](https://docs.developers.symphony.com/building-bots-on-symphony/messages/overview-of-presentationml)\
> [Message Format - ExtensionML](https://docs.developers.symphony.com/building-extension-applications-on-symphony/overview-of-extension-api/extension-api-services/entity-service/message-format-extensionml)\
> [Colors](https://docs.developers.symphony.com/developer-tools/developer-tools/ui-style-guide/colors)


# Create Message

Posts a message to an existing stream.

## Post a message to one existing stream.

> Post a new message to the given stream. The stream can be a chatroom,,an IM or a multiparty IM.\
> \
> You may include an attachment on the message.\
> \
> The message can be provided as MessageMLV2 or PresentationML. Both formats support Freemarker templates.\
> \
> The optional parameter "data" can be used to provide a JSON payload containing entity data.\
> If the message contains explicit references to entity data (in "data-entity-id" element attributes),\
> this parameter is required.\
> \
> If the message is in MessageML and fails schema validation a client error will be returned.\
> \
> If the message is sent then 200 is returned.\
> \
> Regarding authentication, you must either use the sessionToken which was created for delegated app access\
> or both the sessionToken and keyManagerToken together.<br>

```json
{"openapi":"3.0.1","info":{"title":"Agent API","version":"25.8.1"},"servers":[{"url":"youragentURL.symphony.com/agent"}],"paths":{"/v4/stream/{sid}/message/create":{"post":{"tags":["Messages"],"summary":"Post a message to one existing stream.","description":"Post a new message to the given stream. The stream can be a chatroom,,an IM or a multiparty IM.\n\nYou may include an attachment on the message.\n\nThe message can be provided as MessageMLV2 or PresentationML. Both formats support Freemarker templates.\n\nThe optional parameter \"data\" can be used to provide a JSON payload containing entity data.\nIf the message contains explicit references to entity data (in \"data-entity-id\" element attributes),\nthis parameter is required.\n\nIf the message is in MessageML and fails schema validation a client error will be returned.\n\nIf the message is sent then 200 is returned.\n\nRegarding authentication, you must either use the sessionToken which was created for delegated app access\nor both the sessionToken and keyManagerToken together.\n","parameters":[{"name":"sid","in":"path","description":"Stream ID","required":true,"schema":{"type":"string"}},{"name":"sessionToken","in":"header","description":"Authorization token used to make delegated calls.","required":true,"schema":{"type":"string"}},{"name":"keyManagerToken","in":"header","description":"Key Manager authentication token.","schema":{"type":"string"}}],"requestBody":{"content":{"multipart/form-data":{"schema":{"properties":{"message":{"type":"string","description":"The message payload in MessageML."},"data":{"type":"string","description":"Optional message data in EntityJSON."},"version":{"type":"string","description":"Optional message version in the format \"major.minor\". If empty, defaults to the latest supported version.\n"},"attachment":{"type":"string","description":"Optional file attachment.","format":"binary"},"preview":{"type":"string","description":"Optional attachment preview.","format":"binary"}}}}}},"responses":{"200":{"description":"Message sent.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/V4Message"}}}},"400":{"description":"Client error, see response body for further details.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/V2Error"}}}},"401":{"description":"Unauthorized: Session tokens invalid.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/V2Error"}}}},"403":{"description":"Forbidden: Caller lacks necessary entitlement.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/V2Error"}}}},"451":{"description":"Compliance Issues found in message or file","content":{"application/json":{"schema":{"$ref":"#/components/schemas/V2Error"}}}},"500":{"description":"Server error, see response body for further details.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/V2Error"}}}}}}}},"components":{"schemas":{"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."}}},"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"}}},"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"}}}},"V2Error":{"required":["code","message"],"type":"object","properties":{"code":{"type":"integer","format":"int32"},"message":{"type":"string"},"details":{"type":"object"}}}}}}
```

* You can specify one or more attachments to the message. The attachment file can be uploaded along with the message using this endpoint.
* You can also specify [Structured Objects](https://docs.developers.symphony.com/building-bots-on-symphony/messages/structured-objects) as part of the message, and use [Apache FreeMarker templates](http://freemarker.org/) with these objects. See **Use Apache FreeMarker Templates** section below.
* Interactive Elements can be sent with your messages. See **Sending messages with Symphony Elements** section below.
* For authentication, you must either use the `sessionToken` that was created for delegated application access, or both the `sessionToken` and `keyManagerToken` together.
* When calling this as an [OBO-Enabled Endpoints](/main/apps-on-behalf-of-obo/obo-enabled-endpoints#api-endpoints-enabled-for-obo), use the [OBO User Authenticate](/main/apps-on-behalf-of-obo/obo-rsa-user-authentication-by-user-id) token for `sessionToken`.

> #### 🚧 Known Limitations
>
> * You can’t send a message that contains only an attachment without any message content. `message` must contain a least one space.
> * DLP (Expression Filters) only works with 1.53 version onwards.
> * Symphony Elements only works with 1.55.3 version onwards.
> * To send messages to not public rooms, the caller needs to be part of the stream.
> * To send numeric cashtags as signals, add a `*` before the number such as `$*122450`.\
>   E.g. `<messageML><cash tag="*122450"/></messageML>`\
>   For more information, refer to [Message Format - MessageML](https://docs.developers.symphony.com/building-bots-on-symphony/messages/overview-of-messageml).
> * Attachments: The limit is set to 30Mb total size; also, it is recommended not to exceed 25 files.
> * For more information on the size limits of messages, please refer to [Messages](https://docs.developers.symphony.com/building-bots-on-symphony/messages#message-size-limits) under the section Messages Size Limits.

### Sending messages with Symphony Elements

[Symphony Elements](https://docs.developers.symphony.com/building-bots-on-symphony/symphony-elements) is a collection of interactive elements that can be sent within messages to facilitate communication with Symphony users.

Through the use of the elements, bots can send messages that contain forms with text fields, dropdown menus, person selectors, buttons and more! To use the Elements, you just need to call the `/agent/v4/stream/:sid/message/create` API using the [MessageML](https://docs.developers.symphony.com/building-bots-on-symphony/messages/overview-of-messageml) format. For more information and examples, refer to [Symphony Elements](https://docs.developers.symphony.com/building-bots-on-symphony/symphony-elements).

*Sending Symphony Elements is only supported for `SYSTEM` users (Service Accounts).*

### Use Apache FreeMarker Templates

The `message` and `data` parameters of the [Create Message v4](/main/messages/create-message-v4) endpoint supports using [Apache FreeMarker templates](http://freemarker.org/) with [Structured Objects](https://docs.developers.symphony.com/building-bots-on-symphony/messages/structured-objects).

**Important!** To support the use of Freemarker variables, the top-level variable name in the `div` or `span` tag in `<messageML>` must be `$entity` or `$data`.

Using the [Freemarker](https://freemarker.apache.org/) template, you can also create tables that contain a special column with `checkboxes` or `buttons` on it, allowing users to select one or more rows of the table. For more information, refer to [Symphony Elements - Table Select](https://docs.developers.symphony.com/building-bots-on-symphony/symphony-elements/available-elements/table-select).

The first and second examples show the FreeMarker template content enclosed in `<messageML>` for the `message` parameter and the associated data model for the `data` parameter. The third example shows the resulting [PresentationML](https://docs.developers.symphony.com/building-bots-on-symphony/messages/overview-of-presentationml) representation of the message.

See also **cURL - Message + Data** in the examples below.

```xml
<messageML>
	<div>Messages for user <b>${data["messageList"].user.userName}</b>:</div>
	<table>
		<#list data["messageList"].messages as msg>
		<tr>
			<td>${msg.timestamp}</td>
			<td>${msg.text}</td>
		</tr>
		</#list>
	</table>
</messageML>
```

```json
{
  "messageList": {
    "version": "1.0",
    "user": {
      "id": 123456,
      "userName": "bot.user01"
    },
    "messages": [
      {
        "timestamp": "1504736061894",
        "text": "Ping"
      },
      {
        "timestamp": "1504736023993",
        "text": "Pong"
      }
    ]
  }
}
```

```xml
<div data-format="PresentationML" data-version="2.0">
   <div>Messages for user <b>bot.user01</b>:</div>
   <table>
      <tr>
         <td>1504736061894</td>
         <td>Ping</td>
      </tr>
      <tr>
         <td>1504736023993</td>
         <td>Pong</td>
      </tr>
   </table>
</div>
```

### Other request examples

```bash
curl -X POST \
  https://acme.symphony.com/agent/v4/stream/xFfPil_o26qXzGwWvcw5RH___qQr0W7EdA/message/create \
  -H 'Content-Type: multipart/form-data' \
  -H 'sessionToken: SESSION_TOKEN' \
	-H 'keyManagerToken: KEY_MANAGER_TOKEN' \
  --form-string 'message=<messageML>Hello world!</messageML>'
```

```bash
curl -X POST \
  https://acme.symphony.com:443/agent/v4/stream/xFfPil_o26qXzGwWvcw5RH___qQr0W7EdA/message/create \
  -H 'content-type: multipart/form-data' \
  -H 'keyManagerToken: KEY_MANAGER_TOKEN' \
  -H 'sessionToken: SESSION_TOKEN' \
  --form-string 'message=<messageML>Hello world!</messageML>' \
  -F 'attachment=@image1.png' \
  -F 'attachment=@image2.png'
```

```bash
curl -X POST \
https://acme.symphony.com:443/agent/v4/stream/xFfPil_o26qXzGwWvcw5RH___qQr0W7EdA/message/create \
  -H 'Content-Type: multipart/form-data' \
  -H 'keyManagerToken: KEY_MANAGER_TOKEN' \
  -H 'sessionToken: SESSION_TOKEN' \
  --form-string 'message=<messageML>This is an <div class="entity" data-entity-id="object001"><b>important</b></div> message.</messageML>' \
  -F 'data={
    "object001":
    {
        "type":     "org.symphonyoss.taxonomy",
        "version":  "0.1",
        "id":
        [
            {
                "type":     "org.symphonyoss.taxonomy.keyword",
                "value":    "important"
            }
        ]
    }
}'
```

```bash
curl -X POST \
  https://acme.symphony.com:443/agent/v4/stream/xFfPil_o26qXzGwWvcw5RH___qQr0W7EdA/message/create \

-H "sessionToken: SESSION_TOKEN" \
-H "keyManagerToken: KEY_MANAGER_TOKEN" \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "message='<messageML>Hello world</messageML>'&data='{'foo':'bar'}'"
```

```bash
curl -X POST \
  https://acme.symphony.com:443/agent/v4/stream/xFfPil_o26qXzGwWvcw5RH___qQr0W7EdA/message/create \

-H "sessionToken: SESSION_TOKEN" \
-H "keyManagerToken: KEY_MANAGER_TOKEN" \
-H "Content-Type: application/json" \
-d '{
        "message": "<messageML>Hello world</messageML>",
        "data": "{\"foo\":\"bar\"}"
    }'
```

> 📘 See also
>
> [Message](https://docs.developers.symphony.com/building-bots-on-symphony/messages)\
> [MessageML](https://docs.developers.symphony.com/building-bots-on-symphony/messages/overview-of-messageml)\
> [Message ID<br>](https://docs.developers.symphony.com/bots/messages#message-identifiers)\
> [Message Format - MessageML](https://docs.developers.symphony.com/building-bots-on-symphony/messages/overview-of-messageml)\
> [PresentationML](https://docs.developers.symphony.com/building-bots-on-symphony/messages/overview-of-presentationml)\
> [Message Format - ExtensionML](https://docs.developers.symphony.com/building-extension-applications-on-symphony/overview-of-extension-api/extension-api-services/entity-service/message-format-extensionml)\
> [Colors](https://docs.developers.symphony.com/developer-tools/developer-tools/ui-style-guide/colors)\
> [Symphony Elements](https://docs.developers.symphony.com/building-bots-on-symphony/symphony-elements)


# Blast Message

Posts a message to multiple existing streams.

`Available on Agent 2.62.0 and above.  Starting with Agent 23.6, this endpoint is OBO-enabled.`

## Post a message to multiple existing streams.

> Post a new message to the given list of streams. The stream can be a chatroom,\
> an IM or a multiparty IM.\
> \
> You may include an attachment on the message.\
> \
> The message can be provided as MessageMLV2 or PresentationML. Both formats support Freemarker templates.\
> \
> The optional parameter "data" can be used to provide a JSON payload containing entity data.\
> If the message contains explicit references to entity data (in "data-entity-id" element attributes),\
> this parameter is required.\
> \
> If the message is in MessageML and fails schema validation a client error results\
> \
> This endpoint is idempotent, it means that a 200 response will be returned even if the message has not been\
> delivered to some streams. Check the \`errors\` map from the response in order to see on which stream(s) the\
> message has not been delivered.\
> \
> The maximum number of streams where the message can be sent is limitted to 100.\
> \
> Regarding authentication, you must either use the sessionToken which was created for delegated app access\
> or both the sessionToken and keyManagerToken together.<br>

```json
{"openapi":"3.0.1","info":{"title":"Agent API","version":"25.8.1"},"servers":[{"url":"youragentURL.symphony.com/agent"}],"paths":{"/v4/message/blast":{"post":{"tags":["Messages"],"summary":"Post a message to multiple existing streams.","description":"Post a new message to the given list of streams. The stream can be a chatroom,\nan IM or a multiparty IM.\n\nYou may include an attachment on the message.\n\nThe message can be provided as MessageMLV2 or PresentationML. Both formats support Freemarker templates.\n\nThe optional parameter \"data\" can be used to provide a JSON payload containing entity data.\nIf the message contains explicit references to entity data (in \"data-entity-id\" element attributes),\nthis parameter is required.\n\nIf the message is in MessageML and fails schema validation a client error results\n\nThis endpoint is idempotent, it means that a 200 response will be returned even if the message has not been\ndelivered to some streams. Check the `errors` map from the response in order to see on which stream(s) the\nmessage has not been delivered.\n\nThe maximum number of streams where the message can be sent is limitted to 100.\n\nRegarding authentication, you must either use the sessionToken which was created for delegated app access\nor both the sessionToken and keyManagerToken together.\n","parameters":[{"name":"sessionToken","in":"header","description":"Authorization token used to make delegated calls.","required":true,"schema":{"type":"string"}},{"name":"keyManagerToken","in":"header","description":"Key Manager authentication token.","schema":{"type":"string"}}],"requestBody":{"content":{"multipart/form-data":{"schema":{"required":["sids"],"properties":{"sids":{"type":"array","description":"A comma-separated list of Stream IDs","items":{"type":"string"}},"message":{"type":"string","description":"The message payload in MessageML."},"data":{"type":"string","description":"Optional message data in EntityJSON."},"version":{"type":"string","description":"Optional message version in the format \"major.minor\". If empty, defaults to the latest supported version.\n"},"attachment":{"type":"string","description":"Optional file attachment.","format":"binary"},"preview":{"type":"string","description":"Optional attachment preview.","format":"binary"}}}}}},"responses":{"200":{"description":"Blast message sent.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/V4MessageBlastResponse"}}}},"400":{"description":"Client error, see response body for further details.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/V2Error"}}}},"401":{"description":"Unauthorized: Session tokens invalid.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/V2Error"}}}},"403":{"description":"Forbidden: Caller lacks necessary entitlement.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/V2Error"}}}},"451":{"description":"Compliance Issues found in message or file","content":{"application/json":{"schema":{"$ref":"#/components/schemas/V2Error"}}}},"500":{"description":"Server error, see response body for further details.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/V2Error"}}}}}}}},"components":{"schemas":{"V4MessageBlastResponse":{"type":"object","required":["messages","errors"],"properties":{"messages":{"type":"array","default":[],"description":"List of messages successfully sent","items":{"$ref":"#/components/schemas/V4Message"}},"errors":{"type":"object","additionalProperties":{"$ref":"#/components/schemas/Error"},"description":"List of streams where the messages ingestion has failed"}},"description":"Wrapper response for a single message sent to multiple streams"},"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."}}},"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"}}},"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"}}}},"Error":{"type":"object","properties":{"code":{"type":"integer","format":"int32"},"message":{"type":"string"}}},"V2Error":{"required":["code","message"],"type":"object","properties":{"code":{"type":"integer","format":"int32"},"message":{"type":"string"},"details":{"type":"object"}}}}}}
```

Blast Message enables you to post a new message to a given list of streams (each stream can either be a chatroom, an IM or a multiparty IM).\
It also includes all capabilities and limitations from Create Message V4 endpoint (i.e. using Symphony Elements, Apache FreeMarker Template, etc.)\
\&#xNAN;*Please check* [*Create Message V4*](/main/messages/create-message-v4) *where you will find those capabilities and limitations*

Please note that the blast message is not transactional, so you could have some failures sending some messages while others are successfully sent; for this reason, the service returns 200 OK even in case of error (i.e. there is an incorrect stream id within the list of `sids` provided). But in this case, each message failed is detailed.

> #### 🚧 Known Limitations
>
> * Considering performance purposes for encryption/decryption, the maximum number of stream Ids is set to 100. In case you want to send more messages, you will need to perform multiple requests to the endpoint.
> * See [Create Message V4](/main/messages/create-message-v4) for more information about other limitations

> 📘 See also
>
> [Create Message V4](ref:create-message-v4)\
> [Message](https://docs.developers.symphony.com/building-bots-on-symphony/messages)\
> [MessageML](https://docs.developers.symphony.com/building-bots-on-symphony/messages/overview-of-messageml)\
> [Message ID](https://docs.developers.symphony.com/bots/messages#message-identifiers)\
> [Message Format - MessageML](https://docs.developers.symphony.com/building-bots-on-symphony/messages/overview-of-messageml/message-format-messageml)\
> [PresentationML](https://docs.developers.symphony.com/building-bots-on-symphony/messages/overview-of-presentationml)\
> [Message Format - ExtensionML](https://docs.developers.symphony.com/building-extension-applications-on-symphony/overview-of-extension-api/extension-api-services/entity-service/message-format-extensionml)\
> [Colors](https://docs.developers.symphony.com/developer-tools/developer-tools/ui-style-guide/colors)\
> [Symphony Elements](https://docs.developers.symphony.com/building-bots-on-symphony/symphony-elements)


# Attachment

Downloads the attachment body by the attachment ID, stream ID, and message ID.

## Download an attachment.

> Downloads the attachment body by the attachment ID, stream ID, and message ID.

```json
{"openapi":"3.0.1","info":{"title":"Agent API","version":"25.8.1"},"servers":[{"url":"youragentURL.symphony.com/agent"}],"paths":{"/v1/stream/{sid}/attachment":{"get":{"tags":["Attachments"],"summary":"Download an attachment.","description":"Downloads the attachment body by the attachment ID, stream ID, and message ID.","parameters":[{"name":"sid","in":"path","description":"Stream ID","required":true,"schema":{"type":"string"}},{"name":"fileId","in":"query","description":"The attachment ID (Base64-encoded)","required":true,"schema":{"type":"string"}},{"name":"messageId","in":"query","description":"The ID of the message containing the attachment","required":true,"schema":{"type":"string"}},{"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"}}],"responses":{"200":{"description":"Attachment body as Base64 encoded string.","content":{"application/octet-stream":{"schema":{"type":"string","format":"byte"}}}},"400":{"description":"Client error, see response body for further details.","content":{"application/octet-stream":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Unauthorized: Session tokens invalid.","content":{"application/octet-stream":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Forbidden: Caller lacks necessary entitlement.","content":{"application/octet-stream":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Server error, see response body for further details.","content":{"application/octet-stream":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}}},"components":{"schemas":{"Error":{"type":"object","properties":{"code":{"type":"integer","format":"int32"},"message":{"type":"string"}}}}}}
```

> #### 🚧 Note
>
> A successful call returns the attachment body encoded in Base64. Be sure to decode the downloaded attachment.

> #### 📘 Attachments
>
> * Anyone can download attachments from public rooms or rooms with *viewHistory* enabled.
> * The Content Export service user is able to download attachments even from rooms he is not a member of.


# Import Message

Organizations can import messages to Symphony from another system using Symphony’s REST API. Typically message import is performed before an organization begins using Symphony, so that users' previous content and context are available from day one within Symphony.&#x20;

This endpoint Imports a message into Symphony from another system. Imported messages will be displayed in Symphony clients with the original system's content, sender, and timestamp.&#x20;

This endpoint takes as input a list of messages to be imported and outputs a status for each message. If a message is successfully imported, the `messageId` of the message created in Symphony is returned. If import fails on a given message, the rest of the operation will continue. It will be possible to detect any failures only after the entire operation is completed.

## Import messages from other systems into Symphony.

> Sends a message to be imported into the system.\
> Allows you to override the timestamp and author of the message with your desired values.\
> The requesting user must have the Content Management role.\
> The user that the message is intended to have come from must also be present in the conversation.\
> The intended message timestamp must be a valid time from the past. It cannot be a future timestamp.\
> Optionally the original message ID can be specified to identify the imported message for the purpose of repeat imports.<br>

```json
{"openapi":"3.0.1","info":{"title":"Agent API","version":"25.8.1"},"servers":[{"url":"youragentURL.symphony.com/agent"}],"paths":{"/v4/message/import":{"post":{"tags":["Messages"],"summary":"Import messages from other systems into Symphony.","description":"Sends a message to be imported into the system.\nAllows you to override the timestamp and author of the message with your desired values.\nThe requesting user must have the Content Management role.\nThe user that the message is intended to have come from must also be present in the conversation.\nThe intended message timestamp must be a valid time from the past. It cannot be a future timestamp.\nOptionally the original message ID can be specified to identify the imported message for the purpose of repeat imports.\n","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/V4MessageImportList"}}},"required":true},"responses":{"200":{"description":"Message sent.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/V4ImportResponseList"}}}},"400":{"description":"Client error, see response body for further details.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/V2Error"}}}},"401":{"description":"Unauthorized: Session tokens invalid.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/V2Error"}}}},"403":{"description":"Forbidden: Caller lacks necessary entitlement.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/V2Error"}}}},"500":{"description":"Server error, see response body for further details.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/V2Error"}}}}}}}},"components":{"schemas":{"V4MessageImportList":{"type":"array","description":"An ordered list of historic messages to be imported.\nA list of import responses will be returned in the same order.\n","items":{"$ref":"#/components/schemas/V4ImportedMessage"}},"V4ImportedMessage":{"required":["intendedMessageFromUserId","intendedMessageTimestamp","message","originatingSystemId","streamId"],"type":"object","properties":{"message":{"type":"string","description":"Message text in MessageMLV2","format":"MessageML"},"data":{"type":"string","description":"Entity data in EntityJSON","format":"JSON"},"intendedMessageTimestamp":{"type":"integer","description":"The timestamp representing the time when the message was sent in the original system\nin milliseconds since Jan 1st 1970.\n","format":"int64"},"intendedMessageFromUserId":{"type":"integer","description":"The long integer userid of the Symphony user who you intend to show sent the message.","format":"int64"},"originatingSystemId":{"type":"string","description":"The ID of the system through which the message was originally sent."},"originalMessageId":{"type":"string","description":"The ID of the message in the original system."},"streamId":{"type":"string"},"attachments":{"type":"array","description":"List of message attachments. Since Agent 20.14.","items":{"$ref":"#/components/schemas/V4ImportedMessageAttachment"}},"previews":{"type":"array","description":"List of attachments previews. Since Agent 20.14.","items":{"$ref":"#/components/schemas/V4ImportedMessageAttachment"}}},"description":"A historic message to be imported into the system.\nThe importing user must have the Content Management role.\nAlso, the importing user must be a member of the conversation it is importing into.\nThe user that the message is intended to have come from must also be present in the conversation.\nThe intended message timestamp must be a valid time from the past. It cannot be a future timestamp.\nBy design, imported messages do not stream to datafeed or firehose endpoints.\n"},"V4ImportedMessageAttachment":{"type":"object","properties":{"filename":{"type":"string","description":"Attachment filename"},"content":{"type":"string","description":"Attachment content as Base64 encoded string"}}},"V4ImportResponseList":{"type":"array","items":{"$ref":"#/components/schemas/V4ImportResponse"}},"V4ImportResponse":{"type":"object","properties":{"messageId":{"type":"string","description":"If the message was successfully imported then the message ID in the system\nof the newly created message.\n"},"originatingSystemId":{"type":"string","description":"The ID of the system through which the message was originally sent."},"originalMessageId":{"type":"string","description":"The ID of the message in the original system."},"diagnostic":{"type":"string","description":"A diagnostic message containing an error message in the event that the\nmessage import failed. May also be present in the case of a successful\ncall if there is useful narrative to return.\n"}}},"V2Error":{"required":["code","message"],"type":"object","properties":{"code":{"type":"integer","format":"int32"},"message":{"type":"string"},"details":{"type":"object"}}}}}}
```

### Request Examples

```bash
curl -X POST \
https://acme.symphony.com/agent/v4/message/import \
-H "sessionToken: SESSION_TOKEN" \
-H "keyManagerToken: KEY_MANAGER_TOKEN" \
-H "Content-Type: application/json" \
-d '[
    {
        "message": "<messageML>Imported message</messageML>",
        "format": "MESSAGEML",
        "intendedMessageTimestamp": 1433045622000,
        "intendedMessageFromUserId": 7215545057281,
        "originatingSystemId": "fooChat",
        "streamId": "Z3oQRAZGTCNl5KjiUH2G1n___qr9lLT8dA",
        "attachments": [
          {
            "filename": "symphonyLogo.png",
            "content": "iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAIAAACQkWg2AAAAAXNSR0IArs4c6QAAAMJlWElmTU0AKgAAAAgABwESAAMAAAABAAEAAAEaAAUAAAABAAAAYgEbAAUAAAABAAAAagEoAAMAAAABAAIAAAExAAIAAAARAAAAcgEyAAIAAAAUAAAAhIdpAAQAAAABAAAAmAAAAAAAAACQAAAAAQAAAJAAAAABUGl4ZWxtYXRvciAzLjkuOQAAMjAyMjowNDoxMSAyMjowNDozNwAAA6ABAAMAAAABAAEAAKACAAQAAAABAAAAEKADAAQAAAABAAAAEAAAAACv5s2fAAAACXBIWXMAABYlAAAWJQFJUiTwAAADqmlUWHRYTUw6Y29tLmFkb2JlLnhtcAAAAAAAPHg6eG1wbWV0YSB4bWxuczp4PSJhZG9iZTpuczptZXRhLyIgeDp4bXB0az0iWE1QIENvcmUgNi4wLjAiPgogICA8cmRmOlJERiB4bWxuczpyZGY9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvMDIvMjItcmRmLXN5bnRheC1ucyMiPgogICAgICA8cmRmOkRlc2NyaXB0aW9uIHJkZjphYm91dD0iIgogICAgICAgICAgICB4bWxuczp0aWZmPSJodHRwOi8vbnMuYWRvYmUuY29tL3RpZmYvMS4wLyIKICAgICAgICAgICAgeG1sbnM6ZXhpZj0iaHR0cDovL25zLmFkb2JlLmNvbS9leGlmLzEuMC8iCiAgICAgICAgICAgIHhtbG5zOnhtcD0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wLyI+CiAgICAgICAgIDx0aWZmOkNvbXByZXNzaW9uPjA8L3RpZmY6Q29tcHJlc3Npb24+CiAgICAgICAgIDx0aWZmOlJlc29sdXRpb25Vbml0PjI8L3RpZmY6UmVzb2x1dGlvblVuaXQ+CiAgICAgICAgIDx0aWZmOlhSZXNvbHV0aW9uPjE0NDwvdGlmZjpYUmVzb2x1dGlvbj4KICAgICAgICAgPHRpZmY6WVJlc29sdXRpb24+MTQ0PC90aWZmOllSZXNvbHV0aW9uPgogICAgICAgICA8dGlmZjpPcmllbnRhdGlvbj4xPC90aWZmOk9yaWVudGF0aW9uPgogICAgICAgICA8ZXhpZjpQaXhlbFhEaW1lbnNpb24+MTY8L2V4aWY6UGl4ZWxYRGltZW5zaW9uPgogICAgICAgICA8ZXhpZjpDb2xvclNwYWNlPjE8L2V4aWY6Q29sb3JTcGFjZT4KICAgICAgICAgPGV4aWY6UGl4ZWxZRGltZW5zaW9uPjE2PC9leGlmOlBpeGVsWURpbWVuc2lvbj4KICAgICAgICAgPHhtcDpDcmVhdG9yVG9vbD5QaXhlbG1hdG9yIDMuOS45PC94bXA6Q3JlYXRvclRvb2w+CiAgICAgICAgIDx4bXA6TW9kaWZ5RGF0ZT4yMDIyLTA0LTExVDIyOjA0OjM3PC94bXA6TW9kaWZ5RGF0ZT4KICAgICAgPC9yZGY6RGVzY3JpcHRpb24+CiAgIDwvcmRmOlJERj4KPC94OnhtcG1ldGE+CmV+OXgAAAK4SURBVCgVLVJbSFRBGJ7LOWfP6m5FBlqsl1LwrrGREkJpl4elKNyWKOhBkdAWkV6iBxG3pSKiKEQKetB601jah0CLDH3oydoNzEuWpHgrU0lXd/dc5tKc1mFg5v/n+2b+7/8Gcs4Z4whBAMDExEw4/D4anVxcXBGhy5XpdpfW158uLS0QYQoGKWUpdDD4NBweQljh4ogSgUBYggAxani9Zzo6rqc4ULwgdk1N7ZHINGUmIgbREhQgkcSASWoakxSMZLe7sKfnrkhahECgOxT6IMlQj28reSUZNZ49OXkQwI2FubWPA8bcpC3dQUzu850KBFrh2Ni07+INgCFLxqWDZQduddu0BJv/xhnF2UW6w7l8v5XMjuM0B6csFHoi9fUNMAawhIiuIcfeuA7mbnqNpZ9ATbflFu570MczXGTqE05zUgr6+wexJGWtr/9lQqm4OCufHT+J1EwkK9DQ6Mp8cuyz+WeBa3GhlFK6vZ3AnGcQQikhHCIW3zA3TV50DJ7wgprLLN9trP5iS99FMZRZY3NzCzuduYIqpIuiKVLI7BgZemlEh821ZcNVlvD4wI8pOD/OZFUAIIQoOzvLwiPM4jHt0JG19ncUK2wmyl8/4g+vbq8BkyNGCLBK4jk5+1F1daWwEHBOIAa/Z7kdxK7cMzML9NzDWw2PgQrA6gKxbOGCUFVVASORibq6BizaKgw0ksbRC8lLnUCVhEdAp/ZXQWU0DBQ7BOIHgeHhF5ZxbW13envfqCrSdBMkYty+y/D4BV55+wzGN0D6btWmaBptbDzf1dW+8zU8nmsjI18QEvXbmJ5kyZggIPsuZLNTQ2cM19a6BwefW8/utIhzv/+2LJfLcqUsV0i2SmvKFbJUKUnlfn/QaiMXMqhQay3/Qz46+rW5ubOk5JyilItZXHy2pSUgkqnTFOwfBvCVCZxF6WsAAAAASUVORK5CYII="
          },
          {
            "filename": "attachment.txt",
            "content": "VGhpcyBpcyBhbiBhdHRhY2htZW50Lg=="
          }
        ],
        "previews": [
          {
            "filename": "symphonyPreview.png",
            "content": "iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAIAAACQkWg2AAAAAXNSR0IArs4c6QAAAMJlWElmTU0AKgAAAAgABwESAAMAAAABAAEAAAEaAAUAAAABAAAAYgEbAAUAAAABAAAAagEoAAMAAAABAAIAAAExAAIAAAARAAAAcgEyAAIAAAAUAAAAhIdpAAQAAAABAAAAmAAAAAAAAACQAAAAAQAAAJAAAAABUGl4ZWxtYXRvciAzLjkuOQAAMjAyMjowNDoxMSAyMjowNDozNwAAA6ABAAMAAAABAAEAAKACAAQAAAABAAAAEKADAAQAAAABAAAAEAAAAACv5s2fAAAACXBIWXMAABYlAAAWJQFJUiTwAAADqmlUWHRYTUw6Y29tLmFkb2JlLnhtcAAAAAAAPHg6eG1wbWV0YSB4bWxuczp4PSJhZG9iZTpuczptZXRhLyIgeDp4bXB0az0iWE1QIENvcmUgNi4wLjAiPgogICA8cmRmOlJERiB4bWxuczpyZGY9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvMDIvMjItcmRmLXN5bnRheC1ucyMiPgogICAgICA8cmRmOkRlc2NyaXB0aW9uIHJkZjphYm91dD0iIgogICAgICAgICAgICB4bWxuczp0aWZmPSJodHRwOi8vbnMuYWRvYmUuY29tL3RpZmYvMS4wLyIKICAgICAgICAgICAgeG1sbnM6ZXhpZj0iaHR0cDovL25zLmFkb2JlLmNvbS9leGlmLzEuMC8iCiAgICAgICAgICAgIHhtbG5zOnhtcD0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wLyI+CiAgICAgICAgIDx0aWZmOkNvbXByZXNzaW9uPjA8L3RpZmY6Q29tcHJlc3Npb24+CiAgICAgICAgIDx0aWZmOlJlc29sdXRpb25Vbml0PjI8L3RpZmY6UmVzb2x1dGlvblVuaXQ+CiAgICAgICAgIDx0aWZmOlhSZXNvbHV0aW9uPjE0NDwvdGlmZjpYUmVzb2x1dGlvbj4KICAgICAgICAgPHRpZmY6WVJlc29sdXRpb24+MTQ0PC90aWZmOllSZXNvbHV0aW9uPgogICAgICAgICA8dGlmZjpPcmllbnRhdGlvbj4xPC90aWZmOk9yaWVudGF0aW9uPgogICAgICAgICA8ZXhpZjpQaXhlbFhEaW1lbnNpb24+MTY8L2V4aWY6UGl4ZWxYRGltZW5zaW9uPgogICAgICAgICA8ZXhpZjpDb2xvclNwYWNlPjE8L2V4aWY6Q29sb3JTcGFjZT4KICAgICAgICAgPGV4aWY6UGl4ZWxZRGltZW5zaW9uPjE2PC9leGlmOlBpeGVsWURpbWVuc2lvbj4KICAgICAgICAgPHhtcDpDcmVhdG9yVG9vbD5QaXhlbG1hdG9yIDMuOS45PC94bXA6Q3JlYXRvclRvb2w+CiAgICAgICAgIDx4bXA6TW9kaWZ5RGF0ZT4yMDIyLTA0LTExVDIyOjA0OjM3PC94bXA6TW9kaWZ5RGF0ZT4KICAgICAgPC9yZGY6RGVzY3JpcHRpb24+CiAgIDwvcmRmOlJERj4KPC94OnhtcG1ldGE+CmV+OXgAAAK4SURBVCgVLVJbSFRBGJ7LOWfP6m5FBlqsl1LwrrGREkJpl4elKNyWKOhBkdAWkV6iBxG3pSKiKEQKetB601jah0CLDH3oydoNzEuWpHgrU0lXd/dc5tKc1mFg5v/n+2b+7/8Gcs4Z4whBAMDExEw4/D4anVxcXBGhy5XpdpfW158uLS0QYQoGKWUpdDD4NBweQljh4ogSgUBYggAxani9Zzo6rqc4ULwgdk1N7ZHINGUmIgbREhQgkcSASWoakxSMZLe7sKfnrkhahECgOxT6IMlQj28reSUZNZ49OXkQwI2FubWPA8bcpC3dQUzu850KBFrh2Ni07+INgCFLxqWDZQduddu0BJv/xhnF2UW6w7l8v5XMjuM0B6csFHoi9fUNMAawhIiuIcfeuA7mbnqNpZ9ATbflFu570MczXGTqE05zUgr6+wexJGWtr/9lQqm4OCufHT+J1EwkK9DQ6Mp8cuyz+WeBa3GhlFK6vZ3AnGcQQikhHCIW3zA3TV50DJ7wgprLLN9trP5iS99FMZRZY3NzCzuduYIqpIuiKVLI7BgZemlEh821ZcNVlvD4wI8pOD/OZFUAIIQoOzvLwiPM4jHt0JG19ncUK2wmyl8/4g+vbq8BkyNGCLBK4jk5+1F1daWwEHBOIAa/Z7kdxK7cMzML9NzDWw2PgQrA6gKxbOGCUFVVASORibq6BizaKgw0ksbRC8lLnUCVhEdAp/ZXQWU0DBQ7BOIHgeHhF5ZxbW13envfqCrSdBMkYty+y/D4BV55+wzGN0D6btWmaBptbDzf1dW+8zU8nmsjI18QEvXbmJ5kyZggIPsuZLNTQ2cM19a6BwefW8/utIhzv/+2LJfLcqUsV0i2SmvKFbJUKUnlfn/QaiMXMqhQay3/Qz46+rW5ubOk5JyilItZXHy2pSUgkqnTFOwfBvCVCZxF6WsAAAAASUVORK5CYII="
          },
          {
            "filename": "attachment.txt",
            "content": "VGhpcyBpcyBhbiBhdHRhY2htZW50Lg=="
          }
        ]
    }
]'
```

```bash
curl -X POST \
https://acme.symphony.com/agent/v4/message/import \
-H "sessionToken: SESSION_TOKEN" \
-H "keyManagerToken: KEY_MANAGER_TOKEN" \
-H "Content-Type: application/json" \
-d '[
    {
        "message": "<messageML>Imported message</messageML>",
        "format": "MESSAGEML",
        "intendedMessageTimestamp": 1433045622000,
        "intendedMessageFromUserId": 7215545057281,
        "originatingSystemId": "fooChat",
        "streamId": "Z3oQRAZGTCNl5KjiUH2G1n___qr9lLT8dA"
    }
]'
```

### Prerequisites

* Your pod must be configured for Symphony's REST API, and you must have the [Agent](https://docs.developers.symphony.com/admin-guide/agent-guide/agent-download), the component used for handling encryption and decryption of messages and content, set up.
* You must have a Service User with the **Content Management** roles. This user can be set up in the Admin Portal. In most cases, you will also want this user to have the User Provisioning role as well. This user will be used to import messages.
* You must have a X.509 identity certificate for your import service user for REST API [authentication](/main/bot-authentication), where the common name on the certificate matches your service user's username.

> #### 📘 Service User Accounts
>
> A service account is a type of account used for bots or applications, rather than for real end-users.

> #### 🚧 Importing Messages
>
> The Content Management role is required to call the Import Message endpoint.
>
> Please note that the service user account needs to be part of the room where it imports messages.
>
> See [Bot Permissions](https://docs.developers.symphony.com/building-bots-on-symphony/configuration/bot-permissions) for a list of roles and associated privileges.

### v4ImportedMessage Format

You must specify each message to import as an object with the following fields:

<table><thead><tr><th width="198">Field</th><th width="86">Type</th><th width="68" data-type="checkbox">Required</th><th>Description</th></tr></thead><tbody><tr><td>message</td><td>string</td><td>true</td><td><ul><li>Messages can be sent either in plain text or <a href="https://docs.developers.symphony.com/building-bots-on-symphony/messages/overview-of-messageml">MessageML</a>, Symphony’s message format which allows for basic formatting and entities.</li><li>It is not possible to import file attachments.</li></ul></td></tr><tr><td>data</td><td>string</td><td>false</td><td>Entity data in EntityJSON</td></tr><tr><td>intendedMessageTimestamp</td><td>integer</td><td>true</td><td><p>The timestamp representing the time when the message was sent in the original system in milliseconds since January 1 1970 00:00:00 UTC.</p><p></p><p>Displays in Symphony clients as the timestamp of when the message was sent.</p><p></p><p>For example, if the message was originally sent in another system on January 1, 2016 and was imported on February 1, 2016, the Symphony conversation UI would show the message as being sent on January 1, 2016.</p><p></p><p>Must be a valid time in the past; a timestamp in the future returns an error.</p></td></tr><tr><td>intendedMessageFromUserId</td><td>long integer</td><td>true</td><td><p></p><p>The userId (long integer) of the Symphony user who sent the message. This user must:</p><ul><li>Be a member of the <code>streamId</code> that the message is being imported into.</li><li>Be an active user at the time of import.</li></ul><p>Importing messages from users who are inactive or not stream members results in an error.</p><p></p><p>You can deactivate this user after importing the message.</p><p></p><p>Note that the import service user does not need to be a member of the stream into which the message is imported.</p></td></tr><tr><td>originatingSystemId</td><td>string</td><td>true</td><td>An identifier for the original system through which the message was initially sent.</td></tr><tr><td>originalMessageId</td><td>string</td><td>false</td><td>The ID of the message in the originating system is used to prevent duplicate imports. During message import, the original messages IDs are compared to previously imported entries; in case of an exact match, the matching messages are ignored in the import.</td></tr><tr><td>streamId</td><td>string</td><td>true</td><td>The ID of the stream (IM or chatroom) into which the message is imported. Must be an active stream. Importing a message into an inactive stream results in an error. See <a href="https://docs.developers.symphony.com/building-bots-on-symphony/datafeed/overview-of-streams">Conversation ID</a> for details. It is possible to deactivate the room (or user in the case of an IM) after import.</td></tr><tr><td>attachments</td><td>array of objects</td><td>false</td><td><p>One or more files to be sent along with the message. The limit is set to 30Mb total size; also, it is recommended not to exceed 25 files.</p><p></p><p>Each attachment object is made up of the two following required field:</p><ul><li><code>filename</code> including the extension (i.e. img.png, test.txt)</li><li><code>content</code> as Base64 encoded string</li></ul></td></tr><tr><td>previews</td><td>array of objects</td><td>false</td><td><p>Optional attachment preview.</p><p></p><p>Each preview object is made up of the two following required field:</p><ul><li><code>filename</code> including the extension (i.e. img.png, test.txt) </li><li><code>content</code> as Base64 encoded string</li></ul><p>When using previews, make sure to declare the same number of previews as the attachments declared.</p></td></tr></tbody></table>

### V4ImportResponse

<table><thead><tr><th>Field</th><th width="73.33333333333331">Type</th><th>Description</th></tr></thead><tbody><tr><td><code>messageId</code></td><td><strong>string</strong></td><td>Contains the Symphony message ID if the message is successfully created.</td></tr><tr><td><code>originatingSystemId</code></td><td><strong>string</strong></td><td>See the description in <strong>v4ImportedMessage format</strong>.</td></tr><tr><td><code>originalMessageId</code></td><td><strong>string</strong></td><td>See the description in <strong>v4ImportedMessage format</strong>.</td></tr><tr><td><code>diagnostic</code></td><td><strong>string</strong></td><td>Contains an error message if the message import fails.</td></tr></tbody></table>

**Unread Status and Notifications**

* Imported messages do not generate unread message count badge notifications in the user's left navigation menu.
* Imported messages are not highlighted as unread in conversations.

**Read Receipts**

* Read receipts cannot be imported from another system to Symphony.
* Read receipts will be generated if a user views an imported message. This will be reflected in the Message Status table, displayed when clicking on the timestamp of a message.

**Special Entities**

* Imported messages which contain an at-mentions will appear in Social Activity under Recently Mentioned You; however, they do not generate unread message count badge notifications.
* Imported messages which contain hashtags and cashtags will not appear in Signals.

### Content Export of Imported Messages

Imported messages are reflected in content export based on their `intendedMessageTimestamp`. This means that when the import occurs, content export:

* **Excludes** historical messages with an `intendedMessageTimestamp` outside of the content export range.
* **Includes** include historical messages with an `intendedMessageTimestamp` within the content export range.

For ad-hoc content export, the content export range is specified by the user. For example, for an ad-hoc content export set with a start date of Jan 3 and an end date of Jan 5:

* Messages with an `intendedMessageTimestamp` prior to Jan 3 at 00:00:00 UTC \*\*are not \*\*exported.
* Messages with an `intendedMessageTimestamp` between to Jan 3 at 00:00:00 UTC and Jan 5 at 23:59:59 UTC **are** exported.
* Messages with an `intendedMessageTimestamp` after to Jan 5 at 23:59:59 UTC **are not** exported.

For recurring content export, the content export range is defined as the period until the next scheduled content export, with a duration of the content export frequency. For example, for a frequency of 24 hrs running at 01:00:00 UTC on Feb 10:

* Messages with an `intendedMessageTimestamp` prior to Feb 9 at 01:00:00 UTC \*\*are not \*\* exported.
* Messages with an `intendedMessageTimestamp` between to Feb 9 at 01:00:00 UTC and Feb 10 at 01:00:00 UTC **are** exported.

### Correct and Reimport Failed Messages

If a message import fails, use the information reported in the `diagnostic` field to correct the error and call this endpoint again. Symphony ignores any message with the same `originalMessageId` value as an existing message, and imports only those messages with unique`originalMessageId` values.

### Steps to Import a Message

1. Ensure users involved with the message are provisioned.
2. Ensure all streams have been created .
3. Import the message.
4. (Optional) User and Stream Membership and Deactivation.

### User Provisioning

When you migrate messages from another system to Symphony, you will need to ensure that the accounts of all users involved (all original senders and recipients) are created.

If all these users exist, you can skip this step.

User accounts can be provisioned via Symphony's REST API.

> #### 📘 User Provisioning Service User Account
>
> Accounts are provisioned by a Service User account which must be assigned the User Provisioning role. This user can be set up in the Admin Portal.
>
> It is possible to use the same service user account for both message import and account provisioning provided it has been assigned both the Content Management and User Provisioning roles.

In some cases, you will want to import messages where the original sender is no longer a member of the room or the firm. In this case, you should create the user, import any messages sent by that user, and either remove the user from the room or deactivate the user after the import has been performed.

### Stream Creation

You will also need to ensure that all the streams (IMs or chatrooms) have been created.

If all of these streams exist, you can skip this step.

Chatrooms can be created and managed via Symphony's REST API. Refer to the [Create Room v3](/main/streams-conversations/room-endpoints/create-room-v3) endpoint.

> #### 📘 Changing Chatroom Ownership
>
> If the import service user account is used to create chatrooms, the import service user will be the owner of those chatrooms.
>
> To change this, you can promote a member of the room to an owner and remove the import service user from the room.

In some cases, you may wish to import conversations into chats between two or more users - IMs or MIMs. Please note that MIMs are deprecated and shouldn't be used anymore.

IMs can be created using the [Create IM (admin)](/main/streams-conversations/im-mim-endpoints/create-im-or-mim-admin) endpoint.

> #### 🚧 Admin IM Creation
>
> The User Provisioning role is required to call the [Create IM (admin)](/main/streams-conversations/im-mim-endpoints/create-im-or-mim-admin) endpoint.
>
> You must use this endpoint rather than the [Create IM](/main/streams-conversations/im-mim-endpoints/create-im-or-mim) endpoint, so that the calling service user is not included as a participant of the chat.

### Message Import

Messages are imported using the **Import Message** endpoint described above.

> #### 🚧 Message Import Limits
>
> * We recommend importing in batches of no more than 5,000 messages at a time. Importing more than this number may result in slowness.
> * We recommend to be very precautious when using attachments with this endpoint as it will increase the payload hence the network usage between the Bot and the Agent.

> #### 🚧 Migration Times
>
> You should plan for a migration period, length dependent on the volume of messages to import and network latency.
>
> In our experience, an organization can import about 200K messages / hour.

> #### ❗️ Import Limitations
>
> It is only possible to import messages from another system into Symphony. It is not possible to import read receipts or chatroom events (ex. membership changes).

### User and Stream Membership and Deactivation

Once you have imported all your messages, you may wish to remove certain users from rooms or deactivate certain users or rooms.

For example, if you used the import service user for room creation, you may want to transfer ownership of the room and remove this user from the room.

For example, you may want to deactivate the Symphony user that was created to represent a user who sent messages in the old system, but has since left the firm.

### Admin Impact

**Content Export**\
The following are some notes that may be of interest to admins regarding aspects of imported messages:

* Imported messages are exported in Content Export based on the original timestamp (`intendedMessageTimestamp`).
* After messages are imported, Content Export will not include imported messages where the original timestamp is outside of the Content Export range and will include messages where the original timestamp is within the Content Export range.
* In ad-hoc content export, the range is specified by the admin user.
* For example, for an ad-hoc content export with a start date of January 1 and end date of January 5:
  * Messages with an original timestamp before January 1, 00:00:00 UTC **would not be** exported.
  * Messages with an original timestamp between January 1, 00:00:00 UTC and January 5, 23:59:59 UTC **would be** exported.
  * Messages with an original timestamp after January 5, 23:59:59 **would not be** exported.
* In recurring content export, the range is defined as the period until the next scheduled content export, with a duration of the content export frequency specified by the admin user.
* For example, for a recurring content export with a frequency of 24 hours running on February 2, 00:00:00 UTC:
  * Messages with an original timestamp before February 1, 00:00:00 UTC **would not be** exported.
  * Messages with an original timestamp between February 1, 00:00:00 UTC and January 2, 00:00:00 UTC **would be** exported.

**Room Monitor**

* Imported messages will be displayed in the Room Monitor as they are displayed to room members - with the original sender and original timestamp.

> 📘 See also
>
> [Message](https://docs.developers.symphony.com/building-bots-on-symphony/messages)\
> [MessageML](https://docs.developers.symphony.com/building-bots-on-symphony/messages/overview-of-messageml)\
> [Message ID](https://docs.developers.symphony.com/bots/messages#message-identifiers)\
> [Message Format - MessageML](https://docs.developers.symphony.com/building-bots-on-symphony/messages/overview-of-messageml/message-format-messageml)\
> [PresentationML](https://docs.developers.symphony.com/building-bots-on-symphony/messages/overview-of-presentationml)\
> [Message Format - ExtensionML](https://docs.developers.symphony.com/building-extension-applications-on-symphony/overview-of-extension-api/extension-api-services/entity-service/message-format-extensionml)\
> [Colors](https://docs.developers.symphony.com/developer-tools/developer-tools/ui-style-guide/colors)\
> [Symphony Elements](https://docs.developers.symphony.com/building-bots-on-symphony/symphony-elements)


# Update Message

Update an existing message.

`Available on Agent 20.13.1+ with SBE 20.13.2+ in Beta. Starting with SBE 20.16, the feature is now in Controlled Availability. Starting with Agent 23.6, this endpoint is OBO-enabled.`

## Update an existing message.

> Update an existing message. The existing message must be a valid social message, that has not been deleted.\
> \
> The message can be provided as MessageMLV2 or PresentationML. Both formats support Freemarker templates.\
> \
> The optional parameter "data" can be used to provide a JSON payload containing entity data.\
> If the message contains explicit references to entity data (in "data-entity-id" element attributes),\
> this parameter is required.\
> \
> Regarding authentication, you must either use the sessionToken which was created for delegated app access\
> or both the sessionToken and keyManagerToken together.\
> \
> Starting with SBE v24.1, attachments are supported.<br>

```json
{"openapi":"3.0.1","info":{"title":"Agent API","version":"25.8.1"},"servers":[{"url":"youragentURL.symphony.com/agent"}],"paths":{"/v4/stream/{sid}/message/{mid}/update":{"post":{"tags":["Messages"],"summary":"Update an existing message.","description":"Update an existing message. The existing message must be a valid social message, that has not been deleted.\n\nThe message can be provided as MessageMLV2 or PresentationML. Both formats support Freemarker templates.\n\nThe optional parameter \"data\" can be used to provide a JSON payload containing entity data.\nIf the message contains explicit references to entity data (in \"data-entity-id\" element attributes),\nthis parameter is required.\n\nRegarding authentication, you must either use the sessionToken which was created for delegated app access\nor both the sessionToken and keyManagerToken together.\n\nStarting with SBE v24.1, attachments are supported.\n","parameters":[{"name":"sid","in":"path","description":"Stream ID","required":true,"schema":{"type":"string"}},{"name":"mid","in":"path","description":"ID of the message to be updated","required":true,"schema":{"type":"string"}},{"name":"sessionToken","in":"header","description":"Authorization token used to make delegated calls.","required":true,"schema":{"type":"string"}},{"name":"keyManagerToken","in":"header","description":"Key Manager authentication token.","schema":{"type":"string"}}],"requestBody":{"content":{"multipart/form-data":{"schema":{"properties":{"message":{"type":"string","description":"The message payload in MessageML."},"data":{"type":"string","description":"Optional message data in EntityJSON."},"version":{"type":"string","description":"Optional message version in the format \"major.minor\". If empty, defaults to the latest supported version.\n"},"attachment":{"type":"string","description":"Optional file attachment.","format":"binary"},"preview":{"type":"string","description":"Optional attachment preview.","format":"binary"},"silent":{"type":"string","description":"Optional boolean field that will determine if the user/s should receive the message as read or not (true by default)\n"}}}}}},"responses":{"200":{"description":"Message sent.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/V4Message"}}}},"400":{"description":"Client error, see response body for further details.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/V2Error"}}}},"401":{"description":"Unauthorized: Session tokens invalid.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/V2Error"}}}},"403":{"description":"Forbidden: Caller lacks necessary entitlement.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/V2Error"}}}},"451":{"description":"Compliance Issues found in message or file","content":{"application/json":{"schema":{"$ref":"#/components/schemas/V2Error"}}}},"500":{"description":"Server error, see response body for further details.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/V2Error"}}}}}}}},"components":{"schemas":{"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."}}},"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"}}},"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"}}}},"V2Error":{"required":["code","message"],"type":"object","properties":{"code":{"type":"integer","format":"int32"},"message":{"type":"string"},"details":{"type":"object"}}}}}}
```

* For authentication, you must either use the `sessionToken` that was created for delegated application access, or both the `sessionToken` and `keyManagerToken` together.

> #### 📘 Controlled Availability
>
> Message Update is currently released with **Controlled Availability** because of the following limitations:
>
> * This feature is not yet supported on **Mobile**, where updates are displayed as new messages instead of replacing the existing one.
> * The flag `silent=false`, that can be used to make an update be displayed as an unread message, is not fully supported yet.
>
> Both limits will be lifted in a future release.

> #### 🚧 Permissions and guidelines
>
> * Entitlement `canUpdateMessage` is required.
> * Wall posts cannot be updated.
> * It is not possible to update messages sent by other users (except when using OBO with the proper permissions)
> * There is no time limit to update old messages, however we discourage updating very old messages as this won't provide a good user experience.
> * There is no limit of how many times a message can be updated, but we discourage updating it more than a 1000 times.
> * When used as a OBO endpoint, the end user must have the `canUpdateMessage` entitlement enabled, and the App must have the `SEND_MESSAGES` permission.


# Suppress Message

Suppress a message, preventing its contents from being displayed to users.

{% openapi src="/files/0awfCbIZtOPaANVs6Ftp" path="/v1/admin/messagesuppression/{id}/suppress" method="post" expanded="true" fullWidth="true" %}
[pod-api-public.yaml](https://544392450-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F909t04Fk8FiEI7fBcmlw%2Fuploads%2Fgit-blob-e56143a90f85b2a2e67b6c5a2db19a7b566d4ae2%2Fpod-api-public.yaml?alt=media)
{% endopenapi %}

### Suppressed Message Example

The following image shows how the UI represents a suppressed message.\
The image on the left shows the original message before being suppressed. The image on the right shows how the message will be displayed after being suppressed.

![](https://files.readme.io/a92e02e-suppressed.png)

As of Release v1.45, if the user attempts to suppress a message that has already been suppressed at an earlier point in time, the returned `suppressionDate` will have a value of 0, as shown below:

```json
{
    "messageId":"_Gj13MiR-5IrVtrmPNl6fn___qvWCYI_dA"
    "suppressed":true
    "suppressionDate":0
}
```

In addition, be aware that although the message is suppressed, the data from the original message will be in the Content Export (CE). When the CE exports a suppressed message, the following information are returned:

• Suppressed Message Content -> the content of the suppressed message.\
• Suppressed Message Sent From -> user that sent the suppressed message.\
• Suppressed Message Timestamp -> date when the message was suppressed.

> #### 🚧 Restricted Endpoint
>
> * Users can suppress their own messages only.
> * Users with the Content Management role can suppress any messages.
> * OBO: Please note that the SUPPRESS\_MESSAGES permission is needed for Apps to call this endpoint via OBO.
> * Starting with SBE 20.16, Messages in External rooms can also be suppressed. Please note however that if the counterpart does not yet have SBE 20.16, the message will only be suppressed on your end.
>
> See [Bot Permissions](https://docs.developers.symphony.com/building-bots-on-symphony/configuration/bot-permissions) for a list of roles and associated privileges.


# Message Search

Searches for messages in the context of a specified user, given an argument-based query.

## Search messages

> Search messages according to the specified criteria.

```json
{"openapi":"3.0.1","info":{"title":"Agent API","version":"25.8.1"},"servers":[{"url":"youragentURL.symphony.com/agent"}],"paths":{"/v1/message/search":{"post":{"tags":["Messages"],"summary":"Search messages","description":"Search messages according to the specified criteria.","parameters":[{"name":"skip","in":"query","description":"No. of results to skip.","schema":{"type":"integer"}},{"name":"limit","in":"query","description":"Max no. of results to return. If no value is provided, 50 is the default.","schema":{"type":"integer"}},{"name":"scope","in":"query","description":"Describes where content should be searched for that query.\nIt can exclusively apply to Symphony content or to one Connector.\n","schema":{"type":"string"}},{"name":"sortDir","in":"query","description":"Messages sort direction : ASC or DESC (default to DESC)\n","schema":{"type":"string"}},{"name":"tier","in":"query","description":"Target search tier : hot, warm or all (default to hot)\n","schema":{"type":"string"}},{"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":{"description":"The search query. See above for the query syntax.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MessageSearchQuery"}}},"required":true},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/V4MessageList"}}}},"204":{"description":"No Messages.","content":{}},"400":{"description":"Client error, see response body for further details.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/V2Error"}}}},"401":{"description":"Unauthorized: Session tokens invalid.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/V2Error"}}}},"403":{"description":"Forbidden: Caller lacks necessary entitlement.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/V2Error"}}}},"500":{"description":"Server error, see response body for further details.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/V2Error"}}}}}}}},"components":{"schemas":{"MessageSearchQuery":{"type":"object","properties":{"text":{"type":"string","description":"Search for messages containing this text. Requires streamId to be specified."},"streamId":{"type":"string","description":"Search for messages sent to this stream"},"streamType":{"type":"string","description":"Search for messages sent to this type of streams. Accepted values are CHAT, IM, MIM, ROOM, POST.\n"},"author":{"type":"integer","description":"Search for messages sent by this user ID","format":"int64"},"hashtag":{"type":"string","description":"Search for messages containing this hashtag"},"cashtag":{"type":"string","description":"Search for messages containing this cashtag"},"mention":{"type":"integer","description":"Search for messages mentioning this user ID","format":"int64"},"signal":{"type":"string","description":"Search for messages matching this signal. Can only be combined with date filtering and paging parameters.\n"},"fromDate":{"type":"integer","description":"Search for messages sent on or after this timestamp","format":"int64"},"toDate":{"type":"integer","description":"Search for messages sent before this timestamp","format":"int64"}}},"V4MessageList":{"type":"array","items":{"$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."}}},"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"}}},"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"}}}},"V2Error":{"required":["code","message"],"type":"object","properties":{"code":{"type":"integer","format":"int32"},"message":{"type":"string"},"details":{"type":"object"}}}}}}
```

### Request Example

```bash
curl -X POST https://acme.symphony.com/agent/v1/message/search \
    -H "sessionToken: SESSION_TOKEN" \
    -H "keyManagerToken: KEYMANAGER_TOKEN" \
    -H "Content-Type: application/json" \
    -d '{ "hashtag":"newWorld" }'
```

> #### 📘 Optional attributes returned
>
> Note that some attributes are returned in the payload only under specific conditions:
>
> * `sharedMessage` only when the message represented by this class is a wall post sharing another message;
> * `initialMessageId`, `initialTimestamp`, and `replacing` only when the corresponding message is sent as an update to another message thanks to [Update Message](/main/messages/update-message-v4) endpoint. Note that the first two attributes relate to the original (and therefore first) message sent, whereas the `replacing` attribute relates to the message that has been updated by this message;
> * `replacedBy` only when this message has been updated by a new message. It contains the id of the replacing message.
> * `parentMessageId` only when this message is a reply or a forward of another message which id is returned in this attribute.

### Search Query Arguments

The `query` parameter supports the following combination of arguments. When multiple arguments are supported, the search results are the union of all query arguments. Only a certain combination of arguments is supported.

* At least one argument in the list is required.
* Arguments names and values are case-insensitive.
* The same argument cannot be used multiple times.
* Search terms cannot contain the following reserved characters: colon `:`, parentheses `( )` and whitespaces (except when applying multi-word text search. See the `text` argument in the table below).
* `fromDate`, `toDate`, `mention`, and `author` are integers. All other arguments are strings.

<table><thead><tr><th width="149">Argument</th><th>Usage</th><th>Comment</th></tr></thead><tbody><tr><td><code>hashtag</code></td><td>Searches for a specific hashtag across messages to or in a specific <code>streamType</code></td><td><ul><li>Can be used in conjunction with <code>cashtag</code> or <code>mention</code>.</li><li>Can be used in conjunction to <code>author</code> or <code>text</code> only for a specific <code>streamType</code></li></ul></td></tr><tr><td><code>cashtag</code></td><td>Searches for a specific cashtag across all messages or in a specific <code>streamType</code></td><td><ul><li>Can be used in conjunction with <code>hashtag</code> or <code>mention</code>.</li><li>Can be used in conjunction to <code>author</code> or <code>text</code> only for a specific <code>streamType</code></li></ul></td></tr><tr><td><code>mention</code></td><td>Searches for a specific user mention, by user id, across all messages or in a specific <code>streamType</code></td><td><ul><li>Can be used in conjunction with <code>hashtag</code> or <code>cashtag</code>.</li><li>Can be used in conjunction to <code>author</code> or <code>text</code> only for a specific <code>streamType</code></li></ul></td></tr><tr><td><code>author</code></td><td>Searches for a specific message author, by user id, across all messages or for a specific <code>streamType</code></td><td>(<em>1.52 and later</em>) You can now search for an <code>author</code> in conjunction with a specific <code>streamType</code></td></tr><tr><td><code>text</code></td><td>Searches for plain text field in a specific message, not including any hashtag, cashtag or user mention.</td><td><ul><li>Requires a <code>streamId</code> to be provided.</li><li>Searching for text across all messages or a specific <code>streamType</code> is not supported.</li><li>Multi-word search is allowed.<br>Syntax: <code>"text":"Hello World"</code></li></ul></td></tr><tr><td><code>streamType</code></td><td>Searches for messages in a specific stream type, either:<br>• <code>CHAT</code> (1-1 instant messages and multi-party instant messages),<br>• <code>IM</code> (1-1 instant message),<br>• <code>MIM</code> (multi-party instant message),<br>• <code>ROOM</code>, or<br>• <code>POST</code> (user profile wall posts).</td><td>Can be used in conjunction with <code>author</code>, <code>hashtag</code>, <code>cashtag</code> or <code>mention</code></td></tr><tr><td><code>streamId</code></td><td>Searches for messages in a specific stream. See <a href="doc:room-id">Conversation ID</a> for streamId format.</td><td>Can be used in conjunction with <code>hashtag</code>, <code>cashtag</code>, <code>mention</code>, <code>text</code> or <code>author</code></td></tr><tr><td><code>signal</code></td><td>Search for messages matching this signal.</td><td>Can only be combined with date filtering and paging parameters.</td></tr></tbody></table>

### Date selector

The `query`parameter can optionally support the following date selectors:

* `fromDate`: selects messages sent after `fromDate`. Supported for all query parameters above.
* `toDate`: selects messages sent before `toDate`. Supported for all query parameters above.\
  The date selector parameter is inclusive: a message sent at exactly the same time as the query `fromDate` will be included in the results.

> #### 📘 See also
>
> [Message](https://docs.developers.symphony.com/building-bots-on-symphony/messages)\
> [MessageML](https://docs.developers.symphony.com/building-bots-on-symphony/messages/overview-of-messageml)\
> [Message ID](https://docs.developers.symphony.com/bots/messages#message-identifiers)\
> [Message Format - MessageML](https://docs.developers.symphony.com/building-bots-on-symphony/messages/overview-of-messageml/message-format-messageml)\
> [PresentationML](https://docs.developers.symphony.com/building-bots-on-symphony/messages/overview-of-presentationml)\
> [Message Format - ExtensionML](https://docs.developers.symphony.com/building-extension-applications-on-symphony/overview-of-extension-api/extension-api-services/entity-service/message-format-extensionml)\
> [Colors](https://docs.developers.symphony.com/developer-tools/developer-tools/ui-style-guide/colors)\
> [Symphony Elements](https://docs.developers.symphony.com/building-bots-on-symphony/symphony-elements)

> #### 🚧
>
> The messages returned by this endpoint follow the permissions required by the [Messages](/main/messages/messages-v4) endpoint.


# Message Search

Allows to search messages based on multiple search parameters.

## Search messages

> Search messages according to the specified criteria. The "query" parameter takes a search query defined as\
> "field:value" pairs combined by the operator "AND" (e.g. "text:foo AND autor:bar"). Supported fields are\
> &#x20;(case-insensitive): "text", "author", "hashtag", "cashtag", "mention", "signal", "fromDate", "toDate",\
> &#x20;"streamId", "streamType".\
> &#x20;"text" search requires a "streamId" to be specified.\
> &#x20;"streamType" accepts one of the following values: "chat" (IMs and MIMs), "im", "mim", "chatroom", "post".\
> &#x20;"signal" queries can only be combined with "fromDate", "toDate", "skip" and "limit" parameters.<br>

```json
{"openapi":"3.0.1","info":{"title":"Agent API","version":"25.8.1"},"servers":[{"url":"youragentURL.symphony.com/agent"}],"paths":{"/v1/message/search":{"get":{"tags":["Messages"],"summary":"Search messages","description":"Search messages according to the specified criteria. The \"query\" parameter takes a search query defined as\n\"field:value\" pairs combined by the operator \"AND\" (e.g. \"text:foo AND autor:bar\"). Supported fields are\n (case-insensitive): \"text\", \"author\", \"hashtag\", \"cashtag\", \"mention\", \"signal\", \"fromDate\", \"toDate\",\n \"streamId\", \"streamType\".\n \"text\" search requires a \"streamId\" to be specified.\n \"streamType\" accepts one of the following values: \"chat\" (IMs and MIMs), \"im\", \"mim\", \"chatroom\", \"post\".\n \"signal\" queries can only be combined with \"fromDate\", \"toDate\", \"skip\" and \"limit\" parameters.\n","parameters":[{"name":"query","in":"query","description":"The search query. See above for the query syntax.","required":true,"schema":{"type":"string"}},{"name":"skip","in":"query","description":"No. of results to skip.","schema":{"type":"integer"}},{"name":"limit","in":"query","description":"Max no. of results to return. If no value is provided, 50 is the default.","schema":{"type":"integer"}},{"name":"scope","in":"query","description":"Describes where content should be searched for that query.\nIt can exclusively apply to Symphony content or to one Connector.\n","schema":{"type":"string"}},{"name":"sortDir","in":"query","description":"Messages sort direction : ASC or DESC (default to DESC)\n","schema":{"type":"string"}},{"name":"tier","in":"query","description":"Target search tier : hot, warm or all (default to hot)\n","schema":{"type":"string"}},{"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"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/V4MessageList"}}}},"204":{"description":"No Messages.","content":{}},"400":{"description":"Client error, see response body for further details.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/V2Error"}}}},"401":{"description":"Unauthorized: Session tokens invalid.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/V2Error"}}}},"403":{"description":"Forbidden: Caller lacks necessary entitlement.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/V2Error"}}}},"500":{"description":"Server error, see response body for further details.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/V2Error"}}}}}}}},"components":{"schemas":{"V4MessageList":{"type":"array","items":{"$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."}}},"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"}}},"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"}}}},"V2Error":{"required":["code","message"],"type":"object","properties":{"code":{"type":"integer","format":"int32"},"message":{"type":"string"},"details":{"type":"object"}}}}}}
```

> #### 📘 Optional attributes returned
>
> Note that some attributes are returned in the payload only under specific conditions:
>
> * `sharedMessage` only when the message represented by this class is a wall post sharing another message;
> * `initialMessageId`, `initialTimestamp`, and `replacing` only when the corresponding message is sent as an update to another message thanks to [Update Message](/main/messages/update-message-v4) endpoint. Note that the first two attributes relate to the original (and therefore first) message sent, whereas the `replacing` attribute relates to the message that has been updated by this message;
> * `replacedBy` only when this message has been updated by a new message. It contains the id of the replacing message.
> * `parentMessageId` only when this message is a reply or a forward of another message which id is returned in this attribute.

> #### 🚧 Important
>
> You should use the [POST Message Search](/main/messages/message-search-get) endpoint where the query string is specified in the request body if your Agent is in-cloud. With this GET endpoint, query strings will be transmitted in the clear.

Allow to search messages across the message space the authenticated user has access to. This means all rooms this user is a member of and all public rooms.

### Query arguments

The `query` parameter supports the following combination of arguments. When multiple arguments are supported, the search results are the union of all query arguments, defined as `argument:value` pairs combined by the operator "AND". Only a certain combination of arguments is supported.

<table><thead><tr><th width="143">Argument</th><th>Usage</th><th>Comment</th></tr></thead><tbody><tr><td><code>hashtag</code></td><td>Searches for a specific hashtag across messages to or in a specific <code>streamType</code></td><td><ul><li>Can be used in conjunction with <code>cashtag</code> or <code>mention</code>.</li><li>Can be used in conjunction to <code>author</code> or <code>text</code> only for a specific <code>streamType</code></li></ul></td></tr><tr><td><code>cashtag</code></td><td>Searches for a specific cashtag across all messages or in a specific <code>streamType</code></td><td><ul><li>Can be used in conjunction with <code>hashtag</code> or <code>mention</code>.</li><li>Can be used in conjunction to <code>author</code> or <code>text</code> only for a specific <code>streamType</code></li></ul></td></tr><tr><td><code>mention</code></td><td>Searches for a specific user mention, by user id, across all messages or in a specific <code>streamType</code></td><td><ul><li>Can be used in conjunction with <code>hashtag</code> or <code>cashtag</code>.</li><li>Can be used in conjunction to <code>author</code> or <code>text</code> only for a specific <code>streamType</code></li></ul></td></tr><tr><td><code>author</code></td><td>Searches for a specific message author, by user id, across all messages or for a specific <code>streamType</code></td><td>(<em>1.52 and later</em>) You can now search for an <code>author</code> in conjunction with a specific <code>streamType</code></td></tr><tr><td><code>text</code></td><td>Searches for plain text field in a specific message, not including any hashtag, cashtag or user mention.</td><td><ul><li>Requires a <code>streamId</code> to be provided.</li><li>Searching for text across all messages or a specific <code>streamType</code> is not supported.</li><li>Multi-word search is allowed.<br>Syntax: <code>"text":"Hello World"</code></li></ul></td></tr><tr><td><code>streamType</code></td><td>Searches for messages in a specific stream type, either:<br>• <code>CHAT</code> (1-1 instant messages and multi-party instant messages),<br>• <code>IM</code> (1-1 instant message),<br>• <code>MIM</code> (multi-party instant message),<br>• <code>ROOM</code>, or<br>• <code>POST</code> (user profile wall posts).</td><td>Can be used in conjunction with <code>author</code>, <code>hashtag</code>, <code>cashtag</code> or <code>mention</code></td></tr><tr><td><code>streamId</code></td><td>Searches for messages in a specific stream. See <a href="doc:room-id">Conversation ID</a> for streamId format.</td><td>Can be used in conjunction with <code>hashtag</code>, <code>cashtag</code>, <code>mention</code>, <code>text</code> or <code>author</code></td></tr><tr><td><code>signal</code></td><td>Search for messages matching this signal.</td><td>Can only be combined with date filtering and paging parameters.</td></tr></tbody></table>

### Usage

* At least one argument in the list above is required.
* To provide multiple arguments, the query is formatted as `argument:value`, and separated with the operator `AND`. Returned messages will include messages that match all the arguments.
* Arguments names and values are case-insensitive.
* The same argument cannot be used multiple times.
* Search terms cannot contain the following reserved characters: colon `:`, parentheses `( )` and whitespaces (except when applying multi-word text search. See the `text` argument in the table above).

### Date selector

The `query`parameter can optionally support the following date selectors:

* `fromDate`: selects messages sent after `fromDate`. Supported for all query parameters above.
* `toDate`: selects messages sent before `toDate`. Supported for all query parameters above.\
  The date selector parameter is inclusive: a message sent at exactly the same time as the query `fromDate` will be included in the results

### Examples

* `query=hashtag:newWorld`
* `query=hashtag:newWorld AND mention:7627861917906`
* `query=hashtag:newWorld AND author:7627861917906 AND streamId:YQ_Q3ml8vMp98so2WRK_W3___qTUhq1_dA`
* `query=author:7627861917906`

> #### 📘 Note
>
> Spaces are expected between query arguments joined with AND.

> #### 📘 See also
>
> [Message](https://docs.developers.symphony.com/building-bots-on-symphony/messages)\
> [MessageML](https://docs.developers.symphony.com/building-bots-on-symphony/messages/overview-of-messageml)\
> [Message ID](https://docs.developers.symphony.com/bots/messages#message-identifiers)\
> [Message Format - MessageML](https://docs.developers.symphony.com/building-bots-on-symphony/messages/overview-of-messageml/message-format-messageml)\
> [PresentationML](https://docs.developers.symphony.com/building-bots-on-symphony/messages/overview-of-presentationml)\
> [Message Format - ExtensionML](https://docs.developers.symphony.com/building-extension-applications-on-symphony/overview-of-extension-api/extension-api-services/entity-service/message-format-extensionml)\
> [Colors](https://docs.developers.symphony.com/developer-tools/developer-tools/ui-style-guide/colors)\
> [Symphony Elements](https://docs.developers.symphony.com/building-bots-on-symphony/symphony-elements)


# Message Status

Get the status of a particular message: sent, delivered, and read.

{% openapi src="/files/0awfCbIZtOPaANVs6Ftp" path="/v1/message/{mid}/status" method="get" expanded="true" fullWidth="true" %}
[pod-api-public.yaml](https://544392450-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F909t04Fk8FiEI7fBcmlw%2Fuploads%2Fgit-blob-e56143a90f85b2a2e67b6c5a2db19a7b566d4ae2%2Fpod-api-public.yaml?alt=media)
{% endopenapi %}

The response indicates the status of the message for internal and external users:

* `sent`: All users to whom the message has been sent and received by the Symphony system, but not yet delivered to any user's Symphony client.
* `delivered`: All users who have at least one Symphony client to which the message has been delivered, and not read yet.
* `read`: All users who have read that message, in any Symphony client.

Note:

* For security reasons, the response excludes `userName` for external users.
* If a message is suppressed, the `sent` array will never contain any users as the message would no longer be accessible to users who have not already seen it. If the message has been `read` or `delivered` prior to being suppressed, the relevant arrays are available.

> #### 📘 known exceptions
>
> • If the user was on the stream when the message was sent and the stream had "viewHistory" (for rooms) enabled, he can get the message status.\
> • If the user is a member of the stream, he can get the message status.

> 📘 See also
>
> [Message](https://docs.developers.symphony.com/building-bots-on-symphony/messages)\
> [MessageML](https://docs.developers.symphony.com/building-bots-on-symphony/messages/overview-of-messageml)\
> [Message ID](https://docs.developers.symphony.com/bots/messages#message-identifiers)\
> [Message Format - MessageML](https://docs.developers.symphony.com/building-bots-on-symphony/messages/overview-of-messageml/message-format-messageml)\
> [PresentationML](https://docs.developers.symphony.com/building-bots-on-symphony/messages/overview-of-presentationml)\
> [Message Format - ExtensionML](https://docs.developers.symphony.com/building-extension-applications-on-symphony/overview-of-extension-api/extension-api-services/entity-service/message-format-extensionml)\
> [Colors](https://docs.developers.symphony.com/developer-tools/developer-tools/ui-style-guide/colors)\
> [Symphony Elements](https://docs.developers.symphony.com/building-bots-on-symphony/symphony-elements)


# Attachment Types

Retrieves a list of supported file extensions for attachments.

{% openapi src="/files/0awfCbIZtOPaANVs6Ftp" path="/v1/files/allowedTypes" method="get" expanded="true" fullWidth="true" %}
[pod-api-public.yaml](https://544392450-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F909t04Fk8FiEI7fBcmlw%2Fuploads%2Fgit-blob-e56143a90f85b2a2e67b6c5a2db19a7b566d4ae2%2Fpod-api-public.yaml?alt=media)
{% endopenapi %}

> #### 📘 See also
>
> [Message](https://docs.developers.symphony.com/building-bots-on-symphony/messages)\
> [MessageML](https://docs.developers.symphony.com/building-bots-on-symphony/messages/overview-of-messageml)\
> [Message ID](https://docs.developers.symphony.com/bots/messages#message-identifiers)\
> [Message Format - MessageML](https://docs.developers.symphony.com/building-bots-on-symphony/messages/overview-of-messageml/message-format-messageml)\
> [PresentationML](https://docs.developers.symphony.com/building-bots-on-symphony/messages/overview-of-presentationml)\
> [Message Format - ExtensionML](https://docs.developers.symphony.com/building-extension-applications-on-symphony/overview-of-extension-api/extension-api-services/entity-service/message-format-extensionml)\
> [Colors](https://docs.developers.symphony.com/developer-tools/developer-tools/ui-style-guide/colors)\
> [Symphony Elements](https://docs.developers.symphony.com/building-bots-on-symphony/symphony-elements)


# Get Message

Returns details about the specified message.

## GET /v1/message/{id}

> Get a message by ID

```json
{"openapi":"3.0.1","info":{"title":"Agent API","version":"25.8.1"},"servers":[{"url":"youragentURL.symphony.com/agent"}],"paths":{"/v1/message/{id}":{"get":{"tags":["Messages"],"summary":"Get a message by ID","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"}},{"name":"id","in":"path","description":"Message ID as a URL-safe string","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/V4Message"}}}},"204":{"description":"No Messages.","content":{}},"400":{"description":"Client error, see response body for further details.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/V2Error"}}}},"401":{"description":"Unauthorized: Session tokens invalid.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/V2Error"}}}},"403":{"description":"Forbidden: Caller lacks necessary entitlement.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/V2Error"}}}},"500":{"description":"Server error, see response body for further details.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/V2Error"}}}}}}}},"components":{"schemas":{"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."}}},"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"}}},"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"}}}},"V2Error":{"required":["code","message"],"type":"object","properties":{"code":{"type":"integer","format":"int32"},"message":{"type":"string"},"details":{"type":"object"}}}}}}
```

> #### 📘 Optional attributes returned
>
> Note that some attributes are returned in the payload only under specific conditions:
>
> * `sharedMessage` only when the message represented by this class is a wall post sharing another message;
> * `initialMessageId`, `initialTimestamp`, and `replacing` only when the corresponding message is sent as an update to another message thanks to [Update Message](/main/messages/update-message-v4) endpoint. Note that the first two attributes relate to the original (and therefore first) message sent, whereas the `replacing` attribute relates to the message that has been updated by this message;
> * `replacedBy` only when this message has been updated by a new message. It contains the id of the replacing message.
> * `parentMessageId` only when this message is a reply or a forward of another message which id is returned in this attribute.

> #### 📘 See also
>
> [Message](https://docs.developers.symphony.com/building-bots-on-symphony/messages)\
> [MessageML](https://docs.developers.symphony.com/building-bots-on-symphony/messages/overview-of-messageml)\
> [Message ID](https://docs.developers.symphony.com/bots/messages#message-identifiers)\
> [Message Format - MessageML](https://docs.developers.symphony.com/building-bots-on-symphony/messages/overview-of-messageml/message-format-messageml)\
> [PresentationML](https://docs.developers.symphony.com/building-bots-on-symphony/messages/overview-of-presentationml)\
> [Message Format - ExtensionML](https://docs.developers.symphony.com/building-extension-applications-on-symphony/overview-of-extension-api/extension-api-services/entity-service/message-format-extensionml)\
> [Colors](https://docs.developers.symphony.com/developer-tools/developer-tools/ui-style-guide/colors)\
> [Symphony Elements](https://docs.developers.symphony.com/building-bots-on-symphony/symphony-elements)


# List Attachments

List attachments in a particular stream.

{% openapi src="/files/0awfCbIZtOPaANVs6Ftp" path="/v1/streams/{sid}/attachments" method="get" expanded="true" fullWidth="true" %}
[pod-api-public.yaml](https://544392450-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F909t04Fk8FiEI7fBcmlw%2Fuploads%2Fgit-blob-e56143a90f85b2a2e67b6c5a2db19a7b566d4ae2%2Fpod-api-public.yaml?alt=media)
{% endopenapi %}


# List Message Receipts

Fetches receipts details from a specific message.

{% openapi src="/files/0awfCbIZtOPaANVs6Ftp" path="/v1/admin/messages/{messageId}/receipts" method="get" expanded="true" fullWidth="true" %}
[pod-api-public.yaml](https://544392450-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F909t04Fk8FiEI7fBcmlw%2Fuploads%2Fgit-blob-e56143a90f85b2a2e67b6c5a2db19a7b566d4ae2%2Fpod-api-public.yaml?alt=media)
{% endopenapi %}

> #### 🚧 Required roles
>
> Calling this endpoint requires the Content Management role with the VIEW\_MANAGE\_MESSAGES entitlement.\
> See [Bot Permissions](https://docs.developers.symphony.com/building-bots-on-symphony/configuration/bot-permissions) for a list of roles and associated privileges.


# Message Metadata

Gets the message metadata relationship. This API allows users to track the relationship between a message and all the forwards and replies of that message.

{% openapi src="/files/0awfCbIZtOPaANVs6Ftp" path="/v1/admin/messages/{messageId}/metadata/relationships" method="get" expanded="true" fullWidth="true" %}
[pod-api-public.yaml](https://544392450-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F909t04Fk8FiEI7fBcmlw%2Fuploads%2Fgit-blob-e56143a90f85b2a2e67b6c5a2db19a7b566d4ae2%2Fpod-api-public.yaml?alt=media)
{% endopenapi %}

> #### 📘 Message Relationship
>
> The Message Metadata API returns information about the current message relationships (parent, replies, forwards and form replies).

> #### 🚧 Required Roles
>
> Calling this endpoint requires the Content Management role.\
> See [Bot Permissions](https://docs.developers.symphony.com/building-bots-on-symphony/configuration/bot-permissions) for a list of roles and associated privileges.


# Datafeed - Real Time Events

### Introduction to Datafeed

[Datafeed](https://docs.developers.symphony.com/building-bots-on-symphony/datafeed) is a service that transmits encrypted messages that come from the end users to the bot (e.g. service account). The datafeed provides messages and events from all conversations that the user is in. The types of events surfaced in the datafeed can be found in the [Real Time Events](https://docs.developers.symphony.com/building-bots-on-symphony/datafeed/real-time-events) list.

{% hint style="warning" %}
**End of support for /agent/v4/datafeed endpoints (previously known as Datafeed 1.0)**

The following endpoints are deprecated and should no longer be used:

* /agent/v4/datafeed/create
* /agent/v4/datafeed/{id}/read

If you are still using these endpoints, please upgrade to the new /agent/v5/datafeeds endpoints, by going through the following [migration guide](https://docs.developers.symphony.com/bots/datafeed#changes-required-to-upgrade-to-v5-endpoints).
{% endhint %}

####


# Create Datafeed

Creates a new real time messages / events stream ("datafeed"). The datafeed provides messages and events from all conversations that the user is in. The types of events surfaced in the datafeed can be found in the [Real Time Events](https://docs.developers.symphony.com/building-bots-on-symphony/datafeed/real-time-events) list.

Returns the `ID` of the datafeed that has just been created. This `ID` should then be used as input to the [Read Datafeed](/main/datafeed/read-datafeed-v5) endpoint.

{% hint style="warning" %}
**Number of active feeds**

In the vast majority of the use cases, your bot should have **only one active feed**.

The platform however supports up to **20 feeds per service user**. If you try to create a 21st feed, you will receive a **403 error code**. In that case you need to delete one of your active feeds (i.e. get the list of feeds using [List Datafeed](/main/datafeed/list-datafeed-v5), then [Delete Datafeed](/main/datafeed/delete-datafeed-v5) on one of the listed feeds).
{% endhint %}

## Create a new real time feed of messages and events.

> \_Available on Agent 2.57.0 and above.\_\
> \
> The datafeed provides messages and events from all conversations that the user\
> is in. The types of events surfaced in the datafeed can be found in the Real Time Events list.\
> (see definition on top of the file)\
> \
> Returns the ID of the newly created datafeed.\
> This ID should then be used as input to the Read Datafeed endpoint.<br>

```json
{"openapi":"3.0.1","info":{"title":"Agent API","version":"25.8.1"},"servers":[{"url":"youragentURL.symphony.com/agent"}],"paths":{"/v5/datafeeds":{"post":{"tags":["Datafeed"],"summary":"Create a new real time feed of messages and events.","description":"_Available on Agent 2.57.0 and above._\n\nThe datafeed provides messages and events from all conversations that the user\nis in. The types of events surfaced in the datafeed can be found in the Real Time Events list.\n(see definition on top of the file)\n\nReturns the ID of the newly created datafeed.\nThis ID should then be used as input to the Read Datafeed endpoint.\n","operationId":"createDatafeed","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/V5DatafeedCreateBody"}}},"required":false},"responses":{"201":{"description":"Datafeed sucessfully created.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/V5Datafeed"}}}},"400":{"description":"Bad request.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/V2Error"}}}},"401":{"description":"Unauthorized.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/V2Error"}}}},"500":{"description":"Internal server error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/V2Error"}}}}}}}},"components":{"schemas":{"V5DatafeedCreateBody":{"type":"object","properties":{"tag":{"maxLength":100,"type":"string","description":"A unique identifier to ensure uniqueness of the datafeed."},"includeInvisible":{"type":"boolean","description":"Set to true to retrieve invisible rooms related events. Default is false."}}},"V5Datafeed":{"type":"object","properties":{"id":{"type":"string","description":"ID of the datafeed"},"createdAt":{"type":"integer","description":"[deprecated] Datafeed creation timestamp\n","format":"int64","deprecated":true},"type":{"type":"string","description":"The type of feed. Only allowed value is \"datahose\"."}},"description":"Container for the feed ID"},"V2Error":{"required":["code","message"],"type":"object","properties":{"code":{"type":"integer","format":"int32"},"message":{"type":"string"},"details":{"type":"object"}}}}}}
```


# Read Datafeed

Reads the specified datafeed. The datafeed provides messages and events from all conversations that the user is in. The types of events surfaced in the datafeed can be found in the [Real Time Events](https://docs.developers.symphony.com/building-bots-on-symphony/datafeed/real-time-events) list.

{% hint style="warning" %}
**Backward compatibility breaking notice**: Starting in May 2025, the `ackId` parameter must be either set to an empty string or omitted for the first Datafeed Read call.
{% endhint %}

## Read the specified real time message / event stream ("datafeed").

> \_Available on Agent 2.57.0 and above.\_\
> \
> The datafeed provides messages and events from all conversations that the user\
> is in. The types of events surfaced in the datafeed can be found in the Real Time Events list.\
> (see definition on top of the file)\
> \
> Read the specified datafeed.\
> \
> The ackId sent as parameter can 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; datafeed will remove the events\
> associated with that ackId from your queue<br>

```json
{"openapi":"3.0.1","info":{"title":"Agent API","version":"25.8.1"},"servers":[{"url":"youragentURL.symphony.com/agent"}],"paths":{"/v5/datafeeds/{datafeedId}/read":{"post":{"tags":["Datafeed"],"summary":"Read the specified real time message / event stream (\"datafeed\").","description":"_Available on Agent 2.57.0 and above._\n\nThe datafeed provides messages and events from all conversations that the user\nis in. The types of events surfaced in the datafeed can be found in the Real Time Events list.\n(see definition on top of the file)\n\nRead the specified datafeed.\n\nThe ackId sent as parameter can be empty for the first call. In the response an ackId will be sent back and it can be used for\nthe next call: in this way you acknowledge that you have received the events that came with that ackId; datafeed will remove the events\nassociated with that ackId from your queue\n","operationId":"readDatafeed","parameters":[{"name":"datafeedId","in":"path","description":"ID of the datafeed","required":true,"schema":{"type":"string"}},{"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/AckId"}}},"required":false},"responses":{"200":{"description":"Datafeed successfully read.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/V5EventList"}}}},"400":{"description":"Do not retry: the feed no longer exists, please create a new feed. The datafeed has a 30 minutes ttl. Alternatively, the format of the provided ackId may be incorrect.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/V2Error"}}}},"401":{"description":"Unauthorized.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/V2Error"}}}},"403":{"description":"Too many feeds created. This happens when you reached 20 active feeds. Usually, only one active feed is required per service account.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/V2Error"}}}},"500":{"description":"Internal server error. Please retry reading the datafeed with an exponential backoff.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/V2Error"}}}}}}}},"components":{"schemas":{"AckId":{"type":"object","properties":{"ackId":{"type":"string","description":"A unique id for events that can be deleted from a client's.\nParameter must be omitted or set to empty string for the first read. For successive reads, must be set to the ackId received in the last Datafeed Read.\n"},"updatePresence":{"type":"boolean","description":"Set to false to avoid updating the user's presence when reading events. Default is true.","default":true}},"description":"An object containing the ackId (and parameters) associated with \nevents that the client has received through an individual feed.\n"},"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"}}}}}}
```

{% hint style="info" %}
**ackId**: The `ackId` sent as a parameter **must** be either set to an empty string or omitted in the first call. In the response, an `ackId` will be sent back and it must be used for the next call. This way, you acknowledge that you have received the events that came with that `ackId` and that the datafeed will remove the events associated with that `ackId` from your queue. Events that have not been acknowledged will be re-queued and distributed again in a successive call.
{% endhint %}

{% hint style="warning" %}
**Datafeed ttl**: A datafeed time-to-live (ttl) is 30 minutes which means that, if your code doesn't poll the feed for 30 minutes, the feed will be deleted and your program will not receive queued messages. If your code attempts to read an expired or deleted feed, you will receive a 400 error code. Upon receiving a 400 error code, you need to create a new feed to continue to receive messages. Messages sent between the time the feed is deleted and you re-create a new one, will be lost.
{% endhint %}


# List Datafeed

The datafeed provides messages and events from all conversations that the user is in. The types of events surfaced in the datafeed can be found in the [Real Time Events](https://docs.developers.symphony.com/building-bots-on-symphony/datafeed/real-time-events) list.&#x20;

Returns the list of datafeeds for the user. Any datafeed ID of the list can then be used as input to the [Read Datafeed](/main/datafeed/read-datafeed-v5) endpoint.

## Returns the list of active datafeeds of the user.

> \_Available on Agent 2.57.0 and above.\_\
> \
> The datafeed provides messages and events from all conversations that the user\
> is in. The types of events surfaced in the datafeed can be found in the \[Real Time Events]\(./docs/real-time-events.md) list.\
> In most cases, only one active datafeed per user is required at a time.<br>

```json
{"openapi":"3.0.1","info":{"title":"Agent API","version":"25.8.1"},"servers":[{"url":"youragentURL.symphony.com/agent"}],"paths":{"/v5/datafeeds":{"get":{"tags":["Datafeed"],"summary":"Returns the list of active datafeeds of the user.","description":"_Available on Agent 2.57.0 and above._\n\nThe datafeed provides messages and events from all conversations that the user\nis in. The types of events surfaced in the datafeed can be found in the [Real Time Events](./docs/real-time-events.md) list.\nIn most cases, only one active datafeed per user is required at a time.\n","operationId":"listDatafeed","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"}},{"name":"tag","in":"query","description":"A unique identifier to ensure uniqueness of the datafeed. Used to restrict search.","schema":{"maxLength":100,"type":"string"}}],"responses":{"200":{"description":"Datafeed sucessfully created.","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/V5Datafeed"}}}}},"400":{"description":"Bad request.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/V2Error"}}}},"401":{"description":"Unauthorized.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/V2Error"}}}},"500":{"description":"Internal server error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/V2Error"}}}}}}}},"components":{"schemas":{"V5Datafeed":{"type":"object","properties":{"id":{"type":"string","description":"ID of the datafeed"},"createdAt":{"type":"integer","description":"[deprecated] Datafeed creation timestamp\n","format":"int64","deprecated":true},"type":{"type":"string","description":"The type of feed. Only allowed value is \"datahose\"."}},"description":"Container for the feed ID"},"V2Error":{"required":["code","message"],"type":"object","properties":{"code":{"type":"integer","format":"int32"},"message":{"type":"string"},"details":{"type":"object"}}}}}}
```


# Delete Datafeed

Deletes the specified real-time message/event stream (datafeed). The types of events surfaced in the datafeed can be found in the [Real Time Events](https://docs.developers.symphony.com/building-bots-on-symphony/datafeed/real-time-events) list.

## Delete the specified real time message / event stream ("datafeed").

> \_Available on Agent 2.57.0 and above.\_\
> \
> The datafeed provides messages and events from all conversations that the user\
> is in. The types of events surfaced in the datafeed can be found in the Real Time Events list.\
> (see definition on top of the file)\
> \
> Delete the specified datafeed.<br>

```json
{"openapi":"3.0.1","info":{"title":"Agent API","version":"25.8.1"},"servers":[{"url":"youragentURL.symphony.com/agent"}],"paths":{"/v5/datafeeds/{datafeedId}":{"delete":{"tags":["Datafeed"],"summary":"Delete the specified real time message / event stream (\"datafeed\").","description":"_Available on Agent 2.57.0 and above._\n\nThe datafeed provides messages and events from all conversations that the user\nis in. The types of events surfaced in the datafeed can be found in the Real Time Events list.\n(see definition on top of the file)\n\nDelete the specified datafeed.\n","operationId":"deleteDatafeed","parameters":[{"name":"datafeedId","in":"path","description":"ID of the datafeed","required":true,"schema":{"type":"string"}},{"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"}}],"responses":{"204":{"description":"Datafeed successfully deleted.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/V2Error"}}}},"400":{"description":"Bad request.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/V2Error"}}}},"401":{"description":"Unauthorized.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/V2Error"}}}},"500":{"description":"Internal server error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/V2Error"}}}}}}}},"components":{"schemas":{"V2Error":{"required":["code","message"],"type":"object","properties":{"code":{"type":"integer","format":"int32"},"message":{"type":"string"},"details":{"type":"object"}}}}}}
```


# Datahose - Pod Real Time Events

Datahose is a data streaming service, that gives access to all messages and events in real time.

Similarly to [Datafeed 2](broken://pages/418dsNsIYJxEIrnsq1dA), Datahose allows a service user account (bot) to retrieve [Real Time Events](https://docs.developers.symphony.com/building-bots-on-symphony/datafeed/real-time-events) including all chat messages. However, with Datahose, there is no need for the service user to be part of a chat conversation to receive its messages: the service user will automatically receive **all events from all conversations** of the pod in real time.

Get more information on how to use Datahose with the [Datahose - Read Events](/main/datahose/datahose-read-events) endpoint.

{% content-ref url="/spaces/909t04Fk8FiEI7fBcmlw/pages/6YZgrm0Uz3apHSn2aHXN" %}
[Datahose - Read Events](/main/datahose/datahose-read-events)
{% endcontent-ref %}

{% 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 %}


# 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](/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.


# Streams - Conversations


# Related to IMs


# Create IM

Creates a new instant message conversation or returns an existing IM between the specified users and the calling user.

{% hint style="info" %}
**Important**: This endpoint also allows the creation of Multi-party Instant Messages (MIM), which are not supported anymore. If you need to create a chat with several participants, please create a room instead.
{% endhint %}

## Create a new single or multi party instant message conversation between the caller and specified users.

> At least one user ID must be provided or\
> an error response will be sent.\
> \
> The caller is implicitly included in the members of the\
> created chat.\
> \
> Duplicate users will be included in the membership of the chat but\
> the duplication will be silently ignored.\
> \
> If there is an existing IM conversation with the same set of participants then\
> the id of that existing stream will be returned.\
> \
> This method was incorrectly specified to take a query parameter in\
> version 1.0 of this specification but now expects a JSON array of\
> user IDs in the body of the request.<br>

```json
{"openapi":"3.1.1","info":{"title":"Pod API","version":"20.17.1"},"servers":[{"url":"http://yourpodURL.symphony.com/pod"}],"paths":{"/v1/im/create":{"post":{"summary":"Create a new single or multi party instant message conversation between the caller and specified users.","description":"At least one user ID must be provided or\nan error response will be sent.\n\nThe caller is implicitly included in the members of the\ncreated chat.\n\nDuplicate users will be included in the membership of the chat but\nthe duplication will be silently ignored.\n\nIf there is an existing IM conversation with the same set of participants then\nthe id of that existing stream will be returned.\n\nThis method was incorrectly specified to take a query parameter in\nversion 1.0 of this specification but now expects a JSON array of\nuser IDs in the body of the request.\n","parameters":[{"schema":{"type":"string"},"name":"sessionToken","description":"Session authentication token.","in":"header","required":true}],"tags":["Streams"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Stream"}}}},"400":{"description":"Client error, see response body for further details.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Unauthorized: Invalid session token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Forbidden: Caller lacks necessary entitlement.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Server error, see response body for further details.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserIdList"}}},"description":"List of (integer) User IDs of participants","required":true}}}},"components":{"schemas":{"Stream":{"type":"object","properties":{"id":{"type":"string"}}},"Error":{"type":"object","properties":{"code":{"type":"integer","format":"int32"},"message":{"type":"string"}}},"UserIdList":{"type":"array","items":{"type":"integer","format":"int64"}}}}}
```

* The calling user is implicitly included as a member of the instant message conversation.
* One other participant must be specified.
* If a user ID appears in the list multiple times, duplicates will be ignored.
* If there is an existing IM conversation with the specified participant, then the id of the existing stream will be returned.
* Use [Create IM non-inclusive](/main/streams-conversations/im-mim-endpoints/create-im-or-mim-admin) to exclude the calling user.

When calling this as an [OBO-enabled endpoint](/main/apps-on-behalf-of-obo), use the [OBO User Authenticate](/main/apps-on-behalf-of-obo/obo-rsa-user-authentication-by-user-id) token for `sessionToken`.

A user needs to have the entitlement `isExternalIMEnabled` if he wants to create a crosspod IM (User entitlements are set on Admin Portal).

External users must be connected with the caller before adding them.

> #### 📘 Overview of streams
>
> A stream is like a container for messages exchanged between two or more users via a given instant message (IM) or chat room. For more information, refer to [Overview of streams](https://docs.developers.symphony.com/building-bots-on-symphony/datafeed/overview-of-streams).


# Create IM non-inclusive

Creates a new instant message conversation or returns an existing IM between the specified users, but excluding the calling user.

{% hint style="info" %}
**Important**: This endpoint also allows the creation of Multi-party Instant Messages (MIM), which are not supported anymore. If you need to create a chat with several participants, please create a room instead.
{% endhint %}

## Create a new single or multi party instant message conversation

> At least two user IDs must be provided or\
> an error response will be sent.\
> \
> The caller is not included in the members of the\
> created chat.\
> \
> Duplicate users will be included in the membership of the chat but\
> the duplication will be silently ignored.\
> \
> If there is an existing IM conversation with the same set of participants then\
> the id of that existing stream will be returned.<br>

```json
{"openapi":"3.1.1","info":{"title":"Pod API","version":"20.17.1"},"servers":[{"url":"http://yourpodURL.symphony.com/pod"}],"paths":{"/v1/admin/im/create":{"post":{"summary":"Create a new single or multi party instant message conversation","description":"At least two user IDs must be provided or\nan error response will be sent.\n\nThe caller is not included in the members of the\ncreated chat.\n\nDuplicate users will be included in the membership of the chat but\nthe duplication will be silently ignored.\n\nIf there is an existing IM conversation with the same set of participants then\nthe id of that existing stream will be returned.\n","parameters":[{"schema":{"type":"string"},"name":"sessionToken","description":"Session authentication token.","in":"header","required":true}],"tags":["Streams"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Stream"}}}},"400":{"description":"Client error, see response body for further details.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Unauthorized: Invalid session token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Forbidden: Caller lacks necessary entitlement.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Server error, see response body for further details.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserIdList"}}},"description":"List of (integer) User IDs of participants","required":true}}}},"components":{"schemas":{"Stream":{"type":"object","properties":{"id":{"type":"string"}}},"Error":{"type":"object","properties":{"code":{"type":"integer","format":"int32"},"message":{"type":"string"}}},"UserIdList":{"type":"array","items":{"type":"integer","format":"int64"}}}}}
```

* Two participants must be specified.
* If a user ID appears in the list multiple times, duplicates will be ignored.
* If there is an existing IM conversation with the specified participants, then the id of the existing stream will be returned.
* Use [Create IM](/main/streams-conversations/im-mim-endpoints/create-im-or-mim) to include the calling user.

> #### 🚧 Required Permissions
>
> This endpoint can only be called by Service Users with the User Provisioning role.\
> See [Bot Permissions](https://docs.developers.symphony.com/building-bots-on-symphony/configuration/bot-permissions) for a list of roles and associated privileges.

> #### 📘 Overview of streams
>
> A stream is like a container for messages exchanged between two or more users via a given instant message (IM) or chat room. For more information, refer to [Overview of streams](https://docs.developers.symphony.com/building-bots-on-symphony/datafeed/overview-of-streams).


# Update IM

Updates the attributes of an existing IM conversation.

## POST /v1/im/{id}/update

> Update the attributes of an existing IM.

```json
{"openapi":"3.1.1","info":{"title":"Pod API","version":"20.17.1"},"servers":[{"url":"http://yourpodURL.symphony.com/pod"}],"paths":{"/v1/im/{id}/update":{"post":{"summary":"Update the attributes of an existing IM.","parameters":[{"schema":{"type":"string"},"name":"id","description":"IM streamID","in":"path","required":true},{"schema":{"type":"string"},"name":"sessionToken","description":"Session authentication token.","in":"header","required":true}],"tags":["Streams"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/V1IMDetail"}}}},"400":{"description":"Client error, see response body for further details.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Unauthorized: Invalid session token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Forbidden: Caller lacks necessary entitlement.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"451":{"description":"Unavailable for Legal Reasons: Compliance Issues found in IM update request.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Server error, see response body for further details.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/V1IMAttributes"}}},"required":true}}}},"components":{"schemas":{"V1IMDetail":{"type":"object","properties":{"V1IMAttributes":{"$ref":"#/components/schemas/V1IMAttributes"},"IMSystemInfo":{"$ref":"#/components/schemas/IMSystemInfo"}}},"V1IMAttributes":{"type":"object","properties":{"pinnedMessageId":{"type":"string","description":"UrlSafe message id of the pinned message inside the IM. To perform unpin operation, send an empty string."}}},"IMSystemInfo":{"type":"object","properties":{"id":{"type":"string"},"creationDate":{"type":"integer","format":"int64","description":"The datetime when the stream was originally created. Milliseconds since Jan 1 1970."},"active":{"type":"boolean","description":"If false, no messages can be sent in this stream, and membership is locked."}}},"Error":{"type":"object","properties":{"code":{"type":"integer","format":"int32"},"message":{"type":"string"}}}}}}
```

Returns an error when:

* The call doesn’t include an update to at least one editable attribute.

> #### 📘 Stream ID
>
> The stream ID can be located in the Symphony web or desktop client by clicking on the timestamp of any message in the conversation. This will open the Message Status module overlay, and the Conversation ID can be found in the overlay footer.
>
> The stream ID in the UI is in Standard Base64 encoding. When the stream ID needs to be used in a URL, it should be in URLSafe Base64 encoding. To obtain the URLSafe Base64 stream ID, replace forward slashes with underscores, replace pluses with minuses, and ignore any trailing equal signs.
>
> Note: visit [Overview of streams](https://docs.developers.symphony.com/building-bots-on-symphony/datafeed/overview-of-streams) for more information.

> #### 🚧 Attributes
>
> * The `pinnedMessageId` attribute allows to display an exact copy of the original message in a pinned area placed beneath the chat header and that remains always visible to all users. From this area, they can interact with the message content (i.e. forms or ui actions buttons), and they are able to automatically jump to the original message in the chat canvas. You can use this attribute as follows:
>   * either by entering the URLSafe Base 64 ID of the message you wish to pin beneath the chat header (as you can see in the example). Even if another message is pinned, this new message will replace it in the pinned area;
>   * either by entering an empty value as follows: "pinnedMessageId": "". This is used to upin any message and remove therefore this area from being visible to users;
>   * *Please note that, in an IM, users can only perform unpinning action.*


# IM Info

Returns information about a particular IM conversation.

## GET /v1/im/{id}/info

> Get information about a partcular IM.

```json
{"openapi":"3.1.1","info":{"title":"Pod API","version":"20.17.1"},"servers":[{"url":"http://yourpodURL.symphony.com/pod"}],"paths":{"/v1/im/{id}/info":{"get":{"summary":"Get information about a partcular IM.","parameters":[{"schema":{"type":"string"},"name":"id","description":"IM streamId","in":"path","required":true},{"schema":{"type":"string"},"name":"sessionToken","description":"Session authentication token.","in":"header","required":true}],"tags":["Streams"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/V1IMDetail"}}}},"400":{"description":"Client error, see response body for further details.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Unauthorized: Invalid session token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Forbidden: Caller lacks necessary entitlement.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Server error, see response body for further details.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}}},"components":{"schemas":{"V1IMDetail":{"type":"object","properties":{"V1IMAttributes":{"$ref":"#/components/schemas/V1IMAttributes"},"IMSystemInfo":{"$ref":"#/components/schemas/IMSystemInfo"}}},"V1IMAttributes":{"type":"object","properties":{"pinnedMessageId":{"type":"string","description":"UrlSafe message id of the pinned message inside the IM. To perform unpin operation, send an empty string."}}},"IMSystemInfo":{"type":"object","properties":{"id":{"type":"string"},"creationDate":{"type":"integer","format":"int64","description":"The datetime when the stream was originally created. Milliseconds since Jan 1 1970."},"active":{"type":"boolean","description":"If false, no messages can be sent in this stream, and membership is locked."}}},"Error":{"type":"object","properties":{"code":{"type":"integer","format":"int32"},"message":{"type":"string"}}}}}}
```

> #### 📘 Stream ID
>
> The stream ID can be located in the Symphony web or desktop client by clicking on the timestamp of any message in the conversation. This will open the Message Status module overlay, and the Conversation ID can be found in the overlay footer.
>
> The stream ID in the UI is in Standard Base64 encoding. When the stream ID needs to be used in a URL, it should be in URLSafe Base64 encoding. To obtain the URLSafe Base64 stream ID, replace forward slashes with underscores, replace pluses with minuses, and ignore any trailing equal signs.
>
> See [Overview of streams](https://docs.developers.symphony.com/building-bots-on-symphony/datafeed/overview-of-streams) for details.

> #### 🚧 Required Permissions
>
> Streams information can only be requested by:
>
> * Members of the IM
> * Compliance Officers and Super Compliance Officers who are not members of the stream
> * Service Users with the User Provisioning role (members or not members of the stream)
>
> See [Bot Permissions](https://docs.developers.symphony.com/building-bots-on-symphony/configuration/bot-permissions) for a list of roles and associated privileges.


# Related to Rooms


# Room Attributes

Rooms are specified by name, description, optional keywords, and a variety of settings, such as whether all participants can invite new participants or whether the room is accessible for anyone to join.

The following attributes apply to these Room endpoints:

* [Create Room](/main/streams-conversations/room-endpoints/create-room-v3)
* [Update Room](/main/streams-conversations/room-endpoints/update-room-v3)
* [Room Info](/main/streams-conversations/room-endpoints/room-info-v3)
* [Search Rooms](/main/streams-conversations/room-endpoints/search-rooms-v3)

<table><thead><tr><th width="190">Name</th><th width="116">Type</th><th>Description</th></tr></thead><tbody><tr><td>name</td><td>string</td><td>Room name</td></tr><tr><td>description</td><td>string</td><td>Room description</td></tr><tr><td>keywords</td><td>array</td><td>A list of key-value pairs, describing additional properties of the room. It is possible to search rooms by keyword values using the <a href="/pages/WcJCaaZLaDd0de0bT5pK">Search Rooms</a> endpoint.</td></tr><tr><td>membersCanInvite</td><td>boolean</td><td>If <strong>true</strong>, any chat room participant can add new participants. <br>If <strong>false</strong>, only owners can add new participants.</td></tr><tr><td>discoverable</td><td>boolean</td><td>If <strong>true</strong>, this chat room (name, description and messages) non-participants can search for this room. If <strong>false</strong>, only participants can search for this room.</td></tr><tr><td>public</td><td>boolean</td><td>If <strong>true</strong>, this is a public chatroom and anyone can join. If <strong>false</strong>, this is a private chatroom and participants must be added.</td></tr><tr><td>readOnly</td><td>boolean</td><td>If <strong>true</strong>, only room owners can send messages.</td></tr><tr><td>copyProtected</td><td>boolean</td><td>If <strong>true</strong>, users cannot copy content from this room.</td></tr><tr><td>crossPod</td><td>boolean</td><td>If <strong>true</strong>, this room is a cross pod room.</td></tr><tr><td>viewHistory</td><td>boolean</td><td>If <strong>true</strong>, new members can view the room chat history of the room.</td></tr><tr><td>multiLateralRoom</td><td>boolean</td><td>If <strong>true</strong>, this is a multilateral room where users belonging to more than two companies can be found.</td></tr><tr><td>pinnedMessageId</td><td>string</td><td><a href="https://docs.developers.symphony.com/building-bots-on-symphony/messages/overview-of-messageml#message-identifiers">URLSafe Base64</a> ID of the pinned message.</td></tr></tbody></table>

> #### 🚧 Copy Protection
>
> Once set to `true`, `copyProtected` cannot be set to `false`. Copy protection can be added to a room but cannot be removed.

> #### 📘 Overview of streams
>
> A stream is like a container for messages exchanged between two or more users via a given instant message (IM), multi-party instant message (MIM), or chat room. For more information, refer to [Overview of streams](https://docs.developers.symphony.com/building-bots-on-symphony/datafeed/overview-of-streams).


# Create Room

Creates a new chatroom. See Room Attributes for room creation parameters.

`Starting with SBE 20.14, it is possible to create External chat rooms with view history enabled, depending on a pod parameter.`

## Create a new chatroom.

> Create a new chatroom.\
> \
> If no  attributes are specified, the room is created as a private chatroom.<br>

```json
{"openapi":"3.1.1","info":{"title":"Pod API","version":"20.17.1"},"servers":[{"url":"http://yourpodURL.symphony.com/pod"}],"paths":{"/v3/room/create":{"post":{"summary":"Create a new chatroom.","description":"Create a new chatroom.\n\nIf no  attributes are specified, the room is created as a private chatroom.\n","parameters":[{"schema":{"type":"string"},"name":"sessionToken","description":"Session authentication token.","in":"header","required":true}],"tags":["Streams"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/V3RoomDetail"}}}},"400":{"description":"Client error, see response body for further details.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Unauthorized: Invalid session token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Forbidden: Caller lacks necessary entitlement.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"451":{"description":"Unavailable for Legal Reasons: Compliance Issues found in room creation request.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Server error, see response body for further details.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/V3RoomAttributes"}}},"required":true}}}},"components":{"schemas":{"V3RoomDetail":{"type":"object","properties":{"roomAttributes":{"$ref":"#/components/schemas/V3RoomAttributes"},"roomSystemInfo":{"$ref":"#/components/schemas/RoomSystemInfo"},"groups":{"description":"List of groups (aka SDLs) that were added to the room.","type":"array","items":{"$ref":"#/components/schemas/GroupItem"}}}},"V3RoomAttributes":{"type":"object","properties":{"name":{"type":"string","description":"Room name."},"keywords":{"type":"array","description":"Keywords for search to use to find this room","items":{"$ref":"#/components/schemas/RoomTag"}},"description":{"type":"string","description":"Room description."},"membersCanInvite":{"type":"boolean","description":"If true, any chatroom participant can add new participants. If false, only owners can add new participants."},"discoverable":{"type":"boolean","description":"If true, this chatroom (name, description and messages) can be searched and listed by non-participants. If false, only participants can search this room."},"public":{"type":"boolean","description":"If true, this is a public chatroom. IF false, a private chatroom."},"readOnly":{"type":"boolean","description":"If true, only stream owners can send messages."},"copyProtected":{"type":"boolean","description":"If true, clients disable the clipboard copy for content in this stream."},"crossPod":{"type":"boolean","description":"If true, this room is a cross pod room"},"viewHistory":{"type":"boolean","description":"If true, new members can view the room chat history of the room."},"multiLateralRoom":{"type":"boolean","description":"If true, this is a multi lateral room where we can find users belonging to more than 2 companies."},"scheduledMeeting":{"type":"boolean","description":"If true, this room is for a scheduled meeting."},"subType":{"type":"string","description":"This field is ignored when creating a new room as it was only used for email integration which is now sunset."},"pinnedMessageId":{"type":"string","description":"UrlSafe message id of the pinned message inside the room. To perform unpin operation, send an empty string."},"groupChat":{"type":"boolean","description":"If true, this room is a group chat. Note: this parameter is ignored for creating rooms. Since SBE 20.16."}}},"RoomTag":{"description":"Room Tag object. A key:value pair describing additional properties of the room.","properties":{"key":{"description":"A unique label of the Tag.","type":"string"},"value":{"description":"The value of this Tag's label.","type":"string"}},"required":["key","value"]},"RoomSystemInfo":{"type":"object","properties":{"id":{"type":"string"},"creationDate":{"type":"integer","format":"int64","description":"The datetime when the stream was originally created. Milliseconds since Jan 1 1970."},"createdByUserId":{"type":"integer","format":"int64"},"active":{"type":"boolean","description":"If false, no messages can be sent in this stream, and membership is locked."}}},"GroupItem":{"type":"object","properties":{"id":{"description":"The ID of the added group (aka SDL).","type":"integer","format":"int64"},"addedBy":{"description":"The user ID who added the group to the room.","type":"integer","format":"int64"}}},"Error":{"type":"object","properties":{"code":{"type":"integer","format":"int32"},"message":{"type":"string"}}}}}}
```

*Starting with SBE 20.14, it is possible to create External chat rooms with view history enabled, depending on a pod parameter. See* [*Room Attributes*](/main/streams-conversations/room-endpoints/room-attributes-1) *for room creation parameters.*

> #### 🚧 More Information
>
> * Room names will be considered the same if they only differ in capitalization and whitespace. E.g. "room1" and "R O O M 1" are considered the same. Also, room names must be shorter than 50 characters.
> * `viewHistory`, `discoverable` and `membersCanInvite` attributes cannot be *false* if `public=true`.
> * `readOnly`, `public` and `discoverable` attributes cannot be *true* if `crossPod=true`.
> * When 'crossPod' is true, then `viewHistory` can be true ONLY if the pod entitlement canCreateExternalRoomSharedHistory is enabled.

> #### 📘 Overview of streams
>
> A stream is like a container for messages exchanged between two or more users via a given instant message (IM) or chat room. For more information, refer to [Overview of streams](https://docs.developers.symphony.com/building-bots-on-symphony/datafeed/overview-of-streams).

> #### 🚧 Entitlements
>
> * A user needs to have the entitlement `canCreatePublicRoom` if he wants to create a public room (User entitlements are set on Admin Portal).
> * A user needs to have the entitlement `isExternalRoomEnabled` if he wants to create a crosspod room (User entitlements are set on Admin Portal).


# Update Room

## POST /v3/room/{id}/update

> Update the attributes of an existing chatroom.

```json
{"openapi":"3.1.1","info":{"title":"Pod API","version":"20.17.1"},"servers":[{"url":"http://yourpodURL.symphony.com/pod"}],"paths":{"/v3/room/{id}/update":{"post":{"summary":"Update the attributes of an existing chatroom.","parameters":[{"schema":{"type":"string"},"name":"id","description":"Room streamId","in":"path","required":true},{"schema":{"type":"string"},"name":"sessionToken","description":"Session authentication token.","in":"header","required":true}],"tags":["Streams"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/V3RoomDetail"}}}},"400":{"description":"Client error, see response body for further details.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Unauthorized: Invalid session token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Forbidden: Caller lacks necessary entitlement.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"451":{"description":"Unavailable for Legal Reasons: Compliance Issues found in room update request.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Server error, see response body for further details.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/V3RoomAttributes"}}},"required":true}}}},"components":{"schemas":{"V3RoomDetail":{"type":"object","properties":{"roomAttributes":{"$ref":"#/components/schemas/V3RoomAttributes"},"roomSystemInfo":{"$ref":"#/components/schemas/RoomSystemInfo"},"groups":{"description":"List of groups (aka SDLs) that were added to the room.","type":"array","items":{"$ref":"#/components/schemas/GroupItem"}}}},"V3RoomAttributes":{"type":"object","properties":{"name":{"type":"string","description":"Room name."},"keywords":{"type":"array","description":"Keywords for search to use to find this room","items":{"$ref":"#/components/schemas/RoomTag"}},"description":{"type":"string","description":"Room description."},"membersCanInvite":{"type":"boolean","description":"If true, any chatroom participant can add new participants. If false, only owners can add new participants."},"discoverable":{"type":"boolean","description":"If true, this chatroom (name, description and messages) can be searched and listed by non-participants. If false, only participants can search this room."},"public":{"type":"boolean","description":"If true, this is a public chatroom. IF false, a private chatroom."},"readOnly":{"type":"boolean","description":"If true, only stream owners can send messages."},"copyProtected":{"type":"boolean","description":"If true, clients disable the clipboard copy for content in this stream."},"crossPod":{"type":"boolean","description":"If true, this room is a cross pod room"},"viewHistory":{"type":"boolean","description":"If true, new members can view the room chat history of the room."},"multiLateralRoom":{"type":"boolean","description":"If true, this is a multi lateral room where we can find users belonging to more than 2 companies."},"scheduledMeeting":{"type":"boolean","description":"If true, this room is for a scheduled meeting."},"subType":{"type":"string","description":"This field is ignored when creating a new room as it was only used for email integration which is now sunset."},"pinnedMessageId":{"type":"string","description":"UrlSafe message id of the pinned message inside the room. To perform unpin operation, send an empty string."},"groupChat":{"type":"boolean","description":"If true, this room is a group chat. Note: this parameter is ignored for creating rooms. Since SBE 20.16."}}},"RoomTag":{"description":"Room Tag object. A key:value pair describing additional properties of the room.","properties":{"key":{"description":"A unique label of the Tag.","type":"string"},"value":{"description":"The value of this Tag's label.","type":"string"}},"required":["key","value"]},"RoomSystemInfo":{"type":"object","properties":{"id":{"type":"string"},"creationDate":{"type":"integer","format":"int64","description":"The datetime when the stream was originally created. Milliseconds since Jan 1 1970."},"createdByUserId":{"type":"integer","format":"int64"},"active":{"type":"boolean","description":"If false, no messages can be sent in this stream, and membership is locked."}}},"GroupItem":{"type":"object","properties":{"id":{"description":"The ID of the added group (aka SDL).","type":"integer","format":"int64"},"addedBy":{"description":"The user ID who added the group to the room.","type":"integer","format":"int64"}}},"Error":{"type":"object","properties":{"code":{"type":"integer","format":"int32"},"message":{"type":"string"}}}}}}
```

An error will be returned if no attributes are changed or if one attribute cannot be changed, based on the **Attributes rules** listed below.

#### 🚧 Attributes rules&#x20;

* The room attributes associated with the room type are all read-only and cannot be changed: `public`, `crossPod`, `multiLateral`
* `copyProtected`: Once set to `true`, cannot be set to `false`. Copy protection can be added to a room but cannot be removed.
* `discoverable` : This attribute cannot be true for `crossPod` rooms, and cannot be false for `public` rooms.
* `membersCanInvite` This attribute cannot be false for `public` rooms.
* `viewHistory:` This attribute can be changed only if the calling user is a room owner; or if the calling user has the entitlement "Can Toggle Room's Share History Property".
* `subType`: This attribute is deprecated and cannot be changed.

#### 📘 Note - Pinned message

The `pinnedMessageId` attribute allows to display an exact copy of the original message in a pinned area placed beneath the chat header and that remains always visible to all users. From this area, they can interact with the message content (i.e. forms or ui actions buttons), and they are able to automatically jump to the original message in the chat canvas. You can use this attribute as follows:

* Either by entering the URLSafe Base 64 ID of the message you wish to pin beneath the chat header (as you can see in the example). Even if another message is pinned, this new message will replace it in the pinned area;
* Either by entering an empty value to upin any message and remove therefore this area from being visible to users as follows: "pinnedMessageId": "";
* *Please note that these actions (pin/unpin) can also be performed by end users when they are owners of the room.*

#### 📘 Note - Groups

The `groups` object is added in the response payload only if at least a Group has been added to the room. It is an array containing:

* `id` attribute: ID of the Group,
* `addedBy`: ID of the user who added the Group to the room

See [Groups](ref:groups-distribution-lists) for more information.

#### 🚧 Required Permissions

Rooms can only be updated by owners of the room.\
See [Bot Permissions](https://docs.developers.symphony.com/building-bots-on-symphony/configuration/bot-permissions) for a list of roles and associated privileges.

#### 📘 Stream ID

The stream ID can be located in the Symphony web or desktop client by clicking on the timestamp of any message in the conversation. This will open the Message Status module overlay, and the Conversation ID can be found in the overlay footer.

The stream ID in the UI is in Standard Base64 encoding. When the stream ID needs to be used in a URL, it should be in URLSafe Base64 encoding. To obtain the URLSafe Base64 stream ID, replace forward slashes with underscores, replace pluses with minuses, and ignore any trailing equal signs.

Note: visit [Overview of streams](https://docs.developers.symphony.com/building-bots-on-symphony/datafeed/overview-of-streams) for more information.


# Room Info

Returns information about a particular chat room.

## GET /v3/room/{id}/info

> Get information about a partcular chatroom.

```json
{"openapi":"3.1.1","info":{"title":"Pod API","version":"20.17.1"},"servers":[{"url":"http://yourpodURL.symphony.com/pod"}],"paths":{"/v3/room/{id}/info":{"get":{"summary":"Get information about a partcular chatroom.","parameters":[{"schema":{"type":"string"},"name":"id","description":"Room streamId","in":"path","required":true},{"schema":{"type":"string"},"name":"sessionToken","description":"Session authentication token.","in":"header","required":true}],"tags":["Streams"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/V3RoomDetail"}}}},"400":{"description":"Client error, see response body for further details.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Unauthorized: Invalid session token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Forbidden: Caller lacks necessary entitlement.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Server error, see response body for further details.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}}},"components":{"schemas":{"V3RoomDetail":{"type":"object","properties":{"roomAttributes":{"$ref":"#/components/schemas/V3RoomAttributes"},"roomSystemInfo":{"$ref":"#/components/schemas/RoomSystemInfo"},"groups":{"description":"List of groups (aka SDLs) that were added to the room.","type":"array","items":{"$ref":"#/components/schemas/GroupItem"}}}},"V3RoomAttributes":{"type":"object","properties":{"name":{"type":"string","description":"Room name."},"keywords":{"type":"array","description":"Keywords for search to use to find this room","items":{"$ref":"#/components/schemas/RoomTag"}},"description":{"type":"string","description":"Room description."},"membersCanInvite":{"type":"boolean","description":"If true, any chatroom participant can add new participants. If false, only owners can add new participants."},"discoverable":{"type":"boolean","description":"If true, this chatroom (name, description and messages) can be searched and listed by non-participants. If false, only participants can search this room."},"public":{"type":"boolean","description":"If true, this is a public chatroom. IF false, a private chatroom."},"readOnly":{"type":"boolean","description":"If true, only stream owners can send messages."},"copyProtected":{"type":"boolean","description":"If true, clients disable the clipboard copy for content in this stream."},"crossPod":{"type":"boolean","description":"If true, this room is a cross pod room"},"viewHistory":{"type":"boolean","description":"If true, new members can view the room chat history of the room."},"multiLateralRoom":{"type":"boolean","description":"If true, this is a multi lateral room where we can find users belonging to more than 2 companies."},"scheduledMeeting":{"type":"boolean","description":"If true, this room is for a scheduled meeting."},"subType":{"type":"string","description":"This field is ignored when creating a new room as it was only used for email integration which is now sunset."},"pinnedMessageId":{"type":"string","description":"UrlSafe message id of the pinned message inside the room. To perform unpin operation, send an empty string."},"groupChat":{"type":"boolean","description":"If true, this room is a group chat. Note: this parameter is ignored for creating rooms. Since SBE 20.16."}}},"RoomTag":{"description":"Room Tag object. A key:value pair describing additional properties of the room.","properties":{"key":{"description":"A unique label of the Tag.","type":"string"},"value":{"description":"The value of this Tag's label.","type":"string"}},"required":["key","value"]},"RoomSystemInfo":{"type":"object","properties":{"id":{"type":"string"},"creationDate":{"type":"integer","format":"int64","description":"The datetime when the stream was originally created. Milliseconds since Jan 1 1970."},"createdByUserId":{"type":"integer","format":"int64"},"active":{"type":"boolean","description":"If false, no messages can be sent in this stream, and membership is locked."}}},"GroupItem":{"type":"object","properties":{"id":{"description":"The ID of the added group (aka SDL).","type":"integer","format":"int64"},"addedBy":{"description":"The user ID who added the group to the room.","type":"integer","format":"int64"}}},"Error":{"type":"object","properties":{"code":{"type":"integer","format":"int32"},"message":{"type":"string"}}}}}}
```

> #### 📘 Stream ID
>
> The stream ID can be located in the Symphony web or desktop client by clicking on the timestamp of any message in the conversation. This will open the Message Status module overlay, and the Conversation ID can be found in the overlay footer.
>
> The stream ID in the UI is in Standard Base64 encoding. When the stream ID needs to be used in a URL, it should be in URLSafe Base64 encoding. To obtain the URLSafe Base64 stream ID, replace forward slashes with underscores, replace pluses with minuses, and ignore any trailing equal signs.
>
> See [Overview of streams](https://docs.developers.symphony.com/building-bots-on-symphony/datafeed/overview-of-streams) for details.

> #### 📘 Note - Groups
>
> Since 20.14, please note that the object `groups` has been added in the payload only if at least a Group has been added to the room. It is an array containing:
>
> * `id` attribute: ID of the Group,
> * `addedBy`: ID of the user who added the Group to the room
>
> See [Groups](/main/groups-distribution-lists) for more information.

> #### 🚧 Required Permissions
>
> Rooms information can only be requested by:
>
> * Members of the room
> * Compliance Officers and Super Compliance Officers who are not members of the room
> * Service Users with the User Provisioning role (members or not members of the room)
>
> See [Bot Permissions](https://docs.developers.symphony.com/building-bots-on-symphony/configuration/bot-permissions) for a list of roles and associated privileges.


# De/Re-activate Room

Deactivate or reactivate a chatroom. At creation, a new chatroom is active.

## POST /v1/room/{id}/setActive

> Deactivate or reactivate a chatroom. At creation, a new chatroom is active.

```json
{"openapi":"3.1.1","info":{"title":"Pod API","version":"20.17.1"},"servers":[{"url":"http://yourpodURL.symphony.com/pod"}],"paths":{"/v1/room/{id}/setActive":{"post":{"summary":"Deactivate or reactivate a chatroom. At creation, a new chatroom is active.","parameters":[{"schema":{"type":"string"},"name":"id","description":"Room streamId","in":"path","required":true},{"schema":{"type":"boolean"},"name":"active","in":"query","required":true},{"schema":{"type":"string"},"name":"sessionToken","description":"Session authentication token.","in":"header","required":true}],"tags":["Streams"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RoomDetail"}}}},"400":{"description":"Client error, see response body for further details.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Unauthorized: Invalid session token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Forbidden: Caller lacks necessary entitlement.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Server error, see response body for further details.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}}},"components":{"schemas":{"RoomDetail":{"type":"object","properties":{"roomAttributes":{"$ref":"#/components/schemas/RoomAttributes"},"roomSystemInfo":{"$ref":"#/components/schemas/RoomSystemInfo"},"immutableRoomAttributes":{"$ref":"#/components/schemas/ImmutableRoomAttributes"}}},"RoomAttributes":{"type":"object","properties":{"name":{"type":"string","description":"Room name."},"description":{"type":"string","description":"Room description."},"membersCanInvite":{"type":"boolean","description":"If true, any chatroom participant can add new participants. If false, only owners can add new participants."},"discoverable":{"type":"boolean","description":"If true, this chatroom (name, description and messages) can be searched and listed by non-participants. If false, only participants can search this room."}}},"RoomSystemInfo":{"type":"object","properties":{"id":{"type":"string"},"creationDate":{"type":"integer","format":"int64","description":"The datetime when the stream was originally created. Milliseconds since Jan 1 1970."},"createdByUserId":{"type":"integer","format":"int64"},"active":{"type":"boolean","description":"If false, no messages can be sent in this stream, and membership is locked."}}},"ImmutableRoomAttributes":{"type":"object","description":"These attributes cannot be changed once the room has been created","properties":{"public":{"type":"boolean","description":"If true, this is a public chatroom. IF false, a private chatroom."},"readOnly":{"type":"boolean","description":"If true, only stream owners can send messages."},"copyProtected":{"type":"boolean","description":"If true, clients disable the clipboard copy for content in this stream."}}},"Error":{"type":"object","properties":{"code":{"type":"integer","format":"int32"},"message":{"type":"string"}}}}}}
```

> #### 🚧 Rules and limitations
>
> Only rooms with members can be reactivated

> #### 📘 Room ID
>
> The room ID can be located in the Symphony web or desktop client by clicking on the timestamp of any message in the conversation. This will open the Message Status module overlay, and the Conversation ID can be found in the overlay footer.
>
> The room ID in the UI is in Standard Base64 encoding. When the room ID needs to be used in a URL, it should be in URLSafe Base64 encoding. To obtain the URLSafe Base64 room ID, replace forward slashes with underscores, replace pluses with minuses, and ignore any trailing equal signs.
>
> See [Overview of Streams](https://docs.developers.symphony.com/building-bots-on-symphony/datafeed/overview-of-streams) for details.

> #### 🚧 Required Permissions
>
> **External Rooms that have not been created by your company cannot be de/re-activated.**\
> Rooms can only be de/re-activated by:
>
> * Owners of the room
> * Compliance Officers and Super Compliance Officers who are not members of the room
> * Service Users with the User Provisioning role (members or not members of the room)
>
> See [Bot Permissions](https://docs.developers.symphony.com/building-bots-on-symphony/configuration/bot-permissions) for a list of roles and associated privileges.


# Room Members

Lists the current members of an existing room.

## GET /v2/room/{id}/membership/list

> Lists current members of an existing room.

```json
{"openapi":"3.1.1","info":{"title":"Pod API","version":"20.17.1"},"servers":[{"url":"http://yourpodURL.symphony.com/pod"}],"paths":{"/v2/room/{id}/membership/list":{"get":{"summary":"Lists current members of an existing room.","parameters":[{"schema":{"type":"string"},"name":"id","description":"Room streamId","in":"path","required":true},{"schema":{"type":"string"},"name":"sessionToken","description":"Session authentication token.","in":"header","required":true}],"tags":["Room Membership"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MembershipList"}}}},"400":{"description":"Client error, see response body for further details.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Unauthorized: Invalid session token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Forbidden: Caller lacks necessary entitlement.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Server error, see response body for further details.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}}},"components":{"schemas":{"MembershipList":{"description":"List of members in a room.","type":"array","items":{"$ref":"#/components/schemas/MemberInfo"}},"MemberInfo":{"description":"Detailed membership record.","type":"object","properties":{"id":{"type":"integer","format":"int64"},"owner":{"type":"boolean"},"joinDate":{"type":"integer","format":"int64"},"addedThroughGroups":{"description":"When the user has been added to the stream through a group (aka SDL), this array contains the group ID which the user belongs to. Since SBE 20.14.","type":"array","items":{"type":"integer","format":"int64"}}}},"Error":{"type":"object","properties":{"code":{"type":"integer","format":"int32"},"message":{"type":"string"}}}}}}
```

> #### 🚧 Required Permissions
>
> Room membership can only be read by:
>
> * Members of the room.
> * Compliance Officers and Super Compliance Officers who are not members of the room.
> * Service Users who are members of the room. If not a member, the User Provisioning role is needed.
>
> See [Bot Permissions](https://docs.developers.symphony.com/building-bots-on-symphony/configuration/bot-permissions) for a list of roles and associated privileges.

> #### 📘 Room ID and User ID
>
> **Room ID**
>
> The room ID can be located in the Symphony web or desktop client by clicking on the timestamp of any message in the conversation. This will open the Message Status module overlay, and the Conversation ID can be found in the overlay footer.
>
> The room ID in the UI is in Standard Base64 encoding. When the room ID needs to be used in a URL, it should be in URLSafe Base64 encoding. To obtain the URLSafe Base64 room ID, replace forward slashes with underscores, replace pluses with minuses, and ignore any trailing equal signs.
>
> Visit [Overview](https://docs.developers.symphony.com/building-bots-on-symphony/datafeed/overview-of-streams) for an overview of streams.
>
> **User ID**
>
> The user `id` returns a `long` numeric type.

> #### 📘 Note - Groups
>
> Since 20.14, please note that the object `addedThroughGroups` has been added only for members added to the room via Groups.
>
> See [Groups](/main/groups-distribution-lists) for more information.


# Add Member

Adds a new member to an existing room.

## POST /v1/room/{id}/membership/add

> Adds new member to an existing room.

```json
{"openapi":"3.1.1","info":{"title":"Pod API","version":"20.17.1"},"servers":[{"url":"http://yourpodURL.symphony.com/pod"}],"paths":{"/v1/room/{id}/membership/add":{"post":{"summary":"Adds new member to an existing room.","parameters":[{"schema":{"type":"string"},"name":"id","description":"Room streamId","in":"path","required":true},{"schema":{"type":"string"},"name":"sessionToken","description":"Session authentication token.","in":"header","required":true}],"tags":["Room Membership"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SuccessResponse"}}}},"400":{"description":"Client error, see response body for further details.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Unauthorized: Invalid session token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Forbidden: Caller lacks necessary entitlement.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Server error, see response body for further details.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserId"}}},"required":true}}}},"components":{"schemas":{"SuccessResponse":{"type":"object","properties":{"format":{"type":"string","enum":["TEXT","XML"]},"message":{"type":"string"}}},"Error":{"type":"object","properties":{"code":{"type":"integer","format":"int32"},"message":{"type":"string"}}},"UserId":{"type":"object","properties":{"id":{"type":"integer","format":"int64"}}}}}}
```

> #### 📘 Room ID
>
> The room ID can be located in the Symphony web or desktop client by clicking on the timestamp of any message in the conversation. This will open the Message Status module overlay, and the Conversation ID can be found in the overlay footer.
>
> The room ID in the UI is in Standard Base64 encoding. When the room ID needs to be used in a URL, it should be in URLSafe Base64 encoding. To obtain the URLSafe Base64 room ID, replace forward slashes with underscores, replace pluses with minuses, and ignore any trailing equal signs.
>
> See [Overview of Streams](https://docs.developers.symphony.com/building-bots-on-symphony/datafeed/overview-of-streams) for details.

> #### 🚧 Rules and limitations
>
> * **Joining Public Rooms:** this endpoint can be used by the calling user to join a public room. To do so, specify the ID of the public room the user wishes to join in the URL and specify the user ID of the calling user in the body.
>   * New members cannot be added to deactivated rooms.
>   * For rooms with more than 500 users, members should be added/deleted 1 member every "3 seconds" to allow key management functions time to process.

> #### 🚧 Required Permissions
>
> New room members can only be added by:
>
> * Owners of the room
> * Members of the room (if “Let participants add members” has been specified in Room Preferences)
> * Compliance Officers and Super Compliance Officers who are not members of the room
> * Service Users with the User Provisioning role who are not members of the room
>
> See [Bot Permissions](https://docs.developers.symphony.com/building-bots-on-symphony/configuration/bot-permissions) for a list of roles and associated privileges.

**Jumbo Chat Rooms**

When creating or deconstructing jumbo rooms (i.e. more than 1000 members) in one bulk load, please be advised of the following:

1. Ensure that a member will be added/deleted every "3 seconds".
2. Members should be added out of working hours (best is during weekend maintenance).
3. Ensure at least 2 room owners are created (for room management backup purposes).

Please note, the maximum number of members that can be added to a room is dependent on your service type (i.e. Business or Enterprise Tier). ​ Please notify Symphony Support when creating Jumbo Chat Rooms and our team will advise on maximum room size and monitor your launch.


# Remove Member

Removes an existing member from an existing room.

## POST /v1/room/{id}/membership/remove

> Removes member from an existing room.

```json
{"openapi":"3.1.1","info":{"title":"Pod API","version":"20.17.1"},"servers":[{"url":"http://yourpodURL.symphony.com/pod"}],"paths":{"/v1/room/{id}/membership/remove":{"post":{"summary":"Removes member from an existing room.","parameters":[{"schema":{"type":"string"},"name":"id","description":"Room streamId","in":"path","required":true},{"schema":{"type":"string"},"name":"sessionToken","description":"Session authentication token.","in":"header","required":true}],"tags":["Room Membership"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SuccessResponse"}}}},"400":{"description":"Client error, see response body for further details.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Unauthorized: Invalid session token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Forbidden: Caller lacks necessary entitlement.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Server error, see response body for further details.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserId"}}},"required":true}}}},"components":{"schemas":{"SuccessResponse":{"type":"object","properties":{"format":{"type":"string","enum":["TEXT","XML"]},"message":{"type":"string"}}},"Error":{"type":"object","properties":{"code":{"type":"integer","format":"int32"},"message":{"type":"string"}}},"UserId":{"type":"object","properties":{"id":{"type":"integer","format":"int64"}}}}}}
```

> #### 🚧 Rules and limitations
>
> * Currently, it is possible to remove all members from a room, however, this action is not recommended since the removal of all members leaves the room in an unrecoverable state. At any time, a room should have at least one owner.
> * It is not possible to remove members from deactivated rooms.

> #### 🚧 Required Permissions
>
> New room members can only be removed by:
>
> * Owners of the room
> * Compliance Officers and Super Compliance Officers who are not members of the room
> * Service Users with the User Provisioning role (members or not members of the room)
>
> Note: The service user can always remove itself from the room without the need for a particular permission.
>
> See [Bot Permissions](https://docs.developers.symphony.com/building-bots-on-symphony/configuration/bot-permissions) for a list of roles and associated privileges.

**Jumbo Chat Rooms**

When creating or deconstructing jumbo rooms (i.e. more than 1,000 members) in one bulk load, please be advised of the following:

1. Members should be added/deleted 1 member every "3 seconds" to allow key management functions time to process.
2. Members should be added out of working hours (best is during weekend maintenance)
3. Ensure at least 2 room owners are created (for room management backup purposes)

Please note, the maximum number of members that can be added to a room is dependent on your service type (i.e. Business or Enterprise Tier). ​ Please notify Symphony Support when creating Jumbo Chat Rooms and our team will advise on maximum room size and monitor your launch.


# Promote Owner

Promotes user to owner of the chat room.

## POST /v1/room/{id}/membership/promoteOwner

> Promotes user to owner.

```json
{"openapi":"3.1.1","info":{"title":"Pod API","version":"20.17.1"},"servers":[{"url":"http://yourpodURL.symphony.com/pod"}],"paths":{"/v1/room/{id}/membership/promoteOwner":{"post":{"summary":"Promotes user to owner.","parameters":[{"schema":{"type":"string"},"name":"id","description":"Room streamId","in":"path","required":true},{"schema":{"type":"string"},"name":"sessionToken","description":"Session authentication token.","in":"header","required":true}],"tags":["Room Membership"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SuccessResponse"}}}},"400":{"description":"Client error, see response body for further details.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Unauthorized: Invalid session token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Forbidden: Caller lacks necessary entitlement.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Server error, see response body for further details.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserId"}}},"required":true}}}},"components":{"schemas":{"SuccessResponse":{"type":"object","properties":{"format":{"type":"string","enum":["TEXT","XML"]},"message":{"type":"string"}}},"Error":{"type":"object","properties":{"code":{"type":"integer","format":"int32"},"message":{"type":"string"}}},"UserId":{"type":"object","properties":{"id":{"type":"integer","format":"int64"}}}}}}
```

> #### 📘 Room ID
>
> The room ID can be located in the Symphony web or desktop client by clicking on the timestamp of any message in the conversation. This will open the Message Status module overlay, and the Conversation ID can be found in the overlay footer.
>
> The room ID in the UI is in Standard Base64 encoding. When the room ID needs to be used in a URL, it should be in URLSafe Base64 encoding. To obtain the URLSafe Base64 room ID, replace forward slashes with underscores, replace pluses with minuses, and ignore any trailing equal signs.
>
> Note: visit [Overview](https://docs.developers.symphony.com/building-bots-on-symphony/datafeed/overview-of-streams) for an overview of streams.

> #### 🚧 Required Permissions
>
> Room members can only be promoted to owners by:
>
> * Owners of the room
> * Service Users with the User Provisioning role (members or not members of the room)
>
> See [Bot Permissions](https://docs.developers.symphony.com/building-bots-on-symphony/configuration/bot-permissions) for a list of roles and associated privileges.


# Demote Owner

Demotes room owner to a participant in the chat room.

## POST /v1/room/{id}/membership/demoteOwner

> Demotes room owner.

```json
{"openapi":"3.1.1","info":{"title":"Pod API","version":"20.17.1"},"servers":[{"url":"http://yourpodURL.symphony.com/pod"}],"paths":{"/v1/room/{id}/membership/demoteOwner":{"post":{"summary":"Demotes room owner.","parameters":[{"schema":{"type":"string"},"name":"id","description":"Room streamId","in":"path","required":true},{"schema":{"type":"string"},"name":"sessionToken","description":"Session authentication token.","in":"header","required":true}],"tags":["Room Membership"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SuccessResponse"}}}},"400":{"description":"Client error, see response body for further details.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Unauthorized: Invalid session token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Forbidden: Caller lacks necessary entitlement.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Server error, see response body for further details.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserId"}}},"required":true}}}},"components":{"schemas":{"SuccessResponse":{"type":"object","properties":{"format":{"type":"string","enum":["TEXT","XML"]},"message":{"type":"string"}}},"Error":{"type":"object","properties":{"code":{"type":"integer","format":"int32"},"message":{"type":"string"}}},"UserId":{"type":"object","properties":{"id":{"type":"integer","format":"int64"}}}}}}
```

> #### 📘 Room ID
>
> The room ID can be located in the Symphony web or desktop client by clicking on the timestamp of any message in the conversation. This will open the Message Status module overlay, and the Conversation ID can be found in the overlay footer.
>
> The room ID in the UI is in Standard Base64 encoding. When the room ID needs to be used in a URL, it should be in URLSafe Base64 encoding. To obtain the URLSafe Base64 room ID, replace forward slashes with underscores, replace pluses with minuses, and ignore any trailing equal signs.
>
> Note: visit [Overview](https://docs.developers.symphony.com/building-bots-on-symphony/datafeed/overview-of-streams) for an overview of streams.

> #### 🚧 Required Permissions
>
> Room members can only be demoted to participants by:
>
> * Owners of the room
> * Service Users with the User Provisioning role (members or not members of the room)
>
> See [Bot Permissions](https://docs.developers.symphony.com/building-bots-on-symphony/configuration/bot-permissions) for a list of roles and associated privileges.

At any time, a room must have at least one owner; therefore, it is not possible to demote the last owner of a room.


# Search Rooms

Search for rooms, querying name, description, and specified keywords.

## POST /v3/room/search

> Search rooms according to the specified criteria.

```json
{"openapi":"3.1.1","info":{"title":"Pod API","version":"20.17.1"},"servers":[{"url":"http://yourpodURL.symphony.com/pod"}],"paths":{"/v3/room/search":{"post":{"summary":"Search rooms according to the specified criteria.","parameters":[{"schema":{"type":"string"},"name":"sessionToken","description":"Session authentication token.","in":"header","required":true},{"schema":{"type":"integer"},"name":"skip","description":"No. of results to skip.\n","in":"query"},{"schema":{"type":"integer"},"name":"limit","description":"Max no. of results to return. If no value is provided, 50 is the default. Must be a positive\ninteger and must not exceed 100\n","in":"query","required":false},{"schema":{"type":"boolean","default":false},"name":"includeNonDiscoverable","description":"Whether the non discoverable rooms should be returned. false by default. Parameter introduced in sbe-25.5.0","in":"query","required":false}],"tags":["Streams"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/V3RoomSearchResults"}}}},"400":{"description":"Client error, see response body for further details.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Unauthorized: Invalid session token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Forbidden: Caller lacks necessary entitlement.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Server error, see response body for further details.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/V2RoomSearchCriteria"}}},"description":"The search query object.","required":true}}}},"components":{"schemas":{"V3RoomSearchResults":{"description":"A list of search results and counts per search parameter.","properties":{"count":{"description":"The total number of rooms matched by the search.","type":"integer","format":"int64"},"skip":{"description":"The number of skipped results.","type":"integer"},"limit":{"description":"The number of returned results.","type":"integer"},"query":{"$ref":"#/components/schemas/V2RoomSearchCriteria"},"rooms":{"description":"A list of rooms matched by the query.","type":"array","items":{"$ref":"#/components/schemas/V3RoomDetail"}},"facetedMatchCount":{"description":"Detailed counts of matched rooms per search criterion.","type":"array","items":{"$ref":"#/components/schemas/FacetedMatchCount"}}}},"V2RoomSearchCriteria":{"description":"Room Query Object. Used to specify the parameters for room search.","allOf":[{"$ref":"#/components/schemas/RoomSearchCriteria"},{"type":"object","properties":{"subType":{"description":"Restrict the search to the specific room subtype. Valid values are: EMAIL","type":"string"}}}]},"RoomSearchCriteria":{"description":"Room Query Object. Used to specify the parameters for room search.","properties":{"query":{"description":"The search query. Matches the room name and description.","type":"string"},"labels":{"description":"A list of room tag labels whose values will be queried.","type":"array","items":{"type":"string"}},"searchFields":{"description":"The room fields on which to search. Parameter introduced in sbe-25.10.0","type":"array","items":{"type":"string"}},"active":{"description":"Restrict the search to active/inactive rooms. If unspecified, search all rooms.","type":"boolean"},"private":{"description":"Restrict the search to private rooms. If unspecified, search all rooms.","type":"boolean"},"owner":{"$ref":"#/components/schemas/UserId"},"creator":{"$ref":"#/components/schemas/UserId"},"member":{"$ref":"#/components/schemas/UserId"},"sortOrder":{"description":"Sort algorithm to be used. Supports two values: \"BASIC\" (legacy algorithm)\nand \"RELEVANCE\" (enhanced algorithm).\n","type":"string","enum":["BASIC","RELEVANCE"]}},"required":["query"]},"UserId":{"type":"object","properties":{"id":{"type":"integer","format":"int64"}}},"V3RoomDetail":{"type":"object","properties":{"roomAttributes":{"$ref":"#/components/schemas/V3RoomAttributes"},"roomSystemInfo":{"$ref":"#/components/schemas/RoomSystemInfo"},"groups":{"description":"List of groups (aka SDLs) that were added to the room.","type":"array","items":{"$ref":"#/components/schemas/GroupItem"}}}},"V3RoomAttributes":{"type":"object","properties":{"name":{"type":"string","description":"Room name."},"keywords":{"type":"array","description":"Keywords for search to use to find this room","items":{"$ref":"#/components/schemas/RoomTag"}},"description":{"type":"string","description":"Room description."},"membersCanInvite":{"type":"boolean","description":"If true, any chatroom participant can add new participants. If false, only owners can add new participants."},"discoverable":{"type":"boolean","description":"If true, this chatroom (name, description and messages) can be searched and listed by non-participants. If false, only participants can search this room."},"public":{"type":"boolean","description":"If true, this is a public chatroom. IF false, a private chatroom."},"readOnly":{"type":"boolean","description":"If true, only stream owners can send messages."},"copyProtected":{"type":"boolean","description":"If true, clients disable the clipboard copy for content in this stream."},"crossPod":{"type":"boolean","description":"If true, this room is a cross pod room"},"viewHistory":{"type":"boolean","description":"If true, new members can view the room chat history of the room."},"multiLateralRoom":{"type":"boolean","description":"If true, this is a multi lateral room where we can find users belonging to more than 2 companies."},"scheduledMeeting":{"type":"boolean","description":"If true, this room is for a scheduled meeting."},"subType":{"type":"string","description":"This field is ignored when creating a new room as it was only used for email integration which is now sunset."},"pinnedMessageId":{"type":"string","description":"UrlSafe message id of the pinned message inside the room. To perform unpin operation, send an empty string."},"groupChat":{"type":"boolean","description":"If true, this room is a group chat. Note: this parameter is ignored for creating rooms. Since SBE 20.16."}}},"RoomTag":{"description":"Room Tag object. A key:value pair describing additional properties of the room.","properties":{"key":{"description":"A unique label of the Tag.","type":"string"},"value":{"description":"The value of this Tag's label.","type":"string"}},"required":["key","value"]},"RoomSystemInfo":{"type":"object","properties":{"id":{"type":"string"},"creationDate":{"type":"integer","format":"int64","description":"The datetime when the stream was originally created. Milliseconds since Jan 1 1970."},"createdByUserId":{"type":"integer","format":"int64"},"active":{"type":"boolean","description":"If false, no messages can be sent in this stream, and membership is locked."}}},"GroupItem":{"type":"object","properties":{"id":{"description":"The ID of the added group (aka SDL).","type":"integer","format":"int64"},"addedBy":{"description":"The user ID who added the group to the room.","type":"integer","format":"int64"}}},"FacetedMatchCount":{"description":"An object respresenting the result count of faceted search.","properties":{"facet":{"description":"The matched query.","type":"string"},"count":{"description":"The result count.","type":"integer"}}},"Error":{"type":"object","properties":{"code":{"type":"integer","format":"int32"},"message":{"type":"string"}}}}}}
```

> #### 📘 Room Search Scope
>
> Room search is performed on the set of:
>
> * All rooms that the calling user is a member of (private or public, active or inactive)
> * All active public rooms
> * Private rooms that the calling user is not a member of, where the room is set to be visible in search, is active and the room does not contain any user with whom the calling user has an information barrier
>
> Note: visit [Overview](https://docs.developers.symphony.com/building-bots-on-symphony/datafeed/overview-of-streams) for an overview of streams.

> #### 🚧 Room Description Search
>
> The description is only searched for hashtags and cashtags containing the search query. For example if `query` were `foo` and the description of a room contained "foo", this room would not be returned in the search results; however, if the description contained "#foo", this room would be returned in the search results.


# All streams


# Share Content

Share third-party content, such as a news article, into the specified stream. The stream can be a chat room or an IM.

## PROVISIONAL -  Share a piece of content into Symphony

> Given a 3rd party content (eg. news article), it can share to the given stream.\
> The stream can be a chatroom, an IM or a multiparty IM.<br>

```json
{"openapi":"3.0.1","info":{"title":"Agent API","version":"25.8.1"},"servers":[{"url":"youragentURL.symphony.com/agent"}],"paths":{"/v3/stream/{sid}/share":{"post":{"tags":["Share"],"summary":"PROVISIONAL -  Share a piece of content into Symphony","description":"Given a 3rd party content (eg. news article), it can share to the given stream.\nThe stream can be a chatroom, an IM or a multiparty IM.\n","parameters":[{"name":"sid","in":"path","description":"Stream ID","required":true,"schema":{"type":"string"}},{"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/ShareContent"}}},"required":true},"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/V2Message"}}}},"400":{"description":"Client error, see response body for further details.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Unauthorized: Session tokens invalid.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Forbidden: Caller lacks necessary entitlement.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Server error, see response body for further details.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}}},"components":{"schemas":{"ShareContent":{"type":"object","properties":{"type":{"type":"string","description":"Type of content to be shared.  Currently only support \"com.symphony.sharing.article\""},"content":{"$ref":"#/components/schemas/ShareArticle"}}},"ShareArticle":{"required":["appId","author","publisher","title"],"type":"object","properties":{"articleId":{"type":"string","description":"An ID for this article that should be unique to the calling application. \nEither an articleId or an articleUrl is required.\n"},"title":{"type":"string","description":"The title of the article"},"subTitle":{"type":"string","description":"The subtitle of the article"},"message":{"type":"string","description":"The message text that can be send along with the shared article"},"publisher":{"type":"string","description":"Publisher of the article"},"publishDate":{"type":"integer","description":"Article publish date in unix timestamp","format":"int64"},"thumbnailUrl":{"type":"string","description":"Url to the thumbnail image"},"author":{"type":"string","description":"Author of the article"},"articleUrl":{"type":"string","description":"Url to the article"},"summary":{"type":"string","description":"Preview summary of the article"},"appId":{"type":"string","description":"App ID of the calling application"},"appName":{"type":"string","description":"App name of the calling application"},"appIconUrl":{"type":"string","description":"App icon url of the calling application"}}},"V2Message":{"description":"A representation of a message sent by a user of Symphony.","allOf":[{"$ref":"#/components/schemas/V2BaseMessage"},{"required":["fromUserId","message"],"type":"object","properties":{"message":{"type":"string","description":"Message text in MessageML","format":"MessageML"},"fromUserId":{"type":"integer","description":"the Symphony userId of the user who sent the message. This will be populated by the server (and actually ignored if included when sending a message).","format":"int64"},"attachments":{"type":"array","default":[],"items":{"$ref":"#/components/schemas/AttachmentInfo"}}}}]},"V2BaseMessage":{"required":["streamId","timestamp","v2messageType"],"type":"object","properties":{"id":{"type":"string","description":"The messageId is assigned by the ingestor service when a message is sent."},"timestamp":{"type":"string"},"v2messageType":{"type":"string"},"streamId":{"type":"string"}},"discriminator":{"propertyName":"v2messageType"}},"AttachmentInfo":{"required":["id","name","size"],"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"}}},"Error":{"type":"object","properties":{"code":{"type":"integer","format":"int32"},"message":{"type":"string"}}}}}}
```

### Request Example

```url
curl -X POST \
https://acme.symphony.com/agent/v3/stream/7w68A8sAG_qv1GwVc9ODzX___ql_RJ6zdA/share \
-H "sessionToken: SESSION_TOKEN" \
-H "keyManagerToken: KEY_MANAGER_TOKEN" \
-H "Content-Type: application/json" \
-d '{
   "type": "com.symphony.sharing.article",
   "content":{
        "articleId":"tsla",
        "title": "The Secret'"'"'s Out: Tesla Enters China and Is Winning",
        "description": "Check this out",
        "publisher": "Capital Market Laboratories",
        "thumbnailUrl": "http://www.cmlviz.com/cmld3b/images/tesla-supercharger-stop.jpg",
        "author": "OPHIRGOTTLIEB",
        "articleUrl": "http://ophirgottlieb.tumblr.com/post/146623530819/the-secrets-out-tesla-enters-china-and-is",
        "summary": "Tesla Motors Inc. (NASDAQ:TSLA) has a CEO more famous than the firm itself, perhaps. Elon Musk has made some bold predictions, first stating that the firm would grow sales from 50,000 units in 2015 to 500,000 by 2020 powered by the less expensive Model 3 and the massive manufacturing capability of the Gigafactory.",
        "appId": "ticker",
        "appName": "Market Data Demo",
        "appIconUrl": "https://apps-dev.symphony.com/ticker/assets/images/logo.png"
    }
}'
```

> #### 📘 Note
>
> Visit [Overview](https://docs.developers.symphony.com/building-bots-on-symphony/datafeed/overview-of-streams) for an overview of streams.

> #### 🚧 Roles and Privileges
>
> For not public rooms, the caller needs to be on the stream or have the Content Management role.\
> See [Bot Permissions](https://docs.developers.symphony.com/building-bots-on-symphony/configuration/bot-permissions) for a list of roles and associated privileges.

### Content Fields

<table><thead><tr><th width="179">Parameter</th><th width="85">Type</th><th width="140">Required</th><th>Description</th></tr></thead><tbody><tr><td><code>articleId</code></td><td>string</td><td>Yes, if <code>articleUrl</code> not specified</td><td>A unique ID for this article, not used by any other article</td></tr><tr><td><code>title</code></td><td>string</td><td>Yes</td><td>The title of the article</td></tr><tr><td><code>subTitle</code></td><td>string</td><td>No</td><td>The subtitle of the article</td></tr><tr><td><code>message</code></td><td>string</td><td>No</td><td>The message text that can be sent along with the shared article</td></tr><tr><td><code>publisher</code></td><td>string</td><td>Yes</td><td>Publisher of the article</td></tr><tr><td><code>publishDate</code></td><td>string</td><td>No</td><td>Article publish date in unix timestamp (in seconds)</td></tr><tr><td><code>thumbnailUrl</code></td><td>string</td><td>No</td><td>URL to the thumbnail image</td></tr><tr><td><code>author</code></td><td>string</td><td>Yes</td><td>Author of the article</td></tr><tr><td><code>articleUrl</code></td><td>string</td><td>Yes, if <code>articleId</code> not specified</td><td>URL to the article</td></tr><tr><td><code>summary</code></td><td>string</td><td>No</td><td>Preview summary of the article</td></tr><tr><td><code>appId</code></td><td>string</td><td>Yes</td><td>App ID of the calling application</td></tr><tr><td><code>appName</code></td><td>string</td><td>No</td><td>App name of the calling application</td></tr><tr><td><code>appIconUrl</code></td><td>string</td><td>No</td><td>App icon URL of the calling application</td></tr></tbody></table>


# List User Streams

Returns a list of all the streams of which the requesting user is a member, sorted by creation date (ascending - oldest to newest).

## POST /v1/streams/list

> Retrieve a list of all streams of which the requesting user is a member,\
> sorted by creation date (ascending).<br>

```json
{"openapi":"3.1.1","info":{"title":"Pod API","version":"20.17.1"},"servers":[{"url":"http://yourpodURL.symphony.com/pod"}],"paths":{"/v1/streams/list":{"post":{"summary":"Retrieve a list of all streams of which the requesting user is a member,\nsorted by creation date (ascending).\n","parameters":[{"schema":{"type":"string"},"name":"sessionToken","description":"Session authentication token.","in":"header","required":true},{"schema":{"type":"integer"},"name":"skip","description":"No. of results to skip.\n","in":"query"},{"schema":{"type":"integer"},"name":"limit","description":"Max no. of results to return. If no value is provided, 50 is the default.\n","in":"query"}],"tags":["Streams"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/StreamList"}}}},"204":{"description":"Stream not found."},"400":{"description":"Client error, see response body for further details.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Unauthorized: Invalid session token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Forbidden: Caller lacks necessary entitlement.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Server error, see response body for further details.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/StreamFilter"}}},"description":"Stream filtering criteria."}}}},"components":{"schemas":{"StreamList":{"description":"A list of streams of which the requesting user is a member.","type":"array","items":{"$ref":"#/components/schemas/StreamAttributes"}},"StreamAttributes":{"type":"object","properties":{"id":{"type":"string","description":"The stream ID."},"crossPod":{"type":"boolean","description":"If true, this is a cross-pod stream."},"active":{"type":"boolean","description":"If true, this stream is active."},"streamType":{"$ref":"#/components/schemas/StreamType"},"streamAttributes":{"$ref":"#/components/schemas/ConversationSpecificStreamAttributes"},"roomAttributes":{"$ref":"#/components/schemas/RoomSpecificStreamAttributes"}}},"StreamType":{"type":"object","properties":{"type":{"type":"string","enum":["IM","MIM","ROOM","POST"]}}},"ConversationSpecificStreamAttributes":{"type":"object","properties":{"members":{"$ref":"#/components/schemas/UserIdList"}}},"UserIdList":{"type":"array","items":{"type":"integer","format":"int64"}},"RoomSpecificStreamAttributes":{"type":"object","properties":{"name":{"type":"string","description":"Room name."}}},"Error":{"type":"object","properties":{"code":{"type":"integer","format":"int32"},"message":{"type":"string"}}},"StreamFilter":{"description":"Stream filtering parameters.","properties":{"streamTypes":{"description":"Types of streams to search for.","type":"array","items":{"$ref":"#/components/schemas/StreamType"}},"includeInactiveStreams":{"description":"Whether to include inactive streams in the list of results.","type":"boolean"}}}}}}
```

### Request Example

```bash
curl -X POST \
https://acme.symphony.com/pod/v1/streams/list \
-H "sessionToken: SESSION_TOKEN" \
-H "Content-Type: application/json" \
-d '{
	"streamTypes": [
  	{"type": "IM"},
    {"type": "ROOM"},
    {"type": "POST"}
  ],
  "includeInactiveStreams": true
}'
```

### streamTypes

`streamTypes`: A list of stream types (defined as an object) that will be returned. Options are IM (1-1 instant messages), ROOM (rooms), POST (the user's wall).

```json
{
	"streamTypes": [
    {"type": "IM"}, 
    {"type": "ROOM"}, 
    {"type": "POST"}
  ],
	"includeInactiveStreams": true
}
```

> #### 📘 Overview of streams
>
> A stream is like a container for messages exchanged between two or more users via a given instant message (IM) or chat room. For more information, refer to [Overview of streams](https://docs.developers.symphony.com/building-bots-on-symphony/datafeed/overview-of-streams).


# List User Streams (Admin)

Returns a list of all the streams of which the specified user is a member, sorted by creation date (ascending - oldest to newest).

`Released in 20.16.`&#x20;

## POST /v1/admin/user/{uid}/streams/list

> Retrieve a list of all streams of which this user is a member,\
> sorted by creation date (ascending). Since SBE 20.16.<br>

```json
{"openapi":"3.1.1","info":{"title":"Pod API","version":"20.17.1"},"servers":[{"url":"http://yourpodURL.symphony.com/pod"}],"paths":{"/v1/admin/user/{uid}/streams/list":{"post":{"summary":"Retrieve a list of all streams of which this user is a member,\nsorted by creation date (ascending). Since SBE 20.16.\n","parameters":[{"schema":{"type":"string"},"name":"sessionToken","description":"Session authentication token.","in":"header","required":true},{"schema":{"type":"integer","format":"int64"},"name":"uid","description":"User ID as a decimal integer\n","in":"path","required":true},{"schema":{"type":"integer"},"name":"skip","description":"No. of results to skip.\n","in":"query"},{"schema":{"type":"integer"},"name":"limit","description":"Max no. of results to return. If no value is provided, 50 is the default.\n","in":"query"}],"tags":["Streams"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/StreamList"}}}},"204":{"description":"Stream not found."},"400":{"description":"Client error, see response body for further details.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Unauthorized: Invalid session token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Forbidden: Caller lacks necessary entitlement.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Server error, see response body for further details.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/StreamFilter"}}},"description":"Stream filtering criteria."}}}},"components":{"schemas":{"StreamList":{"description":"A list of streams of which the requesting user is a member.","type":"array","items":{"$ref":"#/components/schemas/StreamAttributes"}},"StreamAttributes":{"type":"object","properties":{"id":{"type":"string","description":"The stream ID."},"crossPod":{"type":"boolean","description":"If true, this is a cross-pod stream."},"active":{"type":"boolean","description":"If true, this stream is active."},"streamType":{"$ref":"#/components/schemas/StreamType"},"streamAttributes":{"$ref":"#/components/schemas/ConversationSpecificStreamAttributes"},"roomAttributes":{"$ref":"#/components/schemas/RoomSpecificStreamAttributes"}}},"StreamType":{"type":"object","properties":{"type":{"type":"string","enum":["IM","MIM","ROOM","POST"]}}},"ConversationSpecificStreamAttributes":{"type":"object","properties":{"members":{"$ref":"#/components/schemas/UserIdList"}}},"UserIdList":{"type":"array","items":{"type":"integer","format":"int64"}},"RoomSpecificStreamAttributes":{"type":"object","properties":{"name":{"type":"string","description":"Room name."}}},"Error":{"type":"object","properties":{"code":{"type":"integer","format":"int32"},"message":{"type":"string"}}},"StreamFilter":{"description":"Stream filtering parameters.","properties":{"streamTypes":{"description":"Types of streams to search for.","type":"array","items":{"$ref":"#/components/schemas/StreamType"}},"includeInactiveStreams":{"description":"Whether to include inactive streams in the list of results.","type":"boolean"}}}}}}
```

> #### 🚧 Required Permissions
>
> Only service users with the User Provisioning role can use this endpoint.

> #### 📘 Overview of streams
>
> A stream is like a container for messages exchanged between two or more users via a given instant message (IM) or chat room. For more information, refer to [Overview of streams](https://docs.developers.symphony.com/building-bots-on-symphony/datafeed/overview-of-streams).


# Stream Info

Returns information about a particular stream.

## GET /v2/streams/{sid}/info

> Get information about a partcular stream.

```json
{"openapi":"3.1.1","info":{"title":"Pod API","version":"20.17.1"},"servers":[{"url":"http://yourpodURL.symphony.com/pod"}],"paths":{"/v2/streams/{sid}/info":{"get":{"summary":"Get information about a partcular stream.","parameters":[{"schema":{"type":"string"},"name":"sid","description":"Stream Id","in":"path","required":true},{"schema":{"type":"string"},"name":"sessionToken","description":"Session authentication token.","in":"header","required":true}],"tags":["Streams"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/V2StreamAttributes"}}}},"400":{"description":"Client error, see response body for further details.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Unauthorized: Invalid session token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Forbidden: Caller lacks necessary entitlement.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Server error, see response body for further details.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}}},"components":{"schemas":{"V2StreamAttributes":{"type":"object","properties":{"id":{"type":"string","description":"The stream ID."},"crossPod":{"type":"boolean","description":"If true, this is a cross-pod stream."},"origin":{"type":"string","description":"INTERNAL if the creator of this stream belongs to the pod, EXTERNAL otherwise"},"active":{"type":"boolean","description":"If true, this stream is active."},"lastMessageDate":{"type":"integer","format":"int64","description":"unix timestamp of the last message sent in the stream"},"streamType":{"description":"The type of the stream (IM = IM, multi-IM = MIM, chat room = ROOM, user wall = POST).","$ref":"#/components/schemas/V2StreamType"},"streamAttributes":{"$ref":"#/components/schemas/V2ConversationSpecificStreamAttributes"},"roomAttributes":{"$ref":"#/components/schemas/V2RoomSpecificStreamAttributes"}}},"V2StreamType":{"type":"object","properties":{"type":{"type":"string"}}},"V2ConversationSpecificStreamAttributes":{"type":"object","properties":{"members":{"$ref":"#/components/schemas/UserIdList"}}},"UserIdList":{"type":"array","items":{"type":"integer","format":"int64"}},"V2RoomSpecificStreamAttributes":{"type":"object","properties":{"name":{"type":"string","description":"Room name."},"groups":{"description":"List of groups (aka SDLs) that were added to the room. Since SBE 20.14.","type":"array","items":{"$ref":"#/components/schemas/GroupItem"}}}},"GroupItem":{"type":"object","properties":{"id":{"description":"The ID of the added group (aka SDL).","type":"integer","format":"int64"},"addedBy":{"description":"The user ID who added the group to the room.","type":"integer","format":"int64"}}},"Error":{"type":"object","properties":{"code":{"type":"integer","format":"int32"},"message":{"type":"string"}}}}}}
```

Note: visit [Overview](https://docs.developers.symphony.com/building-bots-on-symphony/datafeed/overview-of-streams) for an overview of streams.

In the response,

* The `crossPod` field indicates whether the stream is External or Internal.
* The `origin` field indicates the origin of the room: INTERNAL (created by a user of the calling user's company) or EXTERNAL (created by a user of another company). Only applies to chatrooms with External scope.
* The `active` field indicates whether the stream is active or inactive. An IM is inactive if at least one of the participants is a deactivated user. A room is inactive if it has been deactivated by an owner or an administrator.
* `lastMessageDate` states when the last message sent in that stream. The time is in epoch format.
* `streamType` can be `IM` (1-1 instant message), `MIM` (multi-party instant message, deprecated), `ROOM`, or `POST` (user profile wall posts).
* For IMs and walls, `streamAttributes` contains the `members` array with userIds of participants. In the case of wall posts, there is only one participant (the user whose wall it is).
* For rooms, `roomAttributes` contains the `name` of the room. To get the participants of the room, call the [Room Members](/main/streams-conversations/all-streams-endpoints/stream-members) endpoint.
* If the stream is IM or room with `discoverable`set as "false", the caller needs to have the VIEW\_ANY\_STREAM\_DETAILS privilege. Refer to [Bot Permissions](https://docs.developers.symphony.com/building-bots-on-symphony/configuration/bot-permissions) for a list of roles and associated privileges.

> #### 📘 Note - Groups
>
> Since 20.14, please note that the object `groups` has been added in the roomAttributes object only if at least a Group has been added to the room. It is an array containing:
>
> * `id` attribute: ID of the Group,
> * `addedBy`: ID of the user who added the Group to the room
>
> See [Groups](/main/groups-distribution-lists) for more information.


# List Streams for Enterprise

Returns a list of all the streams (IMs, chatrooms, Wall posts as well as streams reserved for internal use) for the calling user's company, sorted by creation date (ascending – oldest to newest).&#x20;

**Filtering** parameters can be used to narrow the list of streams that are returned. For more information, refer to the **Filtering Returned Streams** section below.

## POST /v2/admin/streams/list

> Retrieve all the streams across the enterprise where the membership of the stream has been modified between a given time range<br>

```json
{"openapi":"3.1.1","info":{"title":"Pod API","version":"20.17.1"},"servers":[{"url":"http://yourpodURL.symphony.com/pod"}],"paths":{"/v2/admin/streams/list":{"post":{"summary":"Retrieve all the streams across the enterprise where the membership of the stream has been modified between a given time range\n","parameters":[{"schema":{"type":"string"},"name":"sessionToken","description":"Session authentication token.","in":"header","required":true},{"schema":{"type":"integer"},"name":"skip","description":"Number of items to skip. Default is 0.\n","in":"query"},{"schema":{"type":"integer"},"name":"limit","description":"Maximum number of items to return. Default is 50.  This value cannot exceed 100.\n","in":"query"}],"tags":["Streams"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/V2AdminStreamList"}}}},"400":{"description":"Client error, see response body for further details.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Unauthorized: Invalid session token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Forbidden: Caller lacks necessary entitlement.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Server error, see response body for further details.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/V2AdminStreamFilter"}}},"description":"Stream filtering criteria."}}}},"components":{"schemas":{"V2AdminStreamList":{"description":"list of streams info","type":"object","properties":{"count":{"type":"integer","format":"int64","description":"total number of streams which match the filter criteria"},"skip":{"type":"integer","description":"number of streams skipped"},"limit":{"type":"integer","description":"maximum number of streams return"},"filter":{"$ref":"#/components/schemas/V2AdminStreamFilter"},"streams":{"$ref":"#/components/schemas/V2AdminStreamInfoList"}}},"V2AdminStreamFilter":{"description":"stream filter criteria","type":"object","properties":{"streamTypes":{"description":"type of streams to search for","type":"array","items":{"description":"Valid values are IM, MIM or ROOM","$ref":"#/components/schemas/V2AdminStreamType"}},"scope":{"description":"Scope of the room. Valid values are INTERNAL or EXTERNAL.\nIf not specified, it will include both Internal and External scope\n","type":"string"},"origin":{"description":"Origin of the room. It indicates whether the room was created by a user within the company by another company.\nValid values are INTERNAL or EXTERNAL.\nIf not specified, it will include both Internal and External origin\n","type":"string"},"status":{"description":"Status of the room.\nValid values are ACTIVE or INACTIVE.\nIf not specified, it will include both Active and Inactive status\n","type":"string"},"privacy":{"description":"Privacy setting of the stream.\nValid values are PUBLIC or PRIVATE.\nIf not specified, it will include both public and private streams\n","type":"string"},"startDate":{"description":"Start date in unix timestamp in millseconds","type":"integer","format":"int64"},"endDate":{"description":"End date in unix timestamp in millseconds.  If not specified, it assume to be current time.","type":"integer","format":"int64"}}},"V2AdminStreamType":{"type":"object","properties":{"type":{"type":"string"}}},"V2AdminStreamInfoList":{"type":"array","description":"list of stream info","items":{"$ref":"#/components/schemas/V2AdminStreamInfo"}},"V2AdminStreamInfo":{"description":"Stream information","type":"object","properties":{"id":{"type":"string","description":"stream id"},"isExternal":{"type":"boolean","description":"true indicate this stream has the scope of external and false indictate this stream has the scope of internal. Deprecated, use origin"},"isActive":{"type":"boolean","description":"true indicate that this stream has the status of active and false indicate this stream has the scope of inactive"},"isPublic":{"type":"boolean","description":"true indicate that this stream has a privacy setting of public.  This only apply a ROOM stream type."},"type":{"type":"string","description":"type of stream (IM, MIM, ROOM)"},"crossPod":{"type":"boolean","description":"If true, this is a cross-pod stream."},"origin":{"type":"string","description":"INTERNAL if the creator of this stream belongs to the pod, EXTERNAL otherwise"},"attributes":{"$ref":"#/components/schemas/V2AdminStreamAttributes"}}},"V2AdminStreamAttributes":{"description":"additional optional properties for the stream","type":"object","properties":{"roomName":{"type":"string","description":"room name (room only)"},"roomDescription":{"type":"string","description":"description of the room (room only)"},"members":{"type":"array","description":"list of userid who is member of the stream - im or mim only","items":{"type":"integer","format":"int64"}},"createdByUserId":{"type":"integer","format":"int64","description":"creator user id"},"createdDate":{"type":"integer","format":"int64","description":"created date"},"lastModifiedDate":{"type":"integer","format":"int64","description":"last modified date"},"originCompany":{"type":"string","description":"company name of the creator"},"originCompanyId":{"type":"integer","description":"company id of the creator"},"membersCount":{"type":"integer","description":"total number of members in the stream"},"lastMessageDate":{"type":"integer","format":"int64","description":"last date a message was sent in this stream"},"groupChat":{"type":"boolean","description":"whether a stream is a group chat or not. Since SBE 20.16."}}},"Error":{"type":"object","properties":{"code":{"type":"integer","format":"int32"},"message":{"type":"string"}}}}}}
```

### Request Example

```bash
curl -X POST \
https://acme.symphony.com/pod/v2/admin/streams/list \
    -H 'Content-Type: application/json' \ 
    -H 'sessionToken: SESSION_TOKEN' \ 
    -d '{
          "streamTypes": [
            {"type": "IM"},
            {"type": "MIM"},
            {"type": "ROOM"},
            {"type": "POST"}
          ]
        }'
```

> #### 🚧 Required Permissions
>
> This endpoint may only be called by Service User accounts with the User Provisioning role.

{% hint style="info" %}
**Required Permissions:** This endpoint may only be called by Service User accounts with the User Provisioning role.
{% endhint %}

{% hint style="warning" %}
The property `attributes.originCompany` may be missing, in the rare event where the company owning the cross pod stream is no longer a Symphony customer.
{% endhint %}

Note: visit [Overview](https://docs.developers.symphony.com/building-bots-on-symphony/datafeed/overview-of-streams) for an overview of streams.

### Filtering Returned Streams

You can filter the streams that are returned by specifying optional body parameters.

For instance, the filter below would return active external chatrooms created by users who do not belong to your firm, created between Mon, 12 Dec 2016 20:37:36.047 GMT and Thu, 29 Dec 2016 19:01:29.833 GMT.

```json
{
	"streamTypes": [{"type": "ROOM"}],
	"scope": "EXTERNAL",
	"origin": "EXTERNAL",
	"privacy": "PRIVATE",
	"status": "ACTIVE",
	"startDate": 1481575056047,
	"endDate": 1483038089833
}
```

> #### 📘 lastMessageDate
>
> This is the date that the last message was sent in that room. The time is in epoch format.

> #### 📘 Scope vs. Origin
>
> The `scope` property refers to the participants of the room: whether the room contains only users within the company (internal scope) or whether the room contains users within the company as well as users belonging to another company (external scope). The scope property can apply to IMs and MIMs as well.
>
> The `origin` property applies only to rooms with external scope. Origin refers to the creator of the room with external scope: whether the room was created by a user of the company (internal origin) or whether the room was created by a user belonging to another company (external origin).
>
> A room with external scope and internal origin would be a room created by a user within the company, where members can belong to both the origin company and one other company.
>
> The response has defined variable "isExternal", and for external scope, can have two values {true, false}. This value is false, whenever the stream is created by an internal user.

> #### 📘 Privacy
>
> The `privacy` property applies only to rooms with internal scope. It refers to the privacy setting of the internal room: whether members (who must belong to the same company) must be added to the room or whether anyone in the company can find and join the room.
>
> External rooms are always private - members must be added to the room.

> #### 📘 Date Range Filter
>
> The `startDate` and `endDate` properties can be used to filter the list of streams to return only streams that were modified within the specified time range.
>
> For rooms, modification entails a change of room properties (ex. name or description updated, settings changed) or a change in room membership (ex. users added/removed, roles changed). Modification does not include message activity.
>
> IMs and MIMs are immutable - there can be no membership changes or properties changes. Therefore, filtering is performed upon the stream creation date.
>
> If neither `startDate` nor `endDate` are specified, all rooms since the beginning of the enterprise's time until the time of call are returned.
>
> If `startDate` is specified, but not endDate, all rooms modified since the startDate until the time of call are returned.
>
> If `endDate` is specified, but not `startDate`, all rooms modified since the beginning of the enterprise's time until the endDate are returned.


# Stream Members

Returns a list of all the current members of a stream (IM or chatroom).

## GET /v1/admin/stream/{id}/membership/list

> List the current members of an existing stream.  The stream can be of type IM, MIM, or ROOM

```json
{"openapi":"3.1.1","info":{"title":"Pod API","version":"20.17.1"},"servers":[{"url":"http://yourpodURL.symphony.com/pod"}],"paths":{"/v1/admin/stream/{id}/membership/list":{"get":{"summary":"List the current members of an existing stream.  The stream can be of type IM, MIM, or ROOM","parameters":[{"schema":{"type":"string"},"name":"id","description":"stream Id","in":"path","required":true},{"schema":{"type":"string"},"name":"sessionToken","description":"Session authentication token.","in":"header","required":true},{"schema":{"type":"integer"},"name":"skip","description":"Number of items to skip. Default is 0.","in":"query","required":false},{"schema":{"type":"integer"},"name":"limit","description":"Maximum number of items to return. Default is 100 and not to exceed 1000.","in":"query","required":false}],"tags":["Streams"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/V2MembershipList"}}}},"400":{"description":"Client error, see response body for further details.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Unauthorized: Invalid session token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Forbidden: Caller lacks necessary entitlement.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Server error, see response body for further details.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}}},"components":{"schemas":{"V2MembershipList":{"description":"List of members in the stream.","type":"object","properties":{"count":{"type":"integer","description":"total members count"},"skip":{"type":"integer","description":"number of items to skip from the request"},"limit":{"type":"integer","description":"maximum number of items to return"},"members":{"$ref":"#/components/schemas/V2MemberInfoList"}}},"V2MemberInfoList":{"type":"array","items":{"$ref":"#/components/schemas/V2MemberInfo"}},"V2MemberInfo":{"description":"Detailed membership record.","type":"object","properties":{"user":{"$ref":"#/components/schemas/V2MemberUserDetail"},"isOwner":{"type":"boolean","description":"true if this is an owner of the room"},"isCreator":{"type":"boolean","description":"true if this is the creator of the room"},"joinDate":{"description":"unix timestamp for join date","type":"integer","format":"int64"},"addedThroughGroups":{"description":"When the user has been added to the stream through a group (aka SDL), this array contains the group ID which the user belongs to. Since SBE 20.14.","type":"array","items":{"type":"integer","format":"int64"}}}},"V2MemberUserDetail":{"description":"User detail information for stream membership","type":"object","properties":{"userId":{"type":"integer","format":"int64"},"email":{"type":"string"},"firstName":{"type":"string"},"lastName":{"type":"string"},"displayName":{"type":"string","description":"Display name for the user"},"company":{"type":"string","description":"Company name"},"companyId":{"type":"integer","description":"Company ID"},"isExternal":{"type":"boolean","description":"true indicate that this user belong to another company"}}},"Error":{"type":"object","properties":{"code":{"type":"integer","format":"int32"},"message":{"type":"string"}}}}}}
```

Note: visit [Overview](https://docs.developers.symphony.com/building-bots-on-symphony/datafeed/overview-of-streams) for an overview of streams.

> #### 🚧 Required Permissions
>
> To get the stream membership of any stream in your enterprise, you should call this endpoint with a Service User account with the User Provisioning role. The Service User does not need to be a member of the stream.
>
> See [Bot Permissions](https://docs.developers.symphony.com/building-bots-on-symphony/configuration/bot-permissions) for a list of roles and associated privileges.

> #### 📘 External users
>
> If you call this endpoint with a user that has the User Provisioning role, you will get the email address for both internal and external users.

> #### 📘 Creation and Ownership
>
> The `isCreator` field is relevant to IMs and chatrooms. For an IM, this is the person who initiated the first chat with the other user(s).
>
> The `isOwner` field is relevant only to chatrooms. It denotes whether the user is an owner of the chatroom. While a room can only have one creator, it can have multiple owners.

> #### 📘 Join Date
>
> The `joinDate` field is most relevant for chatrooms. It represents the time the user was added to the chatroom. If a user was added, removed, and then added back to the room, the `joinDate` reflects the most recent add date.
>
> In the case of IMs and MIMs, the `joinDate` reflects the initiation date of the conversation. Every member will have the same `joinDate`.

> #### 📘 Note - Groups
>
> Since 20.14, please note that the object `addedThroughGroups` has been added only for members added to the room via Groups.
>
> See [Groups](/main/groups-distribution-lists) for more information.


# Signals


# List Signals

Lists signals on behalf of the user. The response includes signals that the user has created and public signals to which they have subscribed.

## GET /v1/signals/list

> List signals for the requesting user. This includes signals that the user has created and public signals\
> to which they subscribed.<br>

```json
{"openapi":"3.0.1","info":{"title":"Agent API","version":"25.8.1"},"servers":[{"url":"youragentURL.symphony.com/agent"}],"paths":{"/v1/signals/list":{"get":{"tags":["Signals"],"summary":"List signals for the requesting user. This includes signals that the user has created and public signals\nto which they subscribed.\n","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"}},{"name":"skip","in":"query","description":"No. of signals to skip.","schema":{"type":"integer"}},{"name":"limit","in":"query","description":"Max no. of signals to return. If no value is provided, 50 is the default. The maximum supported value is 500.\n","schema":{"type":"integer"}}],"responses":{"200":{"description":"List of signals for the requesting user.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SignalList"}}}},"400":{"description":"Client error, see response body for further details.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/V2Error"}}}},"401":{"description":"Unauthorized: Session tokens invalid.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/V2Error"}}}},"403":{"description":"Forbidden: Caller lacks necessary entitlement.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/V2Error"}}}},"500":{"description":"Server error, see response body for further details.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/V2Error"}}}}}}}},"components":{"schemas":{"SignalList":{"type":"array","items":{"$ref":"#/components/schemas/Signal"}},"Signal":{"allOf":[{"$ref":"#/components/schemas/BaseSignal"},{"type":"object","properties":{"id":{"type":"string","description":"Signal ID"},"timestamp":{"type":"integer","description":"Timestamp when the signal was created, in milliseconds since Jan 1 1970","format":"int64"}}}]},"BaseSignal":{"type":"object","properties":{"name":{"type":"string","description":"Signal name"},"query":{"type":"string","description":"The query used to define this signal. The query is defined as \"field:value\" pairs combined by the operators\n\"AND\" or \"OR\". Supported fields are (case-insensitive): \"author\", \"hashtag\" and \"cashtag\".\nMUST contain at least one \"hashtag\" or \"cashtag\" definition.\n"},"visibleOnProfile":{"type":"boolean","description":"Whether the signal is visible on its creator's profile"},"companyWide":{"type":"boolean","description":"Whether the signal is a push signal"}}},"V2Error":{"required":["code","message"],"type":"object","properties":{"code":{"type":"integer","format":"int32"},"message":{"type":"string"},"details":{"type":"object"}}}}}}
```


# Get Signal

Gets details about the specified signal.

## GET /v1/signals/{id}/get

> Get details of the requested signal.

```json
{"openapi":"3.0.1","info":{"title":"Agent API","version":"25.8.1"},"servers":[{"url":"youragentURL.symphony.com/agent"}],"paths":{"/v1/signals/{id}/get":{"get":{"tags":["Signals"],"summary":"Get details of the requested signal.","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"}},{"name":"id","in":"path","description":"The ID of the signal to display.","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"List of signals for the requesting user.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Signal"}}}},"400":{"description":"Client error, see response body for further details.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/V2Error"}}}},"401":{"description":"Unauthorized: Session tokens invalid.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/V2Error"}}}},"403":{"description":"Forbidden: Caller lacks necessary entitlement.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/V2Error"}}}},"500":{"description":"Server error, see response body for further details.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/V2Error"}}}}}}}},"components":{"schemas":{"Signal":{"allOf":[{"$ref":"#/components/schemas/BaseSignal"},{"type":"object","properties":{"id":{"type":"string","description":"Signal ID"},"timestamp":{"type":"integer","description":"Timestamp when the signal was created, in milliseconds since Jan 1 1970","format":"int64"}}}]},"BaseSignal":{"type":"object","properties":{"name":{"type":"string","description":"Signal name"},"query":{"type":"string","description":"The query used to define this signal. The query is defined as \"field:value\" pairs combined by the operators\n\"AND\" or \"OR\". Supported fields are (case-insensitive): \"author\", \"hashtag\" and \"cashtag\".\nMUST contain at least one \"hashtag\" or \"cashtag\" definition.\n"},"visibleOnProfile":{"type":"boolean","description":"Whether the signal is visible on its creator's profile"},"companyWide":{"type":"boolean","description":"Whether the signal is a push signal"}}},"V2Error":{"required":["code","message"],"type":"object","properties":{"code":{"type":"integer","format":"int32"},"message":{"type":"string"},"details":{"type":"object"}}}}}}
```


# Create Signal

Creates a new Signal.

## POST /v1/signals/create

> Create a signal.

```json
{"openapi":"3.0.1","info":{"title":"Agent API","version":"25.8.1"},"servers":[{"url":"youragentURL.symphony.com/agent"}],"paths":{"/v1/signals/create":{"post":{"tags":["Signals"],"summary":"Create a signal.","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":{"description":"Signal definition.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BaseSignal"}}},"required":true},"responses":{"200":{"description":"Signal created.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Signal"}}}},"400":{"description":"Client error, see response body for further details.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/V2Error"}}}},"401":{"description":"Unauthorized: Session tokens invalid.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/V2Error"}}}},"403":{"description":"Forbidden: Caller lacks necessary entitlement.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/V2Error"}}}},"451":{"description":"Compliance Issues found in signal","content":{"application/json":{"schema":{"$ref":"#/components/schemas/V2Error"}}}},"500":{"description":"Server error, see response body for further details.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/V2Error"}}}}}}}},"components":{"schemas":{"BaseSignal":{"type":"object","properties":{"name":{"type":"string","description":"Signal name"},"query":{"type":"string","description":"The query used to define this signal. The query is defined as \"field:value\" pairs combined by the operators\n\"AND\" or \"OR\". Supported fields are (case-insensitive): \"author\", \"hashtag\" and \"cashtag\".\nMUST contain at least one \"hashtag\" or \"cashtag\" definition.\n"},"visibleOnProfile":{"type":"boolean","description":"Whether the signal is visible on its creator's profile"},"companyWide":{"type":"boolean","description":"Whether the signal is a push signal"}}},"Signal":{"allOf":[{"$ref":"#/components/schemas/BaseSignal"},{"type":"object","properties":{"id":{"type":"string","description":"Signal ID"},"timestamp":{"type":"integer","description":"Timestamp when the signal was created, in milliseconds since Jan 1 1970","format":"int64"}}}]},"V2Error":{"required":["code","message"],"type":"object","properties":{"code":{"type":"integer","format":"int32"},"message":{"type":"string"},"details":{"type":"object"}}}}}}
```

### Request Example

```bash
curl -X POST \  
  https://acme.symphony.com/agent/v1/signals/create \
  -H 'content-type: application/json' \
  -H 'keymanagertoken: KEYMANAGER_TOKEN' \
  -H 'sessiontoken: SESSION_TOKEN' \
  -d '{
	  "name": "hash and cash",
	  "query": "HASHTAG:hash AND CASHTAG:cash",
	  "visibleOnProfile": true,
    "companyWide": false
  }'
```

> 🚧 Known Limitations
>
> * DLP only works with 1.53 version and onwards.
> * To create a company-wide signal, the requesting user needs to have the `canCreatePushedSignals` entitlement.
> * To send numeric cashtags as signals, add a `*` before the number, for example, `$*122450`.


# Update Signal

Updates an existing Signal.

## POST /v1/signals/{id}/update

> Update a signal.

```json
{"openapi":"3.0.1","info":{"title":"Agent API","version":"25.8.1"},"servers":[{"url":"youragentURL.symphony.com/agent"}],"paths":{"/v1/signals/{id}/update":{"post":{"tags":["Signals"],"summary":"Update a signal.","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"}},{"name":"id","in":"path","description":"The id of the signal.","required":true,"schema":{"type":"string"}}],"requestBody":{"description":"Signal definition.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BaseSignal"}}},"required":true},"responses":{"200":{"description":"Signal updated.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Signal"}}}},"400":{"description":"Client error, see response body for further details.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/V2Error"}}}},"401":{"description":"Unauthorized: Session tokens invalid.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/V2Error"}}}},"403":{"description":"Forbidden: Caller lacks necessary entitlement.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/V2Error"}}}},"451":{"description":"Compliance Issues found in signal","content":{"application/json":{"schema":{"$ref":"#/components/schemas/V2Error"}}}},"500":{"description":"Server error, see response body for further details.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/V2Error"}}}}}}}},"components":{"schemas":{"BaseSignal":{"type":"object","properties":{"name":{"type":"string","description":"Signal name"},"query":{"type":"string","description":"The query used to define this signal. The query is defined as \"field:value\" pairs combined by the operators\n\"AND\" or \"OR\". Supported fields are (case-insensitive): \"author\", \"hashtag\" and \"cashtag\".\nMUST contain at least one \"hashtag\" or \"cashtag\" definition.\n"},"visibleOnProfile":{"type":"boolean","description":"Whether the signal is visible on its creator's profile"},"companyWide":{"type":"boolean","description":"Whether the signal is a push signal"}}},"Signal":{"allOf":[{"$ref":"#/components/schemas/BaseSignal"},{"type":"object","properties":{"id":{"type":"string","description":"Signal ID"},"timestamp":{"type":"integer","description":"Timestamp when the signal was created, in milliseconds since Jan 1 1970","format":"int64"}}}]},"V2Error":{"required":["code","message"],"type":"object","properties":{"code":{"type":"integer","format":"int32"},"message":{"type":"string"},"details":{"type":"object"}}}}}}
```

### Request Example

```bash
curl -X POST \
  https://acme.symphony.com/agent/v1/signals/5a8da7edb9d82100011d508f/update \
  -H 'content-type: application/json' \
  -H 'sessiontoken: SESSION_TOKEN' \
  -H 'keymanagertoken: KEYMANAGER_TOKEN' \
  -d '{
    "name": "hashtag only",
    "query": "HASHTAG:hash",
    "visibleOnProfile": false,
    "companyWide": false
   }'
```

> #### 🚧 Known Limitations
>
> * To update a company-wide signal, the requesting user needs to have the `canCreatePushedSignals` entitlement.
> * To update a normal signal, the requesting user needs to be the owner of the signal.
> * To send numeric cashtags as signals, add a `*` before the number, for example, `$*122450`.


# Delete Signal

Deletes an existing Signal.

## POST /v1/signals/{id}/delete

> Delete a signal.

```json
{"openapi":"3.0.1","info":{"title":"Agent API","version":"25.8.1"},"servers":[{"url":"youragentURL.symphony.com/agent"}],"paths":{"/v1/signals/{id}/delete":{"post":{"tags":["Signals"],"summary":"Delete a signal.","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"}},{"name":"id","in":"path","description":"The id of the signal.","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Signal deleted.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SuccessResponse"}}}},"400":{"description":"Client error, see response body for further details.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/V2Error"}}}},"401":{"description":"Unauthorized: Session tokens invalid.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/V2Error"}}}},"403":{"description":"Forbidden: Caller lacks necessary entitlement.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/V2Error"}}}},"500":{"description":"Server error, see response body for further details.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/V2Error"}}}}}}}},"components":{"schemas":{"SuccessResponse":{"type":"object","properties":{"format":{"type":"string","enum":["TEXT","XML"]},"message":{"type":"string"}}},"V2Error":{"required":["code","message"],"type":"object","properties":{"code":{"type":"integer","format":"int32"},"message":{"type":"string"},"details":{"type":"object"}}}}}}
```


# Subscribe Signal

Subscribe an array of users to a Signal. To subscribe an entire pod to a Signal, set the companyWide field in Create Signal.

## POST /v1/signals/{id}/subscribe

> Subscribe to a Signal.

```json
{"openapi":"3.0.1","info":{"title":"Agent API","version":"25.8.1"},"servers":[{"url":"youragentURL.symphony.com/agent"}],"paths":{"/v1/signals/{id}/subscribe":{"post":{"tags":["Signals"],"summary":"Subscribe to a Signal.","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"}},{"name":"id","in":"path","description":"The id of the signal.","required":true,"schema":{"type":"string"}},{"name":"pushed","in":"query","description":"Prevent the user to unsubscribe (only for bulk subscription)","schema":{"type":"boolean"}}],"requestBody":{"description":"UserIds to subscribe (only for bulk subscription)","content":{"application/json":{"schema":{"type":"array","items":{"type":"integer","format":"int64"}}}},"required":false},"responses":{"200":{"description":"Signal subscribed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ChannelSubscriptionResponse"}}}},"400":{"description":"Client error, see response body for further details.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/V2Error"}}}},"401":{"description":"Unauthorized: Session tokens invalid.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/V2Error"}}}},"403":{"description":"Forbidden: Caller lacks necessary entitlement.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/V2Error"}}}},"500":{"description":"Server error, see response body for further details.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/V2Error"}}}}}}}},"components":{"schemas":{"ChannelSubscriptionResponse":{"type":"object","properties":{"requestedSubscription":{"type":"integer","description":"The number of requested userIds to subscribe","format":"int64"},"successfulSubscription":{"type":"integer","description":"The number of successful subscriptions done","format":"int64"},"failedSubscription":{"type":"integer","description":"The number of subscription failures","format":"int64"},"subscriptionErrors":{"type":"array","items":{"$ref":"#/components/schemas/ChannelSubscriptionError"}}}},"ChannelSubscriptionError":{"type":"object","properties":{"userId":{"type":"integer","description":"The userId on which failure happened","format":"int64"},"code":{"type":"string","description":"subscription failure code"},"message":{"type":"string","description":"subscription failure message"}}},"V2Error":{"required":["code","message"],"type":"object","properties":{"code":{"type":"integer","format":"int32"},"message":{"type":"string"},"details":{"type":"object"}}}}}}
```

### Request Examples

```bash
curl -X POST \
https://acme.symphony.com/agent/v1/signals/5a6efc9db9d8210001b9960b/subscribe \
  -H 'content-type: application/json' \
  -H 'sessiontoken: SESSION_TOKEN' \
  -H 'keymanagertoken: KEYMANAGER_TOKEN' \   
  -d '[68719476759, 68719476760, 68719476761]'
```

```bash
curl -X POST
  -H 'content-type: application/json'
  -H 'sessiontoken: SESSION_TOKEN'
  -H 'keymanagertoken: KEYMANAGER_TOKEN'  
  https://acme.symphony.com/agent/v1/signals/5a6efc9db9d8210001b9960b/subscribe
```

> #### 🚧 Required Permissions
>
> To subscribe other users to a specific signal, the requesting user needs to have the `canManageSignalSubscription` entitlement.


# Unsubscribe Signal

Unsubscribes an array of users from the specified Signal.

## POST /v1/signals/{id}/unsubscribe

> Unsubscribe to a Signal.

```json
{"openapi":"3.0.1","info":{"title":"Agent API","version":"25.8.1"},"servers":[{"url":"youragentURL.symphony.com/agent"}],"paths":{"/v1/signals/{id}/unsubscribe":{"post":{"tags":["Signals"],"summary":"Unsubscribe to a Signal.","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"}},{"name":"id","in":"path","description":"The id of the signal.","required":true,"schema":{"type":"string"}}],"requestBody":{"description":"UserIds to unsubscribe (only for bulk unsubscription)","content":{"application/json":{"schema":{"type":"array","items":{"type":"integer","format":"int64"}}}},"required":false},"responses":{"200":{"description":"Signal unsubscribed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ChannelSubscriptionResponse"}}}},"400":{"description":"Client error, see response body for further details.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/V2Error"}}}},"401":{"description":"Unauthorized: Session tokens invalid.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/V2Error"}}}},"403":{"description":"Forbidden: Caller lacks necessary entitlement.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/V2Error"}}}},"500":{"description":"Server error, see response body for further details.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/V2Error"}}}}}}}},"components":{"schemas":{"ChannelSubscriptionResponse":{"type":"object","properties":{"requestedSubscription":{"type":"integer","description":"The number of requested userIds to subscribe","format":"int64"},"successfulSubscription":{"type":"integer","description":"The number of successful subscriptions done","format":"int64"},"failedSubscription":{"type":"integer","description":"The number of subscription failures","format":"int64"},"subscriptionErrors":{"type":"array","items":{"$ref":"#/components/schemas/ChannelSubscriptionError"}}}},"ChannelSubscriptionError":{"type":"object","properties":{"userId":{"type":"integer","description":"The userId on which failure happened","format":"int64"},"code":{"type":"string","description":"subscription failure code"},"message":{"type":"string","description":"subscription failure message"}}},"V2Error":{"required":["code","message"],"type":"object","properties":{"code":{"type":"integer","format":"int32"},"message":{"type":"string"},"details":{"type":"object"}}}}}}
```

> #### 🚧 Permissions
>
> * To unsubscribe from a signal, the requesting user cannot be the owner of the signal.
> * To unsubscribe other users from a signal, the requesting user needs to have the `canManageSignalSubscription` entitlement and the signal cannot be a company-wide signal.


# Suscribers

Gets the subscribers for the specified signal.

## GET /v1/signals/{id}/subscribers

> Get the subscribers of a signal

```json
{"openapi":"3.0.1","info":{"title":"Agent API","version":"25.8.1"},"servers":[{"url":"youragentURL.symphony.com/agent"}],"paths":{"/v1/signals/{id}/subscribers":{"get":{"tags":["Signals"],"summary":"Get the subscribers of a signal","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"}},{"name":"id","in":"path","description":"The id of the signal.","required":true,"schema":{"type":"string"}},{"name":"skip","in":"query","description":"No. of results to skip.","schema":{"type":"integer","default":0}},{"name":"limit","in":"query","description":"Max No. of subscribers to return. If no value is provided, 100 is the default.","schema":{"type":"integer","default":100}}],"responses":{"200":{"description":"Signal Subscribers.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ChannelSubscriberResponse"}}}},"400":{"description":"Client error, see response body for further details.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/V2Error"}}}},"401":{"description":"Unauthorized: Session tokens invalid.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/V2Error"}}}},"403":{"description":"Forbidden: Caller lacks necessary entitlement.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/V2Error"}}}},"500":{"description":"Server error, see response body for further details.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/V2Error"}}}}}}}},"components":{"schemas":{"ChannelSubscriberResponse":{"type":"object","properties":{"offset":{"type":"integer","description":"The number of subscribers skipped","format":"int64"},"hasMore":{"type":"boolean","description":"True if there are more subscribers"},"total":{"type":"integer","description":"The total number of subscribers"},"data":{"type":"array","items":{"$ref":"#/components/schemas/ChannelSubscriber"}}}},"ChannelSubscriber":{"type":"object","properties":{"subscriptionId":{"type":"string"},"pushed":{"type":"boolean","description":"True if the subscriber is allowed to unsubscribe","default":false},"owner":{"type":"boolean","description":"True if the subscriber is the creator","default":false},"subscriberName":{"type":"string","description":"User display name"},"userId":{"type":"integer","description":"The user ID of the subscriber","format":"int64"},"timestamp":{"type":"integer","description":"Timestamp when the signal was subscribed, in milliseconds since Jan 1 1970","format":"int64"}}},"V2Error":{"required":["code","message"],"type":"object","properties":{"code":{"type":"integer","format":"int32"},"message":{"type":"string"},"details":{"type":"object"}}}}}}
```


# Signal Object

The Signal object must be included in the body of the request. Signal objects can be subscribed and unsubscribed. The management of those subscriptions at both the individual and company-wide scales requires entitlements (see Entitlements below). The Signal object contains the following fields:

<table><thead><tr><th width="175">Field</th><th width="84">Type</th><th>Description</th></tr></thead><tbody><tr><td>name</td><td>String</td><td>Signal name</td></tr><tr><td>query</td><td>String</td><td>The query used to define this signal and is composed of <code>field:value</code> pairs combined by the operators <code>AND</code> or <code>OR</code>. <br><br>Supported fields are: <code>author</code>, <code>hashtag</code> and <code>cashtag</code> (<em>case-insensitive</em>), and MUST contain at least one <code>hashtag</code> or <code>cashtag</code> definition.<br><br>This field uses the same syntax as the <a href="/pages/I2VvZUQKB517cJgyA7FD">Message Search</a> with these fields: <code>HASHTAG</code>, <code>CASHTAG</code>, <code>AUTHOR</code>, <code>POSTEDBY</code>. <br><code>POSTEDBY</code> refers to wall posts by the end user.</td></tr><tr><td>visibleOnProfile</td><td>Boolean</td><td>Specifies whether the signal is visible on its creator's profile.</td></tr><tr><td>companyWide</td><td>Boolean</td><td>Specifies whether the signal is a company-wide signal. Users in the pod cannot unsubscribe. The <strong>Can create push signals</strong> entitlement is required to set this field. See Entitlements for more information.</td></tr></tbody></table>

### Entitlements

The following entitlements, which appear in the **Admin Portal**, provide you with subscription capabilities for both specified users and company-wide pods.

<table><thead><tr><th width="307">Entitlement</th><th>Capability</th></tr></thead><tbody><tr><td><strong>Can manage signal subscriptions</strong></td><td>Allows you to subscribe specified users who cannot unsubscribe from a given signal.</td></tr><tr><td><strong>Can create push signals</strong></td><td>Allows you to create company-wide signals that cannot be unsubscribed.</td></tr></tbody></table>


# Connections


# Get Connection

Get connection status, i.e. check if the calling user is connected to the specified user.

## GET /v1/connection/user/{userId}/info

> The status of the connection invitation to another user.

```json
{"openapi":"3.1.1","info":{"title":"Pod API","version":"20.17.1"},"servers":[{"url":"http://yourpodURL.symphony.com/pod"}],"paths":{"/v1/connection/user/{userId}/info":{"get":{"summary":"The status of the connection invitation to another user.","parameters":[{"schema":{"type":"string"},"name":"sessionToken","description":"Session authentication token.","in":"header","required":true},{"schema":{"type":"string"},"name":"userId","description":"user Id","in":"path","required":true}],"tags":["Connection"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserConnection"}}}},"400":{"description":"Client error, see response body for further details.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Unauthorized: Invalid session token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Forbidden: Caller lacks necessary entitlement.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not Found: Connection cannot be found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Server error, see response body for further details.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}}},"components":{"schemas":{"UserConnection":{"type":"object","description":"Connection status between two users","properties":{"userId":{"type":"integer","format":"int64","description":"user id"},"status":{"type":"string","description":"Connection status between the requesting user and the request sender","enum":["PENDING_INCOMING","PENDING_OUTGOING","ACCEPTED","REJECTED"]},"firstRequestedAt":{"type":"integer","format":"int64","description":"unix timestamp when the first request was made"},"updatedAt":{"type":"integer","format":"int64","description":"unix timestamp on the last updated date"},"requestCounter":{"type":"integer","format":"int32","description":"number of requests made"}}},"Error":{"type":"object","properties":{"code":{"type":"integer","format":"int32"},"message":{"type":"string"}}}}}}
```

> #### 📘 Note
>
> * When calling this as an [OBO-enabled endpoint](/main/apps-on-behalf-of-obo), use the [OBO User Authenticate](/main/apps-on-behalf-of-obo/obo-rsa-user-authentication-by-user-id) token for `sessionToken`.
> * Pods from all users involved need to have `crossPod` enabled between them.

> #### 📘 404 Not Found
>
> A `404 Not Found` error indicates either:
>
> * The specified user doesn’t exist.
> * The calling user and specified user are not connected because a [Create Connection](/main/connections/create-connection) request has not yet been sent.

> #### 📘 Internal Connections
>
> Users who belong to the same private pod are implicitly connected. Getting the connection status with an internal user will return the corresponding connection object with a status of `ACCEPTED`.

### Connection Status

Currently, there are four possible connection status:

* `PENDING_INCOMING`: The specified user requested to connect with the calling user.
* `PENDING_OUTGOING`: The calling user requested to connect with the specified user.
* `ACCEPTED`: The two users are connected.
* `REJECTED`: The two users are not connected.


# List Connection

List all current connection statuses with external or specified users.

## List of requesting user's connection

> This retrieves all connections of the requesting user. (i.e. both connections in which the requesting user is the sender and those\
> in which the requesting user is the inivtee) By default, if you haven't specified the connection status to filter on, this call will only\
> return results for both "pending\_incoming" and "pending\_outgoing". You can optionally filter by userIds to further restrict the results of\
> a specific connection status. If the users are in the same private pod, the users have an implicit connection status of "accepted". Those\
> users will not be returned in the response if you don't specify the connection status as "accepted" (default is "pending")\
> and the explicit userIds in the request.<br>

```json
{"openapi":"3.1.1","info":{"title":"Pod API","version":"20.17.1"},"servers":[{"url":"http://yourpodURL.symphony.com/pod"}],"paths":{"/v1/connection/list":{"get":{"summary":"List of requesting user's connection","description":"This retrieves all connections of the requesting user. (i.e. both connections in which the requesting user is the sender and those\nin which the requesting user is the inivtee) By default, if you haven't specified the connection status to filter on, this call will only\nreturn results for both \"pending_incoming\" and \"pending_outgoing\". You can optionally filter by userIds to further restrict the results of\na specific connection status. If the users are in the same private pod, the users have an implicit connection status of \"accepted\". Those\nusers will not be returned in the response if you don't specify the connection status as \"accepted\" (default is \"pending\")\nand the explicit userIds in the request.\n","parameters":[{"schema":{"type":"string"},"name":"sessionToken","description":"Session authentication token.","in":"header","required":true},{"schema":{"type":"string","enum":["PENDING_INCOMING","PENDING_OUTGOING","ACCEPTED","REJECTED","ALL"]},"name":"status","description":"Filter the connection list based on the connection status.\nThe connection status can only be pending_incoming, pending_outgoing, accepted, rejected, or all (all of the above)\n","in":"query"},{"schema":{"type":"string"},"name":"userIds","description":"The userIds parameter should be specified as a comma delimited list of user ids and can be used to restrict the results of a specific connection.\nNote that this is particularly important if the caller intends to retrieve results for implicit connection (user within the same pod).\nImplicit connections will not be included in the response if userId is not provided.\n","in":"query"}],"tags":["Connection"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserConnectionList"}}}},"400":{"description":"Client error, see response body for further details.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Unauthorized: Invalid session token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Forbidden: Caller lacks necessary entitlement.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not Found: Connection cannot be found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Server error, see response body for further details.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}}},"components":{"schemas":{"UserConnectionList":{"type":"array","items":{"$ref":"#/components/schemas/UserConnection"}},"UserConnection":{"type":"object","description":"Connection status between two users","properties":{"userId":{"type":"integer","format":"int64","description":"user id"},"status":{"type":"string","description":"Connection status between the requesting user and the request sender","enum":["PENDING_INCOMING","PENDING_OUTGOING","ACCEPTED","REJECTED"]},"firstRequestedAt":{"type":"integer","format":"int64","description":"unix timestamp when the first request was made"},"updatedAt":{"type":"integer","format":"int64","description":"unix timestamp on the last updated date"},"requestCounter":{"type":"integer","format":"int32","description":"number of requests made"}}},"Error":{"type":"object","properties":{"code":{"type":"integer","format":"int32"},"message":{"type":"string"}}}}}}
```

This endpoint retrieves all connections of the requesting user. (i.e. both connections in which the requesting user is the sender and those in which the requesting user is the invitee). By default, if you have not specified the connection status to filter on, this call will only return results for both PENDING\_INCOMING and PENDING\_OUTGOING. You can optionally filter by userIds to further restrict the results of a specific connection status. If the users are in the same private pod, the users have an implicit connection status of ACCEPTED. Those users will not be returned in the response if you do not specify the connection status as ACCEPTED (default is "pending") and the explicit userIds in the request.

> #### 📘 Note
>
> * When calling this as an [OBO-enabled endpoint](/main/apps-on-behalf-of-obo), use the [OBO User Authenticate](/main/apps-on-behalf-of-obo/obo-rsa-user-authentication-by-user-id) token for `sessionToken`.
> * Pods from all users involved need to have `crossPod` enabled between them.

### Connection Status

Currently, there are four possible connection status:

* PENDING\_INCOMING: The specified user requested to connect with the calling user.
* PENDING\_OUTGOING: The calling user requested to connect with the specified user.
* ACCEPTED: The two users are connected.
* REJECTED: The two users are not connected.


# Create Connection

Sends a connection request to another user.

## POST /v1/connection/create

> Sends an invitation to connect with another user

```json
{"openapi":"3.1.1","info":{"title":"Pod API","version":"20.17.1"},"servers":[{"url":"http://yourpodURL.symphony.com/pod"}],"paths":{"/v1/connection/create":{"post":{"summary":"Sends an invitation to connect with another user","parameters":[{"schema":{"type":"string"},"name":"sessionToken","description":"Session authentication token.","in":"header","required":true}],"tags":["Connection"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserConnection"}}}},"400":{"description":"Client error, see response body for further details.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Unauthorized: Invalid session token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Forbidden: Caller lacks necessary entitlement.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not Found: User cannot be found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Server error, see response body for further details.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserConnectionRequest"}}},"required":true}}}},"components":{"schemas":{"UserConnection":{"type":"object","description":"Connection status between two users","properties":{"userId":{"type":"integer","format":"int64","description":"user id"},"status":{"type":"string","description":"Connection status between the requesting user and the request sender","enum":["PENDING_INCOMING","PENDING_OUTGOING","ACCEPTED","REJECTED"]},"firstRequestedAt":{"type":"integer","format":"int64","description":"unix timestamp when the first request was made"},"updatedAt":{"type":"integer","format":"int64","description":"unix timestamp on the last updated date"},"requestCounter":{"type":"integer","format":"int32","description":"number of requests made"}}},"Error":{"type":"object","properties":{"code":{"type":"integer","format":"int32"},"message":{"type":"string"}}},"UserConnectionRequest":{"type":"object","description":"Request body for the Connection APIs","properties":{"userId":{"type":"integer","format":"int64","description":"user id"}}}}}}
```

> #### 📘 Internal Connections
>
> Users who belong to the same private pod are implicitly connected. If you attempt to connect with an internal user, this endpoint will return the corresponding connection object with a status of `accepted`.

> #### 📘 Note
>
> * When calling this as an [OBO-enabled endpoint](/main/apps-on-behalf-of-obo), use the [OBO User Authenticate](/main/apps-on-behalf-of-obo/obo-rsa-user-authentication-by-user-id) token for `sessionToken`.
> * Pods from all users involved need to have `crossPod` enabled between them.
> * Only one connection request is allowed between two users. When this limit is exceeded, no more connections requests are allowed. A new connection request will be allowed only if the user that received the connection request declines it.

### Connection Behaviour

Currently, there are four possible connection status:

* PENDING\_INCOMING: The specified user requested to connect with the calling user.
* PENDING\_OUTGOING: The calling user requested to connect with the specified user.
* ACCEPTED: The two users are connected.
* REJECTED: The two users are not connected.

The following table shows the connection current behaviors:

<table><thead><tr><th width="301.3333333333333">Initial Connection Status</th><th>Request Action</th><th>New Connection Status</th></tr></thead><tbody><tr><td>None (connection did not exist)</td><td>Connect</td><td>PENDING_OUTGOING</td></tr><tr><td>PENDING_INCOMING</td><td>Accept</td><td>ACCEPTED</td></tr><tr><td>PENDING_INCOMING</td><td>Reject</td><td>REJECTED</td></tr></tbody></table>


# Accept Connection

Accept the connection request from a requesting user.

## POST /v1/connection/accept

> Accept the connection request for the requesting user

```json
{"openapi":"3.1.1","info":{"title":"Pod API","version":"20.17.1"},"servers":[{"url":"http://yourpodURL.symphony.com/pod"}],"paths":{"/v1/connection/accept":{"post":{"summary":"Accept the connection request for the requesting user","parameters":[{"schema":{"type":"string"},"name":"sessionToken","description":"Session authentication token.","in":"header","required":true}],"tags":["Connection"],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserConnection"}}}},"400":{"description":"Client error, see response body for further details.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Unauthorized: Invalid session token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Forbidden: Caller lacks necessary entitlement.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not Found: Connection cannot be found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Server error, see response body for further details.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserConnectionRequest"}}},"required":true}}}},"components":{"schemas":{"UserConnection":{"type":"object","description":"Connection status between two users","properties":{"userId":{"type":"integer","format":"int64","description":"user id"},"status":{"type":"string","description":"Connection status between the requesting user and the request sender","enum":["PENDING_INCOMING","PENDING_OUTGOING","ACCEPTED","REJECTED"]},"firstRequestedAt":{"type":"integer","format":"int64","description":"unix timestamp when the first request was made"},"updatedAt":{"type":"integer","format":"int64","description":"unix timestamp on the last updated date"},"requestCounter":{"type":"integer","format":"int32","description":"number of requests made"}}},"Error":{"type":"object","properties":{"code":{"type":"integer","format":"int32"},"message":{"type":"string"}}},"UserConnectionRequest":{"type":"object","description":"Request body for the Connection APIs","properties":{"userId":{"type":"integer","format":"int64","description":"user id"}}}}}}
```

This endpoint allows the user to accept a specific connection request. To define which connection request is to be accepted, the `userId` of the user who initiated the connection request must be included in the body.

> #### 📘 Note
>
> Pods from all users involved need to have `crossPod` enabled between them.

> #### 📘 Accepted Connections
>
> For users of the same private pod who are implicitly connected, this endpoint returns the connection with status of "Accepted".

### Connection Behaviour

Currently, there are four possible connection status:

* PENDING\_INCOMING: The specified user requested to connect with the calling user.
* PENDING\_OUTGOING: The calling user requested to connect with the specified user.
* ACCEPTED: The two users are connected.
* REJECTED: The two users are not connected.

The following table shows the connection current behaviors:

<table><thead><tr><th width="324.3333333333333">Initial Connection Status</th><th>Request Action</th><th>New Connection Status</th></tr></thead><tbody><tr><td>None (connection did not exist)</td><td>Connect</td><td>PENDING_OUTGOING</td></tr><tr><td>PENDING_INCOMING</td><td>Accept</td><td>ACCEPTED</td></tr><tr><td>PENDING_INCOMING</td><td>Reject</td><td>REJECTED</td></tr></tbody></table>


# Reject Connection

## Reject the connection request for the requesting user.

> Reject the connection between the requesting user and request sender. If both users are in the same private pod,\
> an error will be returned because both users have an implicit connection which cannot be rejected.<br>

```json
{"openapi":"3.1.1","info":{"title":"Pod API","version":"20.17.1"},"servers":[{"url":"http://yourpodURL.symphony.com/pod"}],"paths":{"/v1/connection/reject":{"post":{"summary":"Reject the connection request for the requesting user.","description":"Reject the connection between the requesting user and request sender. If both users are in the same private pod,\nan error will be returned because both users have an implicit connection which cannot be rejected.\n","parameters":[{"schema":{"type":"string"},"name":"sessionToken","description":"Session authentication token.","in":"header","required":true}],"tags":["Connection"],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserConnection"}}}},"400":{"description":"Client error, see response body for further details.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Unauthorized: Invalid session token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Forbidden: Caller lacks necessary entitlement.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not Found: Connection cannot be found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Server error, see response body for further details.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserConnectionRequest"}}},"required":true}}}},"components":{"schemas":{"UserConnection":{"type":"object","description":"Connection status between two users","properties":{"userId":{"type":"integer","format":"int64","description":"user id"},"status":{"type":"string","description":"Connection status between the requesting user and the request sender","enum":["PENDING_INCOMING","PENDING_OUTGOING","ACCEPTED","REJECTED"]},"firstRequestedAt":{"type":"integer","format":"int64","description":"unix timestamp when the first request was made"},"updatedAt":{"type":"integer","format":"int64","description":"unix timestamp on the last updated date"},"requestCounter":{"type":"integer","format":"int32","description":"number of requests made"}}},"Error":{"type":"object","properties":{"code":{"type":"integer","format":"int32"},"message":{"type":"string"}}},"UserConnectionRequest":{"type":"object","description":"Request body for the Connection APIs","properties":{"userId":{"type":"integer","format":"int64","description":"user id"}}}}}}
```

This endpoint allows the user to reject a specific connection request. To define which connection request is to be rejected, the `userId` of the user who initiated the connection request must be included in the body.

Pods from all users involved need to have `crossPod` enabled between them.

> #### 📘 Rejected Connections
>
> Reject the connection between the requesting user and request sender. If both users are in the same private pod, an error will be returned because both users have an implicit connection which cannot be rejected.

### Connection Behaviour

Currently, there are four possible connection status:

* PENDING\_INCOMING: The specified user requested to connect with the calling user.
* PENDING\_OUTGOING: The calling user requested to connect with the specified user.
* ACCEPTED: The two users are connected.
* REJECTED: The two users are not connected.

The following table shows the connection current behaviors:

| Initial Connection Status       | Request Action | New Connection Status |
| ------------------------------- | -------------- | --------------------- |
| None (connection did not exist) | Connect        | PENDING\_OUTGOING     |
| PENDING\_INCOMING               | Accept         | ACCEPTED              |
| PENDING\_INCOMING               | Reject         | REJECTED              |


# Remove Connection

Removes a connection with a user.

## POST /v1/connection/user/{uid}/remove

> Removes a connection with a user.

```json
{"openapi":"3.1.1","info":{"title":"Pod API","version":"20.17.1"},"servers":[{"url":"http://yourpodURL.symphony.com/pod"}],"paths":{"/v1/connection/user/{uid}/remove":{"post":{"summary":"Removes a connection with a user.","parameters":[{"schema":{"type":"string"},"name":"sessionToken","description":"Session authentication token.","in":"header","required":true},{"schema":{"type":"integer","format":"int64"},"name":"uid","description":"User ID as a decimal integer\n","in":"path","required":true}],"tags":["Connection"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SuccessResponse"}}}},"400":{"description":"Client error, see response body for further details.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Unauthorized: Invalid session token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Forbidden: Caller lacks necessary entitlement.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not Found: Connection cannot be found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Server error, see response body for further details.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}}},"components":{"schemas":{"SuccessResponse":{"type":"object","properties":{"format":{"type":"string","enum":["TEXT","XML"]},"message":{"type":"string"}}},"Error":{"type":"object","properties":{"code":{"type":"integer","format":"int32"},"message":{"type":"string"}}}}}}
```

> #### 📘 Note
>
> Pods from all users involved need to have `crossPod` enabled between them.

> #### 📘 HTTP 400
>
> This endpoint returns **400 Bad Request** when the users are not connected. For example, when a user has not yet accepted a connection request from another user.

### Connection Behaviour

Currently, there are four possible connection status:

* PENDING\_INCOMING: The specified user requested to connect with the calling user.
* PENDING\_OUTGOING: The calling user requested to connect with the specified user.
* ACCEPTED: The two users are connected.
* REJECTED: The two users are not connected.

The following table shows the connection current behaviors:

| Initial Connection Status | Request Action | New Connection Status                 |
| ------------------------- | -------------- | ------------------------------------- |
| ACCEPTED                  | Remove         | None (the connection no longer exist) |
| PENDING\_INCOMING         | Remove         | REJECTED                              |
| REJECTED                  | Remove         | PENDING\_INCOMING                     |


# Presence


# Get Presence

Returns the online status of the calling user.

## GET /v2/user/presence

> Get presence information about the requesting user.

```json
{"openapi":"3.1.1","info":{"title":"Pod API","version":"20.17.1"},"servers":[{"url":"http://yourpodURL.symphony.com/pod"}],"paths":{"/v2/user/presence":{"get":{"summary":"Get presence information about the requesting user.","parameters":[{"schema":{"type":"string"},"name":"sessionToken","description":"Session authentication token.","in":"header","required":true}],"tags":["Presence"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/V2Presence"}}}},"400":{"description":"Client error, see response body for further details.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Unauthorized: Invalid session token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Server error, see response body for further details.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}}},"components":{"schemas":{"V2Presence":{"allOf":[{"$ref":"#/components/schemas/V2UserPresence"},{"type":"object","properties":{"timestamp":{"type":"integer","format":"int64","description":"The time, in milliseconds since Jan 1 1970, when the presence state was set."}}}]},"V2UserPresence":{"allOf":[{"$ref":"#/components/schemas/V2PresenceStatus"},{"type":"object","properties":{"userId":{"type":"integer","format":"int64","description":"The ID of the user to whom the presence state relates."}}}]},"V2PresenceStatus":{"type":"object","properties":{"category":{"type":"string","description":"Presence status. Possible values are:\n  - UNDEFINED\n  - AVAILABLE\n  - BUSY\n  - DO_NOT_DISTURB\n  - ON_THE_PHONE\n  - BE_RIGHT_BACK\n  - IN_A_MEETING\n  - AWAY\n  - OUT_OF_OFFICE\n  - OFF_WORK\n  - OFFLINE\n"}},"required":["category"]},"Error":{"type":"object","properties":{"code":{"type":"integer","format":"int32"},"message":{"type":"string"}}}}}}
```

When calling this as an [OBO-enabled endpoint](/main/apps-on-behalf-of-obo), use the [OBO User Authenticate](/main/apps-on-behalf-of-obo/obo-rsa-user-authentication-by-user-id) token for `sessionToken`.

The available online status values (presence categories) for users are:

| Presence category | Interface icon   | External view   | Comment             |
| ----------------- | ---------------- | --------------- | ------------------- |
| `AVAILABLE`       | Green check mark | `AVAILABLE`     | Released in 1.46    |
| `AWAY`            | Yellow clock     | `AWAY`          | Released in 1.46    |
| `OFFLINE`         | Grey cross       | `OFFLINE`       | Introduced in 20.16 |
| `BUSY`            | Red sign         | `BUSY`          | Released in 1.46    |
| `ON_THE_PHONE`    | Red phone        | `ON_THE_PHONE`  | Released in 1.46    |
| `BE_RIGHT_BACK`   | Yellow clock     | `AWAY`          | Released in 1.47    |
| `IN_A_MEETING`    | Red phone        | `IN_A_MEETING`  | Released in 1.47    |
| `OUT_OF_OFFICE`   | Purple circle    | `OUT_OF_OFFICE` | Released in 1.47    |
| `OFF_WORK`        | Yellow clock     | `OFFLINE`       | Deprecated in 20.16 |
| `DO_NOT_DISTURB`  | Red circle       | `AWAY`          | Deprecated in 20.16 |

See [Set Presence](/main/presence/set-presence) for a description of the **Presence category** and **External view** values for internal and external users.

**Note**: It is also possible for Symphony users to have other presence values, which should be handled in your implementation as edge cases.


# Get All Presence

Returns the presence of all users in a pod.

## Get presence information about all company (pod) users.

> The returned data is taken from the in-memory cache for performance\
> reasons which means inactive users may be omitted from the response.\
> \
> All non-inactive users WILL be returned and some inactive users MAY\
> be included. Any omitted user IS inactive.\
> \
> Returned records are sorted by user ID, ascending.\
> \
> This method is expensive. It pulls ALL records from the cache, sorts them and then only uses a subset.\
> For large numbers of users, this can be very inefficient both due to sorting\
> and due to the cache being distributed across many nodes.\
> \
> Addiionally, there is the potential to miss users if they become active\
> after the page in which their user ID falls has already been read by the client.\
> To avoid this situation, a presence feed should be created (and optionally read from)\
> first to capture presence changes of users who get reactivated during a paged call to this endpoint.<br>

```json
{"openapi":"3.1.1","info":{"title":"Pod API","version":"20.17.1"},"servers":[{"url":"http://yourpodURL.symphony.com/pod"}],"paths":{"/v2/users/presence":{"get":{"summary":"Get presence information about all company (pod) users.","description":"The returned data is taken from the in-memory cache for performance\nreasons which means inactive users may be omitted from the response.\n\nAll non-inactive users WILL be returned and some inactive users MAY\nbe included. Any omitted user IS inactive.\n\nReturned records are sorted by user ID, ascending.\n\nThis method is expensive. It pulls ALL records from the cache, sorts them and then only uses a subset.\nFor large numbers of users, this can be very inefficient both due to sorting\nand due to the cache being distributed across many nodes.\n\nAddiionally, there is the potential to miss users if they become active\nafter the page in which their user ID falls has already been read by the client.\nTo avoid this situation, a presence feed should be created (and optionally read from)\nfirst to capture presence changes of users who get reactivated during a paged call to this endpoint.\n","parameters":[{"schema":{"type":"string"},"name":"sessionToken","description":"Session authentication token.","in":"header","required":true},{"schema":{"type":"integer","format":"int64"},"name":"lastUserId","description":"Last user ID retrieved. Used for paging; if provided, results will skip users with IDs less than this parameter.","in":"query","required":false},{"schema":{"type":"integer"},"name":"limit","description":"Max number of records to return. If no value is provided, 1000 is the default. The maximum supported value is 5000.","in":"query","required":false}],"tags":["Presence"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/V2PresenceList"}}}},"400":{"description":"Client error, see response body for further details.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Unauthorized: Invalid session token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Forbidden: Caller lacks necessary entitlement.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Server error, see response body for further details.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}}},"components":{"schemas":{"V2PresenceList":{"type":"array","items":{"$ref":"#/components/schemas/V2Presence"}},"V2Presence":{"allOf":[{"$ref":"#/components/schemas/V2UserPresence"},{"type":"object","properties":{"timestamp":{"type":"integer","format":"int64","description":"The time, in milliseconds since Jan 1 1970, when the presence state was set."}}}]},"V2UserPresence":{"allOf":[{"$ref":"#/components/schemas/V2PresenceStatus"},{"type":"object","properties":{"userId":{"type":"integer","format":"int64","description":"The ID of the user to whom the presence state relates."}}}]},"V2PresenceStatus":{"type":"object","properties":{"category":{"type":"string","description":"Presence status. Possible values are:\n  - UNDEFINED\n  - AVAILABLE\n  - BUSY\n  - DO_NOT_DISTURB\n  - ON_THE_PHONE\n  - BE_RIGHT_BACK\n  - IN_A_MEETING\n  - AWAY\n  - OUT_OF_OFFICE\n  - OFF_WORK\n  - OFFLINE\n"}},"required":["category"]},"Error":{"type":"object","properties":{"code":{"type":"integer","format":"int32"},"message":{"type":"string"}}}}}}
```

> 📘 All non-inactive users are returned and some inactive users may be included. Any omitted user is inactive.

> 🚧 Only users with the "User Provisioning" role can call this endpoint

When calling this as an [OBO-enabled endpoint](/main/apps-on-behalf-of-obo), use the [OBO User Authenticate](/main/apps-on-behalf-of-obo/obo-rsa-user-authentication-by-user-id) token for `sessionToken`.

For a list of the available presence statuses, please see the [Get Presence](/main/presence/get-presence)


# Get User Presence

Returns the online status of the specified user.

## GET /v3/user/{uid}/presence

> Get presence information about a particular user.

```json
{"openapi":"3.1.1","info":{"title":"Pod API","version":"20.17.1"},"servers":[{"url":"http://yourpodURL.symphony.com/pod"}],"paths":{"/v3/user/{uid}/presence":{"get":{"summary":"Get presence information about a particular user.","parameters":[{"schema":{"type":"integer","format":"int64"},"name":"uid","description":"User ID as a decimal integer\n","in":"path","required":true},{"schema":{"type":"boolean","default":false},"name":"local","description":"If true, a local query will be performed and the presence will be\nset to OFFLINE for users who are not local to the calling user's\npod. If false or absent, then the presence of all local users and\nthe presence of all external users to whom the calling user is\nconnected will be queried.\n\nFor external users, a \"presence interest\" should be registered through\n/v1/user/presence/register before querying for presence.\n","in":"query","required":false},{"schema":{"type":"string"},"name":"sessionToken","description":"Session authentication token.","in":"header","required":true}],"tags":["Presence"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/V2Presence"}}}},"400":{"description":"Client error, see response body for further details.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Unauthorized: Invalid session token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Forbidden: Caller lacks necessary entitlement.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not Found: user id cannot be located.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Server error, see response body for further details.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}}},"components":{"schemas":{"V2Presence":{"allOf":[{"$ref":"#/components/schemas/V2UserPresence"},{"type":"object","properties":{"timestamp":{"type":"integer","format":"int64","description":"The time, in milliseconds since Jan 1 1970, when the presence state was set."}}}]},"V2UserPresence":{"allOf":[{"$ref":"#/components/schemas/V2PresenceStatus"},{"type":"object","properties":{"userId":{"type":"integer","format":"int64","description":"The ID of the user to whom the presence state relates."}}}]},"V2PresenceStatus":{"type":"object","properties":{"category":{"type":"string","description":"Presence status. Possible values are:\n  - UNDEFINED\n  - AVAILABLE\n  - BUSY\n  - DO_NOT_DISTURB\n  - ON_THE_PHONE\n  - BE_RIGHT_BACK\n  - IN_A_MEETING\n  - AWAY\n  - OUT_OF_OFFICE\n  - OFF_WORK\n  - OFFLINE\n"}},"required":["category"]},"Error":{"type":"object","properties":{"code":{"type":"integer","format":"int32"},"message":{"type":"string"}}}}}}
```

The `timestamp` in the response is in UTC format and contains the time when the presence was set using [Set Presence](/main/presence/set-presence). For users who are offline, the `timestamp` contains the current time when the Get User Presence endpoint was invoked.

To get the presence of external users, you must first [register interest](/main/presence/register-user-presence-interest) about their presence.

When calling this as an [OBO-enabled endpoint](/main/apps-on-behalf-of-obo), use the [OBO User Authenticate](/main/apps-on-behalf-of-obo/obo-rsa-user-authentication-by-user-id) token for `sessionToken`.

The available online status values (presence categories) for users are listed on the [Get Presence](/main/presence/get-presence) page.

### Query Presence of External Users

To query the presence of external users, you must first perform an additional step:

1. Call the [Register Interest in External User Presence](/main/presence/register-user-presence-interest) endpoint to register interest in those users.
2. Call this endpoint to query the presence of each user.

To query the presence of internal users, you do not need to register interest and can call this endpoint directly.


# External Presence Interest

To get the presence state of external users, you must first register interest in those users using this endpoint.

## POST /v1/user/presence/register

> Register interest in a user's presence status

```json
{"openapi":"3.1.1","info":{"title":"Pod API","version":"20.17.1"},"servers":[{"url":"http://yourpodURL.symphony.com/pod"}],"paths":{"/v1/user/presence/register":{"post":{"summary":"Register interest in a user's presence status","parameters":[{"schema":{"type":"string"},"name":"sessionToken","description":"Session authentication token.","in":"header","required":true}],"tags":["Presence"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SuccessResponse"}}}},"400":{"description":"Client error, see response body for further details.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Unauthorized: Invalid session token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Forbidden: Caller lacks necessary entitlement.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not Found: user id cannot be located.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Server error, see response body for further details.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserIdList"}}},"description":"List of (integer) User IDs of users whose presence to query","required":true}}}},"components":{"schemas":{"SuccessResponse":{"type":"object","properties":{"format":{"type":"string","enum":["TEXT","XML"]},"message":{"type":"string"}}},"Error":{"type":"object","properties":{"code":{"type":"integer","format":"int32"},"message":{"type":"string"}}},"UserIdList":{"type":"array","items":{"type":"integer","format":"int64"}}}}}
```

### Request Example

```bash
curl -X POST \
  https://acme.symphony.com/pod/v1/user/presence/register \
  -H 'cache-control: no-cache' \
  -H 'content-type: application/json' \
  -H 'sessiontoken: SESSION_TOKEN' \
  -d '[7215545078541, 7215545078461]'
```

When calling this as an [OBO-enabled endpoint](/main/apps-on-behalf-of-obo), use the [OBO User Authenticate](/main/apps-on-behalf-of-obo/obo-rsa-user-authentication-by-user-id) token for `sessionToken`.

### Querying Presence of External Users

> #### 📘 External Users Presence Visibility
>
> Any user can see the presence of other users of the same company. For users of a different company, the two users must be connected to see presence.

To query the presence of external users:

1. Call this endpoint to register interest in the desired users.
2. Call the [Get User Presence](/main/presence/user-presence-v3) endpoint to query the presence of each user.\
   To keep the registration active, call this endpoint every hour.

To query the presence of internal users, you do not need to register interest.

> #### ❗️ Rate Limit
>
> Getting an external user’s presence is limited to one call every 5 minutes.

> #### 🚧 Roles and Privileges
>
> Calling this endpoint requires the ADMIN\_PRESENCE\_UPDATE privilege.\
> See [Bot Permissions](https://docs.developers.symphony.com/building-bots-on-symphony/configuration/bot-permissions) for a list of roles and associated privileges.


# Set Presence

Sets the online status of the calling user.

## POST /v2/user/presence

> Set the presence of the requesting user.

```json
{"openapi":"3.1.1","info":{"title":"Pod API","version":"20.17.1"},"servers":[{"url":"http://yourpodURL.symphony.com/pod"}],"paths":{"/v2/user/presence":{"post":{"summary":"Set the presence of the requesting user.","parameters":[{"schema":{"type":"string"},"name":"sessionToken","description":"Session authentication token.","in":"header","required":true},{"schema":{"type":"boolean"},"name":"soft","description":"If true, the user's current status is taken into consideration. If the user is currently OFFLINE,\nthe user's presence will still be OFFLINE, but the new presence will take effect when the\nuser comes online. If the user is currently online, the user's activity state will be\napplied to the presence if applicable. (e.g. if you are setting their presence to AVAILABLE,\nbut the user is currently idle, their status will be represented as AWAY)\n","in":"query","required":false}],"tags":["Presence"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/V2Presence"}}}},"400":{"description":"Client error, see response body for further details.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Unauthorized: Invalid session token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Server error, see response body for further details.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/V2PresenceStatus"}}},"required":true}}}},"components":{"schemas":{"V2Presence":{"allOf":[{"$ref":"#/components/schemas/V2UserPresence"},{"type":"object","properties":{"timestamp":{"type":"integer","format":"int64","description":"The time, in milliseconds since Jan 1 1970, when the presence state was set."}}}]},"V2UserPresence":{"allOf":[{"$ref":"#/components/schemas/V2PresenceStatus"},{"type":"object","properties":{"userId":{"type":"integer","format":"int64","description":"The ID of the user to whom the presence state relates."}}}]},"V2PresenceStatus":{"type":"object","properties":{"category":{"type":"string","description":"Presence status. Possible values are:\n  - UNDEFINED\n  - AVAILABLE\n  - BUSY\n  - DO_NOT_DISTURB\n  - ON_THE_PHONE\n  - BE_RIGHT_BACK\n  - IN_A_MEETING\n  - AWAY\n  - OUT_OF_OFFICE\n  - OFF_WORK\n  - OFFLINE\n"}},"required":["category"]},"Error":{"type":"object","properties":{"code":{"type":"integer","format":"int32"},"message":{"type":"string"}}}}}}
```

When calling this as an [OBO-enabled endpoint](/main/apps-on-behalf-of-obo), use the [OBO User Authenticate](/main/apps-on-behalf-of-obo/obo-rsa-user-authentication-by-user-id) token for `sessionToken`.

The available online status values (presence categories) for users are are available in [Get Presence](/main/presence/get-presence)

> #### 📘 Idle state
>
> When the end-user is idle on the Symphony clients and either in `AVAILABLE` or `BUSY` categories, the online status of the user is automatically changed to `AWAY`. When the user is active again on the client, then the online status is automatically changed back to the prior category.

> #### 🚧 Roles and Privileges
>
> Calling this endpoint requires the ADMIN\_PRESENCE\_UPDATE privilege.\
> See [Bot Permissions](https://docs.developers.symphony.com/building-bots-on-symphony/configuration/bot-permissions) for a list of roles and associated privileges.


# Set Other User's Presence - Admin

Sets the presence state of a another user.

## POST /v3/user/presence

> Set presence information for a particular user.

```json
{"openapi":"3.1.1","info":{"title":"Pod API","version":"20.17.1"},"servers":[{"url":"http://yourpodURL.symphony.com/pod"}],"paths":{"/v3/user/presence":{"post":{"summary":"Set presence information for a particular user.","parameters":[{"schema":{"type":"string"},"name":"sessionToken","description":"Session authentication token.","in":"header","required":true},{"schema":{"type":"boolean"},"name":"soft","description":"If true, the user's current status is taken into consideration. If the user is currently OFFLINE,\nthe user's presence will still be OFFLINE, but the new presence will take effect when the\nuser comes online. If the user is currently online, the user's activity state will be\napplied to the presence if applicable. (e.g. if you are setting their presence to AVAILABLE,\nbut the user is currently idle, their status will be represented as AWAY)\n","in":"query","required":false}],"tags":["Presence"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/V2Presence"}}}},"400":{"description":"Client error, see response body for further details.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Unauthorized: Invalid session token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Forbidden: Caller lacks necessary entitlement.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not Found: user id cannot be located.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Server error, see response body for further details.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/V2UserPresence"}}},"required":true}}}},"components":{"schemas":{"V2Presence":{"allOf":[{"$ref":"#/components/schemas/V2UserPresence"},{"type":"object","properties":{"timestamp":{"type":"integer","format":"int64","description":"The time, in milliseconds since Jan 1 1970, when the presence state was set."}}}]},"V2UserPresence":{"allOf":[{"$ref":"#/components/schemas/V2PresenceStatus"},{"type":"object","properties":{"userId":{"type":"integer","format":"int64","description":"The ID of the user to whom the presence state relates."}}}]},"V2PresenceStatus":{"type":"object","properties":{"category":{"type":"string","description":"Presence status. Possible values are:\n  - UNDEFINED\n  - AVAILABLE\n  - BUSY\n  - DO_NOT_DISTURB\n  - ON_THE_PHONE\n  - BE_RIGHT_BACK\n  - IN_A_MEETING\n  - AWAY\n  - OUT_OF_OFFICE\n  - OFF_WORK\n  - OFFLINE\n"}},"required":["category"]},"Error":{"type":"object","properties":{"code":{"type":"integer","format":"int32"},"message":{"type":"string"}}}}}}
```

> #### 🚧 User role requirement
>
> To set the presence of another user, this endpoint requires to be called by a service user with the "User Provisioning" Entitlement.


# Users


# Users Lookup

Search users by emails, ids or username.

## GET /v3/users

> Search users by emails or ids.\
> Only one of the search lists should be informed at a time.\
> Search lists may containt up to 100 elements.<br>

```json
{"openapi":"3.1.1","info":{"title":"Pod API","version":"20.17.1"},"servers":[{"url":"http://yourpodURL.symphony.com/pod"}],"paths":{"/v3/users":{"get":{"summary":"Search users by emails or ids.\nOnly one of the search lists should be informed at a time.\nSearch lists may containt up to 100 elements.\n","parameters":[{"schema":{"type":"string"},"name":"uid","description":"User IDs as a list of decimal integers separated by comma","in":"query","required":false},{"schema":{"type":"string"},"name":"email","description":"List of email addresses separated by comma","in":"query","required":false},{"schema":{"type":"string"},"name":"username","description":"List of username separated by comma","in":"query","required":false},{"schema":{"type":"boolean"},"name":"local","description":"If true then a local DB search will be performed and only local pod users will be\nreturned. If absent or false then a directory search will be performed and users\nfrom other pods who are visible to the calling user will also be returned.\n","in":"query","required":false},{"schema":{"type":"boolean"},"name":"active","description":"If not set all user status will be returned,\nif true all active users will be returned,\nif false all inactive users will be returned\n","in":"query","required":false},{"schema":{"type":"string"},"name":"sessionToken","description":"Session authentication token.","in":"header","required":true}],"tags":["Users"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/V2UserList"}}}},"204":{"description":"No user found."},"400":{"description":"Client error, see response body for further details.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Unauthorized: Invalid session token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Forbidden: Caller lacks necessary entitlement.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Server error, see response body for further details.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}}},"components":{"schemas":{"V2UserList":{"description":"List of User record version 2","type":"object","properties":{"users":{"type":"array","items":{"$ref":"#/components/schemas/UserV2"},"description":"List of all users found with the search"},"errors":{"type":"array","items":{"$ref":"#/components/schemas/UserError"},"description":"List of all errors found with the informed search criteria"}}},"UserV2":{"description":"User record version 2","type":"object","properties":{"id":{"type":"integer","format":"int64"},"emailAddress":{"type":"string","format":"email"},"firstName":{"type":"string"},"lastName":{"type":"string"},"displayName":{"type":"string"},"title":{"type":"string"},"company":{"type":"string"},"username":{"type":"string"},"location":{"type":"string"},"accountType":{"type":"string","enum":["NORMAL","SYSTEM","SDL"]},"avatars":{"$ref":"#/components/schemas/AvatarList"},"workPhoneNumber":{"type":"string","description":"Note: only available if the application has the extended user or contact permission"},"mobilePhoneNumber":{"type":"string","description":"Note: only available if the application has the extended user or contact permission"},"jobFunction":{"type":"string","description":"Note: only available if the application has the extended user or contact permission"},"department":{"type":"string","description":"Note: only available if the application has the extended user or contact permission"},"division":{"type":"string","description":"Note: only available if the application has the extended user or contact permission"},"roles":{"$ref":"#/components/schemas/StringList"},"userMetadata":{"type":"object","description":"Metadata map of key/values","additionalProperties":{"type":"object"}}}},"AvatarList":{"type":"array","items":{"$ref":"#/components/schemas/Avatar"}},"Avatar":{"type":"object","properties":{"size":{"description":"The Avatar Size","type":"string"},"url":{"description":"Url of the image","type":"string"}}},"StringList":{"type":"array","items":{"type":"string"}},"UserError":{"description":"User error information","type":"object","properties":{"error":{"type":"string","description":"Error code informing what is wrong"},"email":{"type":"string","description":"Email with error. Only one of the following fields should be present: email or id"},"id":{"type":"string","description":"Id with error. Only one of the following fields should be present: email or id"}}},"Error":{"type":"object","properties":{"code":{"type":"integer","format":"int32"},"message":{"type":"string"}}}}}}
```

### Request Examples

```bash
curl -X GET \
  'https://acme.symphony.com/pod/v3/users?uid=7696581394433,7696581394434&local=true' \
   -H 'SessionToken: SESSION_TOKEN' \
```

```bash
curl -X GET \
'https://cip3-qa.symphony.com/pod/v3/users?email=test_1@symphony.com,test_2@symphony.com&local=true' \
 -H 'SessionToken: SESSION_TOKEN' \
```

```bash
curl -X GET \
  'https://cip3-qa.symphony.com/pod/v3/users?username=test_1,test_2&local=true' \
   -H 'SessionToken: SESSION_TOKEN' \
```

### Search for external users

The caller can specify whether to search locally (within the caller's company) or globally across companies that have enabled external communications.

To search for external users, the parameter `local` needs to be set as **false** and the service account has to be enabled externally. To do so, make sure at least one of the two following external entitlements are enabled, otherwise, the search will return zero results.\
• Can chat in external IMs\
• Can chat in private external rooms

By default, searches are performed externally. Set `local=true` to search locally.

The following fields are stripped for **external** users that **don't have an established connection** with you:

* Email address
* Location
* Title

### Searching external users by email

The service account is allowed to search for users using their registered email even without having a previous connection with them.

### OBO enabled endpoint

When calling this as an [OBO-enabled endpoint](/main/apps-on-behalf-of-obo/obo-enabled-endpoints#api-endpoints-enabled-for-obo), use the [OBO User Authenticate](/main/apps-on-behalf-of-obo/obo-rsa-user-authentication-by-user-id) token for `sessionToken`.

> #### 🚧 Rules & Limitations
>
> * Please note that the endpoint returns only the first 1000 entries.

> #### 📘 Note
>
> **Search list sizes:** search lists may contain up to 100 elements.\
> **Inactive users:** the results will include inactive users.\
> **Account type:** the `accountType` field returns `NORMAL` if the user is a user account and `SYSTEM` if the user is a service account.\
> **User department, location, title and email:** the `department`, `location`, `title` and `emailAddress` fields are returned only if the user is an internal user of the current pod. When searching between cross-pods, these fields will not be returned.


# Search Users

Search for end-users, bots or distribution lists (groups) by first name, last name, display name, and email, and filter results by company, title, location, marketCoverage, responsibility, function, or instrument.

## POST /v1/user/search

> Search for users by name or email address

```json
{"openapi":"3.1.1","info":{"title":"Pod API","version":"20.17.1"},"servers":[{"url":"http://yourpodURL.symphony.com/pod"}],"paths":{"/v1/user/search":{"post":{"summary":"Search for users by name or email address","parameters":[{"schema":{"type":"integer"},"name":"skip","description":"number of records to skip","in":"query"},{"schema":{"type":"integer"},"name":"limit","description":"Max number of records to return. If no value is provided, 50 is the default.","in":"query"},{"schema":{"type":"boolean"},"name":"local","description":"If true then a local DB search will be performed and only local pod users will be\nreturned. If absent or false then a directory search will be performed and users\nfrom other pods who are visible to the calling user will also be returned.\n","in":"query","required":false},{"schema":{"type":"string"},"name":"sessionToken","description":"Session authentication token.","in":"header","required":true}],"tags":["Users"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserSearchResults"}}}},"204":{"description":"No user found."},"400":{"description":"Client error, see response body for further details.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Unauthorized: Invalid session token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Forbidden: Caller lacks necessary entitlement.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Server error, see response body for further details.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserSearchQuery"}}},"description":"search criteria","required":true}}}},"components":{"schemas":{"UserSearchResults":{"type":"object","properties":{"count":{"description":"The total number of users which matched the search criteria.","type":"integer","format":"int64"},"skip":{"description":"The number of skipped results.","type":"integer","format":"int64"},"limit":{"description":"The number of returned results.","type":"integer","format":"int64"},"searchQuery":{"$ref":"#/components/schemas/UserSearchQuery"},"users":{"description":"A list of users which matched by the search criteria.","type":"array","items":{"$ref":"#/components/schemas/UserV2"}}}},"UserSearchQuery":{"type":"object","properties":{"query":{"type":"string","description":"search / query term.  This can be firstname, lastname, displayname or email"},"filters":{"$ref":"#/components/schemas/UserSearchFilter"}}},"UserSearchFilter":{"type":"object","properties":{"accountTypes":{"$ref":"#/components/schemas/StringList","description":"type of user used to search"},"title":{"type":"string","description":"user's job title"},"company":{"type":"string","description":"company name"},"location":{"type":"string","description":"city of the user's job location"},"marketCoverage":{"type":"string","description":"geographic area the user works with"},"responsibility":{"type":"string","description":"user's responsibility"},"function":{"type":"string","description":"user's function"},"instrument":{"type":"string","description":"higher level instrument for the Asset Classes"}}},"StringList":{"type":"array","items":{"type":"string"}},"UserV2":{"description":"User record version 2","type":"object","properties":{"id":{"type":"integer","format":"int64"},"emailAddress":{"type":"string","format":"email"},"firstName":{"type":"string"},"lastName":{"type":"string"},"displayName":{"type":"string"},"title":{"type":"string"},"company":{"type":"string"},"username":{"type":"string"},"location":{"type":"string"},"accountType":{"type":"string","enum":["NORMAL","SYSTEM","SDL"]},"avatars":{"$ref":"#/components/schemas/AvatarList"},"workPhoneNumber":{"type":"string","description":"Note: only available if the application has the extended user or contact permission"},"mobilePhoneNumber":{"type":"string","description":"Note: only available if the application has the extended user or contact permission"},"jobFunction":{"type":"string","description":"Note: only available if the application has the extended user or contact permission"},"department":{"type":"string","description":"Note: only available if the application has the extended user or contact permission"},"division":{"type":"string","description":"Note: only available if the application has the extended user or contact permission"},"roles":{"$ref":"#/components/schemas/StringList"},"userMetadata":{"type":"object","description":"Metadata map of key/values","additionalProperties":{"type":"object"}}}},"AvatarList":{"type":"array","items":{"$ref":"#/components/schemas/Avatar"}},"Avatar":{"type":"object","properties":{"size":{"description":"The Avatar Size","type":"string"},"url":{"description":"Url of the image","type":"string"}}},"Error":{"type":"object","properties":{"code":{"type":"integer","format":"int32"},"message":{"type":"string"}}}}}}
```

### Request Example

```bash
curl -X POST \
https://acme.symphony.com/pod/v1/user/search?local=false \
-H "sessionToken: SESSION_TOKEN" \
-H "Content-Type: application/json"  \
-d '{
  "query": "jane",
  "filters": {
    "title": "Sales Manager",
    "location": "San Francisco",
    "company": "Symphony",
    "marketCoverage":"EMEA",
    "responsibility":"BAU",
    "function":"Trade Management",
    "instrument":"Securities",
    "accountTypes":["NORMAL","SDL"]
  }
}'
```

> #### 📘 Note
>
> * This endpoint can return inexact matches of the specified criteria, while [Find Users](/main/user-management/find-users) returns only exact matches.
> * Account type:
>   * The `accountType` field can contain a list of strings with the following supported values: `NORMAL`, `SYSTEM`, or `SDL`. Please note that if this is not specified, then the default search will return `NORMAL` and `SYSTEM` users in the payload.
>   * The `accountType` field returns `NORMAL` if the user is a user account, `SYSTEM` if the user is a service account, or `SDL` if the user is a Symphony Distribution List (Groups).\
>     **User location, title and email:** the `location`, `title` and `emailAddress` fields are returned only if the user is an internal user of the current pod. When searching between cross-pods, these fields will not be returned.

The caller can specify whether to search locally (within the caller's company) or globally across companies that have enabled external communications.

To search for external users, the parameter **local** needs to be set as **false** and the service account has to be enabled externally. To do so, make sure at least one of the two following external entitlements are enabled, otherwise, the search will return zero results.\
• Can chat in external IM/MIMs\
• Can chat in private external rooms

By default, searches are performed externally. Set `local=true` to search locally.

### Searching external users by email

The service account is allowed to search for users using their registered email even without having a previous connection with them.

### OBO enabled endpoint

When calling this as an [OBO-enabled endpoint](/main/apps-on-behalf-of-obo/obo-enabled-endpoints#api-endpoints-enabled-for-obo), use the [OBO User Authenticate](/main/apps-on-behalf-of-obo/obo-rsa-user-authentication-by-user-id) token for `sessionToken`.


# Follow User

Make a list of users to start following a specific user.

## POST /v1/user/{uid}/follow

> Make a list of users start following a specific user

```json
{"openapi":"3.1.1","info":{"title":"Pod API","version":"20.17.1"},"servers":[{"url":"http://yourpodURL.symphony.com/pod"}],"paths":{"/v1/user/{uid}/follow":{"post":{"summary":"Make a list of users start following a specific user","parameters":[{"schema":{"type":"string"},"name":"sessionToken","description":"Session authentication token.","in":"header","required":true},{"schema":{"type":"integer","format":"int64"},"name":"uid","description":"User ID as a decimal integer of the user to be followed","in":"path","required":true}],"tags":["User"],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SuccessResponse"}}}},"400":{"description":"Client error, see response body for further details.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Unauthorized: Invalid session token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Forbidden: Caller lacks necessary entitlement.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Server error, see response body for further details.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/FollowersList"}}},"description":"List of (integer) User IDs of the followers","required":true}}}},"components":{"schemas":{"SuccessResponse":{"type":"object","properties":{"format":{"type":"string","enum":["TEXT","XML"]},"message":{"type":"string"}}},"Error":{"type":"object","properties":{"code":{"type":"integer","format":"int32"},"message":{"type":"string"}}},"FollowersList":{"type":"object","properties":{"followers":{"$ref":"#/components/schemas/UserIdList"}}},"UserIdList":{"type":"array","items":{"type":"integer","format":"int64"}}}}}
```

> #### 🚧 Rules
>
> * The Service Account should have the Role *"User Provisioning"* in order to make these changes for any user or itself.
> * It is impossible for a user/service account to follow himself. The fact that the user/service account to follow (whose id is the `uid` from path param) is part of the list `followers` will not generate an error in the payload:
>   * a 200 should still be received but the user/service account will not follow himself;
>   * the other users included in the list will however start following the user to be followed (the one whose id is in path param as `uid`).
> * If an invalid user id is part of the list `followers`, then:
>   * a 400 error will be received in the payload mentioning the invalid user id;
>   * the other users included in the list will however start following the user to be followed (the one whose id is in path param as `uid`).
> * The fact that one of the user from the list `followers` already follows the considered user (from the path param as the one to follow) will not generate an error in the payload: a 200 should still be received. The involved user from the `followers` list will continue following the one to be followed.

When calling this as an [OBO-enabled endpoint](/main/apps-on-behalf-of-obo/obo-enabled-endpoints#api-endpoints-enabled-for-obo), use the [OBO User Authenticate](/main/apps-on-behalf-of-obo/obo-rsa-user-authentication-by-user-id) token for `sessionToken`.

> #### 📘 See also
>
> * [Unfollow User](/main/users/unfollow-user) to make a list of users to stop following a specific user


# Unfollow User

Make a list of users to stop following a specific user.

## POST /v1/user/{uid}/unfollow

> Make a list of users unfollowing a specific user

```json
{"openapi":"3.1.1","info":{"title":"Pod API","version":"20.17.1"},"servers":[{"url":"http://yourpodURL.symphony.com/pod"}],"paths":{"/v1/user/{uid}/unfollow":{"post":{"summary":"Make a list of users unfollowing a specific user","parameters":[{"schema":{"type":"string"},"name":"sessionToken","description":"Session authentication token.","in":"header","required":true},{"schema":{"type":"integer","format":"int64"},"name":"uid","description":"User ID as a decimal integer of the user to be unfollowed","in":"path","required":true}],"tags":["User"],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SuccessResponse"}}}},"400":{"description":"Client error, see response body for further details.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Unauthorized: Invalid session token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Forbidden: Caller lacks necessary entitlement.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Server error, see response body for further details.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/FollowersList"}}},"description":"List of (integer) User IDs of the followers","required":true}}}},"components":{"schemas":{"SuccessResponse":{"type":"object","properties":{"format":{"type":"string","enum":["TEXT","XML"]},"message":{"type":"string"}}},"Error":{"type":"object","properties":{"code":{"type":"integer","format":"int32"},"message":{"type":"string"}}},"FollowersList":{"type":"object","properties":{"followers":{"$ref":"#/components/schemas/UserIdList"}}},"UserIdList":{"type":"array","items":{"type":"integer","format":"int64"}}}}}
```

> #### 🚧 Rules
>
> * The Service Account should have the Role *"User Provisioning"* in order to make these changes for any user or itself.
> * It is impossible for a user/service account to follow himself. The fact that the user/service account to unfollow (whose id is the `uid` from path param) is part of the list `followers` will not generate an error in the payload:
>   * a 200 should still be received and nothing will happen regarding the affected user/service account;
>   * the other users included in the list will however stop following the user to be unfollowed (the one whose id is in path param as `uid`).
> * If an invalid user id is part of the list `followers`, then:
>   * a 400 error will be received in the payload mentioning the invalid user id;
>   * the other users included in the list will however stop following the user to be unfollowed (the one whose id is in path param as `uid`).
> * The fact that one of the user from the list `followers` does not follow the considered user (whose id is the `uid` from path param as the one to unfollow) will not generate an error in the payload: a 200 should still be received. The involved user from the `followers` list will still be out of the list of followers of the user to unfollow.

When calling this as an [OBO-enabled endpoint](/main/apps-on-behalf-of-obo/obo-enabled-endpoints#api-endpoints-enabled-for-obo), use the [OBO User Authenticate](/main/apps-on-behalf-of-obo/obo-rsa-user-authentication-by-user-id) token for `sessionToken`.

> #### 📘 See also
>
> * [Follow User](/main/users/follow-user) to make a list of users to start following a specific user


# List User Followers

Returns the list of followers of a specific user.

## GET /v1/user/{uid}/followers

> Returns the list of followers for a specific user

```json
{"openapi":"3.1.1","info":{"title":"Pod API","version":"20.17.1"},"servers":[{"url":"http://yourpodURL.symphony.com/pod"}],"paths":{"/v1/user/{uid}/followers":{"get":{"summary":"Returns the list of followers for a specific user","parameters":[{"schema":{"type":"string"},"name":"sessionToken","description":"Session authentication token.","in":"header","required":true},{"schema":{"type":"integer","format":"int64"},"name":"uid","description":"User ID as a decimal integer of the user we want to get the followers list","in":"path","required":true},{"schema":{"type":"integer"},"name":"limit","description":"This is the maximum number of objects that may be returned.","in":"query","required":false},{"schema":{"type":"string"},"name":"before","description":"Returns results from an opaque “before” cursor value as presented via a response cursor.","in":"query","required":false},{"schema":{"type":"string"},"name":"after","description":"Returns results from an opaque “after” cursor value as presented via a response cursor.","in":"query","required":false}],"tags":["User"],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/FollowersListResponse"}}}},"400":{"description":"Client error, see response body for further details.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Unauthorized: Invalid session token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Forbidden: Caller lacks necessary entitlement.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Server error, see response body for further details.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}}},"components":{"schemas":{"FollowersListResponse":{"type":"object","properties":{"count":{"type":"integer","format":"int64"},"followers":{"type":"array","items":{"type":"integer","format":"int64"}},"pagination":{"$ref":"#/components/schemas/Pagination"}}},"Pagination":{"type":"object","required":["cursors"],"properties":{"cursors":{"type":"object","required":["before"],"properties":{"before":{"type":"string","description":"This is the opaque url-safe string that points to the start of the page of data\nthat has been returned.\n"},"after":{"type":"string","description":"This is the opaque url-safe string that points to the end of the page of data\nthat has been returned.\n"}}},"previous":{"type":"string","description":"API endpoint that will return the previous page of data. If not included, this is\nthe first page of data.\n"},"next":{"type":"string","description":"API endpoint that will return the next page of data. If not included, this is the\nlast page of data. Due to how pagination works with visibility and privacy, it is\npossible that a page may be empty but contain a 'next' paging link. Stop paging when\nthe 'next' link no longer appears.\n"}}},"Error":{"type":"object","properties":{"code":{"type":"integer","format":"int32"},"message":{"type":"string"}}}}}}
```

> #### 👍 Rules for pagination
>
> * The count indicates the total number of items (e.g. the total number of followers)
> * Considering that ranking indexing starts with 1, the cursor `before` indicates:
>   * *in the request:* the rank of the last item wished in the payload (we want to show the maximum number of items positioned right before and including this one)
>   * *in the payload:* the number of items that are present before the first item of the payload
> * Considering that ranking indexing starts with 1, the cursor `after` indicates:
>   * *in the request:* the rank of the first item wished from the payload + 1 (we want to show the maximum number of items positioned right after and excluding this one)
>   * *in the payload:* the rank of the last item from the payload. When it is not present, it means that the last item in the payload is the last follower.

> #### 🚧 Notes & limitations
>
> * No specific entitlement is required to call this endpoint, but it is not possible to have access to external users' information:
>   * It is not possible to get the list of followers of an external user;
>   * No external user is included in the list returned by the endpoint.
> * If no `limit` parameter specified in the path of the request, it will be set by default to 100

> #### 📘 See also
>
> * [List Users Followed](/main/users/list-users-followed) to list users who are followed by a specific user




---

[Next Page](/llms-full.txt/1)

