Products, Perks & Locations

Read-only reference for the six catalog endpoints — products, perks, product perks, paywall locations, and payment provider configuration.

The catalog endpoints expose your project's purchase configuration as flat, read-only lists. They return exactly what is currently deployed for the project your credential resolves to — no pagination, no filters (except the product-perks lookup), no writes.

The catalog model

Six resources make up the catalog:

  • Products are the purchasable items in your app. Every product carries a typesubscription, one-time, or one-time-consumable. See Products.
  • Perks are the entitlements a purchase grants — the things you gate features on. See Perks.
  • Product perks are the join rows linking a product to the perks it unlocks.
  • Paywall locations are the named places in your app where a paywall can be shown (for example onboarding or settings-upsell).
  • Payment provider configurations are your project's store connections (Apple App Store, Google Play) and whether each is enabled.
  • Payment provider products map a catalog product to the actual store SKU via a provider-specific configuration object.

The catalog is written elsewhere

These endpoints only read. The catalog itself is defined in your schema and pushed from your project — there are no POST/PATCH/DELETE routes here. If you want the whole catalog in one response, already joined and keyed the way the CLI and SDK consume it, use the Schema endpoint instead of stitching these six lists together.

Authentication

All catalog endpoints accept any project-scoped credential — a project secret key (x-secret-key) or a user API key (x-api-key). The project is resolved from the credential, so there is no project ID in the path. See Authentication.

The examples below use the production base URL https://api.voidhash.com.

List products

GET /api/v1/products

Returns every product in the project.

curl https://api.voidhash.com/api/v1/products \
  -H "x-secret-key: vh_sk_..."

Each row has the shape:

type Product = {
  id: string;
  name: string;
  projectId: string;
  slug: string;
  type: "subscription" | "one-time" | "one-time-consumable";
};
[
  {
    "id": "prod_01j...",
    "name": "Monthly Premium",
    "projectId": "proj_01j...",
    "slug": "monthly-sub",
    "type": "subscription"
  }
]

The slug is the identifier you defined in your schema; id is Voidhash's internal identifier and is what the product-perks lookup expects.

List perks

GET /api/v1/perks

Returns every perk in the project.

curl https://api.voidhash.com/api/v1/perks \
  -H "x-secret-key: vh_sk_..."
type Perk = {
  id: string;
  name: string;
  projectId: string;
  slug: string;
};

List perks for a product

GET /api/v1/product-perks/by-product-id/:productId

Returns the join rows for one product — which perks it unlocks. productId is the internal product id from the products list, not the slug.

curl https://api.voidhash.com/api/v1/product-perks/by-product-id/prod_01j... \
  -H "x-secret-key: vh_sk_..."
type ProductPerk = {
  id: string;
  perkId: string;
  productId: string;
};

Join perkId back against the perks list to get names and slugs. An invalid productId yields a 400 with Api/ProductPerkValidationError.

List paywall locations

GET /api/v1/paywall-locations

Returns the paywall locations defined for the project. Locations are what the SDK resolves against when it decides which paywall to show at a given point in your app.

curl https://api.voidhash.com/api/v1/paywall-locations \
  -H "x-secret-key: vh_sk_..."
type PaywallLocation = {
  description: string | null;
  id: string;
  name: string;
  projectId: string;
  slug: string;
};

List payment provider configurations

GET /api/v1/payment-provider-configurations

Returns the project's store connections and whether each is currently enabled.

curl https://api.voidhash.com/api/v1/payment-provider-configurations \
  -H "x-secret-key: vh_sk_..."
type PaymentProviderConfiguration = {
  enabled: boolean;
  id: string;
  name: string;
  projectId: string;
  providerId: string;
};

List payment provider products

GET /api/v1/payment-provider-products

Returns the mapping between catalog products and store SKUs. Each row ties a productId to a provider configuration and carries the provider-specific configuration (for example the App Store product identifier, or the Google Play product ID and base plan ID).

curl https://api.voidhash.com/api/v1/payment-provider-products \
  -H "x-secret-key: vh_sk_..."
type PaymentProviderProduct = {
  configuration: Record<string, unknown>;
  id: string;
  paymentProviderConfigurationId: string;
  productId: string;
  providerId: string;
};

The configuration object is intentionally untyped at the API surface — its shape depends on the provider. Set these values in your schema's per-product providers block; see Products for what each provider expects.

Errors

All six endpoints share the same error surface. Errors are JSON objects tagged with _tag:

Status_tagMeaning
401Api/NotAuthenticatedErrorMissing or invalid credential.
403Api/ActionForbiddenErrorCredential lacks the required project permission.
400Api/ProductPerkValidationErrorInvalid productId (product-perks lookup only).
500Api/ProductServiceError, Api/PerkServiceError, Api/ProductPerkServiceError, Api/PaywallLocationServiceError, Api/PaymentProviderConfigurationServiceError, Api/PaymentProviderProductServiceErrorInternal error in the owning service.