Get messages
GET https://qmech2021.zulip.cs.aalto.fi/api/v1/messages
This endpoint is the primary way to fetch a messages. It is used by all official
Zulip clients (e.g. the web, desktop, mobile, and terminal clients) as well as
many bots, API clients, backup scripts, etc.
Most queries will specify a narrow filter,
to fetch the messages matching any supported search
query. If not specified, it will return messages
corresponding to the user's combined feed. There are two
ways to specify which messages matching the narrow filter to fetch:
- 
A range of messages, described by an anchormessage ID (or a string-format
  specification of how the server should computer an anchor to use) and a maximum
  number of messages in each direction from that anchor.
 
- 
A rarely used variant (message_ids) where the client specifies the message IDs
  to fetch.
 
The server returns the matching messages, sorted by message ID, as well as some
metadata that makes it easy for a client to determine whether there are more
messages matching the query that were not returned due to the num_before and
num_after limits.
Note that a user's message history does not contain messages sent to
channels before they subscribe, and newly created
bot users are not usually subscribed to any channels.
We recommend requesting at most 1000 messages in a batch, to avoid generating very
large HTTP responses. A maximum of 5000 messages can be obtained per request;
attempting to exceed this will result in an error.
Changes: The message_ids option is new in Zulip 10.0 (feature level 300).
Usage examples
#!/usr/bin/env python3
import zulip
# Pass the path to your zuliprc file here.
client = zulip.Client(config_file="~/zuliprc")
# Get the 100 last messages sent by "iago@zulip.com" to
# the channel named "Verona".
request: dict[str, Any] = {
    "anchor": "newest",
    "num_before": 100,
    "num_after": 0,
    "narrow": [
        {"operator": "sender", "operand": "iago@zulip.com"},
        {"operator": "channel", "operand": "Verona"},
    ],
}
result = client.get_messages(request)
print(result)
 
More examples and documentation can be found here.
const zulipInit = require("zulip-js");
// Pass the path to your zuliprc file here.
const config = { zuliprc: "zuliprc" };
(async () => {
    const client = await zulipInit(config);
    const readParams = {
        anchor: "newest",
        num_before: 100,
        num_after: 0,
        narrow: [
            {operator: "sender", operand: "iago@zulip.com"},
            {operator: "channel", operand: "Verona"},
        ],
    };
    // Get the 100 last messages sent by "iago@zulip.com" to the channel "Verona"
    console.log(await client.messages.retrieve(readParams));
})();
 
curl -sSX GET -G https://qmech2021.zulip.cs.aalto.fi/api/v1/messages \
    -u BOT_EMAIL_ADDRESS:BOT_API_KEY \
    --data-urlencode anchor=43 \
    --data-urlencode num_before=4 \
    --data-urlencode num_after=8 \
    --data-urlencode 'narrow=[{"operand": "Denmark", "operator": "channel"}]' \
    --data-urlencode allow_empty_topic_name=true
 
 
 
Parameters
    anchor string optional  
    
        Example: "43"
    
    Integer message ID to anchor fetching of new messages. Supports special
string values for when the client wants the server to compute the anchor
to use:
- newest: The most recent message.
- oldest: The oldest message.
- first_unread: The oldest unread message matching the
  query, if any; otherwise, the most recent message.
Changes: String values are new in Zulip 3.0 (feature level 1). The
first_unread functionality was supported in Zulip 2.1.x
and older by not sending anchor and using use_first_unread_anchor.
In Zulip 2.1.x and older, oldest can be emulated with
"anchor": 0, and newest with "anchor": 10000000000000000
(that specific large value works around a bug in Zulip
2.1.x and older in the found_newest return value).
 
    include_anchor boolean optional  
    
        Example: false
    
    Whether a message with the specified ID matching the narrow
should be included.
Changes: New in Zulip 6.0 (feature level 155).
Defaults to true.
 
    num_before integer optional  
    
        Example: 4
    
    The number of messages with IDs less than the anchor to retrieve.
Required if message_ids is not provided.
 
    num_after integer optional  
    
        Example: 8
    
    The number of messages with IDs greater than the anchor to retrieve.
Required if message_ids is not provided.
 
    narrow (object | (string)[])[] optional  
    
        Example: [{"operand": "Denmark", "operator": "channel"}]
    
    The narrow where you want to fetch the messages from. See how to
construct a narrow.
Note that many narrows, including all that lack a channel, channels,
stream, or streams operator, search the user's personal message
history. See searching shared
history
for details.
For example, if you would like to fetch messages from all public channels instead
of only the user's message history, then a specific narrow for
messages sent to all public channels can be used:
{"operator": "channels", "operand": "public"}.
Newly created bot users are not usually subscribed to any
channels, so bots using this API should either be
subscribed to appropriate channels or use a shared history
search narrow with this endpoint.
Changes: See changes section
of search/narrow filter documentation.
Defaults to [].
 
    client_gravatar boolean optional  
    
        Example: false
    
    Whether the client supports computing gravatars URLs. If
enabled, avatar_url will be included in the response only
if there is a Zulip avatar, and will be null for users who
are using gravatar as their avatar. This option
significantly reduces the compressed size of user data,
since gravatar URLs are long, random strings and thus do not
compress well. The client_gravatar field is set to true if
clients can compute their own gravatars.
Changes: The default value of this parameter was false
prior to Zulip 5.0 (feature level 92).
Defaults to true.
 
    apply_markdown boolean optional  
    
        Example: false
    
    If true, message content is returned in the rendered HTML
format. If false, message content is returned in the raw
Markdown-format text that user entered.
Defaults to true.
 
    message_ids (integer)[] optional  
    
        Example: [1, 2, 3]
    
    A list of message IDs to fetch. The server will return messages corresponding to the
subset of the requested message IDs that exist and the current user has access to,
potentially filtered by the narrow (if that parameter is provided).
It is an error to pass this parameter as well as any of the parameters involved in
specifying a range of messages: anchor, include_anchor, use_first_unread_anchor,
num_before, and num_after.
Changes: New in Zulip 10.0 (feature level 300). Previously, there was
no way to request a specific set of messages IDs.
 
    allow_empty_topic_name boolean optional  
    
        Example: true
    
    Whether the client supports processing the empty string as a topic in the
topic name fields in the returned data, including in returned edit_history data.
If false, the server will use the value of realm_empty_topic_display_name
found in the POST /register response instead of empty string
to represent the empty string topic in its response.
Changes: New in Zulip 10.0 (feature level 334). Previously, the empty string
was not a valid topic.
Defaults to false.
 
    use_first_unread_anchor boolean optional Deprecated 
    
        Example: true
    
    Legacy way to specify "anchor": "first_unread" in Zulip 2.1.x and older.
Whether to use the (computed by the server) first unread message
matching the narrow as the anchor. Mutually exclusive with anchor.
Changes: Deprecated in Zulip 3.0 (feature level 1) and replaced by
"anchor": "first_unread".
Defaults to false.
 
Response
Return values
- 
anchor: integer
 The same anchorspecified in the request (or the computed one, ifuse_first_unread_anchoristrue).
 Only present if message_idsis not provided.
 
- 
found_newest: boolean
 Whether the server promises that the messageslist includes the very
newest messages matching the narrow (used by clients that paginate their
requests to decide whether there may be more messages to fetch).
 
- 
found_oldest: boolean
 Whether the server promises that the messageslist includes the very
oldest messages matching the narrow (used by clients that paginate their
requests to decide whether there may be more messages to fetch).
 
- 
found_anchor: boolean
 Whether the anchor message is included in the
response. If the message with the ID specified
in the request does not exist, did not match
the narrow, or was excluded via
"include_anchor": false, this will be false.
 
- 
history_limited: boolean
 Whether the message history was limited due to
plan restrictions. This flag is set to trueonly when the oldest messages(found_oldest)
matching the narrow is fetched.
 
- 
messages: (object)[]
 An array of messageobjects.
 Changes: In Zulip 3.1 (feature level 26), the
sender_short_namefield was removed from message
objects.
 
- 
avatar_url: string | null
 The URL of the message sender's avatar. Can be nullonly if
the current user has access to the sender's real email address
andclient_gravatarwastrue.
 If null, then the sender has not uploaded an avatar in Zulip,
and the client can compute the gravatar URL by hashing the
sender's email address, which corresponds in this case to their
real email address.
 Changes: Before Zulip 7.0 (feature level 163), access to a
user's real email address was a realm-level setting. As of this
feature level, email_address_visibilityis a user setting.
 
- 
client: string
 A Zulip "client" string, describing what Zulip client
sent the message. 
- 
content: string
 The content/body of the message. 
- 
content_type: string
 The HTTP content_typefor the message content. This
will betext/htmlortext/x-markdown, depending on
whetherapply_markdownwas set.
 
- 
display_recipient: string | (object)[]
 Data on the recipient of the message;
either the name of a channel or a dictionary containing basic data on
the users who received the message. 
- 
edit_history: (object)[]
 An array of objects, with each object documenting the
changes in a previous edit made to the message,
ordered chronologically from most recent to least recent
edit. Not present if the message has never been edited or moved,
or if viewing message edit history
is not allowed in the organization. Every object will contain user_idandtimestamp.
 The other fields are optional, and will be present or not
depending on whether the channel, topic, and/or message
content were modified in the edit event. For example, if
only the topic was edited, only prev_topicandtopicwill be present in addition touser_idandtimestamp.
 Changes: In Zulip 10.0 (feature level 284), removed the
prev_rendered_content_versionfield as it is an internal
server implementation detail not used by any client.
 
- 
prev_content: string
 Only present if message's content was edited. The content of the message immediately prior to this
edit event. 
- 
prev_rendered_content: string
 Only present if message's content was edited. The rendered HTML representation of prev_content.
 
- 
prev_stream: integer
 Only present if message's channel was edited. The channel ID of the message immediately prior to this
edit event. Changes: New in Zulip 3.0 (feature level 1). 
- 
prev_topic: string
 Only present if message's topic was edited. The topic of the message immediately prior to this
edit event. Changes: New in Zulip 5.0 (feature level 118).
Previously, this field was called prev_subject;
clients are recommended to renameprev_subjecttoprev_topicif present for compatibility with
older Zulip servers.
 
- 
stream: integer
 Only present if message's channel was edited. The ID of the channel containing the message
immediately after this edit event. Changes: New in Zulip 5.0 (feature level 118). 
- 
timestamp: integer
 The UNIX timestamp for the edit. 
- 
topic: string
 Only present if message's topic was edited. The topic of the message immediately after this edit event. Changes: New in Zulip 5.0 (feature level 118). 
- 
user_id: integer | null
 The ID of the user that made the edit. Will be nullonly for edit history
events predating March 2017.
 Clients can display edit history events where this
is nullas modified by either the sender (for content
edits) or an unknown user (for topic edits).
 
 
- 
id: integer
 The unique message ID. Messages should always be
displayed sorted by ID. 
- 
is_me_message: boolean
 Whether the message is a /me status message 
- 
last_edit_timestamp: integer
 The UNIX timestamp for when the message's content was last edited, in
UTC seconds. Not present if the message's content has never been edited. Clients should use this field, rather than parsing the edit_historyarray, to display an indicator that the message has been edited.
 Changes: Prior to Zulip 10.0 (feature level 365), this was the
time when the message was last edited or moved. 
- 
last_moved_timestamp: integer
 The UNIX timestamp for when the message was last moved to a different
channel or topic, in UTC seconds. Not present if the message has never been moved, or if the only topic
moves for the message are resolving or unresolving
the message's topic. Clients should use this field, rather than parsing the edit_historyarray, to display an indicator that the message has been moved.
 Changes: New in Zulip 10.0 (feature level 365). Previously,
parsing the edit_historyarray was required in order to correctly
display moved message indicators.
 
- 
reactions: (object)[]
 Data on any reactions to the message. 
- 
emoji_name: string
 Name of the emoji. 
- 
emoji_code: string
 A unique identifier, defining the specific emoji codepoint requested,
within the namespace of the reaction_type.
 
- 
reaction_type: string
 A string indicating the type of emoji. Each emoji reaction_typehas an independent namespace for values ofemoji_code.
 Must be one of the following values: 
- 
unicode_emoji: In this namespace,emoji_codewill be a
  dash-separated hex encoding of the sequence of Unicode codepoints
  that define this emoji in the Unicode specification.
 
- 
realm_emoji: In this namespace,emoji_codewill be the ID of
  the uploaded custom emoji.
 
- 
zulip_extra_emoji: These are special emoji included with Zulip.
  In this namespace,emoji_codewill be the name of the emoji (e.g.
  "zulip").
 
 
- 
user_id: integer
 The ID of the user who added the reaction. Changes: New in Zulip 3.0 (feature level 2). The userobject is deprecated and will be removed in the future.
 In Zulip 10.0 (feature level 328), the deprecated userobject
was removed which contained the following properties:id,email,full_nameandis_mirror_dummy.
 
 
- 
recipient_id: integer
 A unique ID for the set of users receiving the
message (either a channel or group of users). Useful primarily
for hashing. Changes: Before Zulip 10.0 (feature level 327), recipient_idwas the same across all incoming 1:1 direct messages. Now, each
incoming message uniquely shares arecipient_idwith outgoing
messages in the same conversation.
 
- 
sender_email: string
 The Zulip API email address of the message's sender. 
- 
sender_full_name: string
 The full name of the message's sender. 
- 
sender_id: integer
 The user ID of the message's sender. 
- 
sender_realm_str: string
 A string identifier for the realm the sender is in. Unique only within
the context of a given Zulip server. E.g. on example.zulip.com, this will beexample.
 
- 
stream_id: integer
 Only present for channel messages; the ID of the channel. 
- 
subject: string
 The topicof the message. Currently always""for direct messages,
though this could change if Zulip adds support for topics in direct
message conversations.
 The field name is a legacy holdover from when topics were
called "subjects" and will eventually change. For clients that don't support the empty_topic_nameclient capability,
the empty string value is replaced with the value ofrealm_empty_topic_display_namefound in the POST /register response, for channel messages.
 Changes: Before Zulip 10.0 (feature level 334), empty_topic_nameclient capability didn't exist and empty string as the topic name for
channel messages wasn't allowed.
 
- 
submessages: (object)[]
 Data used for certain experimental Zulip integrations. 
- 
msg_type: string
 The type of the message. 
- 
content: string
 The new content of the submessage. 
- 
message_id: integer
 The ID of the message to which the submessage has been added. 
- 
sender_id: integer
 The ID of the user who sent the message. 
- 
id: integer
 The ID of the submessage. 
 
- 
timestamp: integer
 The UNIX timestamp for when the message was sent,
in UTC seconds. 
- 
topic_links: (object)[]
 Data on any links to be included in the topicline (these are generated by custom linkification
filters that match content in the
message's topic.)
 Changes: This field contained a list of urls before
Zulip 4.0 (feature level 46). New in Zulip 3.0 (feature level 1). Previously, this field was called
subject_links; clients are recommended to renamesubject_linkstotopic_linksif present for compatibility with older Zulip servers.
 
- 
type: string
 The type of the message: "stream"or"private".
 
- 
flags: (string)[]
 The user's message flags for the message. Changes: In Zulip 8.0 (feature level 224), the wildcard_mentionedflag was deprecated in favor of thestream_wildcard_mentionedandtopic_wildcard_mentionedflags. Thewildcard_mentionedflag exists
for backwards compatibility with older clients and equalsstream_wildcard_mentioned || topic_wildcard_mentioned. Clients
supporting older server versions should treat this field as a previous
name for thestream_wildcard_mentionedflag as topic wildcard mentions
were not available prior to this feature level.
 
- 
match_content: string
 Only present if keyword search was included among the narrow parameters. HTML content of a queried message that matches the narrow, with
<span class="highlight">elements wrapping the matches for the
search keywords.
 
- 
match_subject: string
 Only present if keyword search was included among the narrow parameters. HTML-escaped topic of a queried message that matches the narrow, with
<span class="highlight">elements wrapping the matches for the
search keywords.
 
 
Example response(s)
Changes: As of Zulip 7.0 (feature level 167), if any
parameters sent in the request are not supported by this
endpoint, a successful JSON response will include an
ignored_parameters_unsupported array.
A typical successful JSON response may look like:
{
    "anchor": 21,
    "found_anchor": true,
    "found_newest": true,
    "messages": [
        {
            "avatar_url": "https://secure.gravatar.com/avatar/6d8cad0fd00256e7b40691d27ddfd466?d=identicon&version=1",
            "client": "populate_db",
            "content": "<p>Security experts agree that relational algorithms are an interesting new topic in the field of networking, and scholars concur.</p>",
            "content_type": "text/html",
            "display_recipient": [
                {
                    "email": "hamlet@zulip.com",
                    "full_name": "King Hamlet",
                    "id": 4,
                    "is_mirror_dummy": false
                },
                {
                    "email": "iago@zulip.com",
                    "full_name": "Iago",
                    "id": 5,
                    "is_mirror_dummy": false
                },
                {
                    "email": "prospero@zulip.com",
                    "full_name": "Prospero from The Tempest",
                    "id": 8,
                    "is_mirror_dummy": false
                }
            ],
            "flags": [
                "read"
            ],
            "id": 16,
            "is_me_message": false,
            "reactions": [],
            "recipient_id": 27,
            "sender_email": "hamlet@zulip.com",
            "sender_full_name": "King Hamlet",
            "sender_id": 4,
            "sender_realm_str": "zulip",
            "subject": "",
            "submessages": [],
            "timestamp": 1527921326,
            "topic_links": [],
            "type": "private"
        },
        {
            "avatar_url": "https://secure.gravatar.com/avatar/6d8cad0fd00256e7b40691d27ddfd466?d=identicon&version=1",
            "client": "populate_db",
            "content": "<p>Wait, is this from the frontend js code or backend python code</p>",
            "content_type": "text/html",
            "display_recipient": "Verona",
            "flags": [
                "read"
            ],
            "id": 21,
            "is_me_message": false,
            "reactions": [],
            "recipient_id": 20,
            "sender_email": "hamlet@zulip.com",
            "sender_full_name": "King Hamlet",
            "sender_id": 4,
            "sender_realm_str": "zulip",
            "stream_id": 5,
            "subject": "Verona3",
            "submessages": [],
            "timestamp": 1527939746,
            "topic_links": [],
            "type": "stream"
        }
    ],
    "msg": "",
    "result": "success"
}