> ## Documentation Index
> Fetch the complete documentation index at: https://docs.shoppex.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Serials & license keys

> Sell single-use codes like license keys, game codes, or gift cards.

Shoppex has two related but distinct systems for selling codes:

* **Serials** — simple. Upload a pool of codes, each buyer gets a unique one.
* **Licenses** — advanced. Full license objects with status, HWID binding, IP locks, and an
  event audit trail. For software that needs activation control.

## Serials (simple)

Use **Serials** fulfillment mode for: Steam keys, gift codes, beta access codes, anything where
a buyer just needs a unique string they can paste somewhere else.

### Uploading

Add codes from the product's **Serials** tab — paste one per line or upload a CSV. Shoppex
stores them as an unlocked pool. When a buyer pays, one code locks to their order and is
removed from the pool.

The product lists as "out of stock" once the pool is empty. Top it up at any time.

### Replacements

If a buyer reports an invalid or already-used code, issue a replacement from the order detail
page → **Replace**. The replacement comes from the remaining pool, and the bad code is marked
burned so it won't be issued again.

## Licenses (advanced)

The Licenses system goes far beyond serials. Each license is its own object with:

* **Status**: `ACTIVE`, `SUSPENDED`, `REVOKED`, or `EXPIRED`. Change it any time.
* **HWID binding**: bind a license to the first machine that activates it. Subsequent
  activations from other machines fail unless you reset the HWID.
* **IP locks**: restrict a license to a single IP or range.
* **Expiration**: licenses can be perpetual or expire on a date.
* **Event audit trail**: every validation attempt (success or failure), HWID change, IP lock
  change, status change, and expiration extension is logged.

### Where to find it

The full licensing UI lives at `/licenses` in the dashboard, separate from regular products.

### Hardware-locked licenses

When a buyer activates a license through your software, your client sends the HWID to
`POST /dev/v1/licenses/validate`. Shoppex either:

* accepts and binds the HWID if the license is unbound, or
* accepts if the HWID matches the bound one, or
* rejects if the HWID doesn't match.

When a buyer needs a new machine, they (or you) call **reset HWID** to unbind. Configure this
flow from the license detail page or via the [API](/developers/learn/overview).

### Status changes

Suspending a license blocks future validations without deleting it. Revoking is permanent and
triggers a license event. Expired licenses stop validating but stay in the system for
reference.
