# 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](https://rest-api.symphony.com/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)
