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 | Type | Description |
|---|---|---|
| active | Type: true | false | Only live or only hidden products. |
| categoryId | Type: string | Only this category. |
| q | Type: string | Title or slug contains this text. |
| deliveryType | Type: string | Primary delivery type (file, text, keys, link, discord, dynamic). |
| limit | Type: 1..100 | Page size. Default 50. |
| cursor | Type: string | nextCursor from the previous page. |
curl https://api.sellhidden.com/v1/products \
-H "Authorization: Bearer hsk_live_…"{ "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 | Type | Description |
|---|---|---|
| titlerequired | Type: string | Up to 120 characters. |
| slug | Type: string | URL slug; derived from the title when omitted and made unique. |
| description | Type: string | Markdown or plain text, up to 20,000 characters. |
| imageUrl | Type: string | null | https URL or an uploaded /media URL. |
| categoryId | Type: string | null | One of your categories. |
| variants | Type: array | Variations (see Variations below). At least one. |
| active | Type: boolean | Live on the storefront. Default true. Counts against the plan's product limit. |
| sortOrder | Type: integer | Lower first. Left out: placed after your other products. |
| seoTitle | Type: string | null | Up to 70 characters. |
| seoDescription | Type: string | null | Up 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"
]
}
]
}
]
}'{ "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 | Type | Description |
|---|---|---|
| title | Type: string | |
| slug | Type: string | |
| description | Type: string | |
| imageUrl | Type: string | null | |
| categoryId | Type: string | null | |
| active | Type: boolean | Activating respects the plan limit; a product removed by the platform stays off. |
| sortOrder | Type: integer | |
| seoTitle | Type: string | null | |
| seoDescription | Type: string | null | |
| variants | Type: array | Full 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_…"{ "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 | Type | Description |
|---|---|---|
| labelrequired | Type: string | Shown to buyers. Required when the product has more than one variation. |
| priceUsdrequired | Type: number | Price in USD. |
| compareAtUsd | Type: number | null | Old price shown struck through. |
| stock | Type: integer | null | Units left; null = unlimited. Ignored for variations that deliver keys (the pool is the stock). |
| description | Type: string | Short line under the label. |
| active | Type: boolean | Hidden variations cannot be bought. Default true. |
| minPerOrder | Type: 1..100 | Fewest units per order. Default 1. |
| maxPerOrder | Type: 1..100 | null | Most units per order; null = no limit. |
| billingInterval | Type: week | month | quarter | year | null | A subscription billed per period; null (default) = one-time purchase. |
| trialDays | Type: 0..365 | Subscription: free trial days before the first payment. Default 0. |
| renewalDelivers | Type: boolean | Subscription: deliver again on every renewal (default true); false only extends access. |
| deliverables | Type: array | What 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 | Type | Description |
|---|---|---|
| label | Type: string | Shown to buyers. Required when the product has more than one variation. |
| priceUsd | Type: number | Price in USD. |
| compareAtUsd | Type: number | null | Old price shown struck through. |
| stock | Type: integer | null | Units left; null = unlimited. Ignored for variations that deliver keys (the pool is the stock). |
| description | Type: string | Short line under the label. |
| active | Type: boolean | Hidden variations cannot be bought. Default true. |
| minPerOrder | Type: 1..100 | Fewest units per order. Default 1. |
| maxPerOrder | Type: 1..100 | null | Most units per order; null = no limit. |
| billingInterval | Type: week | month | quarter | year | null | A subscription billed per period; null (default) = one-time purchase. |
| trialDays | Type: 0..365 | Subscription: free trial days before the first payment. Default 0. |
| renewalDelivers | Type: boolean | Subscription: deliver again on every renewal (default true); false only extends access. |
| deliverables | Type: array | What 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 | Type | Description |
|---|---|---|
| variationId | Type: string | Which pool. Default: the product's only variation, else the product-wide shared pool. |
| q | Type: string | Key value contains this text. |
| limit | Type: 1..1000 | Page size. Default 100. |
| cursor | Type: string | nextCursor from the previous page. |
curl https://api.sellhidden.com/v1/products/ID/keys \
-H "Authorization: Bearer hsk_live_…"{ "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 | Type | Description |
|---|---|---|
| keysrequired | Type: string[] | 1 to 50,000 keys, up to 50,000 characters each. |
| variationId | Type: string | Which 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"]}'{ "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 | Type | Description |
|---|---|---|
| ids | Type: string[] | Key ids from the list endpoint. |
| values | Type: 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"]}'{ "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 | Type | Description |
|---|---|---|
| variationId | Type: string | Default: the product's only variation. |
| stock | Type: integer | null | Absolute units; null = unlimited. |
| adjust | Type: integer | Relative 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