> ## Documentation Index
> Fetch the complete documentation index at: https://buttercms.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# .NET SDK

> The ButterCMS .NET SDK provides a strongly-typed C# interface with async/await support for ASP.NET Core, Blazor, and other .NET applications.

## Installation

<Tabs>
  <Tab title="NuGet Package Manager">
    ```powershell theme={null}
    PM> Install-Package ButterCMS
    ```
  </Tab>

  <Tab title=".NET CLI">
    ```bash theme={null}
    dotnet add package ButterCMS
    ```
  </Tab>

  <Tab title="Project File">
    Add to your `.csproj`:

    ```xml theme={null}
    <ItemGroup>
      <PackageReference Include="ButterCMS" Version="2.1.0" />
    </ItemGroup>
    ```
  </Tab>
</Tabs>

## Initialization

Initialize the SDK with your Read API token from the [ButterCMS Settings](https://buttercms.com/settings/).

```csharp theme={null}
using ButterCMS;

// Basic initialization
var butterClient = new ButterCMSClient("your_api_token");

// With custom timeout (default is 10 seconds)
var butterClient = new ButterCMSClient("your_api_token", TimeSpan.FromSeconds(30));

// With preview mode enabled
var butterClient = new ButterCMSClient(
    apiToken: "your_api_token",
    timeout: null,  // Use default
    maxRetryAttempts: 3,
    httpClient: null,
    previewMode: true
);
```

## Configuration options

| Option             | Type       | Default    | Description                              |
| ------------------ | ---------- | ---------- | ---------------------------------------- |
| `apiToken`         | string     | -          | Your ButterCMS Read API token (required) |
| `timeout`          | TimeSpan   | 10 seconds | Request timeout                          |
| `maxRetryAttempts` | int        | `3`        | Number of retry attempts on failure      |
| `httpClient`       | HttpClient | -          | Custom HttpClient instance               |
| `previewMode`      | bool       | `false`    | Enable preview mode for draft content    |

## API methods

All methods are available in both synchronous and asynchronous versions. The async versions are recommended for better performance.

### Pages

Retrieve and search pages created in the ButterCMS dashboard.

Define a strongly-typed model for your page fields:

```csharp theme={null}
// Models/LandingPage.cs
public class LandingPage
{
    public string Headline { get; set; }
    public string Subheadline { get; set; }
    public string HeroImage { get; set; }
    public string Body { get; set; }
}
```

```csharp theme={null}
using ButterCMS;
using ButterCMS.Models;

// Fetch a single page (async)
var page = await butterClient.RetrievePageAsync<LandingPage>(
    pageType: "landing_page",
    pageSlug: "home-page",
    parameterDictionary: new Dictionary<string, string>
    {
        { "locale", "en" },
        { "preview", "1" }
    }
);
Console.WriteLine(page.Data.Fields.Headline);

// Fetch paginated pages (async)
var pages = await butterClient.ListPagesAsync<LandingPage>(
    pageType: "landing_page",
    parameterDictionary: new Dictionary<string, string>
    {
        { "page", "1" },
        { "page_size", "10" },
        { "locale", "en" }
    }
);

foreach (var p in pages.Data)
{
    Console.WriteLine(p.Slug);
}

// Search pages
var results = await butterClient.SearchPagesAsync<LandingPage>(
    query: "search term",
    pageType: "landing_page"
);
```

### Collections

Fetch content from Collections (structured data tables).

Define a model for your collection:

```csharp theme={null}
// Models/FaqCollection.cs
public class FaqCollection
{
    public List<FaqItem> Faq { get; set; }
}

public class FaqItem
{
    public string Question { get; set; }
    public string Answer { get; set; }
}
```

```csharp theme={null}
// Fetch collection content
var content = await butterClient.RetrieveContentFieldsAsync<FaqCollection>(
    keys: new[] { "faq" },
    parameterDictionary: new Dictionary<string, string>
    {
        { "locale", "en" }
    }
);

foreach (var item in content.Data.Faq)
{
    Console.WriteLine(item.Question);
    Console.WriteLine(item.Answer);
}
```

### Blog Posts

Access the built-in Blog Engine for posts, categories, tags, and authors.

```csharp theme={null}
// List blog posts (async)
var postsResponse = await butterClient.ListPostsAsync(
    page: 1,
    pageSize: 10,
    excludeBody: true
);

foreach (var post in postsResponse.Data)
{
    Console.WriteLine(post.Title);
    Console.WriteLine(post.Slug);
}

// Access pagination
Console.WriteLine($"Total: {postsResponse.Meta.Count}");
Console.WriteLine($"Next page: {postsResponse.Meta.NextPage}");

// Filter by author and category
var filteredPosts = await butterClient.ListPostsAsync(
    page: 1,
    pageSize: 10,
    excludeBody: true,
    authorSlug: "jennifer-smith",
    categorySlug: "news"
);

// Fetch a single post (async)
var post = await butterClient.RetrievePostAsync("my-post-slug");
Console.WriteLine(post.Data.Title);
Console.WriteLine(post.Data.Body);

// Search posts
var searchResults = await butterClient.SearchPostsAsync(
    query: "search term",
    page: 1,
    pageSize: 10
);
```

### Authors

```csharp theme={null}
// List all authors (async)
var authorsResponse = await butterClient.ListAuthorsAsync(
    includeRecentPosts: true
);

foreach (var author in authorsResponse)
{
    Console.WriteLine($"{author.FirstName} {author.LastName}");
}

// Retrieve a single author
var author = await butterClient.RetrieveAuthorAsync(
    authorSlug: "jennifer-smith",
    includeRecentPosts: true
);
Console.WriteLine(author.Bio);
```

### Categories

```csharp theme={null}
// List all categories (async)
var categoriesResponse = await butterClient.ListCategoriesAsync(
    includeRecentPosts: true
);

foreach (var category in categoriesResponse)
{
    Console.WriteLine(category.Name);
    Console.WriteLine(category.Slug);
}

// Retrieve a single category
var category = await butterClient.RetrieveCategoryAsync("news");
```

### Tags

```csharp theme={null}
// List all tags (async)
var tagsResponse = await butterClient.ListTagsAsync();

foreach (var tag in tagsResponse)
{
    Console.WriteLine(tag.Name);
    Console.WriteLine(tag.Slug);
}

// Retrieve a single tag
var tag = await butterClient.RetrieveTagAsync("featured");
```

### Feeds

Retrieve RSS, Atom, and Sitemap feeds as XML documents.

```csharp theme={null}
// Get RSS feed
XmlDocument rssFeed = await butterClient.GetRSSFeedAsync();

// Get Atom feed
XmlDocument atomFeed = await butterClient.GetAtomFeedAsync();

// Get Sitemap
XmlDocument sitemap = await butterClient.GetSitemapAsync();
```

## Query parameters reference

| Parameter       | Method Parameter            | Description                                         |
| --------------- | --------------------------- | --------------------------------------------------- |
| `page`          | `page`                      | Page number for pagination                          |
| `page_size`     | `pageSize`                  | Number of items per page                            |
| `exclude_body`  | `excludeBody`               | Exclude post body for faster response               |
| `author_slug`   | `authorSlug`                | Filter posts by author                              |
| `category_slug` | `categorySlug`              | Filter posts by category                            |
| `tag_slug`      | `tagSlug`                   | Filter posts by tag                                 |
| `include`       | `includeRecentPosts`        | Include `recent_posts` with authors/categories/tags |
| `locale`        | `locale` (in dictionary)    | Locale code for localized content                   |
| `preview`       | `previewMode` (constructor) | Enable draft content access                         |
| `levels`        | `levels` (in dictionary)    | Depth of nested references (1–3)                    |

## Synchronous vs asynchronous

All methods have both sync and async versions:

| Async Method             | Sync Method         |
| ------------------------ | ------------------- |
| `ListPostsAsync()`       | `ListPosts()`       |
| `RetrievePostAsync()`    | `RetrievePost()`    |
| `ListPagesAsync<T>()`    | `ListPages<T>()`    |
| `RetrievePageAsync<T>()` | `RetrievePage<T>()` |
| `ListAuthorsAsync()`     | `ListAuthors()`     |
| `ListCategoriesAsync()`  | `ListCategories()`  |
| `GetRSSFeedAsync()`      | `GetRSSFeed()`      |

<Info>
  **Recommendation:** Always use async methods in web applications for better scalability.
</Info>

## Complete example

```csharp theme={null}
using ButterCMS;
using ButterCMS.Models;

class Program
{
    static async Task Main(string[] args)
    {
        var apiToken = Environment.GetEnvironmentVariable("BUTTERCMS_API_TOKEN");
        var client = new ButterCMSClient(apiToken);

        try
        {
            // Fetch the home page
            var homePage = await client.RetrievePageAsync<dynamic>(
                "landing_page",
                "home",
                new Dictionary<string, string> { { "locale", "en" } }
            );
            Console.WriteLine($"Page headline: {homePage.Data.Fields["headline"]}");

            // Fetch navigation collection
            var collections = await client.RetrieveContentFieldsAsync<dynamic>(
                new[] { "main_navigation" },
                new Dictionary<string, string>()
            );
            Console.WriteLine($"Navigation loaded");

            // Fetch recent blog posts
            var postsResponse = await client.ListPostsAsync(
                page: 1,
                pageSize: 3,
                excludeBody: true
            );
            Console.WriteLine($"Recent posts: {postsResponse.Data.Count()}");

            foreach (var post in postsResponse.Data)
            {
                Console.WriteLine($"  - {post.Title}");
            }
        }
        catch (Exception e)
        {
            Console.WriteLine($"Error fetching content: {e.Message}");
        }
    }
}
```

## Resources

<CardGroup cols={2}>
  <Card title="GitHub Repository" icon="github" href="https://github.com/ButterCMS/buttercms-csharp">
    View source code, report issues, and contribute
  </Card>

  <Card title="NuGet Package" icon="box" href="https://www.nuget.org/packages/ButterCMS">
    Package details and version history
  </Card>
</CardGroup>
