Zulip messages API
The messages API from Zulip — 16 operation(s) for messages.
The messages API from Zulip — 16 operation(s) for messages.
openapi: 3.0.1
info:
version: 1.0.0
title: Zulip REST authentication messages API
description: 'Powerful open source group chat
'
contact:
url: https://zulip.com
license:
name: Apache 2.0
url: https://www.apache.org/licenses/LICENSE-2.0.html
servers:
- url: https://{subdomain}.zulipchat.com/api/v1
variables:
subdomain:
default: example
- url: '{server}/api/v1'
variables:
server:
default: https://
- url: https://chat.zulip.org/api/v1
- url: http://localhost:9991/api/v1
- url: http://{subdomain}.testserver/json
security:
- basicAuth: []
tags:
- name: messages
paths:
/mark_all_as_read:
post:
deprecated: true
operationId: mark-all-as-read
summary: Mark all messages as read
tags:
- messages
description: 'Marks all of the current user''s unread messages as read.
Because this endpoint marks messages as read in batches, it is possible
for the request to time out after only marking some messages as read.
When this happens, the `complete` boolean field in the success response
will be `false`. Clients should repeat the request when handling such a
response. If all messages were marked as read, then the success response
will return `"complete": true`.
**Changes**: Deprecated; clients should use the [update personal message
flags for narrow](/api/update-message-flags-for-narrow) endpoint instead
as this endpoint will be removed in a future release.
Before Zulip 8.0 (feature level 211), if the server''s
processing was interrupted by a timeout, but some messages were marked
as read, then it would return `"result": "partially_completed"`, along
with a `code` field for an error string, in the success response to
indicate that there was a timeout and that the client should repeat the
request.
Before Zulip 6.0 (feature level 153), this request did a single atomic
operation, which could time out with 10,000s of unread messages to mark
as read. As of this feature level, messages are marked as read in
batches, starting with the newest messages, so that progress is made
even if the request times out. And, instead of returning an error when
the request times out and some messages have been marked as read, a
success response with `"result": "partially_completed"` is returned.
'
responses:
'200':
description: Success.
content:
application/json:
schema:
allOf:
- $ref: '#/components/schemas/JsonSuccessBase'
- additionalProperties: false
required:
- complete
properties:
result: {}
msg: {}
ignored_parameters_unsupported: {}
complete:
type: boolean
description: 'Whether all unread messages were marked as read.
Will be `false` if the request successfully marked
some, but not all, messages as read.
'
example:
msg: ''
result: success
complete: true
/mark_stream_as_read:
post:
deprecated: true
operationId: mark-stream-as-read
summary: Mark messages in a channel as read
tags:
- messages
description: 'Mark all the unread messages in a channel as read.
**Changes**: Deprecated; clients should use the [update personal message
flags for narrow](/api/update-message-flags-for-narrow) endpoint instead
as this endpoint will be removed in a future release.
'
requestBody:
required: true
content:
application/x-www-form-urlencoded:
schema:
type: object
properties:
stream_id:
description: 'The ID of the channel to access.
'
type: integer
example: 43
required:
- stream_id
encoding:
stream_id:
contentType: application/json
responses:
'200':
$ref: '#/components/responses/SimpleSuccess'
/mark_topic_as_read:
post:
deprecated: true
operationId: mark-topic-as-read
summary: Mark messages in a topic as read
tags:
- messages
description: 'Mark all the unread messages in a topic as read.
**Changes**: Deprecated; clients should use the [update personal message
flags for narrow](/api/update-message-flags-for-narrow) endpoint instead
as this endpoint will be removed in a future release.
'
requestBody:
required: true
content:
application/x-www-form-urlencoded:
schema:
type: object
properties:
stream_id:
description: 'The ID of the channel to access.
'
type: integer
example: 43
topic_name:
description: 'The name of the topic whose messages should be marked as read.
Note: When the value of `realm_empty_topic_display_name` found in
the [POST /register](/api/register-queue) response is used for this
parameter, it is interpreted as an empty string.
**Changes**: Before Zulip 10.0 (feature level 334), empty string
was not a valid topic name for channel messages.
'
type: string
example: new coffee machine
required:
- stream_id
- topic_name
encoding:
stream_id:
contentType: application/json
responses:
'200':
$ref: '#/components/responses/SimpleSuccess'
/messages:
get:
operationId: get-messages
summary: Get messages
tags:
- messages
description: "This endpoint is the primary way to fetch a messages. It is used by all official\nZulip clients (e.g. the web, desktop, mobile, and terminal clients) as well as\nmany bots, API clients, backup scripts, etc.\n\nMost queries will specify a [narrow filter](/api/get-messages#parameter-narrow),\nto fetch the messages matching any supported [search\nquery](/help/search-for-messages). If not specified, it will return messages\ncorresponding to the user's [combined feed](/help/combined-feed). There are two\nways to specify which messages matching the narrow filter to fetch:\n\n- A range of messages, described by an `anchor` message ID (or a string-format\n specification of how the server should computer an anchor to use) and a maximum\n number of messages in each direction from that anchor.\n\n- A rarely used variant (`message_ids`) where the client specifies the message IDs\n to fetch.\n\nThe server returns the matching messages, sorted by message ID, as well as some\nmetadata that makes it easy for a client to determine whether there are more\nmessages matching the query that were not returned due to the `num_before` and\n`num_after` limits.\n\nNote that a user's message history does not contain messages sent to\nchannels before they [subscribe](/api/subscribe), and newly created\nbot users are not usually subscribed to any channels.\n\nWe recommend requesting at most 1000 messages in a batch, to avoid generating very\nlarge HTTP responses. A maximum of 5000 messages can be obtained per request;\nattempting to exceed this will result in an error.\n\n**Changes**: The `message_ids` option is new in Zulip 10.0 (feature level 300).\n"
x-curl-examples-parameters:
oneOf:
- type: exclude
parameters:
enum:
- client_gravatar
- apply_markdown
- use_first_unread_anchor
- include_anchor
- message_ids
- anchor_date
parameters:
- name: anchor
in: query
description: "Integer message ID to anchor fetching of new messages. Supports special\nstring values for when the client wants the server to compute the anchor\nto use:\n\n- `newest`: The most recent message.\n- `oldest`: The oldest message.\n- `first_unread`: The oldest unread message matching the\n query, if any; otherwise, the most recent message.\n- `date`: The first message on or after the datetime indicated by the\n [`anchor_date`](#parameter-anchor_date), if any; otherwise, the most\n recent message.\n\n**Changes**: The `date` value is new in Zulip 12.0 (feature level 445).\n\nString values are new in Zulip 3.0 (feature level 1). The\n`first_unread` functionality was supported in Zulip 2.1.x\nand older by not sending `anchor` and using `use_first_unread_anchor`.\n\nIn Zulip 2.1.x and older, `oldest` can be emulated with\n`\"anchor\": 0`, and `newest` with `\"anchor\": 10000000000000000`\n(that specific large value works around a bug in Zulip\n2.1.x and older in the `found_newest` return value).\n"
schema:
$ref: '#/components/schemas/Anchor'
example: '43'
- name: include_anchor
in: query
description: 'Whether a message with the specified ID matching the narrow
should be included.
**Changes**: New in Zulip 6.0 (feature level 155).
'
schema:
type: boolean
default: true
example: false
- name: anchor_date
in: query
description: 'The date or datetime to use for finding the anchor message when `anchor` is
`date`. Accepted formats include ISO 8601 date-only strings
(e.g. `2005-04-18`) as well as full datetime strings
(e.g. `2005-04-18T12:34:56Z`). If only a date is provided, the datetime is set to
midnight (00:00) on that day in UTC. If no timezone is provided, UTC is
assumed.
**Changes**: New in Zulip 12.0 (feature level 445).
'
schema:
type: string
example: '2005-04-18T12:34:56Z'
- name: num_before
in: query
description: 'The number of messages with IDs less than the anchor to retrieve.
Required if `message_ids` is not provided.
'
schema:
type: integer
minimum: 0
example: 4
required: false
- name: num_after
in: query
description: 'The number of messages with IDs greater than the anchor to retrieve.
Required if `message_ids` is not provided.
'
schema:
type: integer
minimum: 0
example: 8
required: false
- name: narrow
in: query
description: 'The narrow where you want to fetch the messages from. See how to
[construct a narrow](/api/construct-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](/help/search-for-messages#search-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](/api/construct-narrow#changes)
of search/narrow filter documentation.
'
content:
application/json:
schema:
type: array
items:
oneOf:
- type: object
required:
- operator
- operand
additionalProperties: false
properties:
operator:
type: string
operand:
oneOf:
- type: string
- type: integer
- type: array
items:
type: integer
negated:
type: boolean
- type: array
items:
type: string
minItems: 2
maxItems: 2
default: []
example:
- operand: Denmark
operator: channel
- $ref: '#/components/parameters/ClientGravatar'
- name: apply_markdown
in: query
description: '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.
See [Markdown message formatting](/api/message-formatting) for details on Zulip''s HTML format.
'
schema:
type: boolean
default: true
example: false
- name: use_first_unread_anchor
in: query
deprecated: true
description: '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"`.
'
schema:
type: boolean
default: false
example: true
- name: message_ids
in: query
description: '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.
'
content:
application/json:
schema:
type: array
items:
type: integer
example:
- 1
- 2
- 3
- name: allow_empty_topic_name
in: query
description: '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`](/api/register-queue) 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.
'
schema:
type: boolean
default: false
example: true
responses:
'200':
description: Success.
content:
application/json:
schema:
allOf:
- $ref: '#/components/schemas/JsonSuccessBase'
- additionalProperties: false
required:
- result
- msg
- messages
properties:
result: {}
msg: {}
ignored_parameters_unsupported: {}
anchor:
type: integer
description: 'The same `anchor` specified in the request (or the computed one, if
`use_first_unread_anchor` is `true`).
Only present if `message_ids` is not provided.
'
found_newest:
type: boolean
description: 'Whether the server promises that the `messages` list 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:
type: boolean
description: 'Whether the server promises that the `messages` list 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:
type: boolean
description: '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:
type: boolean
description: '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:
type: array
description: 'An array of `message` objects.
**Changes**: In Zulip 3.1 (feature level 26), the
`sender_short_name` field was removed from message
objects.
'
items:
allOf:
- $ref: '#/components/schemas/MessagesBase'
- additionalProperties: false
properties:
avatar_url:
nullable: true
client: {}
content: {}
content_type: {}
display_recipient: {}
edit_history: {}
id: {}
is_me_message: {}
last_edit_timestamp: {}
last_moved_timestamp: {}
reactions: {}
recipient_id: {}
sender_email: {}
sender_full_name: {}
sender_id: {}
sender_realm_str: {}
stream_id: {}
subject: {}
submessages: {}
timestamp: {}
topic_links: {}
type: {}
flags:
type: array
description: 'The user''s [message flags][message-flags] for the message.
**Changes**: In Zulip 8.0 (feature level 224), the `wildcard_mentioned`
flag was deprecated in favor of the `stream_wildcard_mentioned` and
`topic_wildcard_mentioned` flags. The `wildcard_mentioned` flag exists
for backwards compatibility with older clients and equals
`stream_wildcard_mentioned || topic_wildcard_mentioned`. Clients
supporting older server versions should treat this field as a previous
name for the `stream_wildcard_mentioned` flag as topic wildcard mentions
were not available prior to this feature level.
[message-flags]: /api/update-message-flags#available-flags
'
items:
type: string
match_content:
type: string
description: '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:
type: string
description: '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:
anchor: 21
found_newest: true
found_anchor: true
result: success
msg: ''
messages:
- subject: ''
sender_realm_str: zulip
type: private
content: <p>Security experts agree that relational algorithms are an interesting new topic in the field of networking, and scholars concur.</p>
flags:
- read
id: 16
display_recipient:
- id: 4
is_mirror_dummy: false
email: hamlet@zulip.com
full_name: King Hamlet
- id: 5
is_mirror_dummy: false
email: iago@zulip.com
full_name: Iago
- id: 8
is_mirror_dummy: false
email: prospero@zulip.com
full_name: Prospero from The Tempest
content_type: text/html
is_me_message: false
timestamp: 1527921326
sender_id: 4
sender_full_name: King Hamlet
recipient_id: 27
topic_links: []
client: ZulipDataImport
avatar_url: https://secure.gravatar.com/avatar/6d8cad0fd00256e7b40691d27ddfd466?d=identicon&version=1
submessages: []
sender_email: hamlet@zulip.com
reactions: []
- subject: Verona3
stream_id: 5
sender_realm_str: zulip
type: stream
content: <p>Wait, is this from the frontend js code or backend python code</p>
flags:
- read
id: 21
display_recipient: Verona
content_type: text/html
is_me_message: false
timestamp: 1527939746
sender_id: 4
sender_full_name: King Hamlet
recipient_id: 20
topic_links: []
client: ZulipDataImport
avatar_url: https://secure.gravatar.com/avatar/6d8cad0fd00256e7b40691d27ddfd466?d=identicon&version=1
submessages: []
sender_email: hamlet@zulip.com
reactions: []
post:
operationId: send-message
summary: Send a message
tags:
- messages
description: 'Send a [channel message](/help/introduction-to-topics) or a
[direct message](/help/direct-messages).
'
requestBody:
required: true
content:
application/x-www-form-urlencoded:
schema:
type: object
properties:
type:
description: 'The type of message to be sent.
`"direct"` for a direct message and `"stream"` or `"channel"` for a
channel message.
**Changes**: In Zulip 9.0 (feature level 248), `"channel"` was added as
an additional value for this parameter to request a channel message.
In Zulip 7.0 (feature level 174), `"direct"` was added as
the preferred way to request a direct message, deprecating the original
`"private"`. While `"private"` is still supported for requesting direct
messages, clients are encouraged to use to the modern convention with
servers that support it, because support for `"private"` will eventually
be removed.
'
type: string
enum:
- direct
- channel
- stream
- private
example: direct
to:
description: 'The channel or users receiving the message.
For channel messages, this is either the name or integer ID of the
channel.
For direct messages, this is either a list containing integer user IDs or
a list containing string Zulip API email addresses. The ID or email
address of the user sending the message can be included in the list, but
will be ignored by the server, unless the user sending the message is the
only recipient of the message.
**Changes**: In Zulip 2.0.0, support for using user/channel IDs was added.
'
oneOf:
- type: string
- type: integer
- type: array
items:
type: string
- type: array
items:
type: integer
minLength: 1
example:
- 9
- 10
content:
$ref: '#/components/schemas/RequiredContent'
topic:
description: 'The topic of the message. Only required for channel messages
(`"type": "stream"` or `"type": "channel"`), ignored otherwise.
Clients should use the `max_topic_length` returned by the
[`POST /register`](/api/register-queue) endpoint to determine
the maximum topic length.
Note: When `"(no topic)"` or the value of `realm_empty_topic_display_name`
found in the [POST /register](/api/register-queue) response is used for this
parameter, it is interpreted as an empty string.
When [topics are required](/help/require-topics), this parameter can''t
be `"(no topic)"`, an empty string, or the value of `realm_empty_topic_display_name`.
**Changes**: Before Zulip 10.0 (feature level 370), `"(no topic)"`
was not interpreted as an empty string.
Before Zulip 10.0 (feature level 334), empty string
was not a valid topic name for channel messages.
New in Zulip 2.0.0. Previous Zulip releases encoded
this as `subject`, which is currently a deprecated alias.
'
type: string
example: Castle
queue_id:
type: string
description: 'For clients supporting
[local echo](https://zulip.readthedocs.io/en/latest/subsystems/sending-messages.html#local-echo),
the [event queue](/api/register-queue) ID for the client.
If passed, `local_id` is required.
If the message is successfully sent, the server will include
`local_message_id` in the [`message` event](/api/get-events#message) that
the client with this `queue_id` will receive.
'
example: fb67bf8a-c031-47cc-84cf-ed80accacda8
local_id:
type: string
description: 'For clients supporting
[local echo](https://zulip.readthedocs.io/en/latest/subsystems/sending-messages.html#local-echo),
a unique string-format identifier chosen freely by the client.
If passed, `queue_id` is required.
If the message is successfully sent, the server will pass it back to
the client without inspecting it as `local_message_id` in the
[`message` event](/api/get-events#message) that the client with the
above `queue_id` will receive.
'
example: '100.01'
read_by_sender:
type: boolean
description: 'Whether the message should be initially marked read by its
sender. If unspecified, the server uses a heuristic based
on the client name.
**Changes**: New in Zulip 8.0 (feature level 236).
'
example: true
required:
- type
- to
- content
encoding:
to:
contentType: application/json
read_by_sender:
contentType: application/json
responses:
'200':
description: Success.
content:
application/json:
schema:
allOf:
- $ref: '#/components/schemas/JsonSuccessBase'
- additionalProperties: false
required:
- id
properties:
result: {}
msg: {}
ignored_parameters_unsupported: {}
id:
type: integer
description: 'The unique ID assigned to the sent message.
'
automatic_new_visibility_policy:
type: integer
enum:
- 2
- 3
description: 'If the message''s sender had configured their [visibility policy settings](/help/mute-a-topic)
to potentially automatically follow or unmute topics when sending messages,
and one of these policies did in fact change the user''s visibility policy
for the topic where this message was sent, the new value for that user''s
visibility policy for the recipient topic.
Only present if the sender''s visibility was in fact changed.
The value can be either [unmuted or followed](/api/update-user-topic#parameter-visibility_policy).
Clients will also be notified about the change in policy via a
`user_topic` event as usual. This field is intended to be used by clients
# --- truncated at 32 KB (139 KB total) ---
# Full source: https://raw.githubusercontent.com/api-evangelist/zulip/refs/heads/main/openapi/zulip-messages-api-openapi.yml