Kiwicodes.Beacon.Sdk
1.2.5
dotnet add package Kiwicodes.Beacon.Sdk --version 1.2.5
NuGet\Install-Package Kiwicodes.Beacon.Sdk -Version 1.2.5
<PackageReference Include="Kiwicodes.Beacon.Sdk" Version="1.2.5" />
<PackageVersion Include="Kiwicodes.Beacon.Sdk" Version="1.2.5" />
<PackageReference Include="Kiwicodes.Beacon.Sdk" />
paket add Kiwicodes.Beacon.Sdk --version 1.2.5
#r "nuget: Kiwicodes.Beacon.Sdk, 1.2.5"
#:package Kiwicodes.Beacon.Sdk@1.2.5
#addin nuget:?package=Kiwicodes.Beacon.Sdk&version=1.2.5
#tool nuget:?package=Kiwicodes.Beacon.Sdk&version=1.2.5
Beacon.Sdk
Official .NET client for the Beacon support platform's external APIs. Two clients:
BeaconIntakeClient— submit feedback/bug/feature/todo items to a Beacon app, signed with your app's per-app HMAC credentials. (server-to-server)BeaconPublicClient— the anonymous public endpoints: customer-portal ticket submit/track/reply/rate, the public knowledge base, and the inbound-email webhook. (no secret required)
Install
dotnet add package Beacon.Sdk
Targets net8.0 (usable on .NET 8 and later).
Get your credentials
In the Beacon app, sign in, click your name (top-right) → Settings → pick an app you own → Generate key pair. You'll get:
- a public key (
bk_pub_…) — sent with each request - a shared secret — shown once; store it securely (it signs requests and is never transmitted)
The key authorizes posting issues to that one app; the app is set server-side, so you never specify it from the client.
Quick start (standalone)
using Beacon.Sdk;
using Beacon.Sdk.Models;
using var beacon = BeaconIntakeClient.Create(new BeaconSdkOptions
{
BaseUrl = "https://your-beacon.azurewebsites.net/api/",
PublicKey = "bk_pub_xxxxxxxxxxxxxxxxxxxxxxxx",
SharedSecret = Environment.GetEnvironmentVariable("BEACON_SECRET")!,
});
var issue = await beacon.SubmitAsync(new IntakeSubmission
{
Title = "Checkout button does nothing on iOS",
Description = "Tapping Pay on the cart screen has no effect.",
Type = IssueTypes.Bug,
Priority = IssuePriorities.High,
Reporter = "jane@customer.com",
Labels = { "mobile", "checkout" },
Attachments = { new IntakeAttachment("https://files.example.com/crash.txt", "Crash log") },
});
Console.WriteLine($"Filed {issue.Id} against {issue.App}.");
There's also a terse overload:
await beacon.SubmitAsync("Typo on the pricing page", type: IssueTypes.Feedback);
Dependency injection (ASP.NET Core, workers, etc.)
builder.Services.AddBeaconSdk(o =>
{
o.BaseUrl = builder.Configuration["Beacon:BaseUrl"]!;
o.PublicKey = builder.Configuration["Beacon:PublicKey"]!;
o.SharedSecret = builder.Configuration["Beacon:SharedSecret"]!;
});
public class SupportController(BeaconIntakeClient beacon) : ControllerBase
{
[HttpPost("report")]
public async Task<IActionResult> Report(string title)
{
var issue = await beacon.SubmitAsync(title, type: IssueTypes.Feedback);
return Ok(new { issue.Id });
}
}
The typed client is backed by IHttpClientFactory, so handler lifetimes and
connection pooling are managed for you.
Errors
SubmitAsync throws BeaconApiException (with StatusCode and ResponseBody)
on a non-success response. A 401 usually means the signature was wrong or the
key was rotated/disabled; a 400 means the submission was rejected.
Public endpoints (BeaconPublicClient)
These hit Beacon's anonymous /api/public/* routes — no shared secret. The
portal key is simply your app's public key (bk_pub_…); it identifies which
app a ticket is filed against. Set it once as the client's default.
using Beacon.Sdk;
using var portal = BeaconPublicClient.Create(
"https://your-beacon.azurewebsites.net/api/",
defaultPortalKey: "bk_pub_xxxxxxxxxxxxxxxxxxxxxxxx");
// Submit a ticket; you get back an id + a token for the tracking link.
var result = await portal.SubmitTicketAsync(
subject: "Can't reset my password",
description: "The reset email never arrives.",
requesterName: "Sam Lee",
requesterEmail: "sam@example.com");
var trackUrl = $"https://your-beacon/portal/ticket/{result.Id}?token={Uri.EscapeDataString(result.Token)}";
// Track / reply / rate later with that token:
var ticket = await portal.GetTicketAsync(result.Id, result.Token);
await portal.ReplyAsync(result.Id, result.Token, "Any update?");
await portal.RateAsync(result.Id, result.Token, 5); // only after it's resolved
// Knowledge base (published, public articles only):
var articles = await portal.ListArticlesAsync(q: "password");
var article = await portal.GetArticleAsync("KB-103");
await portal.SendArticleFeedbackAsync("KB-103", helpful: true);
DI registration (when you don't need HMAC intake):
builder.Services.AddBeaconPublicClient(
builder.Configuration["Beacon:BaseUrl"]!,
defaultPortalKey: builder.Configuration["Beacon:PublicKey"]);
AddBeaconSdk(...) registers both clients, using your configured public key
as the public client's default portal key. All public methods throw
BeaconApiException on a non-success status; lookups (GetTicketAsync,
GetArticleAsync, GetPortalInfoAsync) return null on 404.
Inbound email
If you're building a custom mail bridge, forward parsed messages to the webhook
(secret is the API's Inbound:Secret):
await portal.SendInboundEmailAsync(new InboundEmail
{
From = "jane@example.com", FromName = "Jane Doe",
Subject = "Re: [TKT-104] Login button does nothing",
Text = "Still broken on Safari.",
}, secret: "your-inbound-secret");
A [TKT-id] tag in the subject threads onto that ticket; otherwise a new
source=email ticket is opened.
How signing works
Each request carries:
Date: current UTC time, RFC1123Authorization:algorithm="hmac-sha256", headers="date", signature="…", apikey="…"
where signature = Base64(HMACSHA256("beacon-intake\ndate: {date}", sharedSecret)).
Requests must be sent within the server's clock-skew window (15 minutes by
default), so keep the machine clock reasonably accurate. If you're using your own
HttpClient pipeline, add BeaconHmacSigningHandler as a delegating handler to
sign automatically.
| Product | Versions 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. |
-
net8.0
- Microsoft.Extensions.Http (>= 8.0.1)
NuGet packages (2)
Showing the top 2 NuGet packages that depend on Kiwicodes.Beacon.Sdk:
| Package | Downloads |
|---|---|
|
Kiwicodes.Beacon.HelpCenter.Wpf
A drop-in, themeable WPF help center (customer portal) control for the Beacon support platform. Renders the knowledge base, request submission and ticket tracking from a single <BeaconHelpCenter> control. Point it at your Beacon API base URL and your app's portal key, set a brand colour, and embed it anywhere in your own WPF app. A faithful port of the Blazor Kiwicodes.Beacon.HelpCenter, backed by Kiwicodes.Beacon.Sdk's BeaconPublicClient for all public/* endpoints. |
|
|
Kiwicodes.Beacon.HelpCenter.Blazor
A drop-in, themeable Blazor help center (customer portal) component for the Beacon support platform. Renders the knowledge base, request submission and ticket tracking from a single <BeaconHelpCenter> component. Point it at your Beacon API base URL and your app's portal key, set a brand colour, and embed it anywhere in your own Blazor app. Backed by Kiwicodes.Beacon.Sdk's BeaconPublicClient for all public/* endpoints. |
GitHub repositories
This package is not used by any popular GitHub repositories.