Documentation

Sentry handles licensing, authentication, software delivery, and user management for desktop applications. This guide covers the APIs, the signed authentication response, and the SDKs.

Introduction

Applications authenticate against the public API with an app key plus either a license key or user credentials. Each application has its own Ed25519 key pair. Responses are signed with the private key and verified in your client against the embedded public key, so a client can tell a real response from a forged one.

Licenses, builds, users, bans and webhooks are managed from the dashboard or the management API.

The platform includes:

  • Tenant dashboard
  • Public client API: what your shipped software calls
  • Management API: server-to-server automation
  • Webhooks
  • C/C++ and C#/.NET SDKs
  • Ed25519-signed authentication responses
New to the API? Start with the Quickstart: create an app, mint a key, and authenticate it.

Quickstart

These steps use the hosted API. There is nothing to install.

1. Create an app

Sign in to the dashboard and create an app. It gets an Ed25519 key pair. Copy its app_key and pubkey_hex. The public key ships in your client.

2. Mint a license key

Create keys with seats, an expiry and tags, one at a time or in bulk from a template.

3. Authenticate a key

POST /api/v1/auth
curl -s https://api.sentry.example/api/v1/auth \
  -H 'content-type: application/json' \
  -d '{"app_key":"app_...","key":"KEY-XXXX-YYYY","hwid":"machine-id","nonce":"a1b2"}'

4. Verify the response

Call auth from an SDK. It checks sig against the public key before reading any field, so you don't touch the signature yourself.

Common mistakeDon't rebuild sd from the JSON fields. Verify the exact bytes the server returned, then read the fields out of them.

Architecture

There are three APIs, each with its own authentication method:

APIPathAuthCalled by
Public client/api/v1/*app_key + license or user credentialsyour shipped software
Dashboard/account/*, /dashboard/api/*session cookiethe tenant dashboard
Management/api/v1/manage/*Authorization: Beareryour backend / automation

The app key identifies the application on every public call. Application-scoped queries are constrained by the owning tenant, so one tenant can't read or modify another's data.

Authentication flow

Client │ POST /api/v1/auth { app_key, key, hwid, nonce } ▼ Public API │ check license (valid, not expired, not disabled) │ check HWID / seat limit │ check bans (hwid, ip) │ sign the response with the app's Ed25519 private key ▼ Client verify the signature, then read the fields

Authentication response

A successful authentication returns two fields:

FieldDescription
sdThe signed payload: key=value pairs joined with |.
sigEd25519 signature over the bytes of sd, base64-encoded.
sd
v=1|ts=..|nonce=..|hwid=..|ok=1|username=..|name=..|expires=..|latest_version=..

Verify in this order and stop on the first failure:

CheckWhy
Verify sig over the exact bytes of sdProves the response came from the app's private key, not a spoofed or proxied server.
Check ok=1The request was allowed.
Check nonce matches the one you sentConfirms the response belongs to this request and blocks replayed responses.
Check hwid matches this machineConfirms the response was issued for this device.
Check ts is recentRejects a stale response captured from an earlier session.

Read name, expires and latest_version only after every check passes.

Rotating keysIf you rotate an application's signing key, existing clients can no longer verify new responses. Ship an update carrying the new public key before you rotate a production key.

Developer notes

  • sd is UTF-8 and uses | as the field delimiter.
  • Field order is fixed. A new field bumps the v= version; verify against the version you built against.
  • Ignore fields you don't recognize.
  • Reject a ts older than five minutes.
  • Verify the signature before parsing anything out of sd.

Public client API

Base path /api/v1. Select the app with app_key (JSON body on POST, query string on GET). Signed endpoints require a hwid and accept an optional nonce.

EndpointBodyPurpose
POST /authkey, hwid, nonce?Validate a bare license key. Signed response.
POST /registerusername, password, key, hwidCreate an account by redeeming a key.
POST /loginusername, password, hwidAuthenticate an existing account.
POST /file/latestkey or username,passwordDownload the latest build; hash + signature verified.
POST /pollsessionLong-poll control channel (protocol v2).
GET /pubkeyqueryThe app's ed25519 public key (bootstrapping).
GET /versionqueryThe advertised latest version.

Seat enforcement is automatic: a key admits an hwid that is already a device, or while the key has fewer active devices than its seats; otherwise it is denied with seat_limit_reached.

Sessions & long-poll (protocol v2)

Send proto: 2 on auth. The response then includes a session token, and the client can hold a control channel with POST /poll: the server holds the request up to ~25 seconds and returns as soon as a directive is queued for that session, otherwise it returns idle.

DirectiveMeaning
revokedSession or device revoked. Stop the client.
killApp paused (kill switch). Stop the client.
update_requiredClient is below the enforced minimum version.
idleWindow elapsed with nothing queued. Reconnect.

A client that doesn't send proto:2 gets the v=1 response unchanged.

REST admin API

Base path /api/v1/manage, authenticated with Authorization: Bearer <token>. Create tokens in the dashboard with per-resource scopes and an optional expiry. An empty scope set means full access.

issue a key from your own systems
curl -X POST https://your-host/api/v1/manage/apps/$APP_ID/keys \
  -H 'authorization: Bearer sk_live_...' \
  -H 'content-type: application/json' \
  -d '{"count":1,"expires_days":365}'

Scopes are drawn from keys, users, files and bans, each :read or :write. A route rejects an out-of-scope token with insufficient_scope; expired tokens are rejected at auth.

Webhooks

Register HTTPS endpoints to receive events (auth.success, auth.fail, ban.hit, and more). Deliveries are signed with a per-webhook secret. Targets are validated against SSRF at creation and at delivery. Private, loopback, link-local and metadata addresses are blocked.

SDKs

The SDKs do the verification, manage the session, and handle the long-poll directives. Available for C/C++ and C#/.NET.

C# / .NET

Program.cs
using Sentry;

using var client = new SentryClient(baseUrl, appKey, publicKeyHex,
    useProtocolV2: true,
    device: new SentryDeviceInfo { Version = "1.4.66", Os = "Windows 11" });

var r = await client.AuthAsync("KEY-XXXX-YYYY");
if (!r.Ok) return;                 // r.Reason explains why

// live control channel (revoke / kill / update)
await client.StartPollingAsync(evt => {
  if (evt.Directive == SentryDirective.Revoked) Environment.Exit(0);
}, ct);

C / C++

main.c · libcurl + libsodium
#include "sentry_auth.h"

sentry_config cfg = {0};
cfg.base_url = base_url; cfg.app_key = app_key; cfg.pubkey_hex = pub_hex;
cfg.use_proto2 = 1;

sentry_client *c = sentry_client_new(&cfg, NULL);
sentry_auth_result r;
if (sentry_auth(c, "KEY-XXXX-YYYY", &r) == SENTRY_OK) {
  /* r.name / r.expires are verified and safe to trust */
}

Each SDK ships with a README covering the full API, the build and link setup, and the long-poll loop.

Enterprise & on-prem

The hosted service needs no infrastructure on your side. Self-managed and on-premise deployments are available on the Enterprise plan for compliance, data-residency, or air-gapped environments.

Enterprise also adds SSO, audit-log exports, an SLA, and priority support. App signing keys are encrypted at rest and never leave your tenant.

Need on-prem, SSO or a security review? Get in touch and we’ll scope an Enterprise plan to your requirements.

Security posture

How the platform protects tenants and clients:

  • Signed-string field injection: values reflected into sd are allowlisted at input and stripped of delimiters.
  • One key, one account: redemption is an atomic conditional update backed by a uniqueness constraint.
  • HWID / seat locks: enforced on every auth path.
  • Webhook SSRF: private/loopback/metadata targets blocked at creation and delivery.
  • CSRF: Origin/Referer checked on cookie-authenticated mutations, with SameSite cookies.
  • Encrypted key vault: per-app private seeds are AES-256-GCM encrypted; only public keys are exposed.
  • Role-gated dashboard: read-only members can view but not mutate; team/token/audit routes require admin.
Sentry · licensing & product authentication. Home  ·  Dashboard