API changelog
This page documents changes to the Zulip Server API over time. See
also the Zulip release lifecycle for background
on why this API changelog is important, and the Zulip server
changelog.
The API feature levels system used in this changelog is designed to
make it possible to write API clients, such as the Zulip mobile and
terminal apps, that work with a wide range of Zulip server
versions. Every change to the Zulip API is recorded both here and in
Changes entries in the API documentation for the modified
endpoint(s).
When using an API endpoint whose behavior has changed, Zulip API
clients should check the zulip_feature_level field, present in the
GET /server_settings and POST
/register responses, to determine the API
format used by the Zulip server that they are interacting with.
Changes in Zulip 5.0
Feature level 122
No changes; feature level used for Zulip 5.0 release.
Feature level 121
GET /events: Added message_details field
appearing in message flag update events when marking previously read
messages as unread.
Feature level 120
GET /messages/{message_id}: This endpoint
now sends the full message details. Previously, it only returned
the message's raw Markdown content.
Feature level 119
POST /register: The unread_msgs section
of the response now prefers other_user_id over the poorly named
sender_id field in the pms dictionaries. This change is
motivated by the possibility that a message you yourself sent to
another user could be marked as unread.
Feature level 118
-
GET /messages, GET
/events: Improved the format of the
edit_history object within message objects. Entries for stream
edits now include a both a prev_stream and stream field to
indicate the previous and current stream IDs. Entries for topic
edits now include both a prev_topic and topic field to indicate
the previous and current topic, replacing the prev_subject
field. These changes substantially simplify client complexity for
processing historical message edits.
-
GET messages/{message_id}/history:
Added stream field to message history snapshot indicating
the updated stream ID of messages moved to a new stream.
Feature level 117
POST /invites, POST /invites/multiuse: Added support for passing
null as the invite_expires_in_days parameter to request an
invitation that never expires.
Feature level 116
GET /server_settings: Added
realm_web_public_access_enabled as a realm-specific server setting,
which can be used by clients to detect whether the realm allows and
has at least one web-public stream.
Feature level 115
- Mobile push notifications about stream messages now include the
stream_id field.
Feature level 114
-
GET /events: Added rendering_only field to
update_message event type to indicate if the message change only
updated the rendering of the message or if it was the result of a
user interaction.
-
GET /events: Updated update_message event type
to always include edit_timestamp and user_id fields. If the event
only updates the rendering of the message, then the user_id field
will be present, but with a value of null as the update was not the
result of a user interaction.
Feature level 113
GET /realm/emoji, POST /realm/emoji/{emoji_name}, GET
/events, POST /register:
The still_url field for custom emoji objects is now always
present, with a value of null for non-animated emoji. Previously, it
only was present for animated emoji.
Feature level 112
GET /events: Updated update_message event type
to include stream_id field for all edits to stream messages.
Feature level 111
Feature level 110
POST /register: Added
server_web_public_streams_enabled to the response.
Feature level 109
Feature level 108
- In the mobile application authentication flow, the authenticated
user's
user_id is now included in the parameters encoded in the
final zulip:// redirect URL.
Feature level 107
Feature level 106
Feature level 105
Feature level 104
- [
PATCH /realm]: Added string_id parameter for changing an
organization's subdomain. Currently, this is only allowed for
changing a demo organization to a normal one.
Feature level 103
POST /register: Added create_web_public_stream_policy
policy for which users can create web-public streams.
- [
PATCH /realm]: Added support for updating create_web_public_stream_policy.
POST /register: Added can_create_web_public_streams boolean
field to the response.
Feature level 102
POST /register, PATCH /realm: The
create_stream_policy setting was split into two settings for
different types of streams: create_private_stream_policy and
create_public_stream_policy.
POST /register: The create_stream_policy
property was deprecated in favor of the
create_private_stream_policy and create_public_stream_policy
properties, but it still available for backwards-compatibility.
Feature level 101
POST /register, PATCH /realm: Replaced
the allow_message_deleting boolean field with an integer field
delete_own_message_policy defining which roles can delete messages
they had sent.
Feature level 100
POST /register, GET
/events: message_content_delete_limit_seconds
now represents no limit using null, instead of the integer 0, and 0 is
no longer a possible value with any meaning.
PATCH /realm: One now sets message_content_delete_limit_seconds
to no limit by passing the string unlimited, rather than the
integer 0.
Feature level 99
-
PATCH /realm/user_settings_defaults,
PATCH /realm: The default_twenty_four_hour_time parameter to
PATCH /realm has been replaced by the twenty_four_hour_time parameter
to PATCH /realm/user_settings_defaults, to match the new model for
user preference defaults settings.
-
POST /register: Removed realm_default_twenty_four_hour_time
from the response object. This value is now available in the
twenty_four_hour_time field of the realm_user_settings_default object.
Feature level 98
POST /subscribe: Added is_web_public parameter
for requesting the creation of a web-public stream.
PATCH /streams/{stream_id}: Added
is_web_public parameter for converting a stream into a web-public stream.
Feature level 97
GET /realm/emoji, POST /realm/emoji/{emoji_name}, GET
/events, POST /register:
Custom emoji objects may now contain a still_url field, with the
URL of a PNG still image version of the emoji. This field will only be
present for animated emoji.
Feature level 96
PATCH /realm/user_settings_defaults:
Added new endpoint to update default values of user settings in a realm.
POST /invites, POST /invites/multiuse: Added
invite_expires_in_days parameter encoding the number days before
the invitation should expire.
Feature level 95
-
POST /register: Added
realm_user_settings_defaults object, containing default values of
personal user settings for new users in the realm.
-
GET /events: Added
realm_user_settings_defaults event type, which is sent when the
organization's configured default settings for new users change.
Feature level 94
POST /register: Added
demo_organization_scheduled_deletion_date field to realm data.
Feature level 93
Feature level 92
Feature level 91
PATCH /realm, PATCH /streams/{stream_id}:
These endpoints now accept "unlimited" for message_retention_days,
replacing "forever" as the way to encode a retention policy where
messages are not automatically deleted.
Feature level 90
POST /register: The unread_msgs section
of the response no longer includes sender_ids in the streams
dictionaries. These were removed because no clients were interested
in using the data, which required substantial complexity to
construct correctly.
Feature level 89
GET /events: Introduced the user_settings
event type, unifying and replacing the previous
update_display_settings and update_global_notifications event
types. The legacy event types are still supported for backwards
compatibility, but will be removed in a future release.
POST /register: Added user_settings field
in the response, which is a dictionary containing all the user's
personal settings. For backwards-compatibility, individual settings
will still appear in the top-level response for clients don't
support the user_settings_object client capability.
POST /register: Added the
user_settings_object property to supported client_capabilities.
When enabled, the server will not include a duplicate copy of
personal settings in the top-level response.
GET /events: update_display_settings and
update_global_notifications events now only sent to clients that
did not include user_settings_object in their
client_capabilities when the event queue was created.
Feature level 88
POST /register: Added zulip_merge_base
field to the response.
GET /events: Added new zulip_merge_base
field to the restart event.
GET /server_settings: Added
zulip_merge_base to the responses which can be used to
make "About Zulip" widgets in clients.
Feature level 87
-
PATCH /settings: Added a new
enable_drafts_synchronization setting, which controls whether the
syncing drafts between different clients is enabled.
-
GET /events, POST /register:
Added new enable_drafts_synchronization setting under
update_display_settings.
-
GET /drafts: Added new endpoint to fetch user's
synced drafts from the server.
-
POST /drafts: Added new endpoint to create
drafts when syncing has been enabled.
-
PATCH /drafts/{draft_id}: Added new endpoint
to edit a draft already owned by the user.
-
DELETE /drafts/{draft_id}: Added new endpoint
to delete a draft already owned by the user.
Feature level 86
GET /events: Added emoji_name,
emoji_code, and reaction_type fields to user_status objects.
POST /register: Added emoji_name,
emoji_code, and reaction_type fields to user_status objects.
POST /users/me/status: Added support for new emoji_name,
emoji_code, and reaction_type parameters.
Feature level 85
POST /register, PATCH /realm: Replaced add_emoji_by_admins_only
field with an integer field add_custom_emoji_policy.
Feature level 84
POST /register: The enter_sends setting
is now sent when update_display_setting is present in
fetch_event_types instead of realm_user.
Feature level 83
-
POST /register: The cross_realm_bots
section of the response now uses the is_system_bot flag to
indicate whether the bot is a system bot.
Feature level 82
PATCH /settings now accepts a new
email_notifications_batching_period_seconds field for setting the
time duration for which the server will collect email notifications
before sending them.
Feature level 81
POST /users/me/enter-sends has been removed. The enter_sends
setting is now edited using the normal PATCH
/settings endpoint.
Feature level 80
PATCH /settings: The
/settings/notifications and /settings/display endpoints were
merged into the main /settings endpoint; now all personal settings
should be edited using that single endpoint. The old URLs are
preserved as deprecated aliases for backwards compatibility.
Feature level 79
GET /users/me/subscriptions: The
subscribers field now returns user IDs if include_subscribers is
passed. Previously, this endpoint returned user display email
addresses in this field.
GET /streams/{stream_id}/members: This endpoint now returns user
IDs. Previously, it returned display email addresses.
Feature level 78
-
PATCH /settings: Added
ignored_parameters_unsupported field, which is a list of
parameters that were ignored by the endpoint, to the response
object.
-
PATCH /settings: Removed full_name and
account_email fields from the response object.
Feature level 77
GET /events: Removed recipient_id and
sender_id field in responses of delete_message event when
message_type is private.
Feature level 76
POST /fetch_api_key, POST
/dev_fetch_api_key: The HTTP status for
authentication errors is now 401. This was previously 403.
- All API endpoints now use the HTTP 401 error status for API requests
involving a deactivated user or realm. This was previously 403.
- Mobile push notifications now include the
mentioned_user_group_id
and mentioned_user_group_name fields when a user group containing
the user is mentioned. Previously, these were indistinguishable
from personal mentions (as both types have trigger="mention").
Feature level 75
POST /register, PATCH /realm: Replaced allow_community_topic_editing
field with an integer field edit_topic_policy.
Feature level 74
POST /register: Added server_needs_upgrade
and event_queue_longpoll_timeout_seconds field when fetching
realm data.
Feature level 73
Feature level 72
POST /register: Renamed max_icon_file_size to
max_icon_file_size_mib, realm_upload_quota to realm_upload_quota_mib
and max_logo_file_size to max_logo_file_size_mib.
Feature level 71
GET /events: Added is_web_public field to
stream events changing invite_only.
Feature level 70
POST /register: Added new top-level
server_timestamp field when fetching presence data, to match the
existing presence API.
Feature levels 66-69 are reserved for future use in 4.x maintenance
releases.
Changes in Zulip 4.0
Feature level 65
No changes; feature level used for Zulip 4.0 release.
Feature level 64
PATCH /streams/{stream_id}: Removed unnecessary JSON-encoding of string
parameters new_name and description.
PATCH /settings/display: Removed unnecessary JSON-encoding of string
parameters default_view, emojiset and timezone.
Feature level 63
PATCH /settings/notifications: Removed unnecessary JSON-encoding of string
parameter notification_sound.
PATCH /settings/display: Removed unnecessary JSON-encoding of string
parameter default_language.
POST /users/me/tutorial_status: Removed unnecessary JSON-encoding of string
parameter status.
POST /realm/domains: Removed unnecessary JSON-encoding of string
parameter domain.
PATCH /default_stream_groups/{user_id}: Removed unnecessary JSON-encoding of string
parameters new_group_name and new_description.
POST /users/me/hotspots: Removed unnecessary JSON-encoding of string
parameter hotspot.
Feature level 62
- Added
moderators only option for wildcard_mention_policy.
Feature level 61
POST /invites, POST /invites/multiuse: Added support for
inviting users as moderators.
Feature level 60
POST /register: Added a new boolean field
is_moderator, similar to the existing is_admin, is_owner and
is_guest fields, to the response.
PATCH /users/{user_id}: Added support for
changing a user's organization-level role to moderator.
- API endpoints that return
role values can now return 300, the
encoding of the moderator role.
Feature level 59
Feature level 58
POST /register: Added the new
stream_typing_notifications property to supported
client_capabilities.
GET /events: Extended format for typing
events to support typing notifications in stream messages. These new
events are only sent to clients with client_capabilities
showing support for stream_typing_notifications.
POST /set-typing-status: Added support
for sending typing notifications for stream messages.
Feature level 57
Feature level 56
POST /register: Added a new setting
move_messages_between_streams_policy for controlling who can
move messages between streams.
Feature level 55
POST /register: Added realm_giphy_rating
and giphy_rating_options fields.
PATCH /realm: Added giphy_rating parameter.
Feature level 54
GET /realm/filters has been removed and replace with GET
/realm/linkifiers which returns the data in a
cleaner dictionary format.
GET /events: Introduced new event type
realm_linkifiers. The previous realm_filters event type is
still supported for backwards compatibility, but will be removed in
a future release.
POST /register: The response now supports a
realm_linkifiers event type, containing the same data as the
legacy realm_filters key, with a more extensible object
format. The previous realm_filters event type is still supported
for backwards compatibility, but will be removed in a future
release. The legacy realm_filters key is deprecated but remains
available for backwards compatibility.
Feature level 53
POST /register: Added max_topic_length
and max_message_length, and renamed max_stream_name_length and
max_stream_description_length to allow clients to transparently
support these values changing in a future server version.
Feature level 52
PATCH /realm: Removed unnecessary JSON-encoding of string
parameters name, description, default_language, and
default_code_block_language.
Feature level 51
Feature level 50
POST /register: Replaced invite_by_admins_only
field with an integer field invite_to_realm_policy.
Feature level 49
Feature level 48
Feature level 47
POST /register: Added a new giphy_api_key
field, which is required to fetch GIFs using the GIPHY API.
Feature level 46
GET /messages and GET
/events: The topic_links field now contains a
list of dictionaries, rather than a list of strings.
Feature level 45
GET /events: Removed useless op field from
custom_profile_fields events. These events contain the full set
of configured custom_profile_fields for the organization
regardless of what triggered the change.
Feature level 44
POST /register: extended the unread_msgs
object to include old_unreads_missing, which indicates whether the
server truncated the unread_msgs due to excessive total unread
messages.
Feature level 43
- [
GET /users/{user_id_or_email}/presence]: Added support for
passing the user_id to identify the target user.
Feature level 42
PATCH /settings/display: Added a new default_view setting allowing
the user to set the default view.
Feature level 41
GET /events: Removed name field from update
subscription events.
Feature level 40
GET /events: Removed email field from update
subscription events.
Feature level 39
Feature level 38
POST /register: Increased
realm_community_topic_editing_limit_seconds time limit value
to 259200s (3 days).
Feature level 37
- Consistently provide
subscribers in stream data when
clients register for subscriptions with include_subscribers,
even if the user can't access subscribers.
Feature level 36
POST /users: Restricted access to organization
administrators with the can_create_users permission.
- Error handling: The
code property will
now be present in errors due to rate limits.
Feature level 35
- The peer_add and peer_remove subscription events now have plural
versions of
user_ids and stream_ids.
Feature level 34
POST /register: Added a new wildcard_mention_policy
setting for controlling who can use wildcard mentions in large streams.
Feature level 33
- Markdown code blocks now have a
data-code-language attribute
attached to the outer div element, recording the programming
language that was selecting for syntax highlighting. This field
supports the upcoming "view in playground" feature for code blocks.
Feature level 32
GET /events: Added op field to
update_message_flags events, deprecating the operation field
(which has the same value). This removes an unintentional anomaly
in the format of this event type.
Feature level 31
-
GET users/me/subscriptions: Added a
role field to Subscription objects representing whether the user
is a stream administrator.
-
GET /events: Added role field to
Subscription objects sent in subscriptions events.
Note that as of this feature level, stream administrators are a
partially completed feature. In particular, it is impossible for a
user to be a stream administrator at this feature level.
Feature level 30
Feature levels 28 and 29 are reserved for future use in 3.x bug fix
releases.
Changes in Zulip 3.1
Feature level 27
- The
short_name field is removed from display_recipients
in POST /users.
Feature level 26
- The
sender_short_name field is no longer included in
GET /messages.
- The
short_name field is removed from display_recipients
in GET /messages.
Changes in Zulip 3.0
Feature level 25
No changes; feature level used for Zulip 3.0 release.
Feature level 24
- The
!avatar() and !gravatar() Markdown syntax, which was never
documented, had inconsistent syntax, and was rarely used, was
removed.
Feature level 23
GET/PUT/POST /users/me/pointer: Removed. Zulip 3.0 removes the
pointer concept from Zulip; this legacy data structure was
replaced by tracking unread messages and loading views centered on
the first unread message.
Feature level 22
GET /attachments: The date when a message
using the attachment was sent is now correctly encoded as
date_sent, replacing the confusingly named name field. The
date_sent and create_time fields of attachment objects are now
encoded as integers; (previously the implementation could send
floats incorrectly suggesting that microsecond precision is
relevant).
GET /invites: Now encodes the user ID of the person who created
the invitation as invited_by_user_id, replacing the previous
ref field (which had that user's Zulip display email address).
POST /register: The encoding of an
unlimited realm_message_retention_days in the response was changed
from null to -1.
Feature level 21
PATCH /settings/display: Replaced the night_mode boolean with
color_scheme as part of supporting automatic night theme detection.
Feature level 20
- Added support for inviting users as organization owners to the
invitation endpoints.
Feature level 19
GET /events: subscriptions event with
op="peer_add" and op="peer_remove" now identify the modified
stream by a stream_id field, replacing the old name field.
Feature level 18
POST /register: Added
user_avatar_url_field_optional to supported client_capabilities.
Feature level 17
Feature level 16
- [
GET /users/me]: Removed pointer from the response, as the
"pointer" concept is being removed in Zulip.
- Changed the rendered HTML markup for mentioning a time to use the
<time> HTML tag. It is OK for clients to ignore the previous time
mention markup, as the feature was not advertised before this change.
Feature level 15
- Added spoilers
to supported Markdown features.
Feature level 14
GET users/me/subscriptions: Removed
the is_old_stream field from Stream objects. This field was
always equivalent to stream_weekly_traffic != null on the same object.
Feature level 13
POST /register: Added
bulk_message_deletion to supported client_capabilities.
GET /events: message_deleted
events have new behavior. The sender and sender_id fields were
removed, and the message_id field was replaced by a message_ids
list for clients with the bulk_message_deletion client capability.
All clients should upgrade; we expect bulk_message_deletion to be
required in the future.
Feature level 12
Feature level 11
POST /register: Added
realm_community_topic_editing_limit_seconds to the response, the
time limit before community topic editing is forbidden. A null
value means no limit. This was previously hard-coded in the server
as 86400 seconds (1 day).
POST /register: The response now contains a
is_owner, similar to the existing is_admin and is_guest fields.
POST /set-typing-status: Removed legacy support for sending email
addresses, rather than user IDs, to encode private message recipients.
Feature level 10
GET users/me: Added avatar_version, is_guest,
is_active, timezone, and date_joined fields to the User objects.
GET users/me: Removed client_id and short_name
from the response to this endpoint. These fields had no purpose and
were inconsistent with other API responses describing users.
Feature level 9
Feature level 8
Feature level 7
GET /events: realm_user and
realm_bot events no longer contain an email field to identify
the user; use the user_id field instead. Previously, some (but
not all) events of these types contained an email key in addition to
to user_id) for identifying the modified user.
PATCH /users/{user_id}: The is_admin and
is_guest parameters were removed in favor of the more general
role parameter for specifying a change in user role.
GET /events: realm_user events
sent when a user's role changes now include role property, instead
of the previous is_guest or is_admin booleans.
GET /realm/emoji: The user who uploaded a given custom emoji is
now indicated by an author_id field, replacing a previous author
object with unnecessary additional data.
Feature level 6
GET /events: realm_user events to
update a user's avatar now include the avatar_version field, which
is important for correctly refetching medium-size avatar images when
the user's avatar changes.
GET /users and GET
/users/{user_id}: User objects now contain the
avatar_version field as well.
Feature level 5
* GET /events: realm_bot events,
sent when changes are made to bot users, now contain an
integer-format owner_id field, replacing the owner field (which
was an email address).
Feature level 4
jitsi_server_url, development_environment, server_generation,
password_min_length, password_min_guesses, max_file_upload_size_mib,
max_avatar_file_size_mib, server_inline_image_preview,
server_inline_url_embed_preview, server_avatar_changes_disabled and
server_name_changes_disabled fields are now available via
POST /register to make them accessible to all the clients;
they were only internally available to Zulip's web app prior to this.
Feature level 3:
zulip_version and zulip_feature_level are always returned
in POST /register; previously they were only returned if event_types
included zulip_version.
- Added new
presence_enabled user notification setting; previously
presence was always enabled.
Feature level 2:
POST /messages/{message_id}/reactions:
The reaction_type parameter is optional; the server will guess the
reaction_type if it is not specified (checking custom emoji, then
Unicode emoji for any with the provided name).
reactions objects returned by the API (both in GET /messages and
in GET /events) now include the user who reacted in a top-level
user_id field. The legacy user dictionary (which had
inconsistent format between those two endpoints) is deprecated.
Feature level 1:
GET /server_settings: Added
zulip_feature_level, which can be used by clients to detect which
of the features described in this changelog are supported.
POST /register: Added zulip_feature_level
to the response if zulip_version is among the requested
event_types.
GET /users: User objects for bots now
contain a bot_owner_id, replacing the previous bot_owner field
(which had the email address of the bot owner).
GET /users/{user_id}: Endpoint added.
GET /messages: Add support for string-format
values for the anchor parameter, deprecating and replacing the
use_first_unread_anchor parameter.
GET /messages and GET
/events: Message objects now use
topic_links rather than subject_links to indicate links either
present in the topic or generated by linkifiers applied to the topic.
POST /users/me/subscriptions: Replaced
is_announcement_only boolean with stream_post_policy enum for
specifying who can post to a stream.
PATCH /streams/{stream_id}: Replaced
is_announcement_only boolean with stream_post_policy enum for
specifying who can post to a stream.
GET /streams: Replaced
is_announcement_only boolean with stream_post_policy enum for
specifying who can post to a stream.
GET /api/v1/user_uploads: Added new endpoint for requesting a
temporary URL for an uploaded file that does not require
authentication to access (e.g. for passing from a Zulip desktop,
mobile, or terminal app to the user's default browser).
- Added
EMAIL_ADDRESS_VISIBILITY_NOBODY possible value for
email_address_visibility.
- Added
private_message_policy realm setting.
muted_topic objects now are a 3-item tuple: (stream_id, topic,
date_muted). Previously, they were a 2-item tuple.
GitLab authentication is now available.
- Added
None as a video call provider option.
Changes in Zulip 2.1
GET /users: Added include_custom_profile_fields
to request custom profile field data.
GET /users/me: Added avatar_url field,
containing the user's avatar URL, to the response.
GET /users/me/subscriptions: Added
include_subscribers parameter controlling whether data on the
other subscribers is included. Previous behavior was to always send
subscriber data.
GET /users/me/subscriptions:
Stream-level notification settings like push_notifications were
changed to be nullable boolean fields (true/false/null), with null
meaning that the stream inherits the organization-level default.
Previously, the only values were true/false. A client communicates
support for this feature using client_capabilities.
GET /users/me/subscriptions: Added
wildcard_mentions_notify notification setting, with the same
global-plus-stream-level-override model as other notification settings.
GET /server_settings: Added
external_authentication_methods structure, used to display login
buttons nicely in the mobile apps.
- Added
first_message_id field to Stream objects. This is helpful
for determining whether the stream has any messages older than a
window cached in a client.
- Added
is_web_public field to Stream objects. This field is
intended to support web-public streams.
- Added
/export/realm endpoints for triggering a data export.
PATCH /realm: Added invite_to_stream_policy,
create_stream_policy, digest_emails_enabled, digest_weekday,
user_group_edit_policy, and avatar_changes_disabled organization settings.
- Added
fluid_layout_width, desktop_icon_count_display, and
demote_inactive_streams display settings.
enable_stream_sounds was renamed to
enable_stream_audible_notifications.
- Deprecated
in_home_view, replacing it with the more readable
is_muted (with the opposite meaning).
- Custom profile fields: Added
EXTERNAL_ACCOUNT field type.
Changes in Zulip 2.0
POST /messages: Added support for using user
IDs and stream IDs for specifying the recipients of a message.
POST /messages, POST
/messages/{message_id}: Added support for
encoding topics using the topic parameter name. The previous
subject parameter name was deprecated but is still supported for
backwards-compatibility.
POST /set-typing-status: Added support for specifying the
recipients with user IDs, deprecating the original API of specifying
them using email addresses.
Changes not yet stabilized
POST /register: Added slim_presence
parameter. Changes the format of presence events, but is still
being changed and should not be used by clients.