First Integration
This guide walks you through building a complete product authentication workflow, from tagging products to verifying them in your app.
Integration Overview
A complete TAG IT integration involves four key steps:
- Register products on the blockchain with unique identifiers and metadata
- Link NFC tags to associate physical tags with blockchain records
- Build verification flows to let users scan and verify products
- Handle results appropriately based on verification outcomes
By the end of this guide, you'll have a working authentication system that can register products, link them to NFC tags, and verify their authenticity.
Make sure you've completed the Quick Start Guide and have your API keys ready before proceeding.
Registering a Product
The first step is to register your product on the TAG IT blockchain. This creates an immutable record that serves as the source of truth for authenticity verification.
import { TagIt } from '@tagit/sdk';
const tagit = new TagIt({
apiKey: process.env.TAGIT_API_KEY,
network: 'testnet' // Use 'testnet' for development
});
async function registerProduct(productData) {
try {
const product = await tagit.products.register({
// Required fields
name: productData.name,
sku: productData.sku,
serialNumber: productData.serialNumber,
// Product metadata
metadata: {
brand: productData.brand,
category: productData.category,
manufactureDate: productData.manufactureDate,
origin: productData.origin,
description: productData.description,
imageUrl: productData.imageUrl
},
// Optional: Set initial owner (defaults to your wallet)
initialOwner: productData.ownerAddress
});
console.log('Product registered:', product.productId);
console.log('Transaction hash:', product.txHash);
console.log('Token ID:', product.tokenId);
return product;
} catch (error) {
console.error('Registration failed:', error.message);
throw error;
}
}
// Example usage
const newProduct = await registerProduct({
name: 'Premium Leather Handbag',
sku: 'PLH-2024-001',
serialNumber: 'SN-98765432',
brand: 'Luxury Goods Co.',
category: 'Accessories',
manufactureDate: '2024-03-15',
origin: 'Italy',
description: 'Handcrafted Italian leather handbag',
imageUrl: 'https://example.com/images/handbag.jpg'
});
Serial numbers must be unique within your organization. Attempting to register a duplicate serial number will result in an error.
Linking NFC Tags
After registering a product, you need to link it to a physical NFC tag. This creates the bridge between the physical item and its blockchain record.
async function linkNfcTag(productId, nfcTagId) {
try {
// Read the NFC tag's unique identifier
// This typically happens via your mobile app or encoding station
const tagInfo = await tagit.nfc.readTag(nfcTagId);
// Verify the tag hasn't been linked before
if (tagInfo.linkedProduct) {
throw new Error('This NFC tag is already linked to a product');
}
// Link the tag to the product
const linkResult = await tagit.products.linkTag({
productId: productId,
tagId: nfcTagId,
tagType: tagInfo.chipType, // e.g., 'NTAG424', 'ICODE SLIX2'
// Optional: Add tamper-evident seal info
sealInfo: {
applied: true,
appliedAt: new Date().toISOString(),
appliedBy: 'Factory Station #12'
}
});
console.log('Tag linked successfully');
console.log('Link ID:', linkResult.linkId);
console.log('Verification URL:', linkResult.verificationUrl);
return linkResult;
} catch (error) {
console.error('Tag linking failed:', error.message);
throw error;
}
}
// Example: Link an NFC tag after product registration
await linkNfcTag(newProduct.productId, 'NFC-04:A2:B8:1C:00:FF');
For high-volume operations, use our batch encoding API to link multiple tags in a single transaction.
Building the Verification Flow
Now let's build the consumer-facing verification flow. This is what happens when a customer scans an NFC tag to verify a product's authenticity.
async function verifyProduct(tagId) {
try {
// Step 1: Read the NFC tag
const tagData = await tagit.nfc.readTag(tagId);
// Step 2: Verify the tag's cryptographic signature
const signatureValid = await tagit.nfc.verifySignature({
tagId: tagId,
challenge: tagData.challenge,
signature: tagData.signature
});
if (!signatureValid) {
return {
status: 'COUNTERFEIT',
message: 'Tag signature verification failed',
confidence: 'HIGH'
};
}
// Step 3: Query the blockchain for product data
const verification = await tagit.products.verify(tagId);
// Step 4: Build the verification result
const result = {
status: verification.verified ? 'AUTHENTIC' : 'UNKNOWN',
product: verification.metadata,
owner: verification.currentOwner,
history: verification.transferHistory,
// Additional verification details
details: {
tagType: tagData.chipType,
scanCount: verification.scanCount,
lastScanned: verification.lastScannedAt,
registeredAt: verification.registeredAt,
blockchainProof: verification.txHash
}
};
// Step 5: Log the scan event
await tagit.analytics.logScan({
tagId: tagId,
location: await getCurrentLocation(),
timestamp: new Date().toISOString()
});
return result;
} catch (error) {
console.error('Verification error:', error.message);
return {
status: 'ERROR',
message: error.message
};
}
}
// Example usage in a mobile app
const scanResult = await verifyProduct('NFC-04:A2:B8:1C:00:FF');
displayVerificationResult(scanResult);
Handling Verification Results
Your application should handle three main verification states: success (authentic), failure (counterfeit), and unknown (unregistered or error).
Success State
When a product is verified as authentic:
function handleAuthenticResult(result) {
// Display success UI
showSuccessScreen({
title: 'Authentic Product',
productName: result.product.name,
brand: result.product.brand,
serialNumber: result.product.serialNumber,
currentOwner: formatAddress(result.owner),
registrationDate: formatDate(result.details.registeredAt)
});
// Optionally show transfer history
if (result.history.length > 1) {
showOwnershipHistory(result.history);
}
// Log successful verification for analytics
trackEvent('verification_success', {
productId: result.product.id,
brand: result.product.brand
});
}
Failure State
When a product is identified as counterfeit:
function handleCounterfeitResult(result) {
// Display warning UI
showWarningScreen({
title: 'Warning: Potential Counterfeit',
message: result.message,
confidence: result.confidence,
reportUrl: 'https://tagit.network/report'
});
// Prompt user to report
promptCounterfeitReport({
tagId: result.tagId,
location: result.scanLocation,
timestamp: new Date().toISOString()
});
// Log counterfeit detection
trackEvent('counterfeit_detected', {
tagId: result.tagId,
confidence: result.confidence
});
}
Unknown State
When a product cannot be verified (unregistered tag or system error):
function handleUnknownResult(result) {
// Display neutral UI
showInfoScreen({
title: 'Product Not Found',
message: 'This product is not registered in the TAG IT Network.',
suggestions: [
'The product may be from before TAG IT integration',
'The tag may have been damaged or replaced',
'Contact the brand for verification'
]
});
// Provide alternative verification options
showAlternativeOptions({
contactBrand: true,
manualLookup: true,
reportIssue: true
});
}
Always provide clear next steps for users, regardless of the verification result. This builds trust and helps combat counterfeits effectively.
Going to Production
Before launching your integration to production, complete this checklist to ensure a smooth transition from testnet to mainnet.
Pre-Launch Checklist
- API Keys: Generate production API keys from your dashboard
- Network Configuration: Update SDK initialization from 'testnet' to 'mainnet'
- Wallet Funding: Ensure your wallet has sufficient MATIC for gas fees
- Rate Limits: Verify your plan supports your expected API volume
- Error Handling: Test all error scenarios and edge cases
- Webhook Endpoints: Configure production webhook URLs
Configuration Changes
// Development configuration
const tagitDev = new TagIt({
apiKey: process.env.TAGIT_API_KEY_DEV,
network: 'testnet'
});
// Production configuration
const tagitProd = new TagIt({
apiKey: process.env.TAGIT_API_KEY_PROD,
network: 'mainnet',
// Production-specific options
options: {
timeout: 30000,
retries: 3,
rateLimitRetry: true
}
});
Security Checklist
- API keys stored in environment variables (never in code)
- HTTPS enabled for all API communications
- Webhook signatures validated on all incoming requests
- Rate limiting implemented on your endpoints
- Logging enabled for audit trails
Test your entire flow on testnet with real NFC tags before switching to mainnet. Mainnet transactions are permanent and incur gas fees.