Get messages
Fetch message history from a Zulip server.
GET https://zulip.dioco.io/api/v1/messages
This GET /api/v1/messages
endpoint is the primary way to fetch
message history from a Zulip server. It is useful both for Zulip
clients (e.g. the web, desktop, mobile, and terminal clients) as well
as bots, API clients, backup scripts, etc.
By specifying a narrow filter, you can use
this endpoint to fetch the messages matching any search query that is
supported by Zulip's powerful full-text search backend.
When a narrow is not specified, it can be used to fetch a user's
message history (We recommend paginating to 1000 messages at a time).
In either case, you specify an anchor
message (or ask the server to
calculate the first unread message for you and use that as the
anchor), as well as a number of messages before and after the anchor
message. The server returns those 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.
We recommend using num_before <= 1000
and num_after <= 1000
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.
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 stream "Verona"
request: Dict[str, Any] = {
'anchor': 'newest',
'num_before': 100,
'num_after': 0,
'narrow': [{'operator': 'sender', 'operand': 'iago@zulip.com'},
{'operator': 'stream', 'operand': 'Verona'}],
}
result = client.get_messages(request)
print(result)
More examples and documentation can be found here.
const Zulip = require('zulip-js');
// Pass the path to your zuliprc file here.
const config = { zuliprc: 'zuliprc' };
Zulip(config).then(async (client) => {
const readParams = {
anchor: "newest",
num_before: 100,
num_after: 0,
narrow: [
{operator: "sender", operand: "iago@zulip.com"},
{operator: "stream", operand: "Verona"},
],
};
// Get the 100 last messages sent by "iago@zulip.com" to the stream "Verona"
return await client.messages.retrieve(readParams);
}).then(console.log).catch(console.err);
curl -sSX GET -G https://zulip.dioco.io/api/v1/messages \
-u BOT_EMAIL_ADDRESS:BOT_API_KEY \
-d 'anchor=42' \
-d 'num_before=4' \
-d 'num_after=8' \
--data-urlencode narrow='[{"operand": "Denmark", "operator": "stream"}]'
Parameters
anchor optional
Example: 42
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.
The special values of 'newest'
and 'oldest'
are also supported
for anchoring the query at the most recent or oldest messages.
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).
num_before required
Example: 4
The number of messages with IDs less than the anchor to retrieve.
num_after required
Example: 8
The number of messages with IDs greater than the anchor to retrieve.
narrow optional
Example: [{"operand": "Denmark", "operator": "stream"}]
client_gravatar optional
Example: True
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.
Defaults to false
.
apply_markdown 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
.
use_first_unread_anchor 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, replaced by
anchor="first_unread"
instead.
Defaults to false
.
Response
Return values
When a request is successful, this endpoint returns a dictionary
containing the following (in addition to the msg
and result
keys
present in all Zulip API responses).
-
anchor
: The same anchor
specified in the request (or the computed one, if
use_first_unread_anchor
is true
).
-
found_newest
: Whether the messages
list includes the very newest messages matching
the narrow (used by clients that paginate their requests to decide
whether there are more messages to fetch).
-
found_oldest
: Whether the messages
list includes the very oldest messages matching
the narrow (used by clients that paginate their requests to decide
whether there are more messages to fetch).
-
found_anchor
: Whether the anchor message is included in the
response. If the message with the ID specified
in the request does not exist or did not match
the narrow, this will be false.
-
history_limited
: Whether the message history was limited due to
plan restrictions. This flag is set to true
only when the oldest messages(found_oldest
)
matching the narrow is fetched.
-
messages
: an array of message
objects, each containing the following
fields:
-
avatar_url
: The URL of the user's avatar. Can be null only if client_gravatar was passed,
which means that the user has not uploaded an avatar in Zulip, and the
client should compute the gravatar URL by hashing the
user's email address itself for this user.
-
client
: A Zulip "client" string, describing what Zulip client
sent the message.
-
content
: The content/body of the message.
-
rendered_content
: The content/body of the message rendered in HTML.
-
content_type
: The HTTP content_type
for the message content. This
will be text/html
or text/x-markdown
, depending on
whether apply_markdown
was set.
-
display_recipient
: Data on the recipient of the message;
either the name of a stream or a dictionary containing basic data on
the users who received the message.
-
flags
: The user's message flags for the message.
-
id
: The unique message ID. Messages should always be
displayed sorted by ID.
-
is_me_message
: Whether the message is a /me status message
-
reactions
: Data on any reactions to the message.
-
emoji_code
: A unique identifier, defining the specific emoji codepoint requested,
within the namespace of the reaction_type
.
For example, for unicode_emoji
, this will be an encoding of the
unicode codepoint.
-
emoji_name
: Name of the emoji.
-
reaction_type
: One of the following values:
unicode_emoji
: Unicode emoji (emoji_code
will be its unicode
codepoint).
realm_emoji
: Custom emoji.
(emoji_code
will be its ID).
zulip_extra_emoji
: Special emoji included with Zulip. Exists to
namespace the zulip
emoji.
-
user_id
: The ID of the user who added the reaction.
Changes: New in Zulip 3.0 (feature level 2). The user
object is deprecated and will be removed in the future.
-
user
: Dictionary with data on the user who added the reaction, including
the user ID as the id
field. Note: In the events
API, this user
dictionary
confusing had the user ID in a field called user_id
instead. We recommend ignoring fields other than the user
ID. Deprecated and to be removed in a future release
once core clients have migrated to use the user_id
field.
-
id
: ID of the user.
-
email
: Email of the user.
-
full_name
: Full name of the user.
-
is_mirror_dummy
: Whether the user is a mirror dummy.
-
recipient_id
: A unique ID for the set of users receiving the
message (either a stream or group of users). Useful primarily
for hashing.
-
sender_email
: The Zulip display email address of the message's sender.
-
sender_full_name
: The full name of the message's sender.
-
sender_id
: The user ID of the message's sender.
-
sender_realm_str
: 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 be example
.
-
stream_id
: Only present for stream messages; the ID of the stream.
-
subject
: The topic
of the message (only present for stream
messages). The field name is a legacy holdover from when topics were
called "subjects" and will eventually change.
-
topic_links
: Data on any links to be included in the topic
line (these are generated by custom linkification
filters that match content in the
message's topic.)
Changes: New in Zulip 3.0 (feature level 1).
Previously, this field was called subject_links
;
clients are recommended to rename subject_links
to topic_links
if present for compatibility with
older Zulip servers.
-
submessages
: Data used for certain experimental Zulip integrations.
-
timestamp
: The UNIX timestamp for when the message was sent,
in UTC seconds.
-
last_edit_timestamp
: The UNIX timestamp for when the message was last edited,
in UTC seconds.
-
type
: The type of the message: stream
or private
.
-
match_content
: 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
: 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
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"
}