POST
Make a variant a digital product

Authorizations

Authorization
string
header
required

A secret API key. Publishable keys cannot reach this API. A key may carry an expiry, and an expired key is refused exactly like an unknown one, with a 401 that names no reason; check the key's expires_at in the dashboard rather than inferring it from a response. When a merchant rolls a key's secret they choose a grace window of up to 3 days, and for its duration BOTH the new secret and the one it replaced authenticate, so an integration moves over on its own deploy schedule instead of at the instant the button is pressed. Move before the window closes: after it, the old secret is refused. Nothing else about this contract moves with a roll. The key keeps its id and its scopes, so the only thing an integration updates is the credential itself.

Headers

Idempotency-Key
string
required

A unique key per logical write. Replaying a request with the same key returns the first response byte for byte instead of applying the write twice.

Body

application/json

Attaches a fulfilment rule to an EXISTING variant. It does not create a product: use POST /api/v1/products first. A variant may carry one rule, so a second create on the same variant is 409 config_exists rather than an upsert, because silently rewriting the terms would change what buyers already hold entitlements under.

variant_id
string
required

The catalogue variant this rule applies to.

fulfillment_type
enum<string>
required

file delivers a download, license_key claims a key from a pool, and subscription grants time-boxed access.

Available options:
file,
license_key,
subscription
file_object_key
string
write-only

Required for fulfillment_type file. It names an object already uploaded into this store's namespace (stores/{store_id}/...); a key outside it is refused. WRITE-ONLY: neither this 201 nor any later read returns it, because a published object key is a capability into the merchant's bucket with no expiry and no revocation. That means you cannot verify from this API which object a paid download is attached to, so RECORD THE KEY YOU SENT against the config id in your own system; there is no route that will tell you afterwards.

max_downloads
integer

Per-buyer download allowance, snapshotted onto each entitlement at grant time. Omit for unlimited; 0 is refused rather than treated as unlimited.

default_expires_after_days
integer

Access window in days, stamped onto each entitlement's expires_at at grant time. Omit for access that does not lapse.

subscription_period_days
integer

Required for a manual subscription. Ignored otherwise.

reveal_mode
enum<string>

Whether a buyer may re-reveal a license key plaintext or gets one window. Defaults to multi. Fixed at creation.

Available options:
multi,
once
subscription_mode
enum<string>

Only manual is accepted here. A stripe-mode product needs a recurring_price_id on the merchant's own Stripe account, which this API holds no authority over, so the request is refused rather than half-completed; create that product in the dashboard.

Available options:
manual

Response

Created

data
object