OnlyFans API with C#
Calling the OnlyFans API from C# needs no external package: ofapis is a plain REST API with Bearer auth, so HttpClient from System.Net.Http is all you need in .NET. System.Text.Json handles serialization out of the box. Every request goes to https://api.ofapis.com/api/public/v1.
ofapis is an independent, unofficial API for OnlyFans, not affiliated with OnlyFans. Accounts are connected once in the dashboard and the session is kept alive server-side, so your C# code only handles your ofapis_sk_... token.
1. Get a token
Create a key in the dashboard (start free) and read it from configuration or an environment variable — never hard-code it. See authentication.
2. Setup
Both System.Net.Http and System.Text.Json are in the base class library, so a fresh console app needs no packages:
dotnet new console -n OfapisDemo
cd OfapisDemo
export OFAPIS_KEY=ofapis_sk_...
dotnet run
3. Verify the token — GET /me
Configure one HttpClient with the BaseAddress and a default Authorization header so every call carries the Bearer token:
using System.Net.Http.Headers;
using System.Net.Http.Json;
using System.Text.Json;
var token = Environment.GetEnvironmentVariable("OFAPIS_KEY")!;
var http = new HttpClient { BaseAddress = new Uri("https://api.ofapis.com/api/public/v1/") };
http.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token);
var res = await http.GetAsync("me");
if (!res.IsSuccessStatusCode)
throw new Exception($"GET /me failed: {(int)res.StatusCode} {await res.Content.ReadAsStringAsync()}");
var me = await res.Content.ReadFromJsonAsync<JsonElement>();
Console.WriteLine($"connected as {me.GetProperty("username").GetString()}");
Note the trailing slash on the BaseAddress and the relative paths without a leading slash — that combination is what HttpClient resolves correctly.
4. List chats
var chats = await http.GetFromJsonAsync<JsonElement>("chats?limit=50");
foreach (var c in chats.GetProperty("data").EnumerateArray())
Console.WriteLine(c.GetProperty("id").GetString());
5. Send a message
var res = await http.PostAsJsonAsync("chats/123/messages", new { text = "Thanks for subscribing!" });
switch ((int)res.StatusCode)
{
case 200: Console.WriteLine("delivered — 1 credit spent"); break;
case 401: throw new InvalidOperationException("bad or revoked token");
case 429: Console.Error.WriteLine("rate limited — back off and retry"); break;
default: throw new Exception($"send failed: {(int)res.StatusCode} {await res.Content.ReadAsStringAsync()}");
}
A 200 means delivered and one credit spent. Failed calls — an expired session, a 429, or an upstream 5xx — are never charged, so retrying after a failure is free.
Dependency injection
In ASP.NET Core, register a typed client instead of newing up HttpClient yourself:
builder.Services.AddHttpClient("ofapis", c => {
c.BaseAddress = new Uri("https://api.ofapis.com/api/public/v1/");
c.DefaultRequestHeaders.Authorization =
new AuthenticationHeaderValue("Bearer", builder.Configuration["Ofapis:Key"]);
});
IHttpClientFactory pools handlers and avoids socket exhaustion — prefer it over a using var http per call.
Agencies: scope by account
Managing several creators? Address each by id under scoped routes, e.g. http.GetAsync("accounts/42/chats"). See agency automation.
FAQ
Do I need a NuGet package to call the OnlyFans API from C#?
No. System.Net.Http.HttpClient and System.Text.Json from the BCL are enough. You can also generate a typed client from the OpenAPI spec linked in the docs.
How do I handle rate limits in .NET?
Check for HTTP 429 and retry after a short backoff — Polly's retry policies work well here. Plan ceilings run from 60 rpm on Free to 500 rpm on Pro — see pricing.
Does a failed request cost a credit?
No. Billing is metered per successful call: one 2xx equals one credit. Timeouts, 429s and upstream 5xx responses are not charged.
Should I reuse HttpClient?
Yes. A single long-lived HttpClient (or IHttpClientFactory) reuses connections. Creating and disposing one per request can exhaust sockets under load.
Next steps
- Messaging API reference
- Subscribers API
- Other languages: Node · Python · Java