{"id":29554190,"url":"https://github.com/posthog/posthog-dotnet","last_synced_at":"2026-04-01T18:50:42.013Z","repository":{"id":272965558,"uuid":"916761375","full_name":"PostHog/posthog-dotnet","owner":"PostHog","description":"A dotnet client sdk to the PostHog API","archived":false,"fork":false,"pushed_at":"2026-03-31T11:03:47.000Z","size":1457,"stargazers_count":40,"open_issues_count":16,"forks_count":14,"subscribers_count":7,"default_branch":"main","last_synced_at":"2026-03-31T13:08:48.571Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"C#","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/PostHog.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":".github/CODEOWNERS","security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-01-14T18:00:45.000Z","updated_at":"2026-03-19T20:46:35.000Z","dependencies_parsed_at":"2025-01-17T18:38:19.266Z","dependency_job_id":"3aebe6d7-3e49-4413-9c11-caf2e5a9f693","html_url":"https://github.com/PostHog/posthog-dotnet","commit_stats":null,"previous_names":["posthog/posthog-dotnet"],"tags_count":40,"template":false,"template_full_name":null,"purl":"pkg:github/PostHog/posthog-dotnet","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/PostHog%2Fposthog-dotnet","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/PostHog%2Fposthog-dotnet/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/PostHog%2Fposthog-dotnet/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/PostHog%2Fposthog-dotnet/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/PostHog","download_url":"https://codeload.github.com/PostHog/posthog-dotnet/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/PostHog%2Fposthog-dotnet/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31290964,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-01T13:12:26.723Z","status":"ssl_error","status_checked_at":"2026-04-01T13:12:25.102Z","response_time":53,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2025-07-18T07:08:28.354Z","updated_at":"2026-04-01T18:50:42.008Z","avatar_url":"https://github.com/PostHog.png","language":"C#","funding_links":[],"categories":[],"sub_categories":[],"readme":"# PostHog DotNet Client SDK ![Build status](https://github.com/PostHog/posthog-dotnet/actions/workflows/main.yaml/badge.svg?branch=main)\n\nThis repository contains a set of packages for interacting with the PostHog API in .NET applications. \nThis README is for those who wish to contribute to these packages.\n\nFor documentation on the specific packages, see the README files in the respective package directories.\n\n## Packages\n\n| Package | Version | Description\n|---------|---------| -----------\n| [PostHog.AspNetCore](src/PostHog.AspNetCore/README.md) | [![NuGet version (PostHog.AspNetCore)](https://img.shields.io/nuget/v/PostHog.AspNetCore.svg?style=flat-square)](https://www.nuget.org/packages/PostHog.AspNetCore/) | For use in ASP.NET Core projects.\n| [PostHog](src/PostHog/README.md) | [![NuGet version (PostHog)](https://img.shields.io/nuget/v/PostHog.svg?style=flat-square)](https://www.nuget.org/packages/PostHog/)                                  | The core library. Over time, this will support client environments such as Unit, Xamarin, etc.\n| [PostHog.AI](src/PostHog.AI/README.md) | [![NuGet version (PostHog.AI)](https://img.shields.io/nuget/v/PostHog.AI.svg?style=flat-square)](https://www.nuget.org/packages/PostHog.AI/) | AI Observability for OpenAI and other LLM providers.\n\n\u003e [!WARNING]  \n\u003e These packages are currently in a pre-release stage. We're making them available publicly to solicit \n\u003e feedback. While we always strive to maintain a high level of quality, use these packages at your own \n\u003e risk. There *will* be many breaking changes until we reach a stable release.\n\n## Platform\n\nThe core [PostHog](./src/PostHog/README.md) package targets `netstandard2.1` and `net8.0` for broad compatibility. The [PostHog.AspNetCore](src/PostHog.AspNetCore/README.md) package targets `net8.0`. The [PostHog.AI](src/PostHog.AI/README.md) package targets `netstandard2.1` and `net8.0` for broad compatibility.\n\n## Building\n\nTo build the solution, run the following commands in the root of the repository:\n\n```bash\n$ dotnet restore\n$ dotnet build\n```\n\n## Docs\n\nMore detailed docs for using this library can be found at [PostHog Docs for the .NET Client SDK](https://posthog.com/docs/libraries/dotnet).\n\n## Samples\n\nSample projects are located in the `samples` directory.\n\nTo run the samples, you'll need to set your PostHog project API key. From the repository root you can run:\n\n```bash\nbin/user-secrets set PostHog:ProjectApiKey YOUR_API_KEY\n```\n\nThe main ASP.NET Core sample app can be run with the following command:\n\n```bash\n$ bin/start\n```\n\nYou can also run it from your favorite IDE or editor.\n\n## Testing\n\nTo run the tests, run the following command in the root of the repository:\n\n```bash\n$ dotnet test\n```\n\n### Test Target Frameworks\n\nThe test projects target both `net8.0` and `netcoreapp3.1`. While .NET Core 3.1 reached end-of-life in December 2022, we continue to test against it because:\n\n- It was the first runtime to fully support .NET Standard 2.1\n- It serves as our minimum test baseline to ensure the `netstandard2.1` library works correctly on older runtimes\n- It helps catch compatibility issues that might not surface on newer runtimes\n\nThis testing approach ensures broad compatibility without requiring users to install legacy runtimes in production.\n\n## Publishing Releases\n\nReleases are driven by PR labels. When a PR with the right labels is merged to `main`, a GitHub Actions workflow handles version bumping, tagging, creating a GitHub Release (with auto-generated notes), and publishing to NuGet.\n\n### Release Process\n\n1. Add the `release` label and exactly one of `bump-patch`, `bump-minor`, or `bump-major` to your PR\n2. Merge the PR to `main`\n3. Approve the release in the GitHub Environment gate (the workflow pauses for maintainer approval)\n4. The workflow bumps the version in `Directory.Build.props`, commits to `main`, creates a git tag, and creates a GitHub Release\n5. The GitHub Release triggers the [`main.yaml`](.github/workflows/main.yaml) workflow, which builds and publishes the packages to NuGet\n\n## Installation\n\nFor ASP.NET Core projects, install the `PostHog.AspNetCore` package:\n\n```bash\n$ dotnet add package PostHog.AspNetCore\n```\n\nAnd register the PostHog services in `Program.cs` (or `Startup.cs`) file by calling the `AddPostHog` extension \nmethod on `IHostApplicationBuilder` like so:\n\n```csharp\nusing PostHog;\nvar builder = WebApplication.CreateBuilder(args);\nbuilder.AddPostHog();\n```\n\nFor other .NET projects, install the `PostHog` package:\n\n```bash\n$ dotnet add package PostHog\n```\n\nAnd if your project supports dependency injection, register the PostHog services in `Program.cs` (or `Startup.cs`) \nfile by calling the `AddPostHog` extension method on `IServiceCollection`. Here's an example for a console app:\n\n```csharp\nusing PostHog;\nvar services = new ServiceCollection();\nservices.AddPostHog();\nvar serviceProvider = services.BuildServiceProvider();\nvar posthog = serviceProvider.GetRequiredService\u003cIPostHogClient\u003e();\n```\n\nFor a console app (or apps not using dependency injection), you can also use the `PostHogClient` directly, just make \nsure it's a singleton:\n\n```csharp\nusing System;\nusing PostHog;\n\nvar posthog = new PostHogClient(Environment.GetEnvironmentVariable(\"PostHog__PersonalApiKey\"));\n```\n\nThe `AddPostHog` methods accept an optional `Action\u003cPostHogOptions\u003e` parameter that you can use to configure the \nclient. For examples, check out the [HogTied.Web sample project](../samples/HogTied.Web/Program.cs) and the unit tests.\n\n## Usage\n\nInject the `IPostHogClient` interface into your controller or page:\n\n```csharp\nposthog.Capture(userId, \"user signed up\", new() { [\"plan\"] = \"pro\" });\n```\n\n```csharp\nclient.CapturePageView(userId, Request.Path.Value ?? \"Unknown\");\n```\n\n### Identity\n\n#### Identify a user\n\nSee the [Identifying users](https://posthog.com/docs/product-analytics/identify) for more information about identifying users.\n\nIdentifying a user typically happens on the front-end. For example, when an authenticated user logs in, you can call `identify` to associate the user with their previously anonymous actions.\n\nWhen `identify` is called the first-time for a distinct id, PostHog will create a new user profile. If the user already exists, PostHog will update the user profile with the new data. So the typical usage of `IdentifyAsync` here will be to update the person properties that PostHog knows about your user.\n\n```csharp\nawait posthog.IdentifyAsync(\n    userId,\n    new() \n    {\n        [\"email\"] = \"haacked@posthog.com\",\n        [\"name\"] = \"Phil Haack\",\n        [\"plan\"] = \"pro\"\n    });\n```\n\n#### Alias a user\n\nUse the `Alias` method to associate one identity with another. This is useful when a user logs in and you want to associate their anonymous actions with their authenticated actions.\n\n```csharp\nawait posthog.AliasAsync(sessionId, userId);\n```\n\n### Analytics\n\n#### Capture an Event\n\nNote that capturing events is designed to be fast and done in the background. You can configure how often batches are sent to the PostHog API using the `FlushAt` and `FlushInterval` settings.\n\n```csharp\nposthog.Capture(userId, \"user signed up\", new() { [\"plan\"] = \"pro\" });\n```\n\n#### Capture a Page View\n\n```csharp\nposthog.CapturePageView(userId, Request.Path.Value ?? \"Unknown\");\n```\n\n#### Capture a Screen View\n\n```csharp\nposthog.CaptureScreen(userId, \"Main Screen\");\n```\n\n### Feature Flags\n\n#### Check if feature flag is enabled\n\nCheck if the `awesome-new-feature` feature flag is enabled for the user with the id `userId`.\n\n```csharp\nvar enabled = await posthog.IsFeatureEnabledAsync(userId, \"awesome-new-feature\");\n```\n\nYou can override properties of the user stored on PostHog servers for the purposes of feature flag evaluation. \nFor example, suppose you offer a temporary pro-plan for the duration of the user's session. You might do this:\n\n```csharp\nif (await posthog.IsFeatureEnabledAsync(\n    \"pro-feature\",\n    \"some-user-id\",\n    personProperties: new() { [\"plan\"] = \"pro\" }))\n{\n    // Access to pro feature\n}\n```\n\nIf you have group analytics enabled, you can also override group properties.\n\n```csharp\nif (await posthog.IsFeatureEnabledAsync(\n        \"large-project-feature\",\n        \"some-user-id\",\n        new FeatureFlagOptions\n        {\n            Groups = [new Group(groupType: \"project\", groupKey: \"project-group-key\") { [\"size\"] = \"large\" }]\n        }))\n{\n    // Access large project feature\n}\n```\n\n\u003e [!NOTE]\n\u003e Specifying `PersonProperties` and `GroupProperties` is necessary when using local evaluation of feature flags.\n\n### Get a single Feature Flag\n\nSome feature flags may have associated payloads.\n\n```csharp\nif (await posthog.GetFeatureFlagAsync(\"awesome-new-feature\", \"some-user-id\") is { Payload: {} payload })\n{\n    // Do something with the payload.\n    Console.WriteLine($\"The payload is: {payload}\");\n}\n```\n\n### Get All Feature Flags\n\nUsing information on the PostHog server.\n\n```csharp\nvar flags = await posthog.GetAllFeatureFlagsAsync(\"some-user-id\");\n```\n\nOverriding the group properties for the current user.\n\n```csharp\nvar flags = await posthog.GetAllFeatureFlagsAsync(\n\"some-user-id\",\noptions: new AllFeatureFlagsOptions\n{\n    Groups =\n    [\n        new Group(\"project\", \"aaaa-bbbb-cccc\")\n        {\n            [\"$group_key\"] = \"aaaa-bbbb-cccc\",\n            [\"size\"] = \"large\"\n        }\n    ]\n});\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fposthog%2Fposthog-dotnet","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fposthog%2Fposthog-dotnet","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fposthog%2Fposthog-dotnet/lists"}