# This file contains the API definitions for the Zulip REST API.
#
# For details on the OpenAPI specification, see https://swagger.io/specification
#
# Our own documentation lives at
#
#   https://zulip.readthedocs.io/en/latest/documentation/openapi.html
#

openapi: 3.0.1
info:
  version: 1.0.0
  title: Zulip REST API
  description: |
    Powerful open source group chat
  contact:
    url: https://zulipchat.com
  license:
    name: Apache 2.0
    url: https://www.apache.org/licenses/LICENSE-2.0.html
servers:
- url: 'https://your.zulip.server/api/v1'
security:
  - basicAuth: []
#######################
# Endpoint definitions
#######################
paths:
  /fetch_api_key:
    post:
      description: |
        Given a username and password, fetch the user's API key.

        Used to authenticate the mobile and terminal apps when the server
        has EmailAuthBackend or LDAPAuthBackend enabled.
      operationId: zerver.views.auth.api_fetch_api_key
      parameters:
      - name: username
        in: query
        description: |
          The username to be used for authentication (typically, the email
          address, but it could be an LDAP username).
        schema:
          type: string
        required: true
      - name: password
        in: query
        schema:
          type: string
        description: |
          The user's Zulip password (or LDAP password, if LDAP authentication is in use).
        required: true
      responses:
        '200':
          description: Success.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApiKeyResponse'
  /dev_fetch_api_key:
    post:
      description: |
        Gather a token bound to a user account, to identify and authenticate
        them when making operations with the API. This token must be used as the
        password in the rest of the endpoints that require Basic authentication.
      parameters:
      - name: username
        in: query
        description: |
          The email address for the user that owns the API key.
        schema:
          type: string
        example: iago@zulip.com
        required: true
      security: []
      responses:
        '200':
          description: Success.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApiKeyResponse'
  /events:
    get:
      description: |
        Receive new events from [a registered event queue](/api/register-queue).
      parameters:
      - $ref: '#/components/parameters/QueueId'
      - name: last_event_id
        in: query
        description: |
          The highest event ID in this queue that you've received and
          wish to acknowledge. See the [code for
          `call_on_each_event`](https://github.com/zulip/python-zulip-api/blob/master/zulip/zulip/__init__.py)
          in the [zulip Python
          module](https://github.com/zulip/python-zulip-api) for an
          example implementation of correctly processing each event
          exactly once.
        schema:
          type: integer
        example: -1
      - name: dont_block
        in: query
        description: |
          Set to `true` if the client is requesting a nonblocking reply. If not
          specified, the request will block until either a new event is available
          or a few minutes have passed, in which case the server will send the
          client a heartbeat event.
        schema:
          type: boolean
          default: false
        example: true
      responses:
        '200':
          description: Success.
          content:
            application/json:
              schema:
                allOf:
                - $ref: '#/components/schemas/JsonSuccess'
                - properties:
                    events:
                      type: array
                      description: |
                        An array of `event` objects (possibly zero-length if `dont_block` is
                        set) of events with IDs newer than `last_event_id`. Event IDs are
                        guaranteed to be increasing, but they are not guaranteed to be
                        consecutive.
                      items:
                        type: object
                - example:
                    {
                        "events": [
                            {
                                "id": 0,
                                "message": {
                                    "avatar_url": "https://url/for/othello-bots/avatar",
                                    "client": "website",
                                    "content": "I come not, friends, to steal away your hearts.",
                                    "content_type": "text/x-markdown",
                                    "display_recipient": "Denmark",
                                    "id": 12345678,
                                    "recipient_id": 12314,
                                    "sender_email": "othello-bot@example.com",
                                    "sender_full_name": "Othello Bot",
                                    "sender_id": 13215,
                                    "sender_realm_str": "example",
                                    "sender_short_name": "othello-bot",
                                    "topic": "Castle",
                                    "topic_links": [],
                                    "timestamp": 1375978403,
                                    "type": "stream"
                                },
                                "type": "message"
                            },
                            {
                                "id": 1,
                                "message": {
                                    "avatar_url": "https://url/for/othello-bots/avatar",
                                    "client": "website",
                                    "content": "With mirth and laughter let old wrinkles come.",
                                    "content_type": "text/x-markdown",
                                    "display_recipient": [
                                        {
                                            "email": "hamlet@example.com",
                                            "full_name": "Hamlet of Denmark",
                                            "id": 31572,
                                            "short_name": "hamlet"
                                        }
                                    ],
                                    "id": 12345679,
                                    "recipient_id": 18391,
                                    "sender_email": "othello-bot@example.com",
                                    "sender_full_name": "Othello Bot",
                                    "sender_id": 13215,
                                    "sender_realm_str": "example",
                                    "sender_short_name": "othello-bot",
                                    "subject": "",
                                    "topic_links": [],
                                    "timestamp": 1375978404,
                                    "type": "private"
                                },
                                "type": "message"
                            }
                        ],
                        "msg": "",
                        "result": "success"
                    }
        '400':
          description: Bad request.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BadEventQueueIdError'
    delete:
      description: |
        Delete a previously registered queue.
      parameters:
      - $ref: '#/components/parameters/QueueId'
      responses:
        '200':
          description: Success.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/JsonSuccess'
        '400':
          description: Bad request.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BadEventQueueIdError'
  /get_stream_id:
    get:
      description: |
        Get the unique ID of a given stream.
      parameters:
      - $ref: '#/components/parameters/Stream'
        required: true
      responses:
        '200':
          description: Success.
          content:
            application/json:
              schema:
                allOf:
                - $ref: '#/components/schemas/JsonSuccess'
                - properties:
                    stream_id:
                      type: integer
                      description: |
                        The ID of the given stream.
                - example:
                    {
                        "msg": "",
                        "result": "success",
                        "stream_id": 15
                    }
        '400':
          description: Bad request.
          content:
            application/json:
              schema:
                allOf:
                - $ref: '#/components/schemas/CodedError'
                - example:
                    {
                        "code": "BAD_REQUEST",
                        "msg": "Invalid stream name 'nonexistent'",
                        "result": "error"
                    }
  /mark_all_as_read:
    post:
      description: |
        Mark all the user's unread messages as read. This is often called
        "bankruptcy" in Zulip.
      responses:
        '200':
          description: Success.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/JsonSuccess'
  /mark_stream_as_read:
    post:
      description: |
        Mark all the unread messages in a stream as read.
      parameters:
      - $ref: '#/components/parameters/StreamIdInQuery'
        required: true
      responses:
        '200':
          description: Success.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/JsonSuccess'
  /mark_topic_as_read:
    post:
      description: |
        Mark all the unread messages in a topic as read.
      parameters:
      - $ref: '#/components/parameters/StreamIdInQuery'
        required: true
      - name: topic_name
        in: query
        description: |
          The name of the topic whose messages should be marked as read.
        schema:
          type: string
        example: new coffee machine
        required: true
      responses:
        '200':
          description: Success.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/JsonSuccess'
  /messages:
    get:
      description: |
        Fetch messages that match a specific narrow.
      parameters:
      - name: anchor
        in: query
        description: |
          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 2.2.  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).
        schema:
          oneOf:
            - type: string
            - type: integer
        example: 42
      - name: num_before
        in: query
        description: |
          The number of messages with IDs less than the anchor to retrieve.
        schema:
          type: integer
        example: 4
        required: true
      - name: num_after
        in: query
        description: |
          The number of messages with IDs greater than the anchor to retrieve.
        schema:
          type: integer
        example: 8
        required: true
      - name: narrow
        in: query
        description: |
          The narrow where you want to fetch the messages from. See how to
          [construct a narrow](/api/construct-narrow).
        schema:
          type: array
          items:
            type: object
          default: []
        example: [{"operand": "Denmark", "operator": "stream"}]
      - $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.
        schema:
          type: boolean
          default: true
        example: false
      - name: use_first_unread_anchor
        in: query
        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 2.2, replaced by
          `anchor="first_unread"` instead.
        schema:
          type: boolean
          default: false
        example: true
      responses:
        '200':
          description: Success.
          content:
            application/json:
              schema:
                allOf:
                - $ref: '#/components/schemas/JsonSuccess'
                - properties:
                    anchor:
                      type: integer
                      description: |
                        The same `anchor` specified in the request (or the computed one, if
                        `use_first_unread_anchor` is `true`).
                    found_newest:
                      type: boolean
                      description: |
                        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:
                      type: boolean
                      description: |
                        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:
                      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 or did not match
                        the narrow, 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
                      items:
                        type: object
                - 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": [
                                    {
                                        "short_name": "hamlet",
                                        "id": 4,
                                        "is_mirror_dummy": false,
                                        "email": "hamlet@zulip.com",
                                        "full_name": "King Hamlet"
                                    },
                                    {
                                        "short_name": "iago",
                                        "id": 5,
                                        "is_mirror_dummy": false,
                                        "email": "iago@zulip.com",
                                        "full_name": "Iago"
                                    },
                                    {
                                        "short_name": "prospero",
                                        "id": 8,
                                        "is_mirror_dummy": false,
                                        "email": "prospero@zulip.com",
                                        "full_name": "Prospero from The Tempest"
                                    }
                                ],
                                "content_type": "text/html",
                                "is_me_message": false,
                                "sender_short_name": "hamlet",
                                "timestamp": 1527921326,
                                "sender_id": 4,
                                "sender_full_name": "King Hamlet",
                                "recipient_id": 27,
                                "topic_links": [],
                                "client": "populate_db",
                                "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,
                                "sender_short_name": "hamlet",
                                "timestamp": 1527939746,
                                "sender_id": 4,
                                "sender_full_name": "King Hamlet",
                                "recipient_id": 20,
                                "topic_links": [],
                                "client": "populate_db",
                                "avatar_url": "https://secure.gravatar.com/avatar/6d8cad0fd00256e7b40691d27ddfd466?d=identicon&version=1",
                                "submessages": [],
                                "sender_email": "hamlet@zulip.com",
                                "reactions": []
                            }
                        ]
                    }
    post:
      description: |
        Send a message.
      parameters:
      - name: type
        in: query
        description: |
          The type of message to be sent. `private` for a private message and
          `stream` for a stream message.
        schema:
          type: string
          enum:
          - private
          - stream
        example: private
        required: true
      - name: to
        in: query
        description: |
          For stream messages, either the name or integer ID of the stream. For
          private messages, either a list containing integer user IDs or a list
          containing string email addresses.

          **Changes**: Support using user/stream IDs was added in Zulip 2.0.0.
        schema:
          type: string
        example: [9, 10]
        required: true
      - $ref: '#/components/parameters/Topic'
      - $ref: '#/components/parameters/Content'
      responses:
        '200':
          description: Success.
          content:
            application/json:
              schema:
                allOf:
                - $ref: '#/components/schemas/JsonSuccess'
                - properties:
                    id:
                      type: integer
                      description: |
                        The ID assigned to the message sent.
                - example:
                    {
                        "msg": "",
                        "id": 42,
                        "result": "success"
                    }
        '400':
          description: Bad request.
          content:
            application/json:
              schema:
                oneOf:
                - $ref: '#/components/schemas/NonExistingStreamError'
                - allOf:
                  - $ref: '#/components/schemas/CodedError'
                  - example:
                      {
                          "code": "BAD_REQUEST",
                          "msg": "Invalid email 'eeshan@zulip.com'",
                          "result": "error"
                      }
  /messages/{message_id}:
    get:
      description: |
        Get the raw content of a message.
      parameters:
      - $ref: '#/components/parameters/MessageId'
      responses:
        '200':
          description: Success.
          content:
            application/json:
              schema:
                allOf:
                - $ref: '#/components/schemas/JsonSuccess'
                - properties:
                    raw_content:
                      type: string
                      description: |
                        The raw content of the message.
                - example:
                    {
                        "raw_content": "**Don't** forget your towel!",
                        "result": "success",
                        "msg": ""
                    }
        '400':
          description: Bad request.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/InvalidMessageError'
    patch:
      description: |
        Edit a message that has already been sent.
      parameters:
      - $ref: '#/components/parameters/MessageId'
      - $ref: '#/components/parameters/Topic'
      - name: propagate_mode
        in: query
        description: |
          "Which message(s) should be edited: just the one indicated in
          `message_id`, messages in the same topic that had been sent after this
          one, or all of them."
        schema:
          type: string
          enum:
          - change_one
          - change_later
          - change_all
          default: change_one
        example: change_all
      - $ref: '#/components/parameters/Content'
      - $ref: '#/components/parameters/StreamIdInQuery'
      responses:
        '200':
          description: Success.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/JsonSuccess'
        '400':
          description: Bad request.
          content:
            application/json:
              schema:
                allOf:
                - $ref: '#/components/schemas/CodedError'
                - properties:
                    msg:
                      enum:
                      - Your organization has turned off message editing
                      - You don't have permission to edit this message
                      - The time limit for editing this message has past
                      - Nothing to change
                      - Topic can't be empty
                - example:
                    {
                        "code": "BAD_REQUEST",
                        "msg": "You don't have permission to edit this message",
                        "result": "error"
                    }
    delete:
      description: |
        Delete a message.
      parameters:
      - $ref: '#/components/parameters/MessageId'
      responses:
        '200':
          description: Success.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/JsonSuccess'
        '400':
          description: Bad request.
          content:
            application/json:
              schema:
                oneOf:
                - $ref: '#/components/schemas/InvalidMessageError'
                - allOf:
                  - $ref: '#/components/schemas/CodedError'
                  - example:
                      {
                          "code": "BAD_REQUEST",
                          "msg": "You don't have permission to delete this message",
                          "result": "error"
                      }
  /messages/{message_id}/history:
    get:
      description: |
        Get the different versions of a previously edited message.
      parameters:
      - $ref: '#/components/parameters/MessageId'
      responses:
        '200':
          description: Success.
          content:
            application/json:
              schema:
                allOf:
                - $ref: '#/components/schemas/JsonSuccess'
                - properties:
                    message_history:
                      type: array
                      items:
                        type: object
                      description: |
                        A chronologically sorted array of `snapshot`
                        objects, each one with the values of the
                        message after the edition.
                - example:
                    {
                        "message_history": [
                            {
                                "content": "Hello!",
                                "topic": "party at my houz",
                                "rendered_content": "<p>Hello!</p>",
                                "timestamp": 1530129122,
                                "user_id": 5
                            },
                            {
                                "topic": "party at my house",
                                "content": "Howdy!",
                                "prev_content": "Hello!",
                                "rendered_content": "<p>Howdy!</p>",
                                "user_id": 5,
                                "prev_rendered_content": "<p>Hello!</p>",
                                "content_html_diff": "<div><p><span class=\"highlight_text_inserted\">Howdy!</span></p> <p><span class=\"highlight_text_deleted\">Hello!</span></p></div>",
                                "prev_topic": "party at my houz",
                                "timestamp": 1530129134
                            }
                        ],
                        "msg": "",
                        "result": "success"
                    }
        '400':
          description: Bad request.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/InvalidMessageError'
  /messages/flags:
    post:
      description: |
        Add or remove flags in a list of messages.
      parameters:
      - name: messages
        in: query
        description: |
          An array containing the IDs of the target messages.
        schema:
          type: array
          items:
            type: integer
        example: [4, 8, 15]
        required: true
      - name: op
        in: query
        description: |
          Whether to `add` the flag or `remove` it.
        schema:
          type: string
          enum:
          - add
          - remove
        example: add
        required: true
      - name: flag
        in: query
        description: |
          The flag that should be added/removed.
        schema:
          type: string
        example: read
        required: true
      responses:
        '200':
          description: Success.
          content:
            application/json:
              schema:
                allOf:
                - $ref: '#/components/schemas/JsonSuccess'
                - properties:
                    messages:
                      type: array
                      items:
                        type: integer
                      description: |
                        An array with the IDs of the modified messages.
                - example:
                    {
                        "msg": "",
                        "messages": [
                            4, 18, 15
                        ],
                        "result": "success"
                    }
  /messages/render:
    post:
      description: |
        Render a message to HTML.
      parameters:
      - $ref: '#/components/parameters/Content'
      responses:
        '200':
          description: Success.
          content:
            application/json:
              schema:
                allOf:
                - $ref: '#/components/schemas/JsonSuccess'
                - properties:
                    rendered:
                      type: string
                      description: |
                        The rendered HTML.
                - example:
                    {
                        "msg": "",
                        "rendered": "<p><strong>foo</strong></p>",
                        "result": "success"
                    }
  /messages/{message_id}/reactions:
    post:
      description: |
        Add an emoji reaction to a message.
      parameters:
      - $ref: '#/components/parameters/MessageId'
      - name: emoji_name
        in: query
        description: |
          Name of the emoji you want to add as as a reaction.

          To find an emoji's name, hover over a message to reveal
          three icons on the right, then click the smiley face icon.
          Images of available reaction emojis appear. Hover over the
          emoji you want, and note that emoji's text name.
        schema:
          type: string
        example: 'octopus'
        required: true
      - name: emoji_code
        in: query
        description: |
          An encoded version of the unicode codepoint.  For most
          clients, you won't need this; it's used to handle a rare
          corner case when upvoting a unicode emoji reaction added
          previously by another user.

          If the existing reaction was added when the Zulip
          server was using a previous version of the emoji
          data mapping from codepoints to human-readable
          names, sending the `emoji_code` in the data for
          the original reaction allows the Zulip server to
          correctly consider your upvote as an upvote
          rather than a reaction with a "diffenent" emoji.
        schema:
          type: string
        example: '1f419'
        required: false
      - name: reaction_type
        in: query
        description: |
          If you are reacting with a [custom emoji](/help/add-custom-emoji), set
          `reaction_type` to `realm_emoji`.
        schema:
          type: string
        example: 'unicode_emoji'
        required: false
      responses:
        '200':
          $ref: '#/components/responses/SimpleSuccess'

        '400':
          description: Bad request.
          content:
            application/json:
              schema:
                allOf:
                - $ref: '#/components/schemas/CodedError'
                - example:
                    {
                        "result": "error",
                        "msg": "Invalid emoji code",
                        "code": "BAD_REQUEST"
                    }

    delete:
      description: |
        Delete an emoji reaction from a message.
      parameters:
      - $ref: '#/components/parameters/MessageId'
      - name: emoji_name
        in: query
        description: |
          Name of the emoji you want to delete from a reaction.

          To find an emoji's name, hover over a message to
          reveal three icons on the right, then click the smiley face icon.
          Images of available reaction emojis appear. Hover over the emoji
          you want, and note that emoji's text name.

          Ignored if emoji_code is also passed.
        schema:
          type: string
        example: 'octopus'
        required: false
      - name: emoji_code
        in: query
        description: |
          Alternative to emoji_name for expressing which emoji to remove. An
          encoded version of the unicode codepoint for the emoji you'd like to
          remove from the message.

          Recommended over using `emoji_name` for Zulip apps
          because this more robustly handles changes in the mapping
          between user-facing names and aliases for emoji (which change from
          time to time) and their unicode codepoints.
        schema:
          type: string
        example: '1f419'
        required: false
      - name: reaction_type
        in: query
        description: |
          When removing a reaction with a [custom emoji](/help/add-custom-emoji),
          set `reaction_type` to `realm_emoji`.
        schema:
          type: string
        example: 'unicode_emoji'
        required: false
      responses:
        '200':
          $ref: '#/components/responses/SimpleSuccess'
        '400':
          description: Bad request.
          content:
            application/json:
              schema:
                allOf:
                - $ref: '#/components/schemas/CodedError'
                - example:
                    {
                        "result": "error",
                        "msg": "Invalid message(s)",
                        "code": "BAD_REQUEST"
                    }
  /user_uploads:
    post:
      description: |
        Upload a single file and get the corresponding URI.
      requestBody:
        content:
          multipart/form-data:
            schema:
              properties:
                filename:
                  type: string
                  format: binary
                  example: /path/to/file
      responses:
        '200':
          description: Success.
          content:
            application/json:
              schema:
                allOf:
                - $ref: '#/components/schemas/JsonSuccess'
                - properties:
                    uri:
                      type: string
                      description: |
                        The URI of the uploaded file.
                - example:
                    {
                        "msg": "",
                        "result": "success",
                        "uri": "/user_uploads/1/4e/m2A3MSqFnWRLUf9SaPzQ0Up_/zulip.txt"
                    }
  /user_uploads/{realm_id_str}/{filename}:
    get:
      description: |
        Get a temporary URL for access to the file that doesn't require authentication.
      parameters:
      - name: realm_id_str
        in: path
        description: |
          The realm id.
        schema:
          type: integer
        example: 1
        required: True
      - name: filename
        in: path
        description: |
          Path to the URL.
        schema:
          type: string
        example: 4e/m2A3MSqFnWRLUf9SaPzQ0Up_/zulip.txt
        required: True
      responses:
        '200':
          description: Success.
          content:
            application/json:
              schema:
                allOf:
                - $ref: '#/components/schemas/JsonSuccess'
                - properties:
                    url:
                      type: string
                      description: |
                        A temporary URL that can be used to access the uploaded file
                        without Zulip's normal API authentication.
                - example:
                    {
                        "msg": "",
                        "result": "success",
                        "url": "/user_uploads/temporary/322F32632F39765378464E4C63306D3961396F4970705A4D74424565432F7A756C69702E7478743A316A5053616A3A3938625F44393446466D37357254315F4F414C425A4553464F6A55"
                    }

  /users:
    get:
      description: |
        Retrieve all users in a realm.
      parameters:
      - $ref: '#/components/parameters/ClientGravatar'
      - name: include_custom_profile_fields
        in: query
        description: |
          Set to `true` if the client wants custom profile field data to be
          included in the response.

          **Changes**: New in Zulip 2.1.0.  Previous versions do no offer these
          data via the API.
        schema:
          type: boolean
          default: false
        example: true
      responses:
        '200':
          description: Success.
          content:
            application/json:
              schema:
                allOf:
                - $ref: '#/components/schemas/JsonSuccess'
                - properties:
                    members:
                      type: array
                      description: |
                        A list of `user` objects, each containing details about a user in the
                        organization.
                      items:
                        type: object
                - example:
                    {
                       "msg": "",
                       "result": "success",
                       "members": [
                          {
                             "is_active": true,
                             "email": "AARON@zulip.com",
                             "is_admin": false,
                             "avatar_url": "https://secure.gravatar.com/avatar/818c212b9f8830dfef491b3f7da99a14?d=identicon&version=1",
                             "bot_type": null,
                             "timezone": "",
                             "is_bot": false,
                             "user_id": 7,
                             "profile_data": {},
                             "is_guest": false,
                             "date_joined": "2019-10-20T07:50:53.728864+00:00",
                             "full_name": "aaron"
                          },
                          {
                             "date_joined": "2019-10-20T07:50:53.729659+00:00",
                             "full_name": "King Hamlet",
                             "is_guest": false,
                             "profile_data": {
                                "4": {
                                   "value": "vim"
                                },
                                "2": {
                                   "value": "I am:\n* The prince of Denmark\n* Nephew to the usurping Claudius",
                                   "rendered_value": "<p>I am:</p>\n<ul>\n<li>The prince of Denmark</li>\n<li>Nephew to the usurping Claudius</li>\n</ul>"
                                },
                                "5": {
                                   "value": "1900-1-1"
                                },
                                "7": {
                                   "value": "[11]"
                                },
                                "6": {
                                   "value": "https://blog.zulig.org"
                                },
                                "1": {
                                   "value": "+0-11-23-456-7890",
                                   "rendered_value": "<p>+0-11-23-456-7890</p>"
                                },
                                "8": {
                                   "value": "zulipbot"
                                },
                                "3": {
                                   "rendered_value": "<p>Dark chocolate</p>",
                                   "value": "Dark chocolate"
                                }
                             },
                             "user_id": 10,
                             "is_bot": false,
                             "bot_type": null,
                             "timezone": "",
                             "is_admin": false,
                             "avatar_url": "https://secure.gravatar.com/avatar/6d8cad0fd00256e7b40691d27ddfd466?d=identicon&version=1",
                             "is_active": true,
                             "email": "hamlet@zulip.com"
                          },
                          {
                             "bot_owner_id": 11,
                             "is_guest": false,
                             "date_joined": "2019-10-20T12:52:17.862053+00:00",
                             "full_name": "Iago's Bot",
                             "email": "iago-bot@zulipdev.com",
                             "is_active": true,
                             "avatar_url": "https://secure.gravatar.com/avatar/7328586831cdbb1627649bd857b1ee8c?d=identicon&version=1",
                             "is_admin": false,
                             "user_id": 23,
                             "bot_type": 1,
                             "timezone": "",
                             "is_bot": true
                          }
                       ]
                    }
    post:
      description: |
        Create a new user in a realm.
      parameters:
      - name: email
        in: query
        description: |
          The email address of the new user.
        schema:
          type: string
        example: username@example.com
        required: true
      - name: password
        in: query
        description: |
          The password of the new user.
        schema:
          type: string
        example: abcd1234
        required: true
      - name: full_name
        in: query
        description: |
          The full name of the new user.
        schema:
          type: string
        example: New User
        required: true
      - name: short_name
        in: query
        description: |
          The short name of the new user.  Not user-visible.
        schema:
          type: string
        example: newuser
        required: true
      responses:
        '200':
          description: Success.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/JsonSuccess'
        '400':
          description: Bad request.
          content:
            application/json:
              schema:
                allOf:
                - $ref: '#/components/schemas/JsonError'
                - example:
                    {
                        "msg": "Email 'newbie@zulip.com' already in use",
                        "result": "error"
                    }

  /users/{user_id}:
    get:
      description: |
        Retrieve a user in a realm.
      parameters:
      - name: user_id
        in: path
        description: |
          The user id of the user.
        schema:
          type: integer
        example: 11
        required: true
      - $ref: '#/components/parameters/ClientGravatar'
      - name: include_custom_profile_fields
        in: query
        description: |
          The client should pass true if it wants to include custom profile field data.
        schema:
          type: boolean
          default: false
        example: true
      responses:
        '200':
          description: Success.
          content:
            application/json:
              schema:
                allOf:
                - $ref: '#/components/schemas/JsonSuccess'
                - properties:
                    user:
                      type: object
                      description: |
                        A dictionary containing the requested user's details.
                - example:
                    {
                       "msg": "",
                       "result": "success",
                       "user": {
                             "date_joined": "2019-10-20T07:50:53.729659+00:00",
                             "full_name": "King Hamlet",
                             "is_guest": false,
                             "profile_data": {
                                "4": {
                                   "value": "vim"
                                },
                                "2": {
                                   "value": "I am:\n* The prince of Denmark\n* Nephew to the usurping Claudius",
                                   "rendered_value": "<p>I am:</p>\n<ul>\n<li>The prince of Denmark</li>\n<li>Nephew to the usurping Claudius</li>\n</ul>"
                                },
                                "5": {
                                   "value": "1900-1-1"
                                },
                                "7": {
                                   "value": "[11]"
                                },
                                "6": {
                                   "value": "https://blog.zulig.org"
                                },
                                "1": {
                                   "value": "+0-11-23-456-7890",
                                   "rendered_value": "<p>+0-11-23-456-7890</p>"
                                },
                                "8": {
                                   "value": "zulipbot"
                                },
                                "3": {
                                   "rendered_value": "<p>Dark chocolate</p>",
                                   "value": "Dark chocolate"
                                }
                             },
                             "user_id": 10,
                             "is_bot": false,
                             "bot_type": null,
                             "timezone": "",
                             "is_admin": false,
                             "avatar_url": "https://secure.gravatar.com/avatar/6d8cad0fd00256e7b40691d27ddfd466?d=identicon&version=1",
                             "is_active": true,
                             "email": "hamlet@zulip.com"
                          }


                    }

    patch:
      description: |
        Update the user.
      parameters:
      - name: user_id
        in: path
        description: |
          The user id of the user.
        schema:
          type: integer
        example: 12
        required: true
      - name: full_name
        in: query
        description: |
          The user's full name.
        schema:
          type: string
          format: json
        example: NewName
        required: false
      - name: is_admin
        in: query
        description: |
          Whether the target user is an administrator.
        schema:
          type: boolean
        example: false
        required: false
      - name: is_guest
        in: query
        description: |
          Whether the target user is a guest.
        schema:
          type: boolean
        example: true
        required: false
      - name: profile_data
        in: query
        description: |
          A dictionary containing the to be updated custom profile field data for the user.
        schema:
          type: array
          items:
           type: object

        example: [
                    {
                        "id": 4,
                        "value": "vim"
                    },
                    {
                        "id": 5,
                        "value": "1909-04-05"
                    },
                  ]
        required: false

      responses:
        '200':
          $ref: '#/components/responses/SimpleSuccess'

        '400':
          description: Bad request.
          content:
            application/json:
              schema:
                allOf:
                - $ref: '#/components/schemas/CodedError'
                - example:
                    {
                        "result": "error",
                        "msg": "Guests cannot be organization administrators",
                        "code": "BAD_REQUEST"
                    }

    delete:
      description: |
        Delete the user with the passed 'user_id' from the realm.
      parameters:
      - name: user_id
        in: path
        description: |
          The user id of the user.
        schema:
          type: integer
        example: 11
        required: true
      responses:
        '200':
          description: Success
          content:
            application/json:
              schema:
                allOf:
                - $ref: '#/components/schemas/JsonSuccess'
                - example:
                    {
                      "msg": "",
                      "result": "success",
                    }
        '400':
          description: Bad Request
          content:
            application/json:
              schema:
                allOf:
                - $ref: '#/components/schemas/JsonError'
                - example:
                    {
                        "msg": "Cannot deactivate the only organization administrator",
                        "result": "error"
                    }

  /users/{email}/presence:
    get:
      description: |
        Get the presence status for a specific user.
      parameters:
      - name: email
        in: path
        description: |
          The email address of the user whose presence you want to fetch.
        schema:
          type: string
        example: iago@zulip.com
        required: true
      responses:
        '200':
          description: Success.
          content:
            application/json:
              schema:
                allOf:
                - $ref: '#/components/schemas/JsonSuccess'
                - properties:
                    presence:
                      type: object
                      description: |
                        An object containing the presence details for every client the user has
                        logged into.
                - example:
                    {
                        "presence": {
                            "website": {
                                "timestamp": 1532697622,
                                "status": "active",
                            },
                            "ZulipMobile": {
                                "timestamp": 1522687421,
                                "status": "active",
                            },
                            "aggregated": {
                                "timestamp": 1532697622,
                                "status": "active",
                            }
                        },
                        "result": "success",
                        "msg": ""
                    }
  /users/me:
    get:
      description: |
        Get the requesting user's profile data from the backend.
      responses:
        '200':
          description: Success
          content:
            application/json:
              schema:
                allOf:
                - $ref: '#/components/schemas/JsonSuccess'
                - properties:
                    avatar_url:
                      type: string
                      description: |
                        URL for the user's avatar.

                        **Changes**: New in Zulip 2.1.0.
                      example: "x"
                    client_id:
                      type: string
                      description: |
                        NA
                      example: "74c768b081076fdb3c4326256c17467e"
                    email:
                      type: string
                      description: |
                        Email of the requesting user.
                      example: "iago@zulip.com"
                    full_name:
                      type: string
                      description: |
                        Full name of the requesting user.
                      example: "Iago"
                    is_admin:
                      type: boolean
                      description: |
                        A boolean indicating if the requesting user is an admin.
                      example: true
                    is_bot:
                      type: boolean
                      description: |
                        A boolean indicating if the requesting user is a bot.
                      example: false
                    max_message_id:
                      type: integer
                      description: |
                        NA.
                      example: 30
                    pointer:
                      type: integer
                      description: |
                        NA
                      example: -1
                    short_name:
                      type: string
                      description: |
                        Short name of the requesting user.
                      example: "iago"
                    user_id:
                      type: integer
                      description: |
                        The user's ID.
                      example: 1
                    profile_data:
                      type: object
                      description: |
                        A dictionary containing custom profile field data for the user. Each entry
                        maps the integer ID of a custom profile field in the organization to a
                        dictionary containing the user's data for that field.  Generally the data
                        includes just a single `value` key; for those custom profile fields
                        supporting markdown, a `rendered_value` key will also be present.
                - example:
                    {
                        "avatar_url": "https://secure.gravatar.com/avatar/af4f06322c177ef4e1e9b2c424986b54?d=identicon&version=1",
                        "client_id": "74c768b081076fdb3c4326256c17467e",
                        "email": "iago@zulip.com",
                        "full_name": "Iago",
                        "is_admin": true,
                        "is_bot": false,
                        "max_message_id": 30,
                        "msg": "",
                        "pointer": -1,
                        "result": "success",
                        "short_name": "iago",
                        "user_id": 5,
                        "profile_data": {
                            "5": {
                               "value": "2000-1-1"
                            },
                            "4": {
                               "value": "emacs"
                            },
                            "7": {
                               "value": "[10]"
                            },
                            "1": {
                               "value": "+1-234-567-8901",
                               "rendered_value": "<p>+1-234-567-8901</p>"
                            },
                            "2": {
                               "rendered_value": "<p>Betrayer of Othello.</p>",
                               "value": "Betrayer of Othello."
                            },
                            "8": {
                               "value": "zulip"
                            },
                            "3": {
                               "value": "Apples",
                               "rendered_value": "<p>Apples</p>"
                            },
                            "6": {
                               "value": "https://zulip.readthedocs.io/en/latest/"
                            }
                         }
                    }
    delete:
      description: |
        Delete the requesting user from the realm.
      responses:
        '200':
          description: Bad Request
          content:
            application/json:
              schema:
                allOf:
                - $ref: '#/components/schemas/JsonSuccess'
                - example:
                    {
                      "msg": "",
                      "result": "success",
                    }
        '400':
          description: Bad Request
          content:
            application/json:
              schema:
                allOf:
                - $ref: '#/components/schemas/JsonError'
                - example:
                    {
                        "msg": "Cannot deactivate the only organization administrator",
                        "result": "error"
                    }
  /users/me/{stream_id}/topics:
    get:
      description: |
        Get all the topics in a specific stream.
      parameters:
      - $ref: '#/components/parameters/StreamIdInPath'
      responses:
        '200':
          description: Success.
          content:
            application/json:
              schema:
                allOf:
                - $ref: '#/components/schemas/JsonSuccess'
                - properties:
                    topics:
                      type: array
                      items:
                        type: object
                        properties:
                          max_id:
                            description: |
                              The ID of the last message sent to the topic.
                            type: number
                          name:
                            description: |
                              The name of the topic.
                            type: string
                - example:
                    {
                        "msg": "",
                        "result": "success",
                        "topics": [
                            {
                                "max_id": 26,
                                "name": "Denmark3"
                            },
                            {
                                "max_id": 23,
                                "name": "Denmark1"
                            },
                            {
                                "max_id": 6,
                                "name": "Denmark2"
                            }
                        ]
                    }
        '400':
          description: Bad request.
          content:
            application/json:
              schema:
                allOf:
                - $ref: '#/components/schemas/JsonError'
                - example:
                    {
                        "code": "BAD_REQUEST",
                        "msg": "Invalid stream id",
                        "result": "error"
                    }
  /users/me/subscriptions:
    get:
      description: |
        Get information on every stream the user is subscribed to.
      # operationId can be used to record which view function
      # corresponds to an endpoint.  TODO: Add these for more
      # endpoints, and perhaps use this to provide links to implementations.
      operationId: zerver.views.streams.list_subscriptions_backend
      parameters:
      - name: include_subscribers
        in: query
        description: |
          Set to `true` if you would like each stream's info to include a list of
          current subscribers to that stream. (This may be significantly slower in
          organizations with thousands of users.)

          **Changes**: New in Zulip 2.1.0.
        schema:
          type: boolean
          default: false
        example: true
      responses:
        '200':
          description: Success.
          content:
            application/json:
              schema:
                allOf:
                - $ref: '#/components/schemas/JsonSuccess'
                # TODO: Is this the best way to declare required elements in 200 responses?
                - required:
                  - subscriptions
                - properties:
                    subscriptions:
                      type: array
                      items:
                        type: object
                - example:
                    {
                      "msg": "",
                      "result": "success",
                      "subscriptions": [
                        {
                          "audible_notifications": true,
                          "color": "#e79ab5",
                          "description": "A Scandinavian country",
                          "desktop_notifications": true,
                          "email_address": "Denmark+187b4125ed36d6af8b5d03ef4f65c0cf@zulipdev.com:9981",
                          "is_muted": false,
                          "invite_only": false,
                          "name": "Denmark",
                          "pin_to_top": false,
                          "push_notifications": false,
                          "stream_id": 1,
                          "subscribers": [
                              "ZOE@zulip.com",
                              "hamlet@zulip.com",
                              "iago@zulip.com",
                              "othello@zulip.com",
                              "prospero@zulip.com"
                          ]
                        },
                        {
                          "audible_notifications": true,
                          "color": "#e79ab5",
                          "description": "Located in the United Kingdom",
                          "desktop_notifications": true,
                          "email_address": "Scotland+f5786390183e60a1ccb18374f9d05649@zulipdev.com:9981",
                          "is_muted": false,
                          "invite_only": false,
                          "name": "Scotland",
                          "pin_to_top": false,
                          "push_notifications": false,
                          "stream_id": 3,
                          "subscribers": [
                              "ZOE@zulip.com",
                              "iago@zulip.com",
                              "othello@zulip.com",
                              "prospero@zulip.com"
                          ]
                        }
                      ]
                    }
    post:
      description: |
        Subscribe one or more users to one or more streams.
      parameters:
      - name: subscriptions
        in: query
        description: |
          "A list of dictionaries containing the the key `name` and value
          specifying the name of the stream to subscribe. If the stream does not
          exist a new stream is created. The description of the stream created can
          be specified by setting the dictionary key `description` with an
          appropriate value.


          **Note**: This argument is called `streams` and not `subscriptions`
          in our Python API."
        schema:
          type: array
          items:
            type: object
        example: [{"name": "Verona", "description": "Italian City"}]
        required: true
      - name: invite_only
        in: query
        description: |
          A boolean specifying whether the streams specified in `subscriptions`
          are invite-only or not.
        schema:
          type: boolean
          default: false
        example: true
      - name: principals
        in: query
        description: |
          A list of email addresses of the users that will be subscribed to the
          streams specified in the `subscriptions` argument. If not provided, then
          the requesting user/bot is subscribed.
        schema:
          type: array
          items:
            type: string
          default: []
        example: ['ZOE@zulip.com']
      - name: authorization_errors_fatal
        in: query
        description: |
          A boolean specifying whether authorization errors (such as when the
          requesting user is not authorized to access a private stream) should be
          considered fatal or not. When `True`, an authorization error is reported
          as such. When set to `False`, the returned JSON payload indicates that
          there was an authorization error, but the response is still considered a
          successful one.
        schema:
          type: boolean
          default: true
        example: false
      - name: history_public_to_subscribers
        in: query
        description: |
          A boolean indicating if the history should be available to newly
          subscribed members.
        schema:
          type: boolean
          default: None
        example: false
      - name: stream_post_policy
        in: query
        description: |
          Policy for which users can post messages to the stream.

          * 1 => Any user can post.
          * 2 => Only administrators can post.
          * 3 => Only new members can post.

          **Changes**: New in Zulip 2.2, replacing the previous is_announcement_only
          boolean.
        schema:
          type: integer
          default: 1
        example: 1
      - name: announce
        in: query
        description: |
          If `announce` is `True` and one of the streams specified in
          `subscriptions` has to be created (i.e. doesn't exist to begin with), an
          announcement will be made notifying that a new stream was created.
        schema:
          type: boolean
        example: true
      responses:
        '200':
          description: Success.
          content:
            application/json:
              schema:
                oneOf:
                - allOf:
                  - $ref: '#/components/schemas/AddSubscriptionsResponse'
                  - example:
                      {
                          "already_subscribed": {},
                          "msg": "",
                          "result": "success",
                          "subscribed": {
                              "iago@zulip.com": [
                                  "new stream"
                              ]
                          }
                      }
                - allOf:
                  - $ref: '#/components/schemas/AddSubscriptionsResponse'
                  - example:
                      {
                          "already_subscribed": {
                              "newbie@zulip.com": [
                                  "new stream"
                              ]
                          },
                          "msg": "",
                          "result": "success",
                          "subscribed": {}
                      }
        '400':
          description: Success.
          content:
            application/json:
              schema:
                oneOf:
                - allOf:
                  - $ref: '#/components/schemas/AddSubscriptionsResponse'
                  - example:
                      {
                          "msg": "Unable to access stream (private_stream).",
                          "result": "error"
                      }
                - allOf:
                  - $ref: '#/components/schemas/AddSubscriptionsResponse'
                  - example:
                      {
                          "already_subscribed": {},
                          "msg": "",
                          "result": "success",
                          "subscribed": {},
                          "unauthorized": [
                              "private_stream"
                          ]
                      }
    patch:
      description: |
        Update which streams you are are subscribed to.
      operationId: zerver.views.streams.update_subscriptions_backend
      parameters:
        - name: delete
          in: query
          description: |
            A list of stream names to unsubscribe from.
          schema:
            type: array
            items:
              type: string
          example: ['Verona', 'Denmark']
          required: false
        - name: add
          in: query
          description: |
            A list of objects describing which streams to subscribe to, optionally
            including per-user subscription parameters (e.g. color) and if the
            stream is to be created, its description.
          schema:
            type: array
            items:
              type: object
              properties:
                name:
                  type: string
                color:
                  type: string
                description:
                  type: string
          example:
            [
              {
                "name": "Verona"
              },
              {
                "name": "Denmark",
                "color": "#e79ab5",
                "description": "A Scandinavian country",
              }
            ]
          required: false
      responses:
        '200':
          description: Success.
          content:
            application/json:
              schema:
                allOf:
                - $ref: '#/components/schemas/JsonSuccess'
                - required:
                  - subscribed
                  - not_subscribed
                  - already_subscribed
                  - removed
                - properties:
                    subscribed:
                      type: object
                      description: |
                        A dictionary where the key is the email
                        address of the user/bot and the value is a
                        list of the names of the streams that were
                        subscribed to as a result of the query.
                    already_subscribed:
                      type: object
                      description: |
                        A dictionary where the key is the email
                        address of the user/bot and the value is a
                        list of the names of the streams that the
                        user/bot is already subscribed to.
                    not_removed:
                      type: array
                      items:
                        type: string
                      description: |
                        A list of the names of streams that the user
                        is already unsubscribed from, and hence
                        doesn't need to be unsubscribed.
                    removed:
                      type: array
                      items:
                        type: string
                      description: |
                        A list of the names of streams which were unsubscribed
                        from as a result of the query.
                - example:
                    {
                        "msg": "",
                        "subscribed": {},
                        "already_subscribed": {"iago@zulip.com":["Verona"]},
                        "not_removed": [],
                        "removed": [
                            "new stream"
                        ],
                        "result": "success"
                    }
    delete:
      description: |
        Unsubscribe yourself or other users from one or more streams.
      parameters:
      - name: subscriptions
        in: query
        description: |
          A list of stream names to unsubscribe from. This argument is called
          `streams` in our Python API.
        schema:
          type: array
          items:
            type: string
        example: ['Verona', 'Denmark']
        required: true
      - name: principals
        in: query
        description: |
          A list of email addresses of the users that will be unsubscribed from
          the streams specified in the `subscriptions` argument. If not provided,
          then the requesting user/bot is unsubscribed.
        schema:
          type: array
          items:
            type: string
        example: ['ZOE@zulip.com']
      responses:
        '200':
          description: Success.
          content:
            application/json:
              schema:
                allOf:
                - $ref: '#/components/schemas/JsonSuccess'
                - properties:
                    not_removed:
                      type: array
                      items:
                        type: string
                      description: |
                        A list of the names of streams that the user is already unsubscribed
                        from, and hence doesn't need to be unsubscribed.
                    removed:
                      type: array
                      items:
                        type: string
                      description: |
                        A list of the names of streams which were unsubscribed from as a result
                        of the query.
                - example:
                    {
                        "msg": "",
                        "not_removed": [],
                        "removed": [
                            "new stream"
                        ],
                        "result": "success"
                    }
        '400':
          description: Bad request.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/NonExistingStreamError'
  /users/me/subscriptions/muted_topics:
    patch:
      description: |
        Toggle muting for a specific topic the user is subscribed to.
      parameters:
      - $ref: '#/components/parameters/Stream'
        required: false
      - $ref: '#/components/parameters/StreamIdInQuery'
        required: false
      - name: topic
        in: query
        description: |
          The topic to (un)mute. Note that the request will succeed regardless of
          whether any messages have been sent to the specified topic.
        schema:
          type: string
        example: dinner
        required: true
      - name: op
        in: query
        description: |
          Whether to mute (`add`) or unmute (`remove`) the provided topic.
        schema:
          type: string
          enum:
          - add
          - remove
        example: add
        required: true
      responses:
        '200':
          description: Success.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/JsonSuccess'
        '400':
          description: Bad request.
          content:
            application/json:
              schema:
                oneOf:
                - allOf:
                  - $ref: '#/components/schemas/JsonError'
                  - example:
                      {
                          "msg": "Topic already muted",
                          "result": "error"
                      }
                - allOf:
                  - $ref: '#/components/schemas/JsonError'
                  - example:
                      {
                          "msg": "Topic is not muted",
                          "result": "error"
                      }
  /realm/emoji/{emoji_name}:
    post:
      description: |
        Upload a single emoji file.
      parameters:
      - name: emoji_name
        required: true
        in: path
        description: |
          The name that should be associated with the uploaded emoji image/gif.
        schema:
          type: string
      requestBody:
        content:
          multipart/form-data:
            schema:
              properties:
                filename:
                  type: string
                  format: binary
                  example: /path/to/img.png
      responses:
        '200':
          description: Success.
          content:
            application/json:
              schema:
                allOf:
                - $ref: '#/components/schemas/JsonSuccess'

  /realm/emoji:
    get:
      description: |
        Get all the custom emoji in the user's realm.
      responses:
        '200':
          description: Success.
          content:
            application/json:
              schema:
                allOf:
                - $ref: '#/components/schemas/JsonSuccess'
                - properties:
                    emoji:
                      type: object
                      description: |
                        An object that contains `emoji` objects, each identified with their
                        emoji ID as the key.
                - example:
                    {
                        "result": "success",
                        "msg": "",
                        "emoji": {
                            "1": {
                                "id": "1",
                                "name": "green_tick",
                                "source_url": "/user_avatars/1/emoji/images/1.png",
                                "deactivated": false,
                                "author": {
                                    "id": 5,
                                    "email": "iago@zulip.com",
                                    "full_name": "Iago"
                                }
                            }
                        }
                    }
  /users/me/subscriptions/properties:
    post:
      description: |
        Make bulk modifications of the subscription properties on one or more
        streams the user is subscribed to.
      parameters:
      - name: subscription_data
        in: query
        description: |
          A list of objects that describe the changes that should be applied in
          each subscription. Each object represents a subscription, and must have
          a `stream_id` key that identifies the stream, as well as the `property`
          being modified and its new `value`.
        schema:
          type: array
          items:
            type: object
        example: [{"stream_id": 1, "property": "pin_to_top", "value": true}, {"stream_id": 3, "property": "color", "value": '#f00f00'}]
        required: true
      responses:
        '200':
          description: Success.
          content:
            application/json:
              schema:
                allOf:
                - $ref: '#/components/schemas/JsonSuccess'
                - properties:
                    subscription_data:
                      type: array
                      items:
                        type: object
                      description: |
                        The same `subscription_data` object sent by the client for the request.
                - example:
                    {
                        "subscription_data": [
                            {
                                "property": "pin_to_top",
                                "value": true,
                                "stream_id": 1
                            },
                            {
                                "property": "color",
                                "value": 'f00',
                                "stream_id": 3
                            }
                        ],
                        "result": "success",
                        "msg": ""
                    }
  /realm/filters:
    get:
      description: |
        Fetch all the filters set up for the user's organization.
      responses:
        '200':
          description: Success.
          content:
            application/json:
              schema:
                allOf:
                - $ref: '#/components/schemas/JsonSuccess'
                - properties:
                    filters:
                      type: array
                      items:
                        type: array
                        items:
                          oneOf:
                            - type: string
                            - type: integer
                      description: |
                        An array of tuples, each representing one of
                        the linkifiers set up in the
                        organization. Each of these tuples contain the
                        pattern, the formatted URL and the filter's
                        ID, in that order. See the [Create
                        linkifiers](/api/add-linkifiers) article for
                        details on what each field means.
                - example:
                    {
                        "msg": "",
                        "filters": [
                            [
                                "#(?P<id>[0-9]+)",
                                "https://github.com/zulip/zulip/issues/%(id)s",
                                1
                            ]
                        ],
                        "result": "success"
                    }
    post:
      description: |
        Establish patterns in the messages that should be automatically
        linkified.
      parameters:
      - name: pattern
        in: query
        description: |
          The [Python regular
          expression](https://docs.python.org/3/howto/regex.html) that should
          trigger the linkifier.
        schema:
          type: string
        example: '#(?P<id>[0-9]+)'
        required: true
      - name: url_format_string
        in: query
        description: |
          The URL used for the link. If you used named groups for the `pattern`,
          you can insert their content here with
          `%(name_of_the_capturing_group)s`.
        schema:
          type: string
        example: https://github.com/zulip/zulip/issues/%(id)s
        required: true
      responses:
        '200':
          description: Success.
          content:
            application/json:
              schema:
                allOf:
                - $ref: '#/components/schemas/JsonSuccess'
                - properties:
                    id:
                      type: integer
                      description: |
                        The numeric ID assigned to this filter.
                - example:
                    {
                        "id": 42,
                        "result": "success",
                        "msg": ""
                    }
  /realm/filters/{filter_id}:
    delete:
      description: |
        Remove an organization filter.
      parameters:
      - name: filter_id
        in: path
        description: |
          The ID of the filter that you want to remove.
        schema:
          type: integer
        example: 42
        required: true
      responses:
        '200':
          description: Success.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/JsonSuccess'
  /register:
    post:
      description: |
        This powerful endpoint can be used to register a Zulip "event queue"
        (subscribed to certain types of "events", or updates to the messages and
        other Zulip data the current user has access to), as well as to fetch
        the current state of that data.
      parameters:
      - name: apply_markdown
        in: query
        description: |
          Set to `true` if you would like the content to be rendered in HTML
          format (otherwise the API will return the raw text that the user
          entered)
        schema:
          type: boolean
          default: false
        example: true
      - $ref: '#/components/parameters/ClientGravatar'
      - name: slim_presence
        in: query
        description: |
          Setting this to `true` will make presence dictionaries be keyed by
          user_id instead of email.

          **Changes**: New in Zulip 2.2.
        schema:
          type: boolean
          default: false
        example: true
      - $ref: '#/components/parameters/Event_types'
        example: ['message']
      - name: all_public_streams
        in: query
        description: |
          Set to `True` if you would like to receive events that occur within all
          public streams.
        schema:
          type: boolean
          default: false
        example: true
      - name: include_subscribers
        in: query
        description: |
          Set to `True` if you would like to receive events that include the
          subscribers for each stream.
        schema:
          type: boolean
          default: false
        example: true
      - name: client_capabilities
        in: query
        description: |
          Dictionary containing details on features the client supports that are
          relevant to the format of responses sent by the server.

          * `notification_settings_null`: Boolean for whether the
            client can handle the current API with null values for
            stream-level notification settings (which means the stream
            is not customized and should inherit the user's global
            notification settings for stream messages).  New in Zulip
            2.1.0; in earlier Zulip releases, stream-level
            notification settings were simple booleans.
        schema:
          type: object
        example:
          {
              "notification_settings_null": true
          }
      - name: fetch_event_types
        in: query
        description: |
          Same as the `event_types` argument except that the values in
          `fetch_event_types` are used to fetch initial data. If
          `fetch_event_types` is not provided, `event_types` is used and if
          `event_types` is not provided, this argument defaults to `None`.
        schema:
          type: array
          items:
            type: string
        example: ['message']
      - $ref: '#/components/parameters/Narrow'
      responses:
        '200':
          description: Success.
          content:
            application/json:
              schema:
                allOf:
                - $ref: '#/components/schemas/JsonSuccess'
                - properties:
                    queue_id:
                      type: string
                      description: |
                        The ID of the queue that has been allocated for your client.
                    last_event_id:
                      type: integer
                      description: |
                        The initial value of `last_event_id` to pass to `GET /api/v1/events`.
                - example:
                    {
                        "last_event_id": -1,
                        "msg": "",
                        "queue_id": "1517975029:0",
                        "realm_emoji": {
                            "1": {
                                "author": {
                                    "email": "iago@zulip.com",
                                    "full_name": "Iago",
                                    "id": 5
                                },
                                "deactivated": false,
                                "id": "1",
                                "name": "green_tick",
                                "source_url": "/user_avatars/1/emoji/images/1.png"
                            }
                        },
                        "result": "success"
                    }
  /server_settings:
    get:
      description: |
        Fetch global settings for the Zulip server.
      responses:
        '200':
          description: Success.
          content:
            application/json:
              schema:
                allOf:
                - $ref: '#/components/schemas/JsonSuccess'
                - properties:
                    authentication_methods:
                      type: object
                      description: |
                        Each key-value pair in the object indicates whether the authentication
                        method is enabled on this server.
                    external_authentication_methods:
                      type: array
                      description: |
                        List of dictionaries describing which external authentication methods
                        are enabled and their parameters - most importantly the login url,
                        display_name and display_icon.
                      items:
                        type: object
                    zulip_version:
                      type: string
                      description: |
                        The version of Zulip running in the server.
                    zulip_feature_level:
                      type: integer
                      description: |
                        An integer to indicate the features added to the server.
                        The feature level increases monotonically; a value of N
                        means the server supports all API features introduced
                        before feature level N. This provides fine-grained
                        distinctions among development versions in between major
                        releases.
                    push_notifications_enabled:
                      type: boolean
                      description: |
                        Whether mobile/push notifications are enabled.
                    is_incompatible:
                      type: boolean
                      description: |
                        Whether the Zulip client that has sent a request to this endpoint is
                        deemed incompatible with the server.
                    email_auth_enabled:
                      type: boolean
                      description: |
                        Setting for allowing users authenticate with an email-password
                        combination.
                    require_email_format_usernames:
                      type: boolean
                      description: |
                        Whether usernames should have an email address format. This is important if your server has [LDAP
                        authentication](https://zulip.readthedocs.io/en/latest/production/authentication-methods.html#ldap-including-active-directory)
                        enabled with a username and password combination.
                    realm_uri:
                      type: string
                      description: |
                        The organization's URI.
                    realm_name:
                      type: string
                      description: |
                        The realm's name.
                    realm_icon:
                      type: string
                      description: |
                        The URI of the organization's mobile icon (usually a square version of
                        the logo).
                    realm_description:
                      type: string
                      description: |
                        HTML description of the organization, as configured by the [organization
                        profile](/help/create-your-organization-profile).
                - example:
                    {
                        "authentication_methods": {
                          "password": true,
                          "dev": true,
                          "email": true,
                          "ldap": false,
                          "remoteuser": false,
                          "github": true,
                          "azuread": false,
                          "google": true,
                          "saml": true
                        },
                        "zulip_version": "2.0.6+git",
                        "push_notifications_enabled": false,
                        "msg": "",
                        "is_incompatible": false,
                        "email_auth_enabled": true,
                        "require_email_format_usernames": true,
                        "realm_uri": "http://localhost:9991",
                        "realm_name": "Zulip Dev",
                        "realm_icon": "https://secure.gravatar.com/avatar/62429d594b6ffc712f54aee976a18b44?d=identicon",
                        "realm_description": "<p>The Zulip development environment default organization.  It's great for testing!</p>",
                        "result": "success",
                        "external_authentication_methods": [
                          {
                            "name": "saml:idp_name",
                            "display_name": "SAML",
                            "display_icon": null,
                            "login_url": "/accounts/login/social/saml/idp_name",
                            "signup_url": "/accounts/register/social/saml/idp_name"
                          },
                          {
                            "name": "google",
                            "display_name": "Google",
                            "display_icon": "/static/images/landing-page/logos/googl_e-icon.png",
                            "login_url": "/accounts/login/social/google",
                            "signup_url": "/accounts/register/social/google"
                          },
                          {
                            "name": "github",
                            "display_name": "GitHub",
                            "display_icon": "/static/images/landing-page/logos/github-icon.png",
                            "login_url": "/accounts/login/social/github",
                            "signup_url": "/accounts/register/social/github"
                          }
                        ]
                    }
  /settings/notifications:
    patch:
      description: |
        Modify the user's preferences for notifications.
      parameters:
      - name: enable_stream_desktop_notifications
        in: query
        description: |
          Enable visual desktop notifications for stream messages.
        schema:
          type: boolean
        example: true
      - name: enable_stream_email_notifications
        in: query
        description: |
          Enable email notifications for stream messages.
        schema:
          type: boolean
        example: true
      - name: enable_stream_push_notifications
        in: query
        description: |
          Enable mobile notifications for stream messages.
        schema:
          type: boolean
        example: true
      - name: enable_stream_audible_notifications
        in: query
        description: |
          Enable audible desktop notifications for stream messages.
        schema:
          type: boolean
        example: true
      - name: notification_sound
        in: query
        description: |
          Notification sound name.
        schema:
          type: string
          format: json
        example: ding
      - name: enable_desktop_notifications
        in: query
        description: |
          Enable visual desktop notifications for private messages and @-mentions.
        schema:
          type: boolean
        example: true
      - name: enable_sounds
        in: query
        description: |
          Enable audible desktop notifications for private messages and
          @-mentions.
        schema:
          type: boolean
        example: true
      - name: enable_offline_email_notifications
        in: query
        description: |
          Enable email notifications for private messages and @-mentions received
          when the user is offline.
        schema:
          type: boolean
        example: true
      - name: enable_offline_push_notifications
        in: query
        description: |
          Enable mobile notification for private messages and @-mentions received
          when the user is offline.
        schema:
          type: boolean
        example: true
      - name: enable_online_push_notifications
        in: query
        description: |
          Enable mobile notification for private messages and @-mentions received
          when the user is online.
        schema:
          type: boolean
        example: true
      - name: enable_digest_emails
        in: query
        description: |
          Enable digest emails when the user is away.
        schema:
          type: boolean
        example: true
      - name: enable_login_emails
        in: query
        description: |
          Enable email notifications for new logins to account.
        schema:
          type: boolean
        example: true
      - name: message_content_in_email_notifications
        in: query
        description: |
          Include the message's content in missed messages email notifications.
        schema:
          type: boolean
        example: true
      - name: pm_content_in_desktop_notifications
        in: query
        description: |
          Include content of private messages in desktop notifications.
        schema:
          type: boolean
        example: true
      - name: wildcard_mentions_notify
        in: query
        description: |
          Whether wildcard mentions (E.g. @**all**) should send notifications
          like a personal mention.
        schema:
          type: boolean
        example: true
      - name: desktop_icon_count_display
        in: query
        description: |
          > Unread count summary (appears in desktop sidebar and browser tab)

           * 1 - All unreads
           * 2 - Private messages and mentions
           * 3 - None
        schema:
          type: integer
          enum:
            - 1
            - 2
            - 3
        example: 1
      - name: realm_name_in_notifications
        in: query
        description: |
          Include organization name in subject of missed message emails.
        schema:
          type: boolean
        example: true
      responses:
        '200':
          description: Success.
          content:
            application/json:
              schema:
                allOf:
                - $ref: '#/components/schemas/JsonSuccess'
                - properties:
                    enable_desktop_notifications:
                      type: boolean
                      description: |
                        The setting for `enable_desktop_notifications`, if it was changed in
                        this request.
                    enable_digest_emails:
                      type: boolean
                      description: |
                        The setting for `enable_digest_emails`, if it was changed in this
                        request.
                    enable_offline_email_notifications:
                      type: boolean
                      description: |
                        The setting for `enable_offline_email_notifications`, if it was changed
                        in this request.
                    enable_offline_push_notifications:
                      type: boolean
                      description: |
                        The setting for `enable_offline_push_notifications`, if it was changed
                        in this request.
                    enable_online_push_notifications:
                      type: boolean
                      description: |
                        The setting for `enable_online_push_notifications`, if it was changed in
                        this request.
                    enable_sounds:
                      type: boolean
                      description: |
                        The setting for `enable_sounds`, if it was changed in this request.
                    enable_stream_email_notifications:
                      type: boolean
                      description: |
                        The setting for `enable_stream_email_notifications`, if it was changed
                        in this request.
                    enable_stream_push_notifications:
                      type: boolean
                      description: |
                        The setting for `enable_stream_push_notifications`, if it was changed in
                        this request.
                    enable_stream_audible_notifications:
                      type: boolean
                      description: |
                        The setting for `enable_stream_audible_notifications`, if it was changed
                        in this request.
                    message_content_in_email_notifications:
                      type: boolean
                      description: |
                        The setting for `message_content_in_email_notifications`, if it was
                        changed in this request.
                - example:
                    {
                        "enable_offline_push_notifications": true,
                        "enable_online_push_notifications": true,
                        "msg": "",
                        "result": "success"
                    }
  /streams:
    get:
      description: |
        Get all streams that the user has access to.
      parameters:
      - name: include_public
        in: query
        description: |
          Include all public streams.
        schema:
          type: boolean
          default: true
        example: false
      - name: include_subscribed
        in: query
        description: |
          Include all streams that the user is subscribed to.
        schema:
          type: boolean
          default: true
        example: false
      - name: include_all_active
        in: query
        description: |
          Include all active streams. The user must have administrative privileges
          to use this parameter.
        schema:
          type: boolean
          default: false
        example: true
      - name: include_default
        in: query
        description: |
          Include all default streams for the user's realm.
        schema:
          type: boolean
          default: false
        example: true
      - name: include_owner_subscribed
        in: query
        description: |
          If the user is a bot, include all streams that the bot's owner is
          subscribed to.
        schema:
          type: boolean
          default: false
        example: true
      responses:
        '200':
          description: Success.
          content:
            application/json:
              schema:
                allOf:
                - $ref: '#/components/schemas/JsonSuccess'
                - properties:
                    streams:
                      type: array
                      items:
                        type: object
                      description: |
                        A list of `stream` objects, which contain a `description`, a `name`,
                        their `stream_id` and whether they are `invite_only` or not.
                - example:
                    {
                        "msg": "",
                        "result": "success",
                        "streams": [
                            {
                                "description": "A Scandinavian country",
                                "invite_only": false,
                                "name": "Denmark",
                                "stream_id": 1
                            },
                            {
                                "description": "Yet another Italian city",
                                "invite_only": false,
                                "name": "Rome",
                                "stream_id": 2
                            },
                            {
                                "description": "Located in the United Kingdom",
                                "invite_only": false,
                                "name": "Scotland",
                                "stream_id": 3
                            },
                            {
                                "description": "A northeastern Italian city",
                                "invite_only": false,
                                "name": "Venice",
                                "stream_id": 4
                            },
                            {
                                "description": "A city in Italy",
                                "invite_only": false,
                                "name": "Verona",
                                "stream_id": 5
                            },
                            {
                                "description": "New stream for testing",
                                "invite_only": false,
                                "name": "new stream",
                                "stream_id": 6
                            }
                        ]
                    }
        '400':
          description: Bad request.
          content:
            application/json:
              schema:
                allOf:
                - $ref: '#/components/schemas/CodedError'
                - example:
                    {
                        "code": "BAD_REQUEST",
                        "msg": "User not authorized for this query",
                        "result": "error"
                    }
  /streams/{stream_id}:
    delete:
      description: |
        Delete the stream with the given ID.
      operationId: zerver.views.streams.deactivate_stream_backend
      parameters:
      - $ref: '#/components/parameters/StreamIdInPath'
      responses:
        '200':
          description: Success.
          content:
            application/json:
              schema:
                allOf:
                - $ref: '#/components/schemas/JsonSuccess'
                - example:
                      {
                          "msg": "",
                          "result": "success"
                      }
        '400':
          description: Bad request.
          content:
            application/json:
              schema:
                allOf:
                - $ref: '#/components/schemas/JsonError'
                - properties:
                    msg:
                      type: string
                - example:
                    {
                        "code": "BAD_REQUEST",
                        "msg": "Invalid stream id",
                        "result": "error"
                    }
    patch:
      description: |
        Update the stream with the given ID.
      operationId: zerver.views.streams.update_stream_backend
      parameters:
      - $ref: '#/components/parameters/StreamIdInPath'
      - name: description
        in: query
        description: |
          The new description for the stream.
        schema:
          type: string
          format: json
        example: "This stream is related to football dicsussions."
        required: false
      - name: new_name
        in: query
        description: |
          The new name for the stream.
        schema:
          type: string
          format: json
        example: "Italy"
        required: false
      - name: is_private
        in: query
        description: |
          Change whether the stream is a private stream.
        schema:
          type: boolean
        example: true
        required: false
      - name: is_announcement_only
        in: query
        description: |
          Whether the stream is limited to announcements.

          **Changes**: Deprecated in Zulip 2.2, use `stream_post_policy` instead.
        schema:
          type: boolean
        example: true
        required: false
      - name: stream_post_policy
        in: query
        description: |
          Policy for which users can post messages to the stream.

          * 1 => Any user can post.
          * 2 => Only administrators can post.
          * 3 => Only new members can post.

          **Changes**: New in Zulip 2.2, replacing the previous `is_announcement_only`
          boolean.
        schema:
          type: integer
        example: 2
        required: false
      - name: history_public_to_subscribers
        in: query
        description: |
          Whether subscribers have access to full stream history, even before they joined
          the stream.
        schema:
          type: boolean
        example: true
        required: false


      responses:
        '200':
          description: Success.
          content:
            application/json:
              schema:
                allOf:
                - $ref: '#/components/schemas/JsonSuccess'
                - example:
                      {
                          "msg": "",
                          "result": "success"
                      }
        '400':
          description: Bad request.
          content:
            application/json:
              schema:
                allOf:
                - $ref: '#/components/schemas/JsonError'
                - example:
                    {
                        "code": "BAD_REQUEST",
                        "msg": "Invalid stream id",
                        "result": "error"
                    }
  /typing:
    post:
      description: |
        Send an event indicating that the user has started or stopped typing on
        their client.
      parameters:
      - name: op
        in: query
        description: |
          Whether the user has started (`start`) or stopped (`stop`) to type.
        schema:
          type: string
          enum:
          - start
          - stop
        example: start
        required: true
      - name: to
        in: query
        description: |
          The user_ids of the recipients of the message being typed. Typing
          notifications are only supported for private messages. Send a
          JSON-encoded list of user_ids. (Use a list even if there is only one
          recipient.).

          **Changes**: Before Zulip 2.0, this parameter accepted only a JSON-encoded
          list of email addresses.  The email address-based format is deprecated
          and will be removed in Zulip 2.2.
        schema:
          type: array
          items:
            type: integer
        example: [9, 10]
        required: true
      responses:
        '200':
          description: Success.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/JsonSuccess'

  /user_groups/create:
    post:
      description: |
        Create a user group.
      parameters:
      - name: name
        in: query
        description: |
          The name of the user group.
        schema:
          type: string
        example: marketing
        required: true
      - name: description
        in: query
        description: |
          The description of the user group.
        schema:
          type: string
        example: The marketing team.
        required: true
      - name: members
        in: query
        description: |
          An array containing the user IDs of the initial members for the
          new user group.
        schema:
          type: array
          items:
            type: integer
        example: [1, 2, 3, 4]
        required: true
      responses:
        '200':
          description: Success.
          content:
            application/json:
              schema:
                allOf:
                - $ref: '#/components/schemas/JsonSuccess'
                - example:
                      {
                          "msg": "",
                          "result": "success"
                      }
        '400':
          description: Bad request.
          content:
            application/json:
              schema:
                allOf:
                - $ref: '#/components/schemas/JsonError'
                - example:
                    {
                      "result": "error",
                      "code": "BAD_REQUEST",
                      "msg": "Invalid user ID: 500"
                    }
  /user_groups/{group_id}:
    patch:
      description: |
        Update the user group.
      parameters:
      - $ref: '#/components/parameters/GroupId'
      - name: name
        in: query
        description: |
          The new name of the group.
        schema:
          type: string
        example: marketing team
        required: true
      - name: description
        in: query
        description: |
          The new description of the group.
        schema:
          type: string
        example: The marketing team.
        required: true
      responses:
        '200':
          $ref: '#/components/responses/SimpleSuccess'

        '400':
          description: Bad request.
          content:
            application/json:
              schema:
                allOf:
                - $ref: '#/components/schemas/JsonError'
                - example:
                    {
                        "code": "BAD_REQUEST",
                        "msg": "Invalid user group",
                        "result": "error"
                    }
    delete:
      description: |
        Delete the user group.
      parameters:
      - $ref: '#/components/parameters/GroupId'
      responses:
        '200':
          description: Success.
          content:
            application/json:
              schema:
                allOf:
                - $ref: '#/components/schemas/JsonSuccess'
                - example:
                      {
                          "result": "success",
                          "msg": "",
                      }

        '400':
          description: Bad request.
          content:
            application/json:
              schema:
                allOf:
                - $ref: '#/components/schemas/JsonError'
                - example:
                    {
                        "code": "BAD_REQUEST",
                        "msg": "Invalid user group",
                        "result": "error"
                    }

  /user_groups:
    get:
      description: |
        Get all user groups of the realm.
      responses:
        '200':
          description: Success.
          content:
            application/json:
              schema:
                allOf:
                - $ref: '#/components/schemas/JsonSuccess'
                - properties:
                    user_groups:
                      type: array
                      items:
                        type: object
                      description: |
                        A list of `user_group` objects, which contain a `description`, a `name`,
                        their `id` and the list of members of the user group.
                - example:
                    {
                        "msg": "",
                        "result": "success",
                        "user_groups": [
                            {
                                "description": "Characters of Hamlet",
                                "id": 1,
                                "name": "hamletcharacters",
                                "members": [3, 4]
                            },
                            {
                                "description": "Other users",
                                "id": 2,
                                "name": "other users",
                                "members": [1, 2]
                            }
                        ]
                    }
  /real-time:
    # This entry is a hack; it exists to give us a place to put the text
    # documenting the arguments for call_on_each_event and friends.
    post:
      description: |
        (Ignored)
      parameters:
      - $ref: '#/components/parameters/Narrow'
      - $ref: '#/components/parameters/Event_types'
        example: event_types=['message']
      security:
      - basicAuth: []
      responses:
      # Makeshift response for this hack entry.
       '200':
         description: Success
  /rest-error-handling:
    post:
      description: |
        Common error to many endpoints
      responses:
        '400':
          description: |
            Bad request.
          content:
            application/json:
              schema:
                oneOf:
                - allOf:
                  - $ref: '#/components/schemas/InvalidApiKeyError'
                - allOf:
                  - $ref: '#/components/schemas/MissingArgumentError'
                - allOf:
                  - $ref: '#/components/schemas/UserNotAuthorizedError'
  /zulip-outgoing-webhook:
    post:
      description: |
        Outgoing Webhooks allows to build or set up Zulip integrations which are
        notified when certain types of messages are sent in Zulip.
      responses:
        '200':
          description: |
            Success
          content:
            application/json:
              schema:
                allOf:
                - $ref: '#/components/schemas/JsonSuccess'
                - properties:
                    data:
                      type: string
                      description: |
                        It contains the content of the message (in Markdown).
                    trigger:
                      type: string
                      description: |
                        It contains the trigger method.
                    token:
                      type: string
                      description: |
                        A string of alphanumeric characters that can be use to authenticate the
                        webhook request (each bot user uses a fixed token).
                    message:
                      type: object
                      description: |
                        A dict containing details on the message which triggered the outgoing
                        webhook
                    bot_email:
                      type: string
                      description: |
                        Email of the bot user
                - example:
                    {
                        "data": "@**Outgoing Webhook Test** Zulip is the world\u2019s most productive group chat!",
                        "trigger": "mention",
                        "token": "xvOzfurIutdRRVLzpXrIIHXJvNfaJLJ0",
                        "message": {
                            "subject": "Verona2",
                            "sender_email": "iago@zulip.com",
                            "timestamp": 1527876931,
                            "client": "website",
                            "submessages": [

                            ],
                            "recipient_id": 20,
                            "topic_links": [

                            ],
                            "sender_full_name": "Iago",
                            "avatar_url": "https://secure.gravatar.com/avatar/1f4f1575bf002ae562fea8fc4b861b09?d=identicon&version=1",
                            "rendered_content": "<p><span class=\"user-mention\" data-user-id=\"25\">@Outgoing Webhook Test</span> Zulip is the world\u2019s most productive group chat!</p>",
                            "sender_id": 5,
                            "stream_id": 5,
                            "content": "@**Outgoing Webhook Test** Zulip is the world\u2019s most productive group chat!",
                            "display_recipient": "Verona",
                            "type": "stream",
                            "id": 112,
                            "is_me_message": false,
                            "reactions": [

                            ],
                            "sender_realm_str": "zulip",
                            "sender_short_name": "iago"
                        },
                        "bot_email": "outgoing-bot@localhost"
                    }

components:
  #######################
  # Security definitions
  #######################
  securitySchemes:
    BasicAuth:
      type: http
      scheme: basic
      description: |
        Basic authentication, with the user's email as the username, and the API
        key as the password. The API key can be fetched using the
        `/fetch_api_key` or `/dev_fetch_api_key` endpoints.

  schemas:
    JsonResponse:
      type: object
      properties:
        result:
          type: string
    JsonSuccess:
      allOf:
      - $ref: '#/components/schemas/JsonResponse'
      - required:
        - result
        - msg
      - properties:
          result:
            enum:
            - success
          msg:
            type: string
      - example:
          {
            "msg": "",
            "result": "success"
          }
    JsonError:
      allOf:
      - $ref: '#/components/schemas/JsonResponse'
      - required:
        - result
        - msg
      - properties:
          result:
            enum:
            - error
          msg:
            type: string
    ApiKeyResponse:
      allOf:
      - $ref: '#/components/schemas/JsonSuccess'
      - required:
        - api_key
        - email
      - properties:
          api_key:
            type: string
            description: |
              The API key that can be used to authenticate as the requested user.
          email:
            type: string
            description: |
              The email address of the user who owns the API key.
      - example:
          {
              "api_key": "gjA04ZYcqXKalvYMA8OeXSfzUOLrtbZv",
              "email": "iago@zulip.com",
              "msg": "",
              "result": "success"
          }
    CodedError:
      allOf:
      - $ref: '#/components/schemas/JsonError'
      - properties:
          code:
            type: string
            description: |
              A string that identifies the error.
    BadEventQueueIdError:
      allOf:
      - $ref: '#/components/schemas/CodedError'
      - properties:
          queue_id:
            type: string
            description: |
              The string that identifies the invalid event queue.
      - example:
          {
              "code": "BAD_EVENT_QUEUE_ID",
              "msg": "Bad event queue id: 1518820930:1",
              "queue_id": "1518820930:1",
              "result": "error"
          }
    InvalidMessageError:
      allOf:
      - $ref: '#/components/schemas/JsonSuccess'
      - properties:
          raw_content:
            type: string
            description: |
              The raw content of the message.
      - example:
          {
              "msg": "Invalid message(s)",
              "code": "BAD_REQUEST",
              "result": "error"
          }
    NonExistingStreamError:
      allOf:
        - $ref: '#/components/schemas/CodedError'
        - properties:
            stream:
              type: string
              description: |
                The name of the stream that could not be found.
        - example:
            {
                "code": "STREAM_DOES_NOT_EXIST",
                "msg": "Stream 'nonexistent_stream' does not exist",
                "result": "error",
                "stream": "nonexistent_stream"
            }
    AddSubscriptionsResponse:
      allOf:
      - $ref: '#/components/schemas/JsonSuccess'
      - properties:
          subscribed:
            type: object
            description: |
              A dictionary where the key is the email address of the user/bot and the
              value is a list of the names of the streams that were subscribed to as a
              result of the query.
          already_subscribed:
            type: object
            description: |
              A dictionary where the key is the email address of the user/bot and the
              value is a list of the names of the streams that the user/bot is already
              subscribed to.
          unauthorized:
            type: array
            items:
              type: string
            description: |
              A list of names of streams that the requesting user/bot was not
              authorized to subscribe to.
    InvalidApiKeyError:
      allOf:
      - $ref: '#/components/schemas/JsonError'
      - example:
          {
              "msg": "Invalid API key",
              "result": "error"
          }
    MissingArgumentError:
      allOf:
      - $ref: '#/components/schemas/CodedError'
      - properties:
          var_name:
            type: string
            description: |
              It contains the information about the missing argument.
      - example:
          {
              "code": "REQUEST_VARIABLE_MISSING",
              "msg": "Missing 'content' argument",
              "result": "error",
              "var_name": "content"
          }
    UserNotAuthorizedError:
      allOf:
      - $ref: '#/components/schemas/CodedError'
      - example:
          {
              "code": "BAD_REQUEST",
              "msg": "User not authorized for this query",
              "result": "error"
          }

  ###################
  # Shared responses
  ###################
  responses:
    SimpleSuccess:
      description: Success.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/JsonSuccess'

  ####################
  # Shared parameters
  ####################
  parameters:
    Event_types:
      name: event_types
      in: query
      description: |
        A JSON-encoded array indicating which types of events you're interested
        in. Values that you might find useful include:

          * **message** (messages)
          * **subscription** (changes in your subscriptions)
          * **realm_user** (changes to users in the organization and
            their properties, such as their name).

        If you do not specify this argument, you will receive all
        events, and have to filter out the events not relevant to
        your client in your client code.  For most applications, one
        is only interested in messages, so one specifies:
        `event_types=['message']`
      schema:
        type: array
        items:
          type: string
      required: false
    Narrow:
      name: narrow
      in: query
      description: |
        A JSON-encoded array of length 2 indicating the narrow for which you'd
        like to receive events for. For instance, to receive events for the
        stream `Denmark`, you would specify `narrow=['stream', 'Denmark']`.
        Another example is `narrow=['is', 'private']` for private messages.
        Default is `[]`.
      schema:
        type: array
        items:
          anyOf:
          - type: string
          - type: integer
        default: []
      example: ['stream', 'Denmark']
      required: false
    GroupId:
      name: group_id
      in: path
      description: |
        The ID of the group.
      schema:
        type: integer
      example: 42
      required: true
    Topic:
      name: topic
      in: query
      description: |
        The topic of the message. Only required for stream messages
        (`type="stream"`), ignored otherwise. Maximum length of 60
        characters.
      schema:
        type: string
      example: Castle
    QueueId:
      name: queue_id
      in: query
      description: |
        The ID of a queue that you registered via `POST /api/v1/register` (see
        [Register a queue](/api/register-queue)).
      schema:
        type: string
      example: 1375801870:2942
      required: true
    Stream:
      name: stream
      in: query
      description: |
        The name of the stream.
      schema:
        type: string
      example: Denmark
    StreamIdInQuery:
      name: stream_id
      in: query
      description: |
        The ID of the stream to access.
      schema:
        type: integer
      example: 42
    StreamIdInPath:
      name: stream_id
      in: path
      description: |
        The ID of the stream to access.
      schema:
        type: integer
      example: 42
      required: true
    ClientGravatar:
      name: client_gravatar
      in: query
      description: |
        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.
      schema:
        type: boolean
        default: false
      example: true
    Content:
      name: content
      in: query
      description: |
        The content of the message. Maximum message size of 10000 bytes.
      schema:
        type: string
      example: Hello
      required: true
    MessageId:
      name: message_id
      in: path
      description: |
        The target message's ID.
      schema:
        type: integer
      example: 42
      required: true
