# Studies API Access and manage Lichess studies. Studies are collaborative analysis boards with multiple chapters. **Namespace:** `LichessSharp.Api.Contracts` **Access:** `client.Studies` --- ## Exporting Studies ### ExportChapterPgnAsync Export one study chapter in PGN format. ```csharp Task ExportChapterPgnAsync( string studyId, string chapterId, StudyExportOptions? options = null, CancellationToken cancellationToken = default) ``` **Example:** ```csharp using var client = new LichessClient(); // Export a single chapter var pgn = await client.Studies.ExportChapterPgnAsync("studyId", "chapterId"); Console.WriteLine(pgn); // Export with options var pgnWithDetails = await client.Studies.ExportChapterPgnAsync("studyId", "chapterId", new StudyExportOptions { Clocks = true, Comments = true, Variations = true, Opening = true }); ``` --- ### ExportStudyPgnAsync Export all chapters of a study in PGN format. ```csharp Task ExportStudyPgnAsync( string studyId, StudyExportOptions? options = null, CancellationToken cancellationToken = default) ``` **Example:** ```csharp using var client = new LichessClient(); // Export entire study var pgn = await client.Studies.ExportStudyPgnAsync("studyId"); // Save to file await File.WriteAllTextAsync("study.pgn", pgn); ``` --- ### ExportUserStudiesPgnAsync Export all chapters of all studies of a user in PGN format. ```csharp Task ExportUserStudiesPgnAsync( string username, StudyExportOptions? options = null, CancellationToken cancellationToken = default) ``` **Example:** ```csharp using var client = new LichessClient(token); // Export all your studies var pgn = await client.Studies.ExportUserStudiesPgnAsync("myusername"); // When authenticated, includes private and unlisted studies Console.WriteLine($"Exported {pgn.Length} characters of PGN"); ``` --- ## Creating Studies ### CreateStudyAsync Create a new study with an empty chapter. You can make up to 30 new studies per day. **Required Scope:** `study:write` ```csharp Task CreateStudyAsync( CreateStudyOptions options, CancellationToken cancellationToken = default) ``` **Example:** ```csharp using var client = new LichessClient(token); var result = await client.Studies.CreateStudyAsync(new CreateStudyOptions { Name = "My Opening Repertoire", Visibility = "private", Computer = "owner", Explorer = "everyone" }); Console.WriteLine($"Created study: {result.Id}"); ``` --- ## Listing Studies ### StreamUserStudiesAsync Stream metadata of all studies of a user. ```csharp IAsyncEnumerable StreamUserStudiesAsync( string username, CancellationToken cancellationToken = default) ``` **Example:** ```csharp using var client = new LichessClient(); await foreach (var study in client.Studies.StreamUserStudiesAsync("DrNykterstein")) { var created = DateTimeOffset.FromUnixTimeMilliseconds(study.CreatedAt); var updated = DateTimeOffset.FromUnixTimeMilliseconds(study.UpdatedAt); Console.WriteLine($"Study: {study.Name}"); Console.WriteLine($" ID: {study.Id}"); Console.WriteLine($" Created: {created:g}"); Console.WriteLine($" Updated: {updated:g}"); } ``` --- ## Managing Chapters ### ImportPgnAsync Import PGN into an existing study. Creates new chapter(s). **Required Scope:** `study:write` ```csharp Task ImportPgnAsync( string studyId, string pgn, StudyImportOptions? options = null, CancellationToken cancellationToken = default) ``` **Parameters:** | Name | Type | Description | |------|------|-------------| | studyId | string | The study ID (8 characters) | | pgn | string | PGN to import (multiple games separated by 2+ newlines) | | options | StudyImportOptions? | Import options | **Example:** ```csharp using var client = new LichessClient(token); var pgn = @" [Event ""My Game""] [White ""Player1""] [Black ""Player2""] 1. e4 e5 2. Nf3 Nc6 3. Bb5 * "; // Import with custom name var result = await client.Studies.ImportPgnAsync("studyId", pgn, new StudyImportOptions { Name = "My Analysis", Orientation = "white" }); foreach (var chapter in result.Chapters) { Console.WriteLine($"Created chapter: {chapter.Name} ({chapter.Id})"); } ``` **Note:** A study can contain at most 64 chapters. --- ### UpdateChapterTagsAsync Add, update, or delete PGN tags of a study chapter. **Required Scope:** `study:write` ```csharp Task UpdateChapterTagsAsync( string studyId, string chapterId, string pgnTags, CancellationToken cancellationToken = default) ``` **Example:** ```csharp using var client = new LichessClient(token); // Update tags (only tags are used, moves are ignored) var tagsPgn = @" [Event ""World Championship 2024""] [Site ""Singapore""] [Date ""2024.11.25""] [White ""Carlsen, Magnus""] [Black ""Nepomniachtchi, Ian""] [Result ""1-0""] "; await client.Studies.UpdateChapterTagsAsync("studyId", "chapterId", tagsPgn); // Delete a tag by providing empty value var deleteTag = @"[Site """"]"; await client.Studies.UpdateChapterTagsAsync("studyId", "chapterId", deleteTag); ``` --- ### DeleteChapterAsync Delete a chapter from a study. **Required Scope:** `study:write` ```csharp Task DeleteChapterAsync( string studyId, string chapterId, CancellationToken cancellationToken = default) ``` **Example:** ```csharp using var client = new LichessClient(token); await client.Studies.DeleteChapterAsync("studyId", "chapterId"); Console.WriteLine("Chapter deleted"); ``` **Note:** A study must have at least one chapter. If you delete the last chapter, an empty one will be automatically created. --- ## Options ### StudyExportOptions | Property | Type | Description | |----------|------|-------------| | Clocks | bool? | Include clock comments (e.g., `{ [%clk 1:59:01] }`) | | Comments | bool? | Include analysis/eval comments | | Variations | bool? | Include non-mainline moves | | Opening | bool? | Include full opening name | | Source | bool? | Add source URL as comment | | Orientation | bool? | Add Lichess orientation tag | ### CreateStudyOptions | Property | Type | Default | Description | |----------|------|---------|-------------| | Name | string | *(required)* | Study name (2-100 characters) | | Visibility | string | "unlisted" | "public", "unlisted", or "private" | | Computer | string | "everyone" | Who can use computer analysis | | Explorer | string | "everyone" | Who can use the opening explorer | | Cloneable | string | "everyone" | Who can clone the study | | Shareable | string | "everyone" | Who can share the study | | Chat | string | "everyone" | Who can use the chat | | Sticky | bool? | null | Keep everyone on the same chapter/position | Permission values: `"nobody"`, `"owner"`, `"contributor"`, `"member"`, `"everyone"` ### StudyImportOptions | Property | Type | Description | |----------|------|-------------| | Name | string? | Chapter name (max 100 chars) | | Orientation | string? | Board orientation: "white" or "black" | | Variant | string? | Chess variant key | --- ## Response Types ### StudyMetadata | Property | Type | Description | |----------|------|-------------| | Id | string | Study ID | | Name | string | Study name | | CreatedAt | long | Creation timestamp (Unix ms) | | UpdatedAt | long | Last update timestamp (Unix ms) | ### StudyImportResult | Property | Type | Description | |----------|------|-------------| | Chapters | IReadOnlyList\ | Created chapters | ### StudyCreateResult | Property | Type | Description | |----------|------|-------------| | Id | string | The created study ID | ### StudyChapter | Property | Type | Description | |----------|------|-------------| | Id | string | Chapter ID | | Name | string | Chapter name | | Players | IReadOnlyList\? | Players in the chapter | | Status | string? | Game result (e.g., "1-0") | --- ## See Also - [Games API](Games.md) - Export games in PGN format - [Broadcasts API](Broadcasts.md) - Relay chess events