Skip to content

API reference

Products

Your catalogue as the seller sees it: hidden products included, every variation with its deliverables, key pools and order counts. Writes follow the dashboard rules: plan limits, unique slugs, deliverable checks, the 2,000,000-key cap per variation and an audit log entry.

Endpoints

GET/productsproducts:read

List products.

Query parameters
Query parametersTypeDescription
activeType: true | falseOnly live or only hidden products.
categoryIdType: stringOnly this category.
qType: stringTitle or slug contains this text.
deliveryTypeType: stringPrimary delivery type (file, text, keys, link, discord, dynamic).
limitType: 1..100Page size. Default 50.
cursorType: stringnextCursor from the previous page.
curl https://api.sellhidden.com/v1/products \
  -H "Authorization: Bearer hsk_live_…"
200 OKjson
{ "ok": true, "products": [ { "id": "clx…", "slug": "lifetime-license", "name": "Lifetime license", "active": true, "displayPriceUsd": 29, "stock": 120, "variations": [ … ], … } ], "nextCursor": null, "hasMore": false }

POST/productsproducts:writeIdempotency-Key201

Create a product. A product has at least one variation. Send variants (recommended), or the short form priceUsd + deliveryType + deliveryData (+ keys for a key product) for a single-price product.

Body
BodyTypeDescription
titlerequiredType: stringUp to 120 characters.
slugType: stringURL slug; derived from the title when omitted and made unique.
descriptionType: stringMarkdown or plain text, up to 20,000 characters.
imageUrlType: string | nullhttps URL or an uploaded /media URL.
categoryIdType: string | nullOne of your categories.
variantsType: arrayVariations (see Variations below). At least one.
activeType: booleanLive on the storefront. Default true. Counts against the plan's product limit.
sortOrderType: integerLower first. Left out: placed after your other products.
seoTitleType: string | nullUp to 70 characters.
seoDescriptionType: string | nullUp to 200 characters.
curl -X POST https://api.sellhidden.com/v1/products \
  -H "Authorization: Bearer hsk_live_…" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{
    "title": "Lifetime license",
    "description": "One key, forever.",
    "variants": [
      {
        "label": "1 device",
        "priceUsd": 29,
        "deliverables": [
          {
            "type": "keys",
            "keys": [
              "AAAA-1111",
              "BBBB-2222"
            ]
          }
        ]
      }
    ]
  }'
201 Createdjson
{ "ok": true, "product": { "id": "clx…", "slug": "lifetime-license", "active": true, "variations": [ { "id": "clx…", "label": "1 device", "priceUsd": 29, "stock": 2, "unusedKeys": 2, "deliverables": [ { "type": "keys", "data": "", "keyOrder": "fifo" } ] } ], … } }

GET/products/{id}products:read

Get a product.

curl https://api.sellhidden.com/v1/products/ID \
  -H "Authorization: Bearer hsk_live_…"

PATCH/products/{id}products:write

Update a product. Only the fields you send change. variants replaces the whole variation list (variations left out are removed); to change one variation use the Variations endpoints instead.

Body
BodyTypeDescription
titleType: string
slugType: string
descriptionType: string
imageUrlType: string | null
categoryIdType: string | null
activeType: booleanActivating respects the plan limit; a product removed by the platform stays off.
sortOrderType: integer
seoTitleType: string | null
seoDescriptionType: string | null
variantsType: arrayFull list of variations (with id for existing ones).
curl -X PATCH https://api.sellhidden.com/v1/products/ID \
  -H "Authorization: Bearer hsk_live_…" \
  -H "Content-Type: application/json" \
  -d '{"active":false}'

DELETE/products/{id}products:write

Delete a product. Deleted for good when it was never ordered; archived (hidden, kept for order history) otherwise. result says which.

curl -X DELETE https://api.sellhidden.com/v1/products/ID \
  -H "Authorization: Bearer hsk_live_…"
200 OKjson
{ "ok": true, "id": "clx…", "result": "deleted" }

GET/products/{id}/variationsproducts:read

List variations.

curl https://api.sellhidden.com/v1/products/ID/variations \
  -H "Authorization: Bearer hsk_live_…"

POST/products/{id}/variationsproducts:writeIdempotency-Key201

Add a variation.

Body
BodyTypeDescription
labelrequiredType: stringShown to buyers. Required when the product has more than one variation.
priceUsdrequiredType: numberPrice in USD.
compareAtUsdType: number | nullOld price shown struck through.
stockType: integer | nullUnits left; null = unlimited. Ignored for variations that deliver keys (the pool is the stock).
descriptionType: stringShort line under the label.
activeType: booleanHidden variations cannot be bought. Default true.
minPerOrderType: 1..100Fewest units per order. Default 1.
maxPerOrderType: 1..100 | nullMost units per order; null = no limit.
billingIntervalType: week | month | quarter | year | nullA subscription billed per period; null (default) = one-time purchase.
trialDaysType: 0..365Subscription: free trial days before the first payment. Default 0.
renewalDeliversType: booleanSubscription: deliver again on every renewal (default true); false only extends access.
deliverablesType: arrayWhat the buyer receives: [{ type: file | text | keys | link | discord | dynamic, data, keyOrder?: fifo | lifo | random, keys?: string[] }]. Each type at most once. Omitted on an existing variation = unchanged.
curl -X POST \
  https://api.sellhidden.com/v1/products/ID/variations \
  -H "Authorization: Bearer hsk_live_…" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{
    "label": "5 devices",
    "priceUsd": 49,
    "compareAtUsd": 69,
    "maxPerOrder": 3,
    "deliverables": [
      {
        "type": "keys"
      }
    ]
  }'

GET/products/{id}/variations/{variationId}products:read

Get a variation.

curl \
  https://api.sellhidden.com/v1/products/ID/variations/VARIATION_ID \
  -H "Authorization: Bearer hsk_live_…"

PATCH/products/{id}/variations/{variationId}products:write

Update a variation. Only the fields you send change. Sending deliverables replaces that variation's deliverables.

Body
BodyTypeDescription
labelType: stringShown to buyers. Required when the product has more than one variation.
priceUsdType: numberPrice in USD.
compareAtUsdType: number | nullOld price shown struck through.
stockType: integer | nullUnits left; null = unlimited. Ignored for variations that deliver keys (the pool is the stock).
descriptionType: stringShort line under the label.
activeType: booleanHidden variations cannot be bought. Default true.
minPerOrderType: 1..100Fewest units per order. Default 1.
maxPerOrderType: 1..100 | nullMost units per order; null = no limit.
billingIntervalType: week | month | quarter | year | nullA subscription billed per period; null (default) = one-time purchase.
trialDaysType: 0..365Subscription: free trial days before the first payment. Default 0.
renewalDeliversType: booleanSubscription: deliver again on every renewal (default true); false only extends access.
deliverablesType: arrayWhat the buyer receives: [{ type: file | text | keys | link | discord | dynamic, data, keyOrder?: fifo | lifo | random, keys?: string[] }]. Each type at most once. Omitted on an existing variation = unchanged.
curl -X PATCH \
  https://api.sellhidden.com/v1/products/ID/variations/VARIATION_ID \
  -H "Authorization: Bearer hsk_live_…" \
  -H "Content-Type: application/json" \
  -d '{"priceUsd":39,"minPerOrder":1,"maxPerOrder":5}'

DELETE/products/{id}/variations/{variationId}products:write

Remove a variation. A product keeps at least one variation (409 otherwise). A variation that was ordered is archived so its orders still deliver.

curl -X DELETE \
  https://api.sellhidden.com/v1/products/ID/variations/VARIATION_ID \
  -H "Authorization: Bearer hsk_live_…"

GET/products/{id}/keysproducts:read

Pool counts and unused keys. pool holds the counts (unused, used, shared pool, per variation); keys is one page of unused keys of one pool, oldest first.

Query parameters
Query parametersTypeDescription
variationIdType: stringWhich pool. Default: the product's only variation, else the product-wide shared pool.
qType: stringKey value contains this text.
limitType: 1..1000Page size. Default 100.
cursorType: stringnextCursor from the previous page.
curl https://api.sellhidden.com/v1/products/ID/keys \
  -H "Authorization: Bearer hsk_live_…"
200 OKjson
{ "ok": true, "pool": { "unused": 1200, "used": 310, "shared": 0, "variations": { "clx…": 1200 } }, "variationId": "clx…", "keys": [ { "id": "k…", "value": "AAAA-1111", "createdAt": "…" } ], "nextCursor": "…", "hasMore": true }

POST/products/{id}/keysproducts:writeIdempotency-Key201

Add keys in bulk. Up to 50,000 keys per request (send big lists in batches); a pool holds up to 2,000,000 unused keys (400 pool_full past that). Keys already in the product's pools and repeats in the list are skipped. Orders that were waiting for keys are delivered, oldest first.

Body
BodyTypeDescription
keysrequiredType: string[]1 to 50,000 keys, up to 50,000 characters each.
variationIdType: stringWhich pool. Default: the product's only variation, else the shared pool.
curl -X POST \
  https://api.sellhidden.com/v1/products/ID/keys \
  -H "Authorization: Bearer hsk_live_…" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{"keys":["AAAA-1111","BBBB-2222"]}'
201 Createdjson
{ "ok": true, "added": 2, "skipped": 0, "skippedExisting": 0, "skippedRepeated": 0, "inOtherProducts": 0, "redelivered": 0, "stillWaiting": 0, "message": null, "pool": { "unused": 1202, "used": 310, "shared": 0, "variations": { "clx…": 1202 } } }

DELETE/products/{id}/keysproducts:write

Remove unused keys. Removes up to 500 unused keys by id or by value. Keys already handed to a buyer are never removed.

Body
BodyTypeDescription
idsType: string[]Key ids from the list endpoint.
valuesType: string[]Key values.
curl -X DELETE \
  https://api.sellhidden.com/v1/products/ID/keys \
  -H "Authorization: Bearer hsk_live_…" \
  -H "Content-Type: application/json" \
  -d '{"values":["AAAA-1111"]}'
200 OKjson
{ "ok": true, "removed": 1, "pool": { … } }

POST/products/{id}/stockproducts:writeIdempotency-Key

Set or adjust stock. Sets (stock) or shifts (adjust, can be negative) the stock of one variation. Variations that deliver keys answer 409 stock_from_keys: add or remove keys instead.

Body
BodyTypeDescription
variationIdType: stringDefault: the product's only variation.
stockType: integer | nullAbsolute units; null = unlimited.
adjustType: integerRelative change, e.g. -3.
curl -X POST \
  https://api.sellhidden.com/v1/products/ID/stock \
  -H "Authorization: Bearer hsk_live_…" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{"adjust":10}'

Get help

Send us the endpoint, the request or delivery id and the response you got. Security findings go through responsible disclosure. Live platform status is on the support page.

See also