Official Go SDK for LicenseKit, the licensing API for software vendors and AI-native products.
It provides typed Management, Runtime, and System clients for the LicenseKit licensing API, including reporting and frozen export operations, plus least-privilege scope metadata and Ed25519 runtime-signature verification helpers for license activation, validation, device binding, metered usage, and offline-aware verification flows.
Links:
- website:
https://licensekit.dev - Go package docs:
https://pkg.go.dev/github.com/drmain1/licensekit-go - docs:
https://licensekit.dev/docs/agent-quickstart - API contract notes:
https://licensekit.dev/docs/api-contract - OpenAPI spec:
https://licensekit.dev/openapi.yaml - TypeScript SDK:
https://www.npmjs.com/package/@licensekit/sdk - Python SDK:
https://pypi.org/project/licensekit-sdk/
The public Go module now lives at github.com/drmain1/licensekit-go.
External users should install:
go get github.com/drmain1/licensekit-goThis sdk/go directory remains the private monorepo source of truth used to generate and test the SDK before public release cuts.
For local development from this repository:
cd sdk/go
go test ./...- Typed Management, Runtime, and System clients generated from the live LicenseKit API contract
- Scope metadata helpers for least-privilege API key design
- Ed25519 runtime-signature verification helpers for trusted runtime validation
- Raw response access for callers that need status codes, headers, or readiness bodies
- Examples that default to
https://api.licensekit.dev
When you are ready to cut the next public Go SDK release:
- Create a dedicated public repository or vanity import path for the Go module.
- Prepare the public module copy with:
bash ./scripts/prepare_public_module.sh /tmp/licensekit-go github.com/drmain1/licensekit-go- From the extracted public module, run:
go test ./...
git tag v1.0.0
git push origin main --tagsThe extraction script rewrites the module path, README examples, and generator imports so the public repo is ready for tagging and indexing.
package main
import (
"context"
"fmt"
"log"
licensekit "github.com/drmain1/licensekit-go"
)
func main() {
ctx := context.Background()
baseURL := "https://api.licensekit.dev"
system, err := licensekit.NewSystemClient(licensekit.SystemClientOptions{
BaseURL: baseURL,
})
if err != nil {
log.Fatal(err)
}
health, err := system.Health(ctx)
if err != nil {
log.Fatal(err)
}
fmt.Println(health.Data.Status)
management, err := licensekit.NewManagementClient(licensekit.ManagementClientOptions{
ClientOptions: licensekit.ClientOptions{
BaseURL: baseURL,
},
Token: "lkm_...",
})
if err != nil {
log.Fatal(err)
}
product, err := management.CreateProduct(ctx, licensekit.CreateProductJSONRequestBody{
Name: "Example App",
Code: "example-app",
})
if err != nil {
log.Fatal(err)
}
runtime, err := licensekit.NewRuntimeClient(licensekit.RuntimeClientOptions{
ClientOptions: licensekit.ClientOptions{
BaseURL: baseURL,
},
LicenseKey: "lsk_...",
})
if err != nil {
log.Fatal(err)
}
fingerprint := "host-123"
result, err := runtime.ValidateLicense(ctx, licensekit.ValidateLicenseJSONRequestBody{
Fingerprint: &fingerprint,
})
if err != nil {
log.Fatal(err)
}
publicKeys, err := system.ListPublicKeys(ctx)
if err != nil {
log.Fatal(err)
}
verified, err := licensekit.VerifyRuntimeResult(result, licensekit.NewPublicKeyStore(publicKeys.Data))
if err != nil {
log.Fatal(err)
}
fmt.Println(product.Data.Id, verified.OK)
}For more usage patterns, see examples/ and the package reference on pkg.go.dev.
ManagementClientUsesAuthorization: Bearer <token>for/api/v1/...management operations, including/api/v1/activitiesand/api/v1/reports/....RuntimeClientUsesAuthorization: License <license-key>for/api/v1/license/...runtime operations.SystemClientUnauthenticated access to/health,/healthz,/readyz,/metrics, and/api/v1/system/public-keys.
Hosted checks should prefer system.Health(ctx) because GET /health is the Cloud Run-safe liveness alias behind api.licensekit.dev.
system.Healthz(ctx) remains available for local and self-hosted compatibility.
required, ok := licensekit.GetRequiredScopes(licensekit.ManagementOperationCreateProduct)
allowed := licensekit.HasRequiredScopes(
licensekit.ManagementOperationCreateProduct,
[]string{"product:write"},
)Each client exposes a Raw companion for callers that need status codes or headers.
ready, err := system.Raw.Readyz(ctx)
if err != nil {
log.Fatal(err)
}
fmt.Println(ready.Status, ready.Data.Data.Status)This is useful for readiness checks, because GET /readyz may legitimately return 503 with a structured JSON body instead of an error envelope.
management.DownloadReportExport(ctx, id) returns raw bytes so JSON, CSV, and PDF report snapshots can all be handled without assuming a single response schema. Use management.Raw.DownloadReportExport(...) when you also need the response headers to branch on Content-Type.
Task-oriented examples live in examples/:
01_create_scoped_api_key.go02_create_product_and_policy.go03_create_customer_and_license.go04_runtime_validate_and_verify.go05_renew_license.go06_reset_device.go
All examples default to https://api.licensekit.dev and can be redirected with LICENSEKIT_BASE_URL.
Regenerate the SDK from the current OpenAPI:
go generate ./...Format and test:
gofmt -w *.go generated/*.go
go test ./...The low-level generated transport layer is recreated from the checked-in OpenAPI snapshot at openapi/openapi.yaml. In the private monorepo, go generate will refresh that snapshot from the backend contract automatically.