VoidhashDocs
DevelopersHelp centerGuidesAPI reference
Dashboard
Essentials
API overview
Authentication
Event capture
Push device API
Webhooks
Webhook delivery
Webhook events
Projects & keys
Projects
API keys
Audit log
Customers & access
Persons
Products
Perks
Sandbox
Paywalls
Paywalls
Paywall locations
Components
Component registry
Assets
Experiments & flags
Experiments
Feature flags
Analytics & events
Analytics
Analytics alerts
Cohorts
Group types
Groups
Events
Ingest policy
VoidQL
Tracking domains
Ads
Ads
Ad accounts
Meta measurement
Payments & stores
Payment providers
Payment provider products
Purchase history imports
Payment sources
Webhooks & notifications
Webhooks
Push notifications
Push configurations
Automations
Organization & team
Organizations
Members
Invitations
Billing
Your account
Profile
Session
Notices
Connected apps
Terms of Service
Developer tools
Schema
SDK

API overview

The base URL, conventions, errors, limits and versioning of the Voidhash HTTP API.

The Voidhash HTTP API is for server integrations and custom tooling. Use it when you need to read or change project data from your own backend or scripts. Mobile apps should use one of the mobile SDKs instead. The SDKs handle device headers, identity, caching, and store transactions for you.

Base URL

All requests go to the same host:

https://api.voidhash.com

The management API lives under /api/v1, and the client API the SDKs call under /api/v1/sdk. Event capture is under /i/v1 on the same host.

Every management path names what it acts on. A project's resources live under /api/v1/projects/{projectId}/..., a team's (an organization in the API) under /api/v1/organizations/{organizationId}/..., and your own under /api/v1/me/.... A project or team your credential cannot use answers 404, like one that does not exist.

First request

Create a project secret key in Studio. Then call the session endpoint to confirm the key works and see what it resolves to:

curl https://api.voidhash.com/api/v1/session \
  -H "Authorization: Bearer $VOIDHASH_SECRET_KEY"

For a secret key, projects in the response holds the one project the key belongs to. Its id is the projectId of every project endpoint:

curl https://api.voidhash.com/api/v1/projects/$VOIDHASH_PROJECT_ID/products \
  -H "Authorization: Bearer $VOIDHASH_SECRET_KEY"

Keep secret keys on the server. See Authentication for the headers each credential uses.

Endpoint groups

GroupUse
Projects and keysProjects, their settings and audit log, and their API keys.
PersonsLook up customers with their access, purchases and subscriptions, and erase their data.
Products and perksThe project catalog and the perks each product grants.
Payment providersStore and payment source connections, product mappings, history imports and payments.
Paywalls and locationsPaywalls with their builds and deploys, and the locations that show them.
ComponentsPaywall components, your team's registry and the components a project installs.
Feature flags and experimentsFlags with their variants and overrides, and experiments with their results.
Analytics and adsReports, stored events, the ingest policy, tracking domains, and ad accounts and reports.
Push notificationsProvider configurations, and notifications with their deliveries.
WebhooksManage endpoints, inspect deliveries, rotate secrets, and retry events.
OrganizationsTeams, their members and invitations, and their Voidhash Cloud billing.
Your accountThe session, your profile, notices, connected apps and the Terms; most need you signed in.
Schema and SDKThe consolidated project schema, and the client API the SDKs call.

Each endpoint page shows its parameters, request and response schemas with every field described, its errors, and a client to try it. Most also show a complete example request and response.

Conventions

  • Lists answer { "data": [...], "pageInfo": { "endCursor", "hasNextPage" } }. Pass limit, from 1 to 100 (default 50), and for the next page the previous page's endCursor as cursor. A cursor from another list fails with invalid_cursor. Filters are plain query parameters named after the field.
  • Creating answers 201 with the new object and a Location header. Deleting answers 204. Work that continues in the background, such as a paywall build, answers 202. Archiving is an action, POST .../{id}/archive, never a delete.
  • Objects carry their own id. Field names are camelCase, booleans start with is or has, enumerations are snake_case strings, times are ISO 8601, and money is an integer number of minor units next to its currency.

Retries and idempotency

GET requests are safe to repeat, and so are reports and queries sent with POST, such as .../analytics/reports/charts. A repeated PUT or DELETE changes nothing more, though a repeated DELETE can answer 404.

Payment source reports are keyed by your own id (PUT .../transactions/{externalId}), so a repeated report records nothing twice. Sending a push notification takes an Idempotency-Key header: repeating the send with the same key returns the first notification instead of sending again. No other endpoint reads Idempotency-Key yet, so check before you repeat any other POST that creates something.

Errors

Every management API error has the same JSON body:

{
  "error": {
    "type": "not_found",
    "code": "product_not_found",
    "message": "This project has no product prod_123.",
    "param": "productId"
  }
}

type is the broad outcome and matches the HTTP status. code is the specific, machine-readable reason. param, when present, names the field at fault. Branch on type and code; never parse message, which can change.

StatustypeMeaning
400invalid_requestThe request is malformed or breaks a rule.
401unauthenticatedThe credential is missing, invalid or expired.
403permission_deniedThe credential does not permit the action.
404not_foundThe resource does not exist in this scope.
409conflictThe request conflicts with the current state.
429rate_limitedA limit is reached; see Limits.
500internalServer failure. Retry safe requests with backoff.
503unavailableThis deployment or a service it depends on cannot do it now.

Codes that any endpoint can return:

codetypeMeaning
invalid_body, invalid_query, invalid_path, invalid_headersinvalid_requestThat part of the request doesn't match the endpoint's schema.
invalid_cursorinvalid_requestThe cursor came from another list.
missing_credential, invalid_api_key, expired_api_key, …unauthenticatedThe credential was refused; see Authentication.
permission_deniedpermission_deniedThe key lacks a permission the endpoint needs.
person_credential_requiredpermission_deniedOnly a signed-in person can do this, not a project secret key.
project_not_found, organization_not_foundnot_foundNo such project or team, or the credential can't use it.
internal_error, authentication_unavailableinternalSomething failed on our side, or the credential couldn't be checked.

Other codes name the resource or rule, such as product_not_found or product_slug_taken. Each operation's page lists the codes it adds in its Errors table, and Error codes lists them across the API, the SDKs and the server libraries.

Every response carries a Request-Id header. Include it when you contact support about a request.

Limits

The management API has no general request rate limit. These limits answer 429 with rate_limited:

WhatLimitcode
VoidQL queries4 running at once per team, and 60 queries a minute and 1,000 an hour per team. See VoidQL limits.voidql_quota
Team invitations50 per team and 100 per person in 24 hours.invitation_limit_reached

These responses have no Retry-After header: retry a query once one of yours finishes or the minute is over, and send invitations again the next day.

The client API limits POST /api/v1/sdk/sync-transaction to 300 requests a minute from one IP address per project. Past that it answers 429 with an Api/SdkRateLimitedError body and a Retry-After header, in seconds; the SDKs wait and resend. Event capture has its own limits; see Event capture.

Versioning

v1 is the only version, and it's part of every path. New endpoints, optional parameters, response fields and enumeration values can appear in it, so write clients that ignore fields and values they don't know. Voidhash hasn't published a deprecation policy for v1 yet.

The OpenAPI document at GET /api/openapi.json always describes the API the server runs, including the client API. The endpoint pages here are generated from the same contracts.

Next steps

  • Authentication: the headers each credential uses, and its errors.
  • API keys: create, restrict, roll and expire secret keys.
  • Event capture: send analytics events from your backend.
  • List persons: a first endpoint to call.
  • Webhook delivery: get notified of purchases instead of polling.

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

NextAuthentication

On this page

Base URLFirst requestEndpoint groupsConventionsRetries and idempotencyErrorsLimitsVersioningNext steps