> Documentation index: https://docs.sellhidden.com/llms.txt

# Public API

Source: https://docs.sellhidden.com/public

Read products, categories, visible reviews and recent sales of any live store. No key, safe to call from a browser.

## Endpoints

No key · CORS open · Cached 60 s · 120/min per IP

A website reads products, prices and stock from Hidden with no key.

Only live stores and active products are served; a suspended store is a `404`. Buyer emails in reviews are masked and order ids are never exposed.

### GET /public/products/{storeSlug} — Products of a store

Active products in storefront order. `displayPriceUsd` is the lowest variation price (or the base price when there are no variations). For serial-key products `stock` is the number of unused keys. When the seller hides sold-out products on the storefront, they are omitted here too. No key needed.

**Query parameters**

| Query parameters | Type | Description |
| --- | --- | --- |
| `categorySlug` | string | Only products in this category. |
| `limit` | 1..100 | Page size. Default 50. |
| `cursor` | string | nextCursor from the previous page. |

```bash
curl https://api.sellhidden.com/v1/public/products/my-store
```

Response (200):

```json
{
  "ok": true,
  "store": { "slug": "my-store", "name": "My Store" },
  "products": [ { "slug": "lifetime-license", "name": "Lifetime license", "displayPriceUsd": 29, "inStock": true, … } ],
  "nextCursor": null,
  "hasMore": false
}
```

### GET /public/products/{storeSlug}/{slug} — One product

One product with its variations, category, stock and rating. This is the call the live-price embed makes. No key needed.

```bash
curl \
  https://api.sellhidden.com/v1/public/products/my-store/lifetime-license
```

Response (200):

```json
{
  "ok": true,
  "store": { "slug": "my-store", "name": "My Store" },
  "product": {
    "id": "clx…",
    "slug": "lifetime-license",
    "name": "Lifetime license",
    "description": "…",
    "priceUsd": 49,
    "displayPriceUsd": 29,
    "compareAtUsd": null,
    "currency": "USD",
    "coverImage": "https://…/cover.png",
    "deliveryType": "keys",
    "inStock": true,
    "stock": 120,
    "variations": [
      { "id": "clx…", "label": "1 device", "priceUsd": 29, "compareAtUsd": null, "inStock": true, "stock": 80, "description": null },
      { "id": "clx…", "label": "5 devices", "priceUsd": 49, "compareAtUsd": 69, "inStock": true, "stock": 40, "description": "Team pack" }
    ],
    "category": { "id": "clx…", "name": "Software", "slug": "software" },
    "salesCount": 312,
    "reviewCount": 41,
    "averageRating": 4.8,
    "url": "https://my-store.sellhidden.com/p/lifetime-license",
    "createdAt": "2026-06-01T10:00:00.000Z",
    "updatedAt": "2026-09-20T08:12:44.000Z"
  }
}
```

### GET /public/categories/{storeSlug} — Categories of a store

Categories in display order with the number of active products in each. Use `slug` as `categorySlug` on the products endpoint. No key needed.

```bash
curl \
  https://api.sellhidden.com/v1/public/categories/my-store
```

Response (200):

```json
{
  "ok": true,
  "store": { "slug": "my-store", "name": "My Store" },
  "categories": [
    { "id": "clx…", "name": "Software", "slug": "software", "position": 0, "productCount": 12, "createdAt": "2026-05-02T09:00:00.000Z" }
  ]
}
```

### GET /public/reviews/{storeSlug} — Visible reviews

Visible reviews with a store-wide summary. `distribution` counts one to five stars in order. Every review is tied to a paid order; sellers can hide reviews but never edit or delete them. `source` is `buyer`, or `auto` for an automatic rating recorded after seven silent days (never `verified`, and replaced as soon as the buyer writes their own). `editedAt` is set when the buyer changed their review. `sellerReply` is the store's public reply (null if none), with `sellerRepliedAt`. No key needed.

**Query parameters**

| Query parameters | Type | Description |
| --- | --- | --- |
| `productSlug` | string | Only reviews of this product. |
| `rating` | 1..5 | Only this star rating. |
| `limit` | 1..100 | Page size. Default 20. |
| `cursor` | string | nextCursor from the previous page. |

```bash
curl https://api.sellhidden.com/v1/public/reviews/my-store
```

Response (200):

```json
{
  "ok": true,
  "store": { "slug": "my-store", "name": "My Store" },
  "summary": { "count": 41, "average": 4.8, "distribution": [0, 1, 1, 5, 34] },
  "reviews": [
    {
      "id": "clx…",
      "productId": "clx…",
      "productSlug": "lifetime-license",
      "productName": "Lifetime license",
      "orderId": null,
      "buyerEmail": "j***e@e***.com",
      "rating": 5,
      "comment": "Delivered in seconds.",
      "verified": true,
      "visible": true,
      "source": "buyer",
      "editedAt": null,
      "sellerReply": "Thanks for the kind words!",
      "sellerRepliedAt": "2026-09-19T16:20:00.000Z",
      "createdAt": "2026-09-19T15:04:00.000Z",
      "updatedAt": "2026-09-19T16:20:00.000Z"
    }
  ],
  "nextCursor": null,
  "hasMore": false
}
```

### GET /public/recent-sales/{storeSlug} — Recent sales

Social-proof feed of the latest paid items. Times are rounded to the hour and no buyer data is included. Returns an empty list when the seller turned the recent-sales widget off. No key needed.

**Query parameters**

| Query parameters | Type | Description |
| --- | --- | --- |
| `limit` | 1..25 | Page size. Default 10. |

```bash
curl \
  https://api.sellhidden.com/v1/public/recent-sales/my-store
```

Response (200):

```json
{
  "ok": true,
  "store": { "slug": "my-store", "name": "My Store" },
  "sales": [
    { "product": { "slug": "lifetime-license", "name": "Lifetime license", "coverImage": null }, "variationLabel": "1 device", "quantity": 1, "country": null, "at": "2026-09-26T10:00:00.000Z" }
  ]
}
```
