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
Rust library
Check access
Receive webhooks
Persons and events
Custom payment providers

Rust library

An async server-side client for the Voidhash API, built on Tokio and reqwest.

The voidhash crate is an async client for Rust backends, built on Tokio and reqwest. It needs a secret key, so run it on your server only.

Install

The voidhash crate installs from a clone of the Voidhash repository, as a path dependency:

git clone https://github.com/voidhashcom/voidhash.git third_party/voidhash
cargo add --path third_party/voidhash/libraries/rust

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 crates.io yet. Pin a commit and update regularly. See Versions and releases.

Requirements: a Tokio runtime. The client sends requests with reqwest. The optional axum feature adds an axum route for provider endpoints.

Create a client

Create one client with your secret key and share it across your server, for example in an Arc:

src/main.rs
use std::sync::Arc;

use voidhash::VoidhashClient;

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    let voidhash = Arc::new(
        VoidhashClient::builder()
            .secret_key(std::env::var("VOIDHASH_SECRET_KEY")?)
            // Event capture is served from the API host for now.
            .ingest_url("https://api.voidhash.com")
            .build()?,
    );
    // Pass `voidhash` to your handlers, for example as axum state.
    Ok(())
}

VoidhashClient::builder() sets these options before build(); VoidhashClient::new(secret_key) uses the defaults:

Builder methodDefaultDescription
secret_key—Required. Sent as Authorization: Bearer <secret_key>.
project_idThe key's projectSkips the project lookup. Concurrent first calls share one lookup.
base_urlhttps://api.voidhash.comThe API origin.
ingest_urlhttps://ingest.voidhash.comThe event capture origin. Use https://api.voidhash.com; the default host doesn't answer yet.
publishable_key—Sent as the body token on event capture. Optional.
header(name, value)—An extra header for every request. Call it again for more.

build() makes no request. It returns voidhash::Error::Request when the secret key or project_id is blank, or a header is invalid or sets authorization or x-secret-key.

Call the API

Each resource is a method on the client that returns a borrowed handle, such as voidhash.persons() or voidhash.webhooks().endpoints(). Methods are async, take IDs as &str and request bodies as generated types from voidhash::generated::types. They return Result<T, voidhash::Error>.

let perks = voidhash.perks().list().await?;
for perk in &perks {
    println!("{}", perk.slug);
}

let person = voidhash.persons().get("person_k2v9x4m8q1r3").await?;

List methods return the first page only, newest first where the API orders that way. Person entitlements are the exception: they follow every page.

MethodCovers
persons()Persons, attributes and access checks.
perks(), products()The catalog, and the perks each product grants.
paywalls()Paywall locations.
webhooks()Webhook endpoints and deliveries.
event_capture()Events.
notifications()Push notifications.
payment_source(id)Payment sources.
api_keys(), schema()The 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 voidhash::Error::Api, holding the API error. Match on its type_ and code:

match voidhash.persons().get("person_k2v9x4m8q1r3").await {
    Ok(person) => Ok(Some(person)),
    Err(voidhash::Error::Api { type_, .. }) if type_ == "not_found" => Ok(None),
    Err(voidhash::Error::Api { type_, .. })
        if type_ == "unauthenticated" || type_ == "permission_denied" =>
    {
        Err("the Voidhash secret key is invalid or lacks access".into())
    }
    Err(error) => Err(error.into()),
}

Error::Api also carries status, param and request_id. error.is_not_found() covers the common branch. Network failures are Error::Transport, and configuration or decoding problems are Error::Request. The library doesn't retry or cache.

Cargo features

FeatureAdds
axumProviderHandler::into_axum, to mount a provider endpoint as an axum route.

Everything else, webhook verification included, needs no feature. Enable it with cargo add voidhash --features axum.

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 errorsCargo featuresNext steps