FoPost.Sdk 0.1.0

dotnet add package FoPost.Sdk --version 0.1.0
                    
NuGet\Install-Package FoPost.Sdk -Version 0.1.0
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="FoPost.Sdk" Version="0.1.0" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="FoPost.Sdk" Version="0.1.0" />
                    
Directory.Packages.props
<PackageReference Include="FoPost.Sdk" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add FoPost.Sdk --version 0.1.0
                    
#r "nuget: FoPost.Sdk, 0.1.0"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package FoPost.Sdk@0.1.0
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=FoPost.Sdk&version=0.1.0
                    
Install as a Cake Addin
#tool nuget:?package=FoPost.Sdk&version=0.1.0
                    
Install as a Cake Tool

FoPost.Sdk

NuGet license CI

Official .NET SDK for the FoPost API. Schedule and publish to +30 social platforms from your code.

dotnet add package FoPost.Sdk

Requires .NET 8 or newer. No third-party dependencies.

0.x release. The public API is still settling and minor versions may contain breaking changes. Pin an exact version if that matters to you.

Quick start

using FoPost;

using var client = new FoPostClient(Environment.GetEnvironmentVariable("FOPOST_API_KEY")!);

// List your accounts
var accounts = await client.Accounts.ListAsync("9b2f6c1e-…");

// Create a post, then publish it immediately
var post = await client.Posts.CreateAsync(
    workspaceId: "9b2f6c1e-…",
    text: "Hello from the SDK",
    accounts: accounts.Select(account => account.Id));

await client.Posts.PublishAsync(post.Id);

// Schedule for later
await client.Posts.CreateAsync(new CreatePostOptions
{
    WorkspaceId = "9b2f6c1e-…",
    Status = PostStatuses.Scheduled,
    ScheduleAt = new DateTimeOffset(2026, 6, 1, 10, 0, 0, TimeSpan.Zero),
    Content = new List<PostContent> { new("Scheduled with the SDK") },
    Accounts = new List<string> { accounts[0].Id },
});

Create an API key in the dashboard under Settings → API Keys. A key is limited to the scopes granted at creation — the calls above need posts and accounts.

Configuration

using var client = new FoPostClient(new FoPostClientOptions
{
    ApiKey = "fp_…",                        // defaults to $FOPOST_API_KEY
    BaseUrl = "https://api.fopost.com",     // override for staging or self-hosted
    Timeout = TimeSpan.FromSeconds(30),
    MaxRetries = 3,                         // total attempts on a 429, including the first
    HttpClient = httpClientFromFactory,     // optional; the SDK will not dispose it
});
Env var Used for
FOPOST_API_KEY API key, when ApiKey is not passed

FoPostClient is thread-safe and meant to be long-lived — register it as a singleton rather than constructing one per request. With IHttpClientFactory:

services.AddHttpClient("fopost");
services.AddSingleton(provider => new FoPostClient(new FoPostClientOptions
{
    HttpClient = provider.GetRequiredService<IHttpClientFactory>().CreateClient("fopost"),
}));

Paging

ListAsync returns one page plus its Meta. ListAllAsync walks every page for you:

await foreach (var post in client.Posts.ListAllAsync(new ListPostsOptions
{
    WorkspaceId = "9b2f6c1e-…",
    Status = PostStatuses.Scheduled,
}))
{
    Console.WriteLine($"{post.ScheduleAt:u}  {post.Content.FirstOrDefault()?.Text}");
}

Partial updates

Every field on UpdatePostOptions is an Optional<T>, so "leave this alone" and "clear this" stay different things:

await client.Posts.UpdateAsync(post.Id, new UpdatePostOptions
{
    Title = "New title",                    // sent
    Summary = Optional<string?>.Of(null),   // sent as null, clearing it
    // ScheduleAt is untouched — not sent at all
});

AI features

// Caption assist — accepts an API key carrying the `ai` scope
var caption = await client.Ai.GenerateCaptionAsync(new GenerateCaptionOptions
{
    CurrentCaption = "shipping a new feature",
    Platforms = new List<string> { Platforms.Twitter, Platforms.LinkedIn },
});

// Check your balance
var balance = await client.Ai.CreditsAsync();
Console.WriteLine($"{balance.CreditsRemaining} of {balance.CreditsTotal} credits left");

RewriteAsync and RepurposeUrlAsync are dashboard-session endpoints: they need a BearerToken rather than an API key, and answer 401 to a key.

Error handling

Every non-2xx response raises a FoPostException carrying the API's status, error code, and body.

try
{
    await client.Posts.PublishAsync(post.Id);
}
catch (FoPostRateLimitException error)
{
    Console.WriteLine($"Slow down for {error.RetryAfter}");
}
catch (FoPostPaymentRequiredException error)
{
    Console.WriteLine($"Upgrade at {error.UpgradeUrl}");
}
catch (FoPostException error)
{
    Console.WriteLine($"API {error.Status} ({error.Code}): {error.Message}");
}
Status Exception
400, 422 FoPostValidationException
401 FoPostAuthenticationException
402 FoPostPaymentRequiredException
403 FoPostPermissionDeniedException
404 FoPostNotFoundException
429 FoPostRateLimitException
any other FoPostException

A 429 is retried automatically, up to MaxRetries attempts, waiting for the interval the API asks for in Retry-After. The exception is raised only once the retries are spent.

Resources

Namespace Methods
Posts ListAsync, ListAllAsync, GetAsync, CreateAsync, UpdateAsync, DeleteAsync, PublishAsync, CancelAsync, RetryAsync, PreflightAsync, DuplicateAsync, DeliveriesAsync
Accounts ListAsync, GetAsync, HealthAsync
Workspaces ListAsync, GetAsync
Labels ListAsync
Ai CreditsAsync, GenerateCaptionAsync, RewriteAsync, RepurposeUrlAsync

The API has more endpoints than the SDK wraps — analytics, webhooks, automations, media, and communities among them. RequestAsync reaches any of them with the same auth, retries, and error handling:

var overview = await client.RequestAsync(
    HttpMethod.Get,
    "/v1/analytics/overview",
    query: new Dictionary<string, object?> { ["workspace_id"] = "9b2f6c1e-…" });

The full surface is documented in the API collection.

Contributing

Issues and pull requests are welcome at fopost/fopost-dotnet.

dotnet build
dotnet test
dotnet pack src/FoPost/FoPost.csproj -c Release

License

MIT

Product Compatible and additional computed target framework versions.
.NET net8.0 is compatible.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed.  net9.0 was computed.  net9.0-android was computed.  net9.0-browser was computed.  net9.0-ios was computed.  net9.0-maccatalyst was computed.  net9.0-macos was computed.  net9.0-tvos was computed.  net9.0-windows was computed.  net10.0 was computed.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.
  • net8.0

    • No dependencies.

NuGet packages (1)

Showing the top 1 NuGet packages that depend on FoPost.Sdk:

Package Downloads
FoPost.AspNetCore

Official ASP.NET Core integration for the FoPost API. Dependency injection, the options pattern, IHttpClientFactory, signature-verified webhook endpoints, and a health check for FoPost.Sdk.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
0.1.0 60 8/31/2026