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

# Verify a serial

> Check a serial, or a GS1 code's serial, and record the scan.

Scope: `scans:verify`. Use it for codes your app or scanner has already decoded: a GS1 DataMatrix
or QR, or a serial-only code.

**serial** `string` *required*

The 16-character serial, with or without hyphens.

**channel** `string` (default: sdk)

Where the scan came from: `mechanic_app`, `consumer_web`, `whatsapp_bot`, `rugged_handheld`, `mobile_app` or `sdk`. A publishable key sets it: `sdk` from a website, `mobile_app` from an app.

**location** `object`

`district`, `state`, `country` and `point` (`{"lat": 18.52, "lng": 73.86}`). Used for clone and
region checks and the hotspot map.

**gtin** `string`

The GTIN printed with the serial (GS1 AI 01). When it isn't the GTIN of the serial's batch, the
verdict is `suspicious` with the reason "GTIN on the label (…) doesn't match batch …".

**lot** `string`

The lot printed with the serial (GS1 AI 10), checked against the batch's lot the same way.

**device** `object`

`os`, `appVersion` and `id` (a stable device id; stored hashed).

**dryRun** `boolean` (default: false)

Check without recording the scan. Ignored for publishable keys, which always record.

**verdict** `string` *required*

`genuine`, `suspicious` or `counterfeit`.

**reason** `string` *required*

Why, in a sentence.

**checks** `object[]` *required*

Each check's `kind` (`signature`, `serial_status`, `clone_pattern`, `region`), `result` (`pass`, `warn` or `fail`) and `detail`.

**scanId** `string`

The recorded scan, unless `dryRun`.

**batchId** `string`

The batch the serial belongs to, such as `B-1045`.

**productId** `string`

**productName** `string`

```bash cURL theme={null}
curl https://api.satyakod.com/v1/verify \
  -H "Authorization: Bearer $SATYAKOD_KEY" \
  -H "Content-Type: application/json" \
  -d '{"serial": "0021-A051-2PXK-20J9", "channel": "rugged_handheld",
       "location": {"district": "Pune", "state": "MH", "country": "IN"}}'
```

```json 200 theme={null}
{
  "verdict": "genuine",
  "reason": "All checks passed",
  "checks": [
    { "kind": "signature", "result": "pass", "detail": "Key acme-gs1-2026-01" },
    { "kind": "serial_status", "result": "pass", "detail": "Issued in B-1045" },
    { "kind": "clone_pattern", "result": "pass", "detail": "No clone pattern" },
    { "kind": "region", "result": "pass", "detail": "Inside authorised region" }
  ],
  "scanId": "scn_8k2m4q7w1z3x5c9v",
  "batchId": "B-1045",
  "productId": "prd_wb18",
  "productName": "Wiper blade WB-18"
}
```


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.