Skip to main content

Verify Code

POST /api/v1/code/verify

Verify the authenticity of an Optropic code. Returns a verdict (AUTHENTIC, COUNTERFEIT, or SUSPICIOUS) along with detailed check results.

Request

Headers

HeaderRequiredDescription
x-api-keyYesYour Optropic API key
Content-TypeYesMust be application/json

Body Parameters

ParameterTypeRequiredDescription
urlstringYes*The complete GS1 Digital Link URL
contentstringYes*Alternative: raw QR code content

*Provide either url or content, not both.

Example Request

curl -X POST https://api.optropic.com/api/v1/code/verify \
-H "x-api-key: optr_live_YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{
"url": "https://id.optropic.com/01/04260799580008/21/SN-2026-001/10/BATCH-A?sig=Kx7mN2..."
}'

Response

Success (200 OK)

{
"verdict": "AUTHENTIC",
"confidence": 0.95,
"gtin": "04260799580008",
"serial": "SN-2026-001",
"batch": "BATCH-A",
"checks": {
"signature": {
"passed": true,
"keyId": "key_abc123",
"algorithm": "Ed25519"
},
"format": {
"passed": true,
"standard": "GS1_DIGITAL_LINK"
},
"scanPattern": {
"passed": true,
"scanNumber": 3,
"riskLevel": "low"
}
},
"metadata": {
"firstSeen": "2026-02-15T08:00:00Z",
"lastSeen": "2026-02-18T10:30:00Z",
"totalScans": 3
},
"riskIndicators": []
}

Response Fields

FieldTypeDescription
verdictstringAUTHENTIC, COUNTERFEIT, or SUSPICIOUS
confidencenumberConfidence score (0.0 to 1.0)
gtinstringExtracted GTIN
serialstringExtracted serial number
batchstringExtracted batch number
checksobjectIndividual verification checks
metadataobjectScan history metadata
riskIndicatorsarrayList of detected risk factors

Verdicts

VerdictMeaningAction
AUTHENTICCode is valid, signature verifiedSafe to sell/use
COUNTERFEITSignature invalid or unknown keyInvestigate immediately
SUSPICIOUSValid signature but unusual patternsReview manually

Checks Explained

signature

Verifies the Ed25519 digital signature against registered public keys.

{
"passed": true,
"keyId": "key_abc123",
"algorithm": "Ed25519"
}

format

Validates GS1 Digital Link URL structure and encoding.

{
"passed": true,
"standard": "GS1_DIGITAL_LINK"
}

scanPattern

Analyzes scan history for anomalies (e.g., excessive scans, geographic impossibilities).

{
"passed": true,
"scanNumber": 3,
"riskLevel": "low"
}

Risk Indicators

When verdict is SUSPICIOUS, check riskIndicators:

IndicatorDescription
EXCESSIVE_SCANSUnusually high scan count
GEOGRAPHIC_IMPOSSIBILITYScans from impossible locations in timeframe
KNOWN_COUNTERFEIT_PATTERNMatches known counterfeit signatures
EXPIRED_CODECode past its valid date

Errors

CodeHTTP StatusDescription
INVALID_URL400URL is malformed or missing signature
MISSING_SIGNATURE400No sig parameter in URL
KEY_NOT_FOUND404Signing key not registered
RATE_LIMITED429Verify rate limit exceeded

Code Examples

JavaScript

async function verifyCode(url) {
const response = await fetch('https://api.optropic.com/api/v1/code/verify', {
method: 'POST',
headers: {
'x-api-key': process.env.OPTROPIC_API_KEY,
'Content-Type': 'application/json',
},
body: JSON.stringify({ url }),
});

const result = await response.json();

if (result.verdict === 'AUTHENTIC') {
console.log('✅ Product is authentic');
} else if (result.verdict === 'COUNTERFEIT') {
console.log('❌ WARNING: Counterfeit detected!');
} else {
console.log('⚠️ Suspicious - manual review needed');
console.log('Risk indicators:', result.riskIndicators);
}

return result;
}

Python

import requests
import os

def verify_code(url: str) -> dict:
response = requests.post(
'https://api.optropic.com/api/v1/code/verify',
headers={
'x-api-key': os.environ['OPTROPIC_API_KEY'],
'Content-Type': 'application/json',
},
json={'url': url}
)
response.raise_for_status()
return response.json()

# Usage
result = verify_code('https://id.optropic.com/01/...')

if result['verdict'] == 'AUTHENTIC':
print('Product verified as authentic')
elif result['verdict'] == 'COUNTERFEIT':
print('WARNING: Counterfeit detected!')

Offline Verification

Because Optropic uses Ed25519 signatures, verification can be performed offline if you have the public key. See Offline Verification for details.