Installation
- NuGet Package Manager
- .NET CLI
- Project File
PM> Install-Package ButterCMS
dotnet add package ButterCMS
Add to your
.csproj:<ItemGroup>
<PackageReference Include="ButterCMS" Version="2.1.0" />
</ItemGroup>
Initialization
Initialize the SDK with your Read API token from the ButterCMS Settings.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:// 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; }
}
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:// 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; }
}
// 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.// 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
// 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
// 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
// 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.// 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() |
Recommendation: Always use async methods in web applications for better scalability.
Complete example
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
GitHub Repository
View source code, report issues, and contribute
NuGet Package
Package details and version history