Products API CRUD

Manage products through the Core API at https://api.licensechain.app/v1 with the same fields you can edit in the Dashboard (seller products), including policy URLs, Stripe options, and (on supported tiers) delivery settings.

Send Authorization: Bearer โ€ฆ with a user JWT or an app API key. Copy-paste examples in many languages: API examples (multi-language).

Endpoints

  • GET /v1/products โ€” list your products (pagination and filters below)
  • POST /v1/products โ€” create (required: name, price; optional fields as in the example)
  • GET /v1/products/{id} โ€” read one
  • PUT /v1/products/{id} โ€” full replace of provided keys (same validation as PATCH)
  • PATCH /v1/products/{id} โ€” partial update; omitted keys stay unchanged
  • DELETE /v1/products/{id} โ€” delete when no licenses or subscriptions reference the product

List query parameters

GET /v1/products?limit=20&offset=0&active=true&search=pro&sortBy=createdAt&sortDir=desc

limit (default 20, max 100), offset, optional active (true/false), search (case-insensitive substring on product name), sortBy (createdAt | name | price), sortDir (asc | desc).

Create product (example body)

Enterprise-only fields (hideEmail, autoRedirect, licenseEmails, sendLicenseToCustomer) return 403 if your account is not on Enterprise. Recurring billing requires stripePriceIdRecurring. Disabling cryptoPaymentsEnabled requires Business or Enterprise. OpenAPI in the API repo lists every field and constraint.

{
  "name": "Pro Monthly",
  "description": "Recurring access to premium feature set",
  "price": 49.99,
  "currency": "USD",
  "active": true,
  "successUrl": "https://merchant.example.com/pay/success",
  "cancelUrl": "https://merchant.example.com/pay/cancel",
  "helpUrl": "https://merchant.example.com/help",
  "supportUrl": "https://merchant.example.com/support",
  "termsUrl": "https://merchant.example.com/terms",
  "privacyUrl": "https://merchant.example.com/privacy",
  "refundUrl": "https://merchant.example.com/refund",
  "productType": "subscription",
  "billingType": "recurring",
  "interval": "month",
  "stripePriceIdRecurring": "price_1AbCdEfGhIjKlMn",
  "stripeTaxEnabled": true,
  "stripeIdentityRequired": false,
  "cryptoPaymentsEnabled": true,
  "hideEmail": false,
  "autoRedirect": false
}

Update product

Use PATCH for partial updates or PUT with the fields you want to change. Redirect URLs must be http or https and at most 2000 characters.

PATCH /v1/products/{id}
{
  "name": "Pro Monthly Updated",
  "price": 59.99,
  "active": true,
  "stripeTaxEnabled": true
}

Delete product

DELETE /v1/products/{id}

Returns 409 when licenses or customer subscriptions are still linked to the product.

Response shape

callbackSecret is issued for new products and may be rotated when enabling hide-email flows; treat it as a secret for webhook signing (see payment webhook guide). userId may be null in some internal or legacy rows; clients should tolerate a missing owner id.

{
  "id": "550e8400-e29b-41d4-a716-446655440000",
  "userId": "user_123",
  "name": "Pro Monthly",
  "description": "Recurring access to premium feature set",
  "price": 49.99,
  "currency": "USD",
  "active": true,
  "successUrl": "https://merchant.example.com/pay/success",
  "cancelUrl": "https://merchant.example.com/pay/cancel",
  "helpUrl": "https://merchant.example.com/help",
  "supportUrl": "https://merchant.example.com/support",
  "termsUrl": "https://merchant.example.com/terms",
  "privacyUrl": "https://merchant.example.com/privacy",
  "refundUrl": "https://merchant.example.com/refund",
  "productType": "subscription",
  "billingType": "recurring",
  "interval": "month",
  "stripePriceIdRecurring": "price_1AbCdEfGhIjKlMn",
  "stripeTaxEnabled": true,
  "stripeIdentityRequired": false,
  "cryptoPaymentsEnabled": true,
  "hideEmail": false,
  "autoRedirect": false,
  "licenseEmails": [
    "licenses-a@merchant.example.com",
    "licenses-b@merchant.example.com"
  ],
  "sendLicenseToCustomer": true,
  "callbackSecret": "base64url_or_base64_secret_from_product_record",
  "createdAt": "2026-05-11T07:00:00.000Z",
  "updatedAt": "2026-05-11T07:00:00.000Z"
}