Error handling

Zulip's API will always return a JSON format response. The HTTP status code indicates whether the request was successful (200 = success, 4xx = user error, 5xx = server error).

Every response, both success and error responses, will contain at least two keys:

  • msg: an internationalized, human-readable error message string.

  • result: either "error" or "success", which is redundant with the HTTP status code, but is convenient when print debugging.

Every error response will also contain an additional key:

  • code: a machine-readable error string, with a default value of "BAD_REQUEST" for general errors.

Clients should always check code, rather than msg, when looking for specific error conditions. The string values for msg are internationalized (e.g., the server will send the error message translated into French if the user has a French locale), so checking those strings will result in buggy code.

If a client needs information that is only present in the string value of msg for a particular error response, then the developers implementing the client should start a conversation here in order to discuss getting a specific error code and/or relevant additional key/value pairs for that error response.

In addition to the keys described above, some error responses will contain other keys with further details that are useful for clients. The specific keys present depend on the error code, and are documented at the API endpoints where these particular errors appear.

Changes: Before Zulip 5.0 (feature level 76), all error responses did not contain a code key, and its absence indicated that no specific error code had been allocated for that error.

Common error responses

Documented below are some error responses that are common to many endpoints:

Invalid API key

A typical failed JSON response for when the API key is invalid.

{
    "code": "INVALID_API_KEY",
    "msg": "Invalid API key",
    "result": "error"
}

Missing request parameter

A typical failed JSON response for when a required request parameter is not supplied.

The value of var_name contains information about the missing parameter.

{
    "code": "REQUEST_VARIABLE_MISSING",
    "msg": "Missing 'content' argument",
    "result": "error",
    "var_name": "content"
}

Incompatible request parameters

A typical failed JSON response for when two or more, optional parameters are supplied that are incompatible with each other.

The value of parameters in the response is string containing the parameters, separated by commas, that are incompatible.

{
    "code": "BAD_REQUEST",
    "msg": "Unsupported parameter combination: object_id, object_name",
    "parameters": "object_id, object_name",
    "result": "error"
}

User not authorized for query

A typical failed JSON response for when the user is not authorized for a query.

{
    "code": "BAD_REQUEST",
    "msg": "User not authorized for this query",
    "result": "error"
}

User account deactivated

A typical failed json response for when user's account is deactivated.

Changes: As of Zulip 5.0 (feature level 76), these errors use the HTTP 401 status code. Before this feature level, they used the HTTP 403 status code.

{
    "code": "USER_DEACTIVATED",
    "msg": "Account is deactivated",
    "result": "error"
}

Realm deactivated

A typical failed json response for when user's organization is deactivated.

Changes: As of Zulip 5.0 (feature level 76), these errors use the HTTP 401 status code. Before this feature level, they used the HTTP 403 status code.

{
    "code": "REALM_DEACTIVATED",
    "msg": "This organization is deactivated",
    "result": "error"
}

Rate limit exceeded

A typical failed JSON response for when a rate limit is exceeded. Zulip sets a few HTTP response headers to help with preventing rate limit errors.

The value of retry-after in the response indicates how many seconds the client must wait before making additional requests.

Changes: Before Zulip 4.0 (feature level 36), the code key was not present in rate limit errors.

{
    "code": "RATE_LIMIT_HIT",
    "msg": "API usage exceeded rate limit",
    "result": "error",
    "retry-after": 28.706807374954224
}

Ignored Parameters

In JSON success responses, all Zulip REST API endpoints may return an array of parameters sent in the request that are not supported by that specific endpoint.

While this can be expected, e.g., when sending both current and legacy names for a parameter to a Zulip server of unknown version, this often indicates either a bug in the client implementation or an attempt to configure a new feature while connected to an older Zulip server that does not support said feature.

Changes: The ignored_parameters_unsupported array was added as a possible return value for all REST API endpoint JSON success responses in Zulip 7.0 (feature level 167).

Previously, it was added to POST /users/me/subscriptions/properties in Zulip 5.0 (feature level 111) and to PATCH /realm/user_settings_defaults in Zulip 5.0 (feature level 96). The feature was introduced in Zulip 5.0 (feature level 78) as a return value for the PATCH /settings endpoint.

A typical successful JSON response with ignored parameters may look like:

{
    "ignored_parameters_unsupported": [
        "invalid_param_1",
        "invalid_param_2"
    ],
    "msg": "",
    "result": "success"
}