### Run Quickstart Example Source: https://github.com/latias94/jellyfin-sdk/blob/main/README.md This command executes the jellyfin-sdk's quickstart example, allowing you to test basic functionality with provided server URL, token, and an option to list views. ```bash cargo run --example quickstart -- --url http://localhost:8096 --token --list-views ``` -------------------------------- ### Basic Jellyfin Client Usage Source: https://github.com/latias94/jellyfin-sdk/blob/main/README.md Demonstrates how to initialize the JellyfinClient, set authentication token, and make a basic API call to get public server information. Requires the server URL and an access token. ```rust use jellyfin_sdk::JellyfinClient; # async fn demo() -> jellyfin_sdk::Result<()> { let client = JellyfinClient::builder("http://localhost:8096")? .client_name("my-app") .device_name("rust") .build()?; client.set_token("your_access_token"); let info = client.system().get_public_info().await?; println!("server={{:?}} version={{:?}}", info.server_name, info.version); # Ok(()) # } ``` -------------------------------- ### Query Jellyfin System Information (Rust) Source: https://context7.com/latias94/jellyfin-sdk/llms.txt Provides examples for retrieving public system information from a Jellyfin server without requiring authentication. It demonstrates fetching server details like name, version, and product name, as well as performing a simple ping to check server responsiveness. ```rust use jellyfin_sdk::JellyfinClient; #[tokio::main] async fn main() -> jellyfin_sdk::Result<()> { let client = JellyfinClient::new("http://localhost:8096")?; // Get public server info (no auth required) let info = client.system().get_public_info().await?; println!("Server: {:?}", info.server_name); println!("Version: {:?}", info.version); println!("Product Name: {:?}", info.product_name); println!("Startup Wizard Completed: {:?}", info.startup_wizard_completed); // Ping the server let pong = client.system().ping().await?; println!("Ping response: {}", pong); Ok(()) } ``` -------------------------------- ### Authenticate Jellyfin Users and Manage Tokens (Rust) Source: https://context7.com/latias94/jellyfin-sdk/llms.txt Shows how to authenticate users with Jellyfin using their username and password. It covers both automatic token setting upon successful authentication and manual token management. The example also demonstrates retrieving current user information after authentication. ```rust use jellyfin_sdk::JellyfinClient; #[tokio::main] async fn main() -> jellyfin_sdk::Result<()> { let client = JellyfinClient::builder("http://localhost:8096")? .client_name("my-app") .device_name("rust") .build()?; // Authenticate and automatically set the token for subsequent requests let auth = client .user() .authenticate_by_name_and_set_token("username", "password") .await?; println!("Logged in! Access token present: {}", auth.access_token.is_some()); println!("User ID: {:?}", auth.user.as_ref().and_then(|u| u.id)); // Get current user info let me = client.user().me().await?; println!("Current user: {:?} (ID: {:?})", me.name, me.id); // Alternative: manual token management let auth_result = client.user().authenticate_by_name("username", "password").await?; if let Some(token) = auth_result.access_token { client.set_token(token); } Ok(()) } ``` -------------------------------- ### Plugins API Source: https://github.com/latias94/jellyfin-sdk/blob/main/docs/ALIGNMENT.md Endpoints for managing plugins, including installation, uninstallation, configuration, and enabling/disabling. ```APIDOC ## GET /Plugins ### Description Retrieves a list of installed plugins. ### Method GET ### Endpoint /Plugins ### Parameters None ### Request Example None ### Response #### Success Response (200) - **Plugins** (array) - A list of installed plugins. #### Response Example ```json { "Plugins": [ { "Id": "plugin-id-1", "Name": "Example Plugin", "Version": "1.0.0" } ] } ``` ## DELETE /Plugins/{pluginId} ### Description Uninstalls a plugin. ### Method DELETE ### Endpoint /Plugins/{pluginId} ### Parameters #### Path Parameters - **pluginId** (string) - Required - The ID of the plugin to uninstall. ### Request Example None ### Response #### Success Response (200) - **Message** (string) - Confirmation of the uninstallation. #### Response Example ```json { "Message": "Plugin uninstalled successfully." } ``` ## GET /Plugins/{pluginId}/Configuration ### Description Retrieves the configuration for a specific plugin. ### Method GET ### Endpoint /Plugins/{pluginId}/Configuration ### Parameters #### Path Parameters - **pluginId** (string) - Required - The ID of the plugin. ### Request Example None ### Response #### Success Response (200) - **Configuration** (object) - The plugin's configuration. #### Response Example ```json { "Configuration": { "Setting1": "value1" } } ``` ## POST /Plugins/{pluginId}/Configuration ### Description Updates the configuration for a specific plugin. ### Method POST ### Endpoint /Plugins/{pluginId}/Configuration ### Parameters #### Path Parameters - **pluginId** (string) - Required - The ID of the plugin. #### Request Body - ``` -------------------------------- ### Low-Level Jellyfin API Request Source: https://github.com/latias94/jellyfin-sdk/blob/main/README.md Shows how to make raw HTTP requests to the Jellyfin API using the client when a specific endpoint is not yet wrapped by the SDK. Supports GET, POST with JSON, and streaming downloads. ```rust // For raw GET requests: // client.request(Method::GET, "/Some/Path")?; // For typed JSON requests: // client.send_json(...); // For streaming downloads: // client.execute(...); ``` -------------------------------- ### Manage Subtitles with Jellyfin SDK (Rust) Source: https://context7.com/latias94/jellyfin-sdk/llms.txt Demonstrates how to search, download, upload, and delete subtitles using the Jellyfin SDK in Rust. It includes examples for searching remote subtitles, attaching them to items, downloading subtitle streams to files, uploading external subtitles, and deleting existing ones. It also shows how to retrieve fallback fonts for subtitle rendering. ```rust use jellyfin_sdk::{ JellyfinClient, models::{PlaybackInfoRequest, SubtitleFormat, SubtitleStreamQuery, UploadSubtitleRequest}, }; use uuid::Uuid; #[tokio::main] async fn main() -> jellyfin_sdk::Result<()> { let client = JellyfinClient::builder("http://localhost:8096")? .client_name("my-app") .device_name("rust") .build()?; client.set_token("your_token"); let user_id = client.user().me().await?.id.unwrap(); let item_id = Uuid::parse_str("00000000-0000-0000-0000-000000000000").unwrap(); // Search for remote subtitles let results = client .subtitles() .search_remote_subtitles(item_id, "eng", Some(false)) .await?; for sub in &results { println!( "Subtitle: {:?} ({:?}) - {} downloads", sub.name, sub.provider_name, sub.download_count.unwrap_or(0) ); } // Download and attach a remote subtitle to the item if let Some(subtitle) = results.first() { if let Some(sub_id) = &subtitle.id { client .subtitles() .download_remote_subtitle(item_id, sub_id) .await?; println!("Attached subtitle to item"); } } // Download subtitle stream to file let playback = client .items() .post_playback_info(item_id, PlaybackInfoRequest::new().user_id(user_id)) .await?; client .subtitles() .download_subtitle_from_playback_info_to_file( item_id, &playback, 0, // subtitle index SubtitleFormat::Srt, SubtitleStreamQuery::new(), "subtitle.srt", ) .await?; // Upload external subtitle client .subtitles() .upload_subtitle_from_file( item_id, "eng", "srt", false, // is_forced false, // is_hearing_impaired "my_subtitle.srt", ) .await?; // Delete subtitle client.subtitles().delete_subtitle(item_id, 2).await?; // Get fallback fonts for subtitle rendering let fonts = client.subtitles().get_fallback_font_list().await?; for font in fonts { println!("Font: {:?} ({:?} bytes)", font.name, font.size); } Ok(()) } ``` -------------------------------- ### Handle Jellyfin SDK Errors Source: https://context7.com/latias94/jellyfin-sdk/llms.txt Illustrates how to gracefully handle various errors that can occur when using the Jellyfin SDK. It covers API-specific errors (like authentication, not found, rate limiting), HTTP errors (timeouts, connection failures), JSON parsing errors, and other general errors. The example uses a `match` statement to differentiate error types and provides specific recovery messages. Dependencies include `jellyfin_sdk`, `reqwest`, and `tokio`. ```rust use jellyfin_sdk::{Error, JellyfinClient}; use reqwest::StatusCode; #[tokio::main] async fn main() { let client = JellyfinClient::new("http://localhost:8096").unwrap(); match client.user().me().await { Ok(user) => println!("Logged in as: {:?}", user.name), Err(Error::Api { status, body, retry_after_seconds }) => { match status { StatusCode::UNAUTHORIZED => { println!("Authentication required or token expired"); } StatusCode::NOT_FOUND => { println!("Resource not found"); } StatusCode::TOO_MANY_REQUESTS => { if let Some(secs) = retry_after_seconds { println!("Rate limited, retry after {} seconds", secs); } } _ => { println!("API error {}: {}", status, body); } } } Err(Error::Http(e)) => { if e.is_timeout() { println!("Request timed out"); } else if e.is_connect() { println!("Connection failed - server unreachable"); } else { println!("HTTP error: {}", e); } } Err(Error::Json(e)) => { println!("Failed to parse response: {}", e); } Err(e) => { println!("Other error: {}", e); } } } ``` -------------------------------- ### Report Playback Progress with Jellyfin SDK (Rust) Source: https://context7.com/latias94/jellyfin-sdk/llms.txt Report playback start, progress, and stop events to sync watch status across devices using the Jellyfin SDK. This requires a Jellyfin client instance and item IDs. It supports both modern and legacy API styles. ```rust use jellyfin_sdk::{ JellyfinClient, api::OnPlaybackQuery, models::{PlaybackStart, PlaybackProgress, PlaybackStop, PlayMethod}, }; use uuid::Uuid; #[tokio::main] async fn main() -> jellyfin_sdk::Result<()> { let client = JellyfinClient::builder("http://localhost:8096")? .client_name("my-app") .device_name("rust") .build()?; client.set_token("your_token"); let item_id = Uuid::parse_str("00000000-0000-0000-0000-000000000000").unwrap(); // Report playback started (modern API) client .playstate() .report_playback_start(PlaybackStart { item_id: Some(item_id), media_source_id: Some("media_source_id".to_string()), play_session_id: Some("session_123".to_string()), can_seek: Some(true), ..Default::default() }) .await?; // Report progress periodically client .playstate() .report_playback_progress(PlaybackProgress { item_id: Some(item_id), position_ticks: Some(300_000_000), // 30 seconds is_paused: Some(false), play_session_id: Some("session_123".to_string()), ..Default::default() }) .await?; // Keep session alive client.playstate().ping_playback_session("session_123").await?; // Report playback stopped client .playstate() .report_playback_stopped(PlaybackStop { item_id: Some(item_id), position_ticks: Some(600_000_000), // 60 seconds play_session_id: Some("session_123".to_string()), ..Default::default() }) .await?; // Mark as fully played client.playstate().mark_played(item_id, None, None).await?; // Legacy API style client .playstate() .on_playback_start( item_id, OnPlaybackQuery::new() .media_source_id("source_id") .play_method(PlayMethod::DirectPlay) .can_seek(true), ) .await?; Ok(()) } ``` -------------------------------- ### User Data and Favorites API Source: https://context7.com/latias94/jellyfin-sdk/llms.txt This section details how to track play state, favorites, and ratings for items using the Jellyfin SDK. It includes endpoints for getting user data, marking items as played, toggling favorite status, liking/unliking items, and deleting ratings. ```APIDOC ## User Data and Favorites Track play state, favorites, and ratings for items. ### Get User Data for an Item Retrieves the user-specific data for a given item, including play state, play count, playback position, and favorite status. ### Method GET ### Endpoint `/Items/{ItemId}/UserData ### Parameters #### Path Parameters - **ItemId** (string) - Required - The ID of the item. #### Query Parameters - **UserId** (string) - Optional - The ID of the user whose data to retrieve. ### Response #### Success Response (200) - **played** (boolean) - Whether the item has been played. - **play_count** (integer) - The number of times the item has been played. - **playback_position_ticks** (integer) - The playback position in ticks. - **is_favorite** (boolean) - Whether the item is marked as favorite. --- ### Update User Data for an Item Updates the user-specific data for a given item. This can be used to mark an item as played, update play count, or set playback position. ### Method POST ### Endpoint `/Items/{ItemId}/UserData ### Parameters #### Path Parameters - **ItemId** (string) - Required - The ID of the item. #### Query Parameters - **UserId** (string) - Optional - The ID of the user whose data to update. #### Request Body - **played** (boolean) - Optional - Whether to mark the item as played. - **play_count** (integer) - Optional - The play count to set. - **playback_position_ticks** (integer) - Optional - The playback position in ticks to set. ### Request Example ```json { "played": true } ``` ### Response #### Success Response (200) - **played** (boolean) - The updated played status. --- ### Mark Item as Favorite Marks a specific item as a favorite for a user. ### Method POST ### Endpoint `/UserLibrary/Items/{ItemId}/Favorite ### Parameters #### Path Parameters - **ItemId** (string) - Required - The ID of the item. #### Query Parameters - **UserId** (string) - Optional - The ID of the user. ### Response #### Success Response (200) - **is_favorite** (boolean) - The updated favorite status. --- ### Unmark Item as Favorite Unmarks a specific item as a favorite for a user. ### Method DELETE ### Endpoint `/UserLibrary/Items/{ItemId}/Favorite ### Parameters #### Path Parameters - **ItemId** (string) - Required - The ID of the item. #### Query Parameters - **UserId** (string) - Optional - The ID of the user. ### Response #### Success Response (200) - **is_favorite** (boolean) - The updated favorite status. --- ### Update Item Like Status Updates the like status of an item for a user. ### Method POST ### Endpoint `/UserLibrary/Items/{ItemId}/Like ### Parameters #### Path Parameters - **ItemId** (string) - Required - The ID of the item. #### Query Parameters - **UserId** (string) - Optional - The ID of the user. - **liked** (boolean) - Required - Whether to like (true) or unlike (false) the item. ### Response #### Success Response (200) - **likes** (integer) - The updated like count. --- ### Delete Item Rating Deletes the rating for a specific item for a user. ### Method DELETE ### Endpoint `/UserLibrary/Items/{ItemId}/Rating ### Parameters #### Path Parameters - **ItemId** (string) - Required - The ID of the item. #### Query Parameters - **UserId** (string) - Optional - The ID of the user. ### Response #### Success Response (200) - **rating** (number) - The cleared rating (likely null or 0). ``` -------------------------------- ### Initialize JellyfinClient with Default and Builder Patterns (Rust) Source: https://context7.com/latias94/jellyfin-sdk/llms.txt Demonstrates how to create and configure a JellyfinClient instance. It shows both a basic initialization with default settings and a more detailed configuration using the builder pattern, including setting timeouts and retry strategies. The client can also manage authentication tokens at runtime. ```rust use jellyfin_sdk::{JellyfinClient, RetryConfig}; use std::time::Duration; #[tokio::main] async fn main() -> jellyfin_sdk::Result<()> { // Basic client with defaults let client = JellyfinClient::new("http://localhost:8096")?; // Builder pattern with full configuration let client = JellyfinClient::builder("http://localhost:8096")? .client_name("my-jellyfin-app") .device_name("rust-client") .device_id("unique-device-id-12345") .client_version("1.0.0") .timeout(Duration::from_secs(60)) .connect_timeout(Duration::from_secs(15)) .retry_config(RetryConfig { max_retries: 3, initial_backoff: Duration::from_millis(500), max_backoff: Duration::from_secs(10), retry_non_idempotent: false, }) .build()?; // Set authentication token at runtime (shared across clones) client.set_token("your_access_token_here"); // Clear token when logging out client.clear_token(); Ok(()) } ``` -------------------------------- ### Scheduled Tasks API Source: https://github.com/latias94/jellyfin-sdk/blob/main/docs/ALIGNMENT.md Endpoints for managing scheduled tasks, including retrieving, starting, stopping, and updating them. ```APIDOC ## GET /ScheduledTasks ### Description Retrieves a list of all scheduled tasks. ### Method GET ### Endpoint /ScheduledTasks ### Parameters None ### Request Example None ### Response #### Success Response (200) - **Tasks** (array) - A list of scheduled tasks. #### Response Example ```json { "Tasks": [ { "Id": "task-id-1", "Name": "Daily Backup" } ] } ``` ## GET /ScheduledTasks/{taskId} ### Description Retrieves details for a specific scheduled task. ### Method GET ### Endpoint /ScheduledTasks/{taskId} ### Parameters #### Path Parameters - **taskId** (string) - Required - The ID of the task. ### Request Example None ### Response #### Success Response (200) - **Task** (object) - Details of the scheduled task. #### Response Example ```json { "Task": { "Id": "task-id-1", "Name": "Daily Backup", "State": "Idle" } } ``` ## POST /ScheduledTasks/Running/{taskId} ### Description Starts a specific scheduled task. ### Method POST ### Endpoint /ScheduledTasks/Running/{taskId} ### Parameters #### Path Parameters - **taskId** (string) - Required - The ID of the task to start. ### Request Example None ### Response #### Success Response (200) - **Message** (string) - Confirmation of the task start. #### Response Example ```json { "Message": "Task started successfully." } ``` ## DELETE /ScheduledTasks/Running/{taskId} ### Description Stops a running scheduled task. ### Method DELETE ### Endpoint /ScheduledTasks/Running/{taskId} ### Parameters #### Path Parameters - **taskId** (string) - Required - The ID of the task to stop. ### Request Example None ### Response #### Success Response (200) - **Message** (string) - Confirmation of the task stop. #### Response Example ```json { "Message": "Task stopped successfully." } ``` ## POST /ScheduledTasks/{taskId}/Triggers ### Description Updates the triggers for a scheduled task. ### Method POST ### Endpoint /ScheduledTasks/{taskId}/Triggers ### Parameters #### Path Parameters - **taskId** (string) - Required - The ID of the task. #### Request Body - **Triggers** (array) - Optional - A list of new triggers for the task. ### Request Example ```json { "Triggers": [ { "Type": "Daily", "TimeOfDay": "02:00:00" } ] } ``` ### Response #### Success Response (200) - **Message** (string) - Confirmation of the trigger update. #### Response Example ```json { "Message": "Task triggers updated successfully." } ``` ``` -------------------------------- ### Download and Stream Media with Jellyfin SDK Source: https://context7.com/latias94/jellyfin-sdk/llms.txt Demonstrates downloading media files in original or transcoded formats and checking video stream information using the Jellyfin SDK. It utilizes the `JellyfinClient` to interact with the API, specifying item IDs and download paths. Dependencies include `jellyfin_sdk`, `uuid`, and `tokio`. ```rust use jellyfin_sdk::{JellyfinClient, models::VideoStreamQuery}; use uuid::Uuid; #[tokio::main] async fn main() -> jellyfin_sdk::Result<()> { let client = JellyfinClient::builder("http://localhost:8096")? .client_name("my-app") .device_name("rust") .build()?; client.set_token("your_token"); let item_id = Uuid::parse_str("00000000-0000-0000-0000-000000000000").unwrap(); // Download item (processed/transcoded if needed) client .items() .download_item_to_file(item_id, "movie.mp4") .await?; // Download original file client .items() .download_file_to_path(item_id, "movie_original.mkv") .await?; // Check video stream info with HEAD request let response = client .videos() .head_video_stream( item_id, VideoStreamQuery::new().static_stream(true), ) .await?; println!("Status: {}", response.status()); println!("Content-Length: {:?}", response.content_length()); println!( "Content-Type: {:?}", response.headers().get(reqwest::header::CONTENT_TYPE) ); // Stream with container format let response = client .videos() .head_video_stream_by_container( item_id, "mp4", VideoStreamQuery::new().static_stream(true), ) .await?; Ok(()) } ``` -------------------------------- ### Fetch Item Details and Playback Info with Jellyfin SDK Source: https://context7.com/latias94/jellyfin-sdk/llms.txt Fetches detailed information about a specific media item and its playback capabilities. Supports retrieving item metadata, playback information for streaming, and finding similar items. Requires a JellyfinClient, user ID, and item ID. ```rust use jellyfin_sdk::{JellyfinClient, models::PlaybackInfoRequest}; use uuid::Uuid; #[tokio::main] async fn main() -> jellyfin_sdk::Result<()> { let client = JellyfinClient::builder("http://localhost:8096")? .client_name("my-app") .device_name("rust") .build()?; client.set_token("your_token"); let user_id = client.user().me().await?.id.unwrap(); let item_id = Uuid::parse_str("00000000-0000-0000-0000-000000000000").unwrap(); // Get item details let item = client.user_library().get_item(item_id, Some(user_id)).await?; println!("Name: {:?}", item.name); println!("Year: {:?}", item.production_year); println!("Genres: {:?}", item.genres); println!("Overview: {:?}", item.overview); println!("Runtime: {:?} ticks", item.run_time_ticks); // Get playback info for streaming let playback = client .items() .post_playback_info(item_id, PlaybackInfoRequest::new().user_id(user_id)) .await?; println!("Play session ID: {:?}", playback.play_session_id); println!("Media sources: {}", playback.media_sources.len()); if let Some(source) = playback.media_sources.first() { println!(" Container: {:?}", source.container); println!(" Bitrate: {:?}", source.bitrate); println!(" Direct play: {:?}", source.supports_direct_play); println!(" Transcoding URL: {:?}", source.transcoding_url); } // Get similar items let similar = client .items() .get_similar_items( item_id, jellyfin_sdk::api::SimilarItemsQuery::new().user_id(user_id).limit(10), ) .await?; println!("Similar items: {}", similar.items.len()); Ok(()) } ``` -------------------------------- ### Retrieve Resume and Latest Media with Jellyfin SDK (Rust) Source: https://context7.com/latias94/jellyfin-sdk/llms.txt This snippet shows how to use the Jellyfin SDK in Rust to fetch 'continue watching' (resume items) and recently added media. It utilizes query parameters to filter and limit results. Requires a Jellyfin client instance and a valid authentication token. ```rust use jellyfin_sdk::{JellyfinClient, api::{LatestMediaQuery, ResumeItemsQuery}}; #[tokio::main] async fn main() -> jellyfin_sdk::Result<()> { let client = JellyfinClient::builder("http://localhost:8096")? .client_name("my-app") .device_name("rust") .build()?; client.set_token("your_token"); let user_id = client.user().me().await?.id.unwrap(); // Get resume items (continue watching) let resume = client .user_library() .get_resume_items(ResumeItemsQuery::new().user_id(user_id).limit(10)) .await?; println!("Continue watching ({:}):", resume.items.len()); for item in resume.items { println!(" {:?} - {:?}", item.name, item.kind); } // Get latest media additions let latest = client .user_library() .get_latest_media( LatestMediaQuery::new() .user_id(user_id) .limit(20) .group_items(false), ) .await?; println!("Recently added ({:}):", latest.len()); for item in latest { println!(" {:?} ({:?})", item.name, item.production_year); } Ok(()) } ``` -------------------------------- ### Resume and Latest Media API Source: https://context7.com/latias94/jellyfin-sdk/llms.txt This section covers endpoints for retrieving continue watching (resume items) and recently added media content for a user. ```APIDOC ## Resume and Latest Media Get continue watching and recently added content. ### Get Resume Items (Continue Watching) Retrieves a list of items that the user has partially watched and can resume. ### Method GET ### Endpoint `/UserLibrary/Items/Resume ### Parameters #### Query Parameters - **UserId** (string) - Required - The ID of the user. - **Limit** (integer) - Optional - The maximum number of items to return. - **StartIndex** (integer) - Optional - The starting index for pagination. ### Response #### Success Response (200) - **items** (array) - An array of resume items. - **name** (string) - The name of the item. - **kind** (string) - The type of the item (e.g., "Movie", "Episode"). --- ### Get Latest Media Retrieves a list of the most recently added media items for a user. ### Method GET ### Endpoint `/UserLibrary/Media/Latest ### Parameters #### Query Parameters - **UserId** (string) - Required - The ID of the user. - **Limit** (integer) - Optional - The maximum number of items to return. - **group_items** (boolean) - Optional - Whether to group items (e.g., by series). ### Response #### Success Response (200) - **items** (array) - An array of the latest media items. - **name** (string) - The name of the item. - **production_year** (integer) - The production year of the item. ``` -------------------------------- ### Browse User Library Views with Jellyfin SDK Source: https://context7.com/latias94/jellyfin-sdk/llms.txt Lists top-level library views (e.g., Movies, TV Shows) for a user and retrieves grouping options for folder organization. Requires a JellyfinClient instance, user authentication token, and user ID. ```rust use jellyfin_sdk::{JellyfinClient, api::UserViewsQuery}; #[tokio::main] async fn main() -> jellyfin_sdk::Result<()> { let client = JellyfinClient::builder("http://localhost:8096")? .client_name("my-app") .device_name("rust") .build()?; client.set_token("your_token"); let me = client.user().me().await?; let user_id = me.id.expect("user has ID"); // Get user's library views let views = client .user_views() .get_user_views(UserViewsQuery::new().user_id(user_id).include_hidden(false)) .await?; println!("Total views: {:?}", views.total_record_count); for view in views.items { println!( "View: {:?} (ID: {:?}, Type: {:?})", view.name, view.id, view.kind ); } // Get grouping options for folder organization let options = client.user_views().get_grouping_options(Some(user_id)).await?; for opt in options { println!("Grouping option: {:?} (ID: {:?})", opt.name, opt.id); } Ok(()) } ``` -------------------------------- ### List and Search Library Items with Jellyfin SDK Source: https://context7.com/latias94/jellyfin-sdk/llms.txt Queries items from the library with filtering, sorting, and pagination capabilities. Supports searching by text and iterating through results page by page. Requires a JellyfinClient, user ID, and query parameters. ```rust use jellyfin_sdk::{ JellyfinClient, api::ItemsQuery, models::{BaseItemKind, ItemField, ItemSortBy, SortOrder}, }; #[tokio::main] async fn main() -> jellyfin_sdk::Result<()> { let client = JellyfinClient::builder("http://localhost:8096")? .client_name("my-app") .device_name("rust") .build()?; client.set_token("your_token"); let user_id = client.user().me().await?.id.unwrap(); // Build a query with filters let query = ItemsQuery::new() .user_id(user_id) .recursive(true) .include_item_type(BaseItemKind::Movie) .field(ItemField::Overview) .field(ItemField::Genres) .sort_by(ItemSortBy::DateCreated) .sort_order(SortOrder::Descending) .genre("Action") .limit(25); // Single page fetch let result = client.items().get_items(query.clone()).await?; println!("Found {} items (total: {:?})", result.items.len(), result.total_record_count); for item in result.items { println!(" {} ({:?}) - {:?}", item.name.unwrap_or_default(), item.production_year, item.id ); } // Paginated iteration through all results let mut pager = client .items() .pager(ItemsQuery::new().user_id(user_id).recursive(true)) .limit(100); let mut total = 0; while let Some(page) = pager.next_page().await? { total += page.items.len(); println!("Fetched page with {} items", page.items.len()); } println!("Total items fetched: {}", total); // Search with text term let search_results = client .items() .get_items(ItemsQuery::new().user_id(user_id).recursive(true).search_term("Matrix")) .await?; println!("Search found {} items", search_results.items.len()); Ok(()) } ``` -------------------------------- ### Manage Images with Jellyfin SDK (Rust) Source: https://context7.com/latias94/jellyfin-sdk/llms.txt Illustrates how to download and manage item and user images using the Jellyfin SDK in Rust. It covers downloading primary item images with specific quality and format settings, retrieving image metadata, downloading backdrop images by index, and downloading user profile images. ```rust use jellyfin_sdk::{ JellyfinClient, api::{ItemImageRequest, UserImageRequest}, models::{ImageFormat, ImageType}, }; use uuid::Uuid; #[tokio::main] async fn main() -> jellyfin_sdk::Result<()> { let client = JellyfinClient::builder("http://localhost:8096")? .client_name("my-app") .device_name("rust") .build()?; client.set_token("your_token"); let item_id = Uuid::parse_str("00000000-0000-0000-0000-000000000000").unwrap(); // Download primary image with options client .items() .download_image_to_file( item_id, ImageType::Primary, ItemImageRequest::new() .max_width(512) .max_height(512) .quality(90) .format(ImageFormat::Jpg), "poster.jpg", ) .await?; // Get image metadata let infos = client.items().get_image_infos(item_id).await?; for info in infos { println!( "Image: {:?} ({}x{}, tag: {:?})", info.image_type, info.width.unwrap_or(0), info.height.unwrap_or(0), info.image_tag ); } // Download backdrop by index client .items() .download_image_by_index_to_file( item_id, ImageType::Backdrop, 0, ItemImageRequest::new().max_width(1920), "backdrop_0.jpg", ) .await?; // Download user profile image let user_id = client.user().me().await?.id.unwrap(); client .images() .download_user_image_to_file(user_id, UserImageRequest::new(), "user_avatar") .await?; Ok(()) } ``` -------------------------------- ### Playstate Management Source: https://github.com/latias94/jellyfin-sdk/blob/main/docs/ALIGNMENT.md Endpoints for reporting and managing playback states. ```APIDOC ## DELETE /PlayingItems/{itemId} ### Description Reports that playback for an item has stopped. ### Method DELETE ### Endpoint /PlayingItems/{itemId} ### Parameters #### Path Parameters - **itemId** (string) - Required - The ID of the item. ### Response #### Success Response (204) No content is returned on successful report. ## POST /PlayingItems/{itemId} ### Description Reports that playback for an item has started. ### Method POST ### Endpoint /PlayingItems/{itemId} ### Parameters #### Path Parameters - **itemId** (string) - Required - The ID of the item. ### Response #### Success Response (204) No content is returned on successful report. ## POST /PlayingItems/{itemId}/Progress ### Description Reports the current playback progress for an item. ### Method POST ### Endpoint /PlayingItems/{itemId}/Progress ### Parameters #### Path Parameters - **itemId** (string) - Required - The ID of the item. ### Request Body - **playbackPositionTicks** (integer) - Required - The current playback position in ticks. - **volumeLevel** (integer) - Optional - The current volume level. ### Request Example { "playbackPositionTicks": 600000000, "volumeLevel": 100 } ### Response #### Success Response (204) No content is returned on successful report. ## POST /Sessions/Playing ### Description Reports the start of playback for a session. ### Method POST ### Endpoint /Sessions/Playing ### Request Body - **item** (object) - Required - Details of the item being played. - **playMethod** (string) - Optional - The method of playback (e.g., 'DirectPlay'). - **deviceInfo** (object) - Optional - Information about the device. ### Request Example { "item": { "Id": "movie456", "Name": "Example Movie" }, "playMethod": "DirectPlay" } ### Response #### Success Response (204) No content is returned on successful report. ## POST /Sessions/Playing/Ping ### Description Pings an active playback session to keep it alive. ### Method POST ### Endpoint /Sessions/Playing/Ping ### Response #### Success Response (204) No content is returned on successful ping. ## POST /Sessions/Playing/Progress ### Description Reports the playback progress for a session. ### Method POST ### Endpoint /Sessions/Playing/Progress ### Request Body - **playState** (string) - Required - The current play state (e.g., 'Playing', 'Paused'). - **playbackPositionTicks** (integer) - Required - The current playback position in ticks. ### Request Example { "playState": "Playing", "playbackPositionTicks": 600000000 } ### Response #### Success Response (204) No content is returned on successful report. ## POST /Sessions/Playing/Stopped ### Description Reports that playback for a session has stopped. ### Method POST ### Endpoint /Sessions/Playing/Stopped ### Response #### Success Response (204) No content is returned on successful report. ## DELETE /UserPlayedItems/{itemId} ### Description Marks an item as unplayed for the user. ### Method DELETE ### Endpoint /UserPlayedItems/{itemId} ### Parameters #### Path Parameters - **itemId** (string) - Required - The ID of the item to mark as unplayed. ### Response #### Success Response (204) No content is returned on successful marking. ## POST /UserPlayedItems/{itemId} ### Description Marks an item as played for the user. ### Method POST ### Endpoint /UserPlayedItems/{itemId} ### Parameters #### Path Parameters - **itemId** (string) - Required - The ID of the item to mark as played. ### Response #### Success Response (204) No content is returned on successful marking. ``` -------------------------------- ### System API Source: https://github.com/latias94/jellyfin-sdk/blob/main/docs/ALIGNMENT.md Endpoints for retrieving system information and checking system status. ```APIDOC ## GET /System/Info/Public ### Description Retrieves public system information. ### Method GET ### Endpoint /System/Info/Public ### Parameters None ### Request Example None ### Response #### Success Response (200) - **SystemInfo** (object) - Information about the system. #### Response Example ```json { "SystemInfo": { "Version": "10.8.10", "ProductName": "Jellyfin", "OperatingSystem": "Linux" } } ``` ## GET /System/Ping ### Description Checks if the system is responsive. ### Method GET ### Endpoint /System/Ping ### Parameters None ### Request Example None ### Response #### Success Response (200) - **Status** (string) - Indicates if the system is online. #### Response Example ```json { "Status": "Online" } ``` ``` -------------------------------- ### Configuration API Source: https://github.com/latias94/jellyfin-sdk/blob/main/docs/ALIGNMENT.md Endpoints for retrieving and updating system-wide configuration, including branding and metadata options. ```APIDOC ## GET /System/Configuration ### Description Retrieves the system configuration. ### Method GET ### Endpoint /System/Configuration ### Parameters None ### Request Example None ### Response #### Success Response (200) - **Configuration** (object) - The system configuration object. #### Response Example ```json { "Configuration": { "EnableExternalContent": true } } ``` ## POST /System/Configuration ### Description Updates the system configuration. ### Method POST ### Endpoint /System/Configuration ### Parameters #### Request Body - **Configuration** (object) - Required - The updated system configuration. ### Request Example ```json { "Configuration": { "EnableExternalContent": false } } ``` ### Response #### Success Response (200) - **Message** (string) - Confirmation of the configuration update. #### Response Example ```json { "Message": "System configuration updated successfully." } ``` ## POST /System/Configuration/Branding ### Description Updates the branding configuration for the system. ### Method POST ### Endpoint /System/Configuration/Branding ### Parameters #### Request Body - **BrandingConfiguration** (object) - Required - The updated branding configuration. ### Request Example ```json { "BrandingConfiguration": { "LogoUrl": "/Branding/Logo" } } ``` ### Response #### Success Response (200) - **Message** (string) - Confirmation of the branding update. #### Response Example ```json { "Message": "Branding configuration updated successfully." } ``` ## GET /System/Configuration/MetadataOptions/Default ### Description Retrieves the default metadata options configuration. ### Method GET ### Endpoint /System/Configuration/MetadataOptions/Default ### Parameters None ### Request Example None ### Response #### Success Response (200) - **DefaultMetadataOptions** (object) - The default metadata options. #### Response Example ```json { "DefaultMetadataOptions": { "ImageFetcher": ["TheMovieDb"], "MetadataFetcher": ["TheMovieDb"] } } ``` ## GET /System/Configuration/{key} ### Description Retrieves a specific named configuration value. ### Method GET ### Endpoint /System/Configuration/{key} ### Parameters #### Path Parameters - **key** (string) - Required - The key of the configuration to retrieve. ### Request Example None ### Response #### Success Response (200) - **Value** (any) - The value of the specified configuration key. #### Response Example ```json { "Value": "some_config_value" } ``` ## POST /System/Configuration/{key} ### Description Updates a specific named configuration value. ### Method POST ### Endpoint /System/Configuration/{key} ### Parameters #### Path Parameters - **key** (string) - Required - The key of the configuration to update. #### Request Body - **Value** (any) - Required - The new value for the configuration key. ### Request Example ```json { "Value": "new_config_value" } ``` ### Response #### Success Response (200) - **Message** (string) - Confirmation of the configuration update. #### Response Example ```json { "Message": "Configuration updated successfully." } ``` ``` -------------------------------- ### Make Raw API Requests with Jellyfin SDK Source: https://context7.com/latias94/jellyfin-sdk/llms.txt Shows how to make custom HTTP requests to Jellyfin API endpoints not directly supported by the SDK. This includes sending JSON payloads, receiving raw bytes, discarding responses, and downloading files directly. It uses `reqwest::Method` and `serde::Deserialize` for request building and response parsing. Dependencies include `jellyfin_sdk`, `reqwest`, `serde`, and `tokio`. ```rust use jellyfin_sdk::JellyfinClient; use reqwest::Method; use serde::Deserialize; #[derive(Deserialize, Debug)] struct CustomResponse { some_field: String, } #[tokio::main] async fn main() -> jellyfin_sdk::Result<()> { let client = JellyfinClient::builder("http://localhost:8096")? .client_name("my-app") .device_name("rust") .build()?; client.set_token("your_token"); // Build custom request let request = client .request(Method::GET, "/Some/Custom/Endpoint")? .query(&[("param1", "value1"), ("param2", "value2")]); // Send and parse JSON response let response: CustomResponse = client.send_json(request).await?; println!("Response: {:?}", response); // Execute and get raw response for streaming let request = client.request(Method::GET, "/Some/Binary/Endpoint")?; let response = client.execute(request).await?; let bytes = response.bytes().await?; println!("Received {} bytes", bytes.len()); // Send and discard response (for 204 No Content) let request = client.request(Method::POST, "/Some/Action/Endpoint")?; client.send_unit(request).await?; // Download directly to file client .download_to_file("/Some/File/Endpoint", "output.bin") .await?; Ok(()) } ```