YandexNet.Metrika
0.1.0-preview.1
dotnet add package YandexNet.Metrika --version 0.1.0-preview.1
NuGet\Install-Package YandexNet.Metrika -Version 0.1.0-preview.1
<PackageReference Include="YandexNet.Metrika" Version="0.1.0-preview.1" />
<PackageVersion Include="YandexNet.Metrika" Version="0.1.0-preview.1" />
<PackageReference Include="YandexNet.Metrika" />
paket add YandexNet.Metrika --version 0.1.0-preview.1
#r "nuget: YandexNet.Metrika, 0.1.0-preview.1"
#:package YandexNet.Metrika@0.1.0-preview.1
#addin nuget:?package=YandexNet.Metrika&version=0.1.0-preview.1&prerelease
#tool nuget:?package=YandexNet.Metrika&version=0.1.0-preview.1&prerelease
<table> <tr> <td width="170" align="center" valign="middle"> <img src="https://raw.githubusercontent.com/ai-iskuzhin/YandexNet.Metrika/main/assets/logo.png" width="140" alt="YandexNet.Metrika logo" /> </td> <td valign="middle"> <h1>YandexNet.Metrika</h1> <p>A small, <strong>stateless</strong> .NET SDK for the <strong>Yandex Metrika</strong> API: manage goals, upload <strong>offline conversions</strong> (server-side revenue attribution), and read reports. Ships Yandex OAuth 2.0 helpers — or <strong>bypass OAuth entirely and pass a token you already have</strong>.</p> <p> <a href="https://github.com/ai-iskuzhin/YandexNet.Metrika/actions/workflows/ci.yml"><img src="https://github.com/ai-iskuzhin/YandexNet.Metrika/actions/workflows/ci.yml/badge.svg?branch=main" alt="CI" /></a> <a href="https://github.com/ai-iskuzhin/YandexNet.Metrika/actions/workflows/deployment.yml"><img src="https://github.com/ai-iskuzhin/YandexNet.Metrika/actions/workflows/deployment.yml/badge.svg" alt="Deployment" /></a> <a href="https://github.com/ai-iskuzhin/YandexNet.Metrika/blob/main/LICENSE"><img src="https://img.shields.io/github/license/ai-iskuzhin/YandexNet.Metrika?style=flat-square" alt="License" /></a> <a href="https://dotnet.microsoft.com/"><img src="https://img.shields.io/badge/targets-netstandard2.0%20%7C%20net8.0%20%7C%20net10.0-512BD4?logo=dotnet&style=flat-square" alt="Targets" /></a> </p> <p> <a href="https://www.nuget.org/packages/YandexNet.Metrika"><img src="https://img.shields.io/nuget/v/YandexNet.Metrika?logo=nuget&style=flat-square" alt="NuGet version" /></a> <a href="https://www.nuget.org/packages/YandexNet.Metrika"><img src="https://img.shields.io/nuget/dt/YandexNet.Metrika?style=flat-square" alt="NuGet downloads" /></a> </p> </td> </tr> </table>
The SDK never stores or refreshes tokens and keeps no background state. Your integration owns the token
lifecycle; the clients are thin wrappers over HttpClient.
- Only dependency:
System.Text.Json. - Targets
netstandard2.0,net8.0,net10.0.
Install
dotnet add package YandexNet.Metrika
Authenticate — two ways
1. Bring your own token (bypass OAuth)
If OAuth is already wired somewhere else in your stack, just pass the access token — you never touch the OAuth client:
using YandexNet.Metrika;
var metrika = new YandexMetrikaClient(httpClient, new YandexMetrikaClientOptions
{
AccessToken = accessToken, // obtained however you like
});
2. Run the OAuth flow (link an account)
Stateless helpers for the authorization-code flow. You store what they return and decide when to refresh — the SDK does neither.
var oauth = new YandexOAuthClient(httpClient, new YandexOAuthOptions
{
ClientId = "…", ClientSecret = "…",
});
// 1) redirect the admin here (verify `state` on the callback):
string url = oauth.BuildAuthorizeUrl(new YandexAuthorizeRequest
{
Scope = $"{YandexMetrikaConstants.Scopes.Read} {YandexMetrikaConstants.Scopes.Write}",
State = state,
RedirectUri = "https://your.app/callback",
});
// 2) on the callback, exchange the code — then persist the tokens yourself:
YandexTokenResponse token = await oauth.ExchangeCodeAsync(code, "https://your.app/callback");
// store token.AccessToken + token.RefreshToken; compute expiry from your clock: now + token.ExpiresIn
// 3) later, when you decide it's expired, refresh (SDK does not auto-refresh):
YandexTokenResponse refreshed = await oauth.RefreshTokenAsync(storedRefreshToken);
When a Metrika call returns 401/403 (YandexMetrikaApiException.IsAuthError), refresh the token and build
a new YandexMetrikaClient.
Goals
var goals = await metrika.ListGoalsAsync(counterId);
var created = await metrika.CreateGoalAsync(counterId, new MetrikaGoal
{
Name = "app_open",
Type = "action", // JS-event goal
Conditions = new[] { new MetrikaGoalCondition { Type = "exact", Url = "app_open" } },
});
await metrika.DeleteGoalAsync(counterId, created.Id!.Value);
Offline conversions (revenue attribution)
Attribute server-side money (a signup that later paid, a verified order) to a visitor Metrika saw earlier.
Capture the ClientId in the browser (ym(id,'getClientID',…)), send it to your backend, then upload:
var result = await metrika.UploadOfflineConversionsAsync(counterId, new[]
{
new OfflineConversion
{
ClientId = clientId, // must be one Metrika already saw
Target = "topup_paid", // a goal identifier — never reuse a browser-side goal name
DateTime = DateTimeOffset.UtcNow,
Price = 1500.50m,
Currency = "RUB",
},
});
// result.Status == "UPLOADED", result.LineQuantity == 1
Use MetrikaClientIdType.UserId to key by your own user id instead. Uploaded conversions surface after a
few hours and dedupe by (ClientId, Target, DateTime) on Yandex's side.
Reporting
var report = await metrika.GetReportAsync(counterId, new MetrikaReportQuery
{
Metrics = new[] { "ym:s:goal12reaches" },
Dimensions = new[] { "ym:s:date" },
Date1 = "7daysAgo", Date2 = "today",
});
foreach (var row in report.Data)
{
var date = row.Dimensions[0].GetProperty("name").GetString();
var reaches = row.Metrics[0];
}
Error model
All failures derive from YandexMetrikaException:
YandexMetrikaTransportException— network/TLS/timeout; no response.YandexMetrikaApiException— Yandex returned an error.Error/ErrorDescription/StatusCode;IsAuthErroris true for 401/403;RequestIdcarriesX-RequestIdfor support.YandexMetrikaProtocolException— a response arrived but couldn't be parsed.
Design
- Stateless. No token storage, no auto-refresh, no timers — the integration owns all of that.
- OAuth is optional.
YandexMetrikaClientonly needs an access token; the OAuth client is a separate, skippable helper. HttpClientis yours. Inject and pool it (e.g. viaIHttpClientFactory); configure handlers/retries at that layer.
License
MIT — see LICENSE.
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net5.0 was computed. net5.0-windows was computed. net6.0 was computed. net6.0-android was computed. net6.0-ios was computed. net6.0-maccatalyst was computed. net6.0-macos was computed. net6.0-tvos was computed. net6.0-windows was computed. net7.0 was computed. net7.0-android was computed. net7.0-ios was computed. net7.0-maccatalyst was computed. net7.0-macos was computed. net7.0-tvos was computed. net7.0-windows was computed. 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 is compatible. 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. |
| .NET Core | netcoreapp2.0 was computed. netcoreapp2.1 was computed. netcoreapp2.2 was computed. netcoreapp3.0 was computed. netcoreapp3.1 was computed. |
| .NET Standard | netstandard2.0 is compatible. netstandard2.1 was computed. |
| .NET Framework | net461 was computed. net462 was computed. net463 was computed. net47 was computed. net471 was computed. net472 was computed. net48 was computed. net481 was computed. |
| MonoAndroid | monoandroid was computed. |
| MonoMac | monomac was computed. |
| MonoTouch | monotouch was computed. |
| Tizen | tizen40 was computed. tizen60 was computed. |
| Xamarin.iOS | xamarinios was computed. |
| Xamarin.Mac | xamarinmac was computed. |
| Xamarin.TVOS | xamarintvos was computed. |
| Xamarin.WatchOS | xamarinwatchos was computed. |
-
.NETStandard 2.0
- System.Net.Http.Json (>= 8.0.1)
- System.Text.Json (>= 8.0.6)
-
net10.0
- No dependencies.
-
net8.0
- No dependencies.
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 0.1.0-preview.1 | 42 | 8/2/2026 |