VoidhashDocs
DocumentationAPI reference
Dashboard
Get started
Introduction
Quickstart
Setup
Setup overview
Create a project
Products and perks
Paywall locations
CLI
Paywall components
Components
Develop a component
Editor panels
Component definition
Publishing
Installing and capabilities
SDKs
Swift
Kotlin
React Native
Web
Store setup
Connect the App Store
Connect Google Play
Connect Stripe
Record payments from other sources
API libraries
Node.js
PHP
Rust
Go
Resources
MCP server
Ad measurement
Meta ads
Migrate in observer mode
Delete a person's data

CLI

Manage your Voidhash projects from the terminal, in scripts and in CI.

The Voidhash CLI, voidhash-cli, manages your projects from the terminal. It answers support questions about your end users, manages products, perks and store connections, deploys paywalls, runs feature flags and experiments, reports revenue and ad performance, debugs webhooks, sends push notifications, and manages your team and settings. It also connects a local app, keeps its generated types in sync, and builds paywall components. It is not a dependency of the SDK, so you can run it directly without installing anything.

Print the available commands to confirm it runs:

npx voidhash-cli --help

pnpm dlx voidhash-cli --help works the same way. Running the CLI this way keeps it out of your app's dependency tree, so it cannot affect your bundle or lockfile resolution.

Install it as a dev dependency

Install the CLI when you run it often, and always when you use the Metro plugin. The plugin spawns voidhash-cli types generate --watch alongside the Metro dev server and looks up the binary on PATH. A dev-dependency install puts it there.

npm install voidhash-cli --save-dev

Then wrap your Metro config with the plugin:

metro.config.js
const { getDefaultConfig } = require("expo/metro-config");
const { withVoidhash } = require("@voidhash/react-native/metro");

module.exports = withVoidhash(getDefaultConfig(__dirname));

If the binary is not on PATH, withVoidhash prints a warning and returns the Metro config unchanged. The dev server still starts.

How commands work

Commands read voidhash <noun> <verb> [arguments] [flags], such as voidhash product list. Installed, the CLI answers to both voidhash and voidhash-cli; otherwise run each command as npx voidhash-cli <command>. Most nouns also answer to their plural (products, webhooks). Every command takes --help, and running a group without a verb lists its commands.

Wherever a command takes something, name it the way you know it: a product, perk, paywall or location by its slug, name or ID; an end user by email, distinct ID or person ID; a webhook by its name, URL or ID; a flag by its key. When a name fits several things, the command lists them with their IDs. In a terminal, a missing argument becomes a question with choices; in scripts nothing is asked (see Use it in scripts).

Initialize an app

Run init from the app root to connect it to a project:

npx voidhash-cli init

The command is interactive. It creates voidhash.config.ts, src/lib/voidhash.ts, and voidhash.gen.d.ts. It does not install packages or create a local schema. At the end it offers to connect your AI agents, as mcp install does.

Sign in

auth login opens your browser, where you confirm the code and can make the CLI read-only on this computer. The CLI then acts as you, with your role in each organization. It appears under Settings → Connected apps in Studio, named after your computer, where you can change the setting or disconnect it. Signing in again on the same computer replaces its key and keeps the setting. auth logout revokes the key on the server. The CLI is signed out after 90 days without use; run auth login again to continue.

For CI or anything else that runs without you, use a project secret key instead of signing in.

Which project a command acts on

A command that works in a project acts on, in this order:

  1. the project --project names: its slug, organization/slug, name or id;
  2. the current directory's project: the one its voidhash.config.ts names, or the one you linked the directory, or a directory above it, to;
  3. your default project;
  4. the only project you can use.

When none of these decides, the CLI asks in a terminal and lists your projects otherwise.

# Commands run in this directory and below act on acme/app
npx voidhash-cli link acme/app

# Commands everywhere else act on acme/web
npx voidhash-cli switch acme/web

# Which project applies here, and what its setup still needs
npx voidhash-cli status

status checks that a store is connected, that every product is mapped to a store product, that no purchases wait for a product, that your apps' SDKs sent events in the last seven days, and that your webhooks deliver. Each line that needs work names the command or Studio page that fixes it.

Links and the default project are yours: they are kept with your sign-in on this computer, not in the repository, so teammates can work in projects of their own. An app's voidhash.config.ts names its project for everyone; run init again to point it at another one. unlink removes a link.

Command reference

The commands below follow the groups of voidhash --help. Each example uses the installed voidhash; prefix npx voidhash-cli instead when it is not installed. Project commands take --project, and organization commands (member, project list, project create, notices) take --org, its slug, name or ID, defaulting to the organization of the current project.

Get started

CommandWhat it does
initConnects an app to a project: config, client and generated types.
loginSigns in through your browser; the CLI then acts as you.
logoutSigns out, and revokes this computer's key.
whoamiShows who the CLI is signed in as, and the organizations and projects it can use.
voidhash init
voidhash login
voidhash logout
voidhash whoami --json

Choose a project

CommandWhat it does
statusShows the project commands act on here, its setup and health, and what to do next.
link [project]Makes a project this directory's: commands run here and below act on it.
unlinkRemoves this directory's link.
switch [project]Chooses your default project, used outside linked directories.
open [page] [item]Opens a Studio page of the project; --no-browser only prints its address.
voidhash status
voidhash link acme/app
voidhash unlink
voidhash switch acme/web
voidhash open product pro-monthly

open takes overview (the default), products, perks, persons, flags, experiments, paywalls, locations, components, events, event-settings, analytics, ads, ad-accounts, campaigns, creatives, cohorts, webhooks, providers, keys, notifications, settings, domains, sandbox and push. product, person, flag, experiment, paywall, location, webhook and provider open one item's page.

Persons and access

CommandWhat it does
person listThe newest persons.
person find <query>Finds persons by exact email, distinct ID or ID. Names cannot be searched.
person view <person>Their profile, the perks they can use and what grants each, subscriptions, purchases, flag overrides and events.
person why <person> <perk>Why they have or lack a perk, where the chain breaks, and how to fix it.
person edit <person>Changes their email, name or attributes; --set-once writes an attribute only when it is unset.
person createAdds a person by the distinct ID your app will identify them by, before your app has seen them.
person erase <person>Erases their personal data for good. Asks you to type their email or distinct ID.
voidhash person list --limit 20
voidhash person find ada@example.com
voidhash person view user-42
voidhash person why ada@example.com premium
voidhash person edit user-42 --set plan=team
voidhash person create --distinct-id user-100 --email new@example.com
voidhash person erase ada@example.com

person why prints the chain from access to purchase and the fix:

Ada <ada@example.com> (user-42) does not have Premium (premium).
  x   access    they cannot use premium now
  ok  catalog   granted by Pro Monthly
  ok  store     com.acme.pro.monthly
  x   purchase  Pro Monthly: ended Oct 1, 2026, 2:00 AM
Fix: access returns when they renew or buy again. If they say they renewed, check the store connection with 'voidhash status'.

Subscriptions, purchases and access are shown for production store purchases. See Data deletion for what erasure removes and keeps.

Catalog

A product is what people buy: a subscription, a one-time purchase, or a consumable they can buy again and again. A perk is the access your app checks for, and a product grants perks. See Products and perks.

CommandWhat it does
product listEach product with the perks it grants and the stores it is sold in.
product view <product>One product: its type, perks and the store products it is sold as.
product createCreates a subscription, one-time purchase or consumable.
product edit <product>Renames a product or changes its slug. Its type and billing period cannot change.
product delete <product>Deletes a product no store product is mapped to. Asks first.
product perks set <product> [perk…]Makes a product grant exactly these perks. Taking one away asks first.
perk listEach perk with the products that grant it.
perk createCreates a perk, and optionally the products that grant it.
perk edit <perk>Renames a perk or changes the slug your app checks for.
perk delete <perk>Deletes a perk: every product stops granting it. Asks first.
voidhash product list --type subscription
voidhash product view pro-monthly
voidhash product create --name "Pro Monthly" --type subscription --period monthly --perk premium
voidhash product edit pro-monthly --name "Pro (monthly)"
voidhash product delete old-plan
voidhash product perks set pro-monthly premium ad-free --dry-run
voidhash perk list
voidhash perk create --name Premium
voidhash perk edit premium --name "Premium access"
voidhash perk delete legacy

product perks set adds what is missing and removes the rest; without perks it lets you pick them in a terminal, and --none removes them all. Map a product to its store products with provider map. After you add or rename products and perks, run types generate in your app.

Payments

provider connects the stores your app sells through, checks them, maps their store products to your products and imports purchase history. Name a provider by its store (app-store, google-play, stripe), a payment source's slug or name, or its ID. Secrets are asked for hidden in a terminal.

CommandWhat it does
provider listEvery provider with its health: enabled, store products read and mapped, purchases waiting for a mapping.
provider view <provider>One provider: status, store products, waiting purchases, history imports and the address its store notifies.
provider connect app-storeSaves the app's IDs and its In-App Purchase and App Store Connect API keys, from their .p8 files.
provider connect google-playSaves the package name and a service account's JSON key file.
provider connect stripeSaves your account ID, API keys and webhook signing secrets; without the secrets it prints where to point Stripe.
provider connect payment-sourceAdds a payment source; with --endpoint it prints the signing secret once.
provider test <provider>Checks a store's saved credentials or a payment source's endpoint. Exits with 1 when it does not work.
provider edit <provider>Renames, enables or disables a provider, or changes a payment source's endpoint and rotates its secret.
provider products [provider]The store products each provider sells and the product each is mapped to.
provider map <store-product> <product>Makes buying a store product grant a product. Moving one mapped elsewhere asks first.
provider unmap <store-product>Removes a mapping made by mistake. Asks first.
provider import <provider>Imports Stripe's or a payment source's earlier purchases; --watch follows it, --cancel stops it.
provider delete <provider>Deletes a provider no store product is mapped to. Asks first.
provider record-payment <source>Records a payment a payment source took, such as a bank transfer; --refunds records a refund.
provider refund <source>Refunds a charge at the payment source. Asks first.
provider cancel-subscription <source>Cancels a subscription at the payment source, at the period's end or --now. Asks first.
voidhash provider list
voidhash provider view app-store
voidhash provider connect app-store --bundle-id com.acme.app --apple-id 1234567890 \
  --issuer-id <issuer-id> --iap-key SubscriptionKey_ABC123.p8 --api-key AuthKey_DEF456.p8
voidhash provider connect google-play --package-name com.acme.app --service-account-key key.json
voidhash provider connect stripe --account-id acct_123
voidhash provider connect payment-source --name "Bank transfer" --endpoint https://pay.example.com/voidhash
voidhash provider test app-store
voidhash provider edit bank-transfer --rotate-secret
voidhash provider products --unmapped
voidhash provider map com.acme.pro.annual pro-annual
voidhash provider unmap com.acme.pro.annual
voidhash provider import stripe --watch
voidhash provider delete bank-transfer
voidhash provider record-payment bank-transfer --amount 49.90 --currency EUR --product lifetime --distinct-id alice
voidhash provider refund paddle --transaction pay_1
voidhash provider cancel-subscription paddle --subscription sub_1

Run provider connect again to change a store's settings. Stripe store products are prices, written prod_…:price_…. The store guides explain where each credential comes from: App Store, Google Play and Stripe.

Paywalls

A paywall's live build is shown at the paywall locations that show it, which your app asks for by slug. Design paywalls in Studio; these commands build, deploy and place them. See Paywall locations.

CommandWhat it does
paywall listEach paywall with the build end users see and where it is shown.
paywall view <paywall>The live build, newer builds, and where it is shown.
paywall createCreates an empty paywall or onboarding flow.
paywall edit <paywall>Renames a paywall. Its slug cannot change.
paywall build <paywall>Builds the current design without deploying it; --wait shows why a build failed.
paywall deploy <paywall>Builds the design and deploys it everywhere it is shown; --build deploys an existing build. Asks first when end users see it.
paywall archive <paywall>Archives a paywall. Locations that show it keep showing its live build.
paywall unarchive <paywall>Restores an archived paywall.
paywall delete <paywall>Deletes a paywall no location shows, with its design and builds. Asks first.
location listEach location with what it shows now.
location view <location>What a location shows now, and what it showed before.
location createCreates a location, optionally showing a paywall right away.
location edit <location>Renames a location or changes its description. Its slug cannot change.
location show <location> <paywall>Shows a paywall's live build at a location. Asks first when it replaces what end users see.
location clear <location>Stops showing anything at a location. Asks first.
location history <location>Everything a location has shown, newest first.
location archive <location>Retires a location your apps no longer ask for. This cannot be undone. Asks first.
voidhash paywall list
voidhash paywall view pro
voidhash paywall create --name "Summer sale"
voidhash paywall edit pro --name "Pro plans"
voidhash paywall build pro --wait
voidhash paywall deploy pro --build 3
voidhash paywall archive summer-sale
voidhash paywall unarchive summer-sale
voidhash paywall delete old-sale
voidhash location list
voidhash location view home
voidhash location create --name "Onboarding end" --show pro
voidhash location edit home --description "Home screen banner"
voidhash location show home summer-sale
voidhash location clear home
voidhash location history home
voidhash location archive old-banner

Flags and experiments

A flag that is off is off for everyone. When it is on, an override fixes it for one end user, the deny and allow lists limit who can get it, and the rollout decides the rest. To say which kind of identifier names an end user, prefix it with email:, distinct_id:, person_id: or external_id:.

CommandWhat it does
flag listEach flag with its state and variants; --archived lists archived ones.
flag view <flag>A flag's state, variants, allow and deny lists and overrides.
flag createCreates a flag, off unless you pass --rollout.
flag enable <flag>Turns a flag on, optionally for a share of end users.
flag disable <flag>Turns a flag off for everyone, overrides included. Asks first.
flag rollout <flag> <percent>Sets the share of end users who get it. Lowering it asks first.
flag edit <flag>Changes its key (which asks first) or description.
flag variants set <flag> <value…>Sets exactly the values it hands out. Removing one asks first.
flag override <flag> <person> <setting>Fixes the flag for one end user (on, off or a variant), or clears it.
flag target <flag> <person> <list>Puts an end user on the allow or deny list, or clears them from both.
flag evaluate <person>What one end user gets from each flag, and why.
flag archive <flag>Stops serving a flag. Asks first when it is on.
flag restore <flag>Brings an archived flag back as it was.
experiment listEach experiment with its status and arms.
experiment view <experiment>Its status, conversion metric and the paywall each arm shows where.
experiment createSets one up as a draft, optionally with its arms.
experiment edit <experiment>Changes its name, hypothesis, metrics (draft only) or arms (not while running).
experiment start <experiment>Starts or resumes it at its paywall locations. Asks first.
experiment pause <experiment>Everyone sees the control arm until it resumes.
experiment results <experiment>Each arm's conversions and revenue, with a verdict that says when it is too early.
experiment conclude <experiment>Ends it for good with a winner, which its locations then show. Asks first.
experiment archive <experiment>Archives a draft or concluded experiment.
experiment restore <experiment>Brings an archived experiment back.
voidhash flag list
voidhash flag view new-checkout
voidhash flag create --key button-color --type string --variant red --variant blue
voidhash flag enable new-checkout --rollout 25%
voidhash flag disable new-checkout
voidhash flag rollout new-checkout 50%
voidhash flag edit new-checkout --description "The redesigned checkout"
voidhash flag variants set button-color red blue green
voidhash flag override new-checkout alice@example.com on
voidhash flag target beta-feature alice@example.com allow
voidhash flag evaluate alice@example.com
voidhash flag archive old-banner
voidhash flag restore old-banner
voidhash experiment list --status running
voidhash experiment view "Annual first"
voidhash experiment create --name "Annual first" --metric trial_started --location onboarding-end \
  --arm Control=monthly --arm Annual=annual
voidhash experiment edit "Annual first" --hypothesis "Annual first raises trial starts"
voidhash experiment start "Annual first"
voidhash experiment pause "Annual first"
voidhash experiment results "Annual first"
voidhash experiment conclude "Annual first" --winner Annual
voidhash experiment archive "Annual first"
voidhash experiment restore "Annual first"

The first --arm is the control unless you pass --control, and --weights 60,40 splits traffic unevenly.

Analytics and ads

Reports take a period of whole days: --last 30d (or 7d, 4w, 3m, 1y) is that many complete days before today, and --from 2026-09-01 --to 2026-09-30 names the days. Ads reports count days in your ad accounts' time zone; the others in UTC unless you pass --timezone. Revenue comes from production purchases unless --environment says otherwise. See Ad measurement and Meta ads.

CommandWhat it does
events listThe latest events, newest first, of one event name or person.
events tailPrints events as they arrive while you use your app; --count 1 waits for one and exits.
events policy viewWhich built-in events are stored and which custom events are blocked.
events policy enable <event>Starts storing a built-in event.
events policy disable <event>Stops storing a built-in event; events sent meanwhile are dropped. Asks first.
events policy block <event>Stops storing a custom event. Asks first.
events policy unblock <event>Stores a blocked custom event again.
insights listThe built-in insights: revenue, MRR, churn, trials, subscriptions and persons.
insights run <insight…>Insights' values and series over a period, optionally against the period before.
analytics acquisitionThe people each network, campaign, ad set, ad or surface brought in, and what they paid.
analytics cohortsHow revenue from each week's new people grows by day 0, 7, 30 and 90.
analytics healthWhether tracking works: web page views by host, app SDKs and versions, people who came from the web.
ads accountsConnected ad accounts and how their syncs are doing.
ads connect [account]Connects a Meta ad account with a system user token, asked for hidden or piped in.
ads disconnect <account>Disconnects an account and deletes what was synced from it. Asks first.
ads campaigns [campaign]Synced campaigns, or one campaign with its ad groups and ads.
ads report performanceSpend and clicks beside the signups, payers, revenue and ROAS Voidhash measured.
ads report creativesCreatives by spend, with what they earn and signs of fatigue.
ads report cohortsPayback by acquisition cohort.
ads issuesFailing syncs, rejected or held campaigns and ads, and active ads missing tracking parameters.
ads settings viewThe landing pages that mark website ads as web-to-app.
ads settings web-to-app <prefix…>Sets exactly which landing pages mark website ads as web-to-app.
voidhash events list --name purchase_completed --person dana@example.com
voidhash events tail --name '$pageview'
voidhash events policy view
voidhash events policy enable '$screen'
voidhash events policy disable '$pageview'
voidhash events policy block debug_ping
voidhash events policy unblock debug_ping
voidhash insights list
voidhash insights run mrr churn-rate --last 90d --by week --compare
voidhash analytics acquisition --by campaign --last 30d
voidhash analytics cohorts --by network --last 13w
voidhash analytics health
voidhash ads accounts
voidhash ads connect act_1234567890 --token-stdin < token.txt
voidhash ads disconnect "Acme EU"
voidhash ads campaigns "Spring sale"
voidhash ads report performance --level ad --last 7d --sort roas
voidhash ads report creatives --format video
voidhash ads report cohorts --by campaign --metric roas
voidhash ads issues
voidhash ads settings view
voidhash ads settings web-to-app example.app/start

The ad account token is never passed as a flag, so it stays out of your shell history.

Your backend

Webhooks send your project's purchase, subscription and person events to your backend. --event takes an event type (purchase.completed), a group (purchase.*, subscription.*, person.*) or all, and can be repeated.

CommandWhat it does
webhook listYour webhooks and whether each delivers, is failing, was stopped by Voidhash or is off.
webhook view <webhook>A webhook's URL, events and health, and its latest deliveries with how your backend answered.
webhook createAdds a webhook and prints its signing secret, shown only this once.
webhook edit <webhook>Changes a webhook's name, URL, events or description.
webhook enable <webhook>Turns a webhook back on, also one Voidhash stopped after repeated failures.
webhook disable <webhook>Stops sending events to a webhook; events that happen meanwhile are never sent. Asks first.
webhook delete <webhook>Deletes a webhook and its delivery history. Asks first.
webhook rotate <webhook>Replaces the signing secret and prints the new one; the old one stops working at once. Asks first.
webhook test <webhook>Sends a signed test event and shows how your backend answered. Exits with 1 when it did not accept it.
webhook deliveries [webhook]Deliveries, newest first, across webhooks or of one; --failed shows only failures.
webhook delivery <delivery>One delivery with every attempt.
webhook retry [delivery…]Sends failed deliveries again now. Exits with 1 unless all were delivered.
voidhash webhook list
voidhash webhook view Orders
voidhash webhook create --name Orders --url https://api.example.com/voidhash --event 'purchase.*'
voidhash webhook edit Orders --event all
voidhash webhook enable Orders
voidhash webhook disable Orders
voidhash webhook delete Orders
voidhash webhook rotate Orders
voidhash webhook test Orders
voidhash webhook deliveries --failed
voidhash webhook delivery wh_del_1
voidhash webhook retry wh_del_1

Your backend receives a retried event again, so it should handle an event it already processed.

Messaging

CommandWhat it does
push sendSends a push notification to people's devices. Shows who it reaches and asks first; --dry-run only shows.
push listRecent push notifications with how many devices each reached, failed or skipped.
push deliveries <push>How a push notification reached each device, and why deliveries failed.
push config listThe push services the project sends through.
push config set apnsSets up APNs with your authentication key, and turns it on.
push config set fcmSets up Firebase Cloud Messaging with a service account key, and turns it on.
push config enable <service>Turns a push service back on with its saved credentials.
push config disable <service>Stops sending through a push service, keeping its credentials.
push config delete <service>Deletes a push service's credentials. Asks first.
voidhash push send --to user-42 --title "Your trial ends tomorrow" --body "Keep Pro for 4.99 a month"
voidhash push list
voidhash push deliveries push_send_123 --failed
voidhash push config list
voidhash push config set apns --team-id ABCDE12345 --key-id XYZ123 --key-file AuthKey.p8 --bundle-id com.example.app
voidhash push config set fcm --service-account-file service-account.json
voidhash push config enable fcm
voidhash push config disable fcm
voidhash push config delete fcm

Team and settings

CommandWhat it does
org listThe organizations you belong to and their projects.
org create [name]Creates an organization, with you as its owner.
org edit [org]Renames it or changes its logo. Its slug never changes.
org delete [org]Deletes it with all its projects and their data. Asks you to type its name.
project listAn organization's projects.
project create [name]Creates a project and shows its publishable key; --switch makes it your default.
project edit [project]Renames a project or changes its logo. Its slug never changes.
project delete [project]Deletes a project and everything in it. Asks you to type its name.
member listAn organization's members and their roles.
member invite <email>Adds someone who has a Voidhash account, as a member or with --role admin.
member role <member> <role>Makes a member an admin, or an admin a member (which asks first).
member remove <member>Removes someone; they lose access to every project of the organization. Asks first.
settings viewEvery project setting, explained.
settings set <key> <value>Changes one setting. Settings that change what production apps get ask first.
domain listYour tracking domains, and what each still needs before it serves.
domain add <hostname>Serves the web SDK from your own subdomain; prints the DNS records to create.
domain verify [domain]Checks a domain's DNS and certificate now.
domain remove [domain]Stops serving a tracking domain. Asks first.
sandbox view <person>A tester's sandbox subscriptions, purchases and the access they grant.
sandbox renew <person> [product]Renews a sandbox subscription for another period, as the store would.
sandbox expire <person> [product]Ends a sandbox subscription now.
sandbox grace-period <person> [product]Starts a sandbox subscription's three-day billing grace period.
sandbox refund <person> [product]Refunds a one-time sandbox purchase; the access it granted ends.
sandbox revoke <person> [product]Revokes a sandbox purchase or subscription.
sandbox resetDeletes every sandbox purchase in the project, to start over. Asks first.
key listThe publishable key your apps ship with, and secret keys by their ends.
auditWho changed what in the project, newest first. Needs permission to change the project.
notices listBilling, security and other notices your organization sent you.
notices read [notice…]Marks notices read, or the whole inbox with --all.
notices archive <notice…>Archives notices, which also marks them read.
notices unarchive <notice…>Brings archived notices back to the inbox.
notices preferencesShows or changes how each category of notices reaches you, and their language.
feedback [message]Sends feedback to the Voidhash team.
voidhash org list
voidhash org create "Acme"
voidhash org edit acme --logo logo.png
voidhash org delete acme
voidhash project list --org acme
voidhash project create "My App" --switch
voidhash project edit app --name "My App"
voidhash project delete acme/old-app
voidhash member list
voidhash member invite sam@example.com --role admin
voidhash member role sam@example.com member
voidhash member remove sam@example.com
voidhash settings view
voidhash settings set sandbox-purchasing on
voidhash domain list
voidhash domain add t.example.com
voidhash domain verify t.example.com
voidhash domain remove t.example.com
voidhash sandbox view tester@example.com
voidhash sandbox renew user-42 pro-monthly
voidhash sandbox expire user-42
voidhash sandbox grace-period user-42
voidhash sandbox refund user-42 lifetime
voidhash sandbox revoke user-42 lifetime
voidhash sandbox reset
voidhash key list
voidhash audit --type product
voidhash notices list
voidhash notices read --all
voidhash notices archive <notice-id>
voidhash notices unarchive <notice-id>
voidhash notices preferences --category product --email off
voidhash feedback "Love the sandbox" --topic sdk

settings set takes paid-access-sharing.production and paid-access-sharing.sandbox (shared, transfer or disabled), store-sandbox-unlocks-production (on or off), ads-key-conversion (signup, trial or payer) and sandbox-purchasing (on or off). Debug builds of your app buy through the Voidhash sandbox while sandbox-purchasing is on; the sandbox commands never change production or store sandbox purchases. API keys are created, rotated and deleted in Studio: voidhash open keys.

Paywall components

dev, new, publish, test and registry develop and share paywall components; see Components below.

More

CommandWhat it does
types generateRefreshes voidhash.gen.d.ts from the project schema; --watch keeps it current.
types checkFails when the committed types are behind the server schema.
mcp installAdds the Voidhash MCP server to the AI agents on this computer.
api list, describe, callFinds and calls any Voidhash API operation. See Call the API.
auth login, logout, statusThe same as login, logout and whoami.
config, config set, config resetShows or changes CLI URLs, credentials, the default project and links.
voidhash types generate
voidhash types check
voidhash mcp install --yes
voidhash api list webhook deliveries
voidhash auth status
voidhash config set api_url https://example.test --profile staging

Use it in scripts

On a terminal, commands print aligned tables and short summaries. For scripts:

  • --json prints the API objects, the stable shape to parse. person view --json, for example, adds the person's entitlements, subscriptions, purchases, flagOverrides and recentEvents.
  • -q (--quiet) prints only IDs, one per line, for piping into another command.
npx voidhash-cli product list --json
npx voidhash-cli product view pro-monthly -q   # the product's id
npx voidhash-cli person find ada@example.com -q | xargs npx voidhash-cli person view --json

Without a terminal, in scripts and CI, the CLI never asks: a missing value fails the command with how to pass it. Color appears only in a terminal, and never when NO_COLOR is set.

Confirmation

Commands whose change cannot be undone, or that change what end users get, ask first and show what will change: deleting a product, perk, paywall or webhook, deploying a paywall end users see, replacing what a location shows, starting or concluding an experiment, turning a flag off, rotating a signing secret, refunding a payment, sending a push notification and resetting the sandbox, among others. Each one's help says so. --yes (-y) confirms without asking; without a terminal, a command that needs confirmation fails unless you pass it. Deleting a project or an organization, and erasing a person, ask you to type its name, email or distinct ID instead. product perks set and push send show their change without making it with --dry-run.

Exit codes

Errors go to standard error with the next command to run. The exit code says what happened:

Exit codeMeaning
0Done, or help printed.
1The command failed, or a check it ran did not pass.
2Wrong usage: a missing, ambiguous or invalid value, or a confirmation it needs.
3Not signed in, or the stored key no longer works.
4Not found: no such product, person, webhook or project here.

provider test, webhook test and webhook retry exit with 1 when the endpoint did not work, so a script can stop on it.

Connect your AI agents

npx voidhash-cli mcp install

The command finds Claude Code, Cursor, Codex, VS Code and Claude Desktop on your computer and adds the Voidhash MCP server to the ones you choose; --yes adds it to all of them. It writes no keys into their configuration: each agent opens your browser to sign in the first time it uses Voidhash.

Call the API

The commands above cover the common tasks. For anything they do not cover yet, and for scripts that want the raw API, api calls any operation of the HTTP API as you: everything you can do in Studio apart from editing a paywall's design. It reads the list of operations from the server it talks to, so it always matches that server.

# Find operations by a few words of their name, path or description
npx voidhash-cli api list webhook endpoints

# Show an operation's parameters, body and response
npx voidhash-cli api describe webhooks.create

# Call it
npx voidhash-cli api call webhooks.list --project <project-id>
npx voidhash-cli api call webhooks.create --project <project-id> \
  --body '{"name": "Orders", "url": "https://example.com/hooks", "events": ["purchase.completed"]}'
npx voidhash-cli api call webhooks.get --project <project-id> --path webhookId=<webhook-id>

--path name=value and --query name=value set path and query parameters; repeat --query with the same name for a list. --body takes JSON inline or @file.json. --project fills in the operation's projectId, and --environment chooses the purchase environment, as the environment switch in Studio does. The response prints as JSON; an error response prints with its status and the command exits with an error.

Calls use your sign-in, so they can do what your role allows, and nothing when the CLI is read-only.

Keep types in sync

After the project schema changes in Studio, regenerate the declaration file:

npx voidhash-cli types generate

Commit the generated declaration. To catch Studio changes that nobody has pulled into the repository yet, add a check to CI:

npx voidhash-cli types check

The check fails when the committed types are behind the server schema.

Components

These commands work on your project's paywall components. Run dev, new and publish in your app's root, signed in with auth login:

CommandUse
devKeep a working copy of the project's components in .voidhash, build them as you edit, and show the builds in the paywall editor.
new <name>Create a component with its editor panel in the working copy.
publishPublish new and changed components as new versions; --all or --component <slug>, and --yes to skip the prompt.
test [component|path]Run the checks publishing runs on a component, a crate or a module; --panel names a panel module.

Develop a component walks through them in the order you use them.

Your organization's components

The registry commands manage the components your organization shares across its projects. Commands that take a [path] use the current directory when you leave it out:

CommandUse
registry listList project, installed and organization components, with owners, updates and warnings.
registry publisher show / claim <name>Show or claim your organization's namespace.
registry publish [path]Publish a bundle, or --from-project <slug>@<version>, to your organization.
registry install <id>Install a component; --yes accepts its review.
registry update <id>Move an install to the newest version in its range.
registry uninstall <id>Remove an installed component.
registry deprecate <id> [version]Deprecate a version or a whole component; --undo lifts it.
registry yank <id> <version>Yank a version for good.
registry transfer <id>Make the project the owner of a component (organization admins).

See Publishing and Installing.

Profiles

A profile keeps environment-specific CLI settings separate. Set a value under a profile, then pass the same profile to later commands:

npx voidhash-cli config set api_url https://example.test --profile staging
npx voidhash-cli types generate --profile staging

The base configuration lives in ~/.voidhash, and each profile keeps its own default project and links. An app's project is named in its committed voidhash.config.ts.

Shell completion

Installed, the CLI prints a completion script for your shell:

voidhash --completions zsh > "${fpath[1]}/_voidhash"
voidhash --completions bash >> ~/.bashrc
voidhash --completions fish > ~/.config/fish/completions/voidhash.fish

Troubleshooting

  • Not logged in. Run npx voidhash-cli login.
  • "Which project?" You can use several projects and none applies here. Pass --project, link the directory with link, or choose a default with switch.
  • Project config missing. Run npx voidhash-cli init from the app root.
  • The paywall editor does not show your local builds. Check that voidhash-cli dev is running and that you opened the editor signed in as the same person, in the project voidhash.config.ts names. If the browser asked to let the site reach devices on your local network, allow it.
  • Generated types are stale. Run npx voidhash-cli types generate and commit the file.
PreviousPaywall locationsNextComponents

On this page

Install it as a dev dependencyHow commands workInitialize an appSign inWhich project a command acts onCommand referenceGet startedChoose a projectPersons and accessCatalogPaymentsPaywallsFlags and experimentsAnalytics and adsYour backendMessagingTeam and settingsPaywall componentsMoreUse it in scriptsConfirmationExit codesConnect your AI agentsCall the APIKeep types in syncComponentsYour organization's componentsProfilesShell completionTroubleshooting