VoidhashDocs
DevelopersHelp centerGuidesAPI reference
Dashboard
Get started
Introduction
Quickstart
How Voidhash works
Glossary
Versions and releases
Concepts
Teams, projects and environments
API keys
Products and perks
Offers
Subscription lifecycle
People and identity
Groups
Events
Features
Paywalls in your app
Feature flags and A/B tests
Paywall components
Push notifications
Ad attribution in your app
Client SDKs
React Native
Swift
Kotlin
Web
Your backend
Node.js
PHP
Go
Rust
Other languages
Payment sources
Forward store notifications
Developer tools
CLI
MCP server
Query analytics with VoidQL
Go library
Check access
Receive webhooks
Persons and events
Custom payment providers

Go library

A context-aware server-side client for the Voidhash API.

github.com/voidhashcom/voidhash-go is a context-aware client for Go backends. It needs a secret key, so run it on your server only.

Install

github.com/voidhashcom/voidhash-go installs from a clone of the Voidhash repository, through a replace directive:

git clone https://github.com/voidhashcom/voidhash.git third_party/voidhash
go mod edit -replace github.com/voidhashcom/voidhash-go=./third_party/voidhash/libraries/go
go get github.com/voidhashcom/voidhash-go

To pin a build, check out a commit in the clone (git -C third_party/voidhash checkout <commit>), or add the repository as a Git submodule so your repository records the commit.

Alpha

The library is an alpha release and isn't on the Go module proxy yet. Pin a commit and update regularly. See Versions and releases.

Requirements: Go 1.22 or later. The client sends requests with net/http.

Create a client

Create one client with your secret key and share it across your server. It is safe for concurrent use.

main.go
package main

import (
	"log"
	"os"

	voidhash "github.com/voidhashcom/voidhash-go"
)

func main() {
	client, err := voidhash.New(
		os.Getenv("VOIDHASH_SECRET_KEY"),
		// Event capture is served from the API host for now.
		voidhash.WithIngestURL("https://api.voidhash.com"),
	)
	if err != nil {
		log.Fatalf("create voidhash client: %v", err)
	}
	_ = client // pass it to your handlers
}

New takes the secret key and these options:

OptionDefaultDescription
WithProjectID(id)The key's projectSkips the project lookup. Concurrent first calls share one lookup.
WithBaseURL(url)https://api.voidhash.comThe API origin.
WithIngestURL(url)https://ingest.voidhash.comThe event capture origin. Use https://api.voidhash.com; the default host doesn't answer yet.
WithPublishableKey(key)—Sent as the body token on event capture. Optional.
WithHTTPClient(client)A client with no timeoutAn *http.Client for timeouts, proxies or tracing.
WithHeader(name, value)—An extra header for every request. Repeat it for more.

New makes no request. It returns an error when the secret key is empty or a header sets Authorization or x-secret-key.

Call the API

Each resource is a service field on the client, such as client.Persons or client.Webhooks. Every method takes a context.Context first, then IDs and a params struct. Request and response types mirror the API reference; optional fields are pointers. List methods follow every page and return a slice.

perks, err := client.Perks.List(ctx)
if err != nil {
	return err
}
for _, perk := range perks {
	fmt.Println(perk.Slug)
}

email := "ada@example.com"
person, err := client.Persons.Create(ctx, voidhash.CreatePersonParams{
	DistinctId: "user_123",
	Email:      &email,
})
FieldCovers
PersonsPersons, attributes and access checks.
Perks, ProductsThe catalog, and the perks each product grants.
PaywallsPaywall locations.
WebhooksWebhook endpoints and deliveries.
EventCaptureEvents.
NotificationsPush notifications.
PaymentSourcesPayment sources.
APIKeys, SchemaThe project's API keys and runtime schema.

For an endpoint without a method here, call the REST API directly.

Handle errors

A failed API call returns a *voidhash.APIError holding the API error. Read it with errors.As and branch on Type and Code:

person, err := client.Persons.Get(ctx, "person_k2v9x4m8q1r3")

var apiErr *voidhash.APIError
switch {
case err == nil:
	return person, nil
case errors.As(err, &apiErr) && apiErr.Type == "not_found":
	return nil, nil
case errors.As(err, &apiErr) && (apiErr.Type == "unauthenticated" || apiErr.Type == "permission_denied"):
	return nil, fmt.Errorf("the Voidhash secret key is invalid or lacks access: %w", err)
default:
	return nil, err
}

It also carries Param, the HTTP StatusCode and the RequestID. voidhash.IsNotFound(err) and voidhash.StatusCode(err) work through wrapped errors. A client misconfiguration is an *APIError with status 400 and no Type. Network failures and context cancellation are returned as the underlying error, not an *APIError. The library doesn't retry or cache.

Timeouts and cancellation

Every call stops when its context ends, so pass the request's context and give it a deadline:

ctx, cancel := context.WithTimeout(r.Context(), 5*time.Second)
defer cancel()

perks, err := client.Perks.List(ctx)

For a client-wide limit, pass voidhash.WithHTTPClient(&http.Client{Timeout: 10 * time.Second}).

Next steps

  • Check access
  • Receive webhooks
  • Persons and events
  • Custom payment providers

Something wrong or missing on this page? Tell us by email or on Discord.

PreviousCustom payment providersNextCheck access

On this page

InstallCreate a clientCall the APIHandle errorsTimeouts and cancellationNext steps