To start using the Jellyfin API, authorization is probably the first thing you'll need to do. Jellyfin's authorization options can be a bit confusing because there are a lot of deprecated options.
Generally there are three ways to authenticate: no authorization, user authorization with an access token or authorization with an API key. The first way is easy, just do nothing. But most often you'll need to use either the access token or API key.
There are multiple methods for transmitting authorization values, however, some are outdated and scheduled to be removed.
It's recommend to use the Authorization header. If header auth isn't an option, the token may be sent through the ApiKey query parameter. Sending secure data in a query parameter is unsafe as the changes of it leaking (via logs, copy-paste actions or by other means) are high. Only use this method as a last resort.
| Type | Name | Method | Deprecated |
|---|---|---|---|
| Header | Authorization |
Schema | No |
| Query | ApiKey |
Token only | No, but discouraged |
| Query | api_key |
Token only | yes |
| Header | X-Emby-Token |
Token only | yes |
| Header | X-MediaBrowser-Token |
Token only | yes |
| Header | X-Emby-Authorization |
Schema | yes |
Avoid sending multiple tokens in one request as it's uncertain which value will be used. Deprecated options might be removed in future server updates.
Starting with Jellyfin 10.11, it is now possible to disable legacy authorization methods that are scheduled for removal in a future release. This option is primarily intended for developers who wish to test their client compatibility and is not recommended for regular users.
To disable deprecated methods, edit the system.xml configuration file and change:
<EnableLegacyAuthorization>true</EnableLegacyAuthorization>to:
<EnableLegacyAuthorization>false</EnableLegacyAuthorization>After making this change, restart your Jellyfin server for it to take effect.
Note: Not all official Jellyfin clients are currently compatible with legacy authorization disabled.
The Authorization header uses the format Authorization: <scheme> <parameters>. The Jellyfin scheme is named MediaBrowser and it uses named values separated by commas. There is no specific order for parameters. All keys are case sensitive and only allow alphanumeric characters. Unknown keys are ignored by the server. Values must be wrapped in double quotes (") and should use url encoding.
MediaBrowser key="value", key2="value2", key3="value3"| Key | Description |
|---|---|
| Token | The access token or API key |
| Client | The name of the client |
| Version | The version of the client |
| DeviceId | A unique id for the device generated by the client |
| Device | The device name |
The token parameter is required to use authenticated endpoints. The client and version properties are used to identify the client in the dashboard.
When it comes to device identifiers in the Jellyfin API, it's important to understand the nuances involved. While generating a random string for the deviceId might seem like a straightforward solution, there are certain limitations to consider. Currently, the server permits only a single access token for each deviceId. This means that you cannot have multiple users signed into your client with a single randomized string. To work around this limitation, you'll need to use a unique identifier for each combination of a device-specific identifier and user-specific identifier.
Since it's often not possible to know the user identifier before signing in at least once, we recommend including the username as user-specific identifier. It is advisable to hash the username because it is user-input that could include double quotes (escaping the header value format) or special characters that your HTTP library might not allow.
Here are a couple of examples for the authorization header:
-
Authorize with API key
Authorization: MediaBrowser Token="8ac3a7abaff943ba9adea7f8754da7f8" -
Authorize with access token
Authorization: MediaBrowser Token="0381cf931f9e42d79fb9c89f729167df", Client="Android TV", Device="Nvidia Shield", DeviceId="ZQ9YQHHrUzk24vV", Version="0.15.3" -
Authorize with client information only
Authorization: MediaBrowser Client="Android TV", Device="Nvidia Shield", DeviceId="ZQ9YQHHrUzk24vV", Version="0.15.3"
Use the ApiKey query parameter when the Authorization header can't be used. The value of the query parameter is the access token or API key. Avoid using this option if possible. Never use the ApiKey query parameter and the Authorization header at the same time.
A note about Apple platforms:
I was initially reluctant to use the
Authorizationheader on macOS and iOS because Apple's API docs state that this header is reserved for exclusive use by the operating system and is discouraged for use by app developers.With the apparently imminent removal of all of Jellyfin's deprecated options, that only leaves
ApiKeyas an option, which does not support the full schema. That said, Jellyfin is far from the only server API that requires use of a customAuthorizationheader, and as such it is a very common problem faced by iOS app developers.Since launching my app several months ago, I have been using
Authorization, in accordance with Jellyfin's advice and against Apple's advice, and have not observed any problems so far. Even so, I wish Jellyfin would consider offering an alternative header like the deprecatedX-Emby-Authorization, in case it becomes apparent that it may be causing problems on Apple platforms.I acknowledge that it should not be the job of the Jellyfin project to work around Apple's unusual and frankly ill-conceived API design choices. Unfortunately, as app developers, we are simply caught in the middle between two situations we can't do much of anything about.