From dfb9f74017f4a6e00d51883ac1b7e7d6d722c5a9 Mon Sep 17 00:00:00 2001 From: Lauryn Menard Date: Mon, 24 Jan 2022 16:55:05 +0100 Subject: [PATCH] api_docs: Add page documenting HTTP headers in the api docs. Adds a page to the general api documentation about HTTP headers, so that information about the special response headers for rate limits have a more logical location in the docs and so that other HTTP header information can be shared, such as `User-Agent` conventions. Adjusts some text and linking on the rest-error-handling page and overview page for the REST API for the addition of the HTTP headers page. --- api_docs/http-headers.md | 80 +++++++++++++++++++++++++++++++++ api_docs/rest-error-handling.md | 28 +----------- api_docs/rest.md | 7 ++- api_docs/sidebar_index.md | 1 + zerver/openapi/zulip.yaml | 5 +++ 5 files changed, 90 insertions(+), 31 deletions(-) create mode 100644 api_docs/http-headers.md diff --git a/api_docs/http-headers.md b/api_docs/http-headers.md new file mode 100644 index 0000000000..07a1f6dbf0 --- /dev/null +++ b/api_docs/http-headers.md @@ -0,0 +1,80 @@ +# HTTP headers + +This page documents the HTTP headers used by the Zulip API. + +Most important is that API clients authenticate to the server using +HTTP Basic authentication. If you're using the official [Python or +JavaScript bindings](/api/installation-instructions), this is taken +care of when you configure said bindings. + +Otherwise, see the `curl` example on each endpoint's documentation +page, which details the request format. + +Documented below are additional HTTP headers and header conventions +generally used by Zulip: + +## The `User-Agent` header + +Clients are not required to pass a `User-Agent` HTTP header, but we +highly recommend doing so when writing an integration. It's easy to do +and it can help save time when debugging issues related to an API +client. + +If provided, the Zulip server will parse the `User-Agent` HTTP header +in order to identify specific clients and integrations. This +information is used by the server for logging, [usage +statistics](/help/analytics), and on rare occasions, for +backwards-compatibility logic to preserve support for older versions +of official clients. + +Official Zulip clients and integrations use a `User-Agent` that starts +with something like `ZulipMobile/20.0.103 `, encoding the name of the +application and it's version. + +Zulip's official API bindings have reasonable defaults for +`User-Agent`. For example, the official Zulip Python bindings have a +default `User-Agent` starting with `ZulipPython/{version}`, where +`version` is the version of the library. + +You can give your bot/integration its own name by passing the `client` +parameter when initializing the Python bindings. For example, the +official Zulip Nagios integration is initialized like this: + +``` python +client = zulip.Client( + config_file=opts.config, client=f"ZulipNagios/{VERSION}" +) +``` + +If you are working on an integration that you plan to share outside +your organization, you can get help picking a good name in +`#integrations` in the [Zulip development +community](https://zulip.com/development-community). + +## Rate-limiting response headers + +To help clients avoid exceeding rate limits, Zulip sets the following +HTTP headers in all API responses: + +* `X-RateLimit-Remaining`: The number of additional requests of this + type that the client can send before exceeding its limit. +* `X-RateLimit-Limit`: The limit that would be applicable to a client + that had not made any recent requests of this type. This is useful + for designing a client's burst behavior so as to avoid ever reaching + a rate limit. +* `X-RateLimit-Reset`: The time at which the client will no longer + have any rate limits applied to it (and thus could do a burst of + `X-RateLimit-Limit` requests). + +[Zulip's rate limiting rules are configurable][rate-limiting-rules], +and can vary by server and over time. The default configuration +currently limits: + +* Every user is limited to 200 total API requests per minute. +* Separate, much lower limits for authentication/login attempts. + +When the Zulip server has configured multiple rate limits that apply +to a given request, the values returned will be for the strictest +limit. + +[rate-limiting-rules]: https://zulip.readthedocs.io/en/latest/production/security-model.html#rate-limiting diff --git a/api_docs/rest-error-handling.md b/api_docs/rest-error-handling.md index 1776ce4c5b..9191b223d5 100644 --- a/api_docs/rest-error-handling.md +++ b/api_docs/rest-error-handling.md @@ -14,37 +14,11 @@ for specific error conditions, since the `msg` strings are internationalized (e.g. the server will send the error message translated into French if the user has a French locale). -Each endpoint documents its own unique errors; below, we document +Each endpoint documents its own unique errors; documented below are errors common to many endpoints: {generate_code_example|/rest-error-handling:post|fixture} -To help clients avoid exceeding rate limits, Zulip sets the following -HTTP headers in all API responses: - -* `X-RateLimit-Remaining`: The number of additional requests of this - type that the client can send before exceeding its limit. -* `X-RateLimit-Limit`: The limit that would be applicable to a client - that had not made any recent requests of this type. This is useful - for designing a client's burst behavior so as to avoid ever reaching - a rate limit. -* `X-RateLimit-Reset`: The time at which the client will no longer - have any rate limits applied to it (and thus could do a burst of - `X-RateLimit-Limit` requests). - -[Zulip's rate limiting rules are configurable][rate-limiting-rules], -and can vary by server and over time. The default configuration -currently limits: - -* Every user is limited to 200 total API requests per minute. -* Separate, much lower limits for authentication/login attempts. - -When the Zulip server has configured multiple rate limits that apply -to a given request, the values returned will be for the strictest -limit. - -[rate-limiting-rules]: https://zulip.readthedocs.io/en/latest/production/security-model.html#rate-limiting - ## Ignored Parameters In JSON success responses, all Zulip REST API endpoints may return diff --git a/api_docs/rest.md b/api_docs/rest.md index 3e8fca7867..755b6e7593 100644 --- a/api_docs/rest.md +++ b/api_docs/rest.md @@ -10,10 +10,9 @@ you can do in Zulip, you can do with Zulip's REST API. To use this API: * Choose what language you'd like to use. You can download the [Python or JavaScript bindings](/api/installation-instructions), projects in [other languages](/api/client-libraries), or - just make HTTP requests with your favorite programming language. If - you're making your own HTTP requests, you'll want to send the - appropriate HTTP basic authentication headers; see each endpoint's - `curl` option for details on the request format. + just make HTTP requests with your favorite programming language. +* If you're making your own HTTP requests, you'll want to send the + appropriate [HTTP basic authentication headers](/api/http-headers). * The Zulip API has a standard [system for reporting errors](/api/rest-error-handling). diff --git a/api_docs/sidebar_index.md b/api_docs/sidebar_index.md index a9c0778f40..ee73201036 100644 --- a/api_docs/sidebar_index.md +++ b/api_docs/sidebar_index.md @@ -18,6 +18,7 @@ * [Installation instructions](/api/installation-instructions) * [API keys](/api/api-keys) * [Configuring the Python bindings](/api/configuring-python-bindings) +* [HTTP headers](/api/http-headers) * [Error handling](/api/rest-error-handling) * [Roles and permissions](/api/roles-and-permissions) * [Client libraries](/api/client-libraries) diff --git a/zerver/openapi/zulip.yaml b/zerver/openapi/zulip.yaml index 8fe2e1a672..40aadad629 100644 --- a/zerver/openapi/zulip.yaml +++ b/zerver/openapi/zulip.yaml @@ -17432,10 +17432,15 @@ components: The `retry-after` parameter in the response indicates how many seconds the client must wait before making additional requests. + Zulip sets a few [HTTP response headers][rate-limit-headers] + to help with preventing rate limit errors. + **Changes**: The `code` field was not present in rate limit errors before Zulip 4.0 (feature level 36). A typical failed JSON response for when a rate limit is exceeded: + + [rate-limit-headers]: /api/http-headers#rate-limiting-response-headers RealmDeactivatedError: allOf: - $ref: "#/components/schemas/CodedError"