For convenience, here's an example of how to interact with our APIs to verify Legitimate's NFC tags in your own application
The following code snippet is an example of a synchronous, blocking javascript function to verify the digital signatures emitted by Legitimate's NFC tags.
This code is provided as an example for your own implementation. For more information on how to implement this exact code into your own website, please see Getting Started.
The code of the javascript is expanded below for reference.
Use our provided javascript function in your own HTML website to easily verify the digital signatures emitted by Legitimate's NFC tags
For convenience, Legitimate provides a simple javascript implementation of the API verification mechanism required to validate the digital signatures emitted by NFC tags. You can see a full HTML example .
To get started, simply add our minified javascript function to the top of your HTML <head> block. Make sure this is at the top of the <head> block as it is required to load first.
This script contains sensible defaults that will hide the entirety of your page's contents until after the digital signature verification is complete. You can see the un-minified implementation of this script
This script calls the exact same API endpoint as described in Verify by passing through the verification parameters present in the URL query parameters. If the verification is successful, the contents of your HTML <body> will be displayed as normal.
By default, the snippet will display an error message if the digital signature verification fails. You may add custom error messages by adding the following HTML elements to your page.
The inner contents of an HTML element with the following id legitimate-expired-cmac-message will be used as the error state content if the verification fails due to the verification parameters being reused.
Our API is designed in such a way that each tag verification can only occur once with a given set of parameters. This is to prevent customers from sharing or replicating any URLs or links emitted by the NFC tag.
The inner contents of an HTML element with the following id legitimate-custom-error-message will be used as the default error state content if the verification fails.
<head>
<script type="text/javascript">
(function(){var a=document.createElement('style');a.innerHTML=`
body { display: none !important; }
`;document.head.appendChild(a);var b='https://api.legitimate.tech/external/v1/tags/verify';document.addEventListener('DOMContentLoaded',()=>{console.log('DOM loaded, making API request');fetch(b,{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify(Object.fromEntries(new URLSearchParams(window.location.search)))}).then(async A=>{var _=await A.json();if(!A.ok){A.status===422&&_.errors.cmac.indexOf('has expired')!==-1?c('expired_cmac'):c();return}!_.errors?a.innerHTML=`
body { display: block !important; }
#legitimate-custom-error-message { display: none !important; }
#legitimate-expired-cmac-message { display: none !important; }
`:c()}).catch(()=>c())});function c(B='default'){let C=document.getElementById('legitimate-error-message-container');!C&&(console.log('Creating error message container'),C=document.createElement('div'),C.id='legitimate-error-message-container',document.body.appendChild(C));let _c=`
<div style="font-family: sans-serif; color: red; padding: 2rem; text-align: center;">
An error occurred. Please try again later.
</div>
`;if(B==='expired_cmac'){var d=document.getElementById('legitimate-expired-cmac-message');d&&(console.log('Using expired cmac error message'),_c=d.innerHTML)}else{var e=document.getElementById('legitimate-custom-error-message');e&&(console.log('Using custom error message'),_c=e.innerHTML)}C.innerHTML=_c;a.innerHTML=`
body { display: block !important; }
body > *:not(#legitimate-error-message-container) { display: none !important; }
`}})();
</script>
<!-- other code that may need to go into the head element -->
</head><div id="legitimate-expired-cmac-message" class="hidden">
<!-- Expired CMAC Error Message -->
</div><div id="legitimate-custom-error-message" class="hidden">
<!-- Your content here -->
</div>Legitimate allows agencies and developers to create entirely custom digital experiences on the Legitimate platform for a given set of tags.
Legitimate's API can be used to redirect to custom web applications or even native app experiences via two different approaches. This page covers the simple flow when redirecting to another web-based application. For information on native app integration, please refer to Native App Implementation
The Legitimate Tags are pre-programmed to link to the Tap by Legitimate web app that then be configured to redirect to your own website.
Legitimate's NFC Tags can be configured to redirect to a different domain or URL with the verification parameters from the tag to create an entirely new user flow and digital experience. This is extremely useful to redirect users to a custom web experience, or redirect to a native mobile app experience.
By default, Legitimate's NFC Tags are pre-programmed to open Legitimate's web URL first and then redirect to another desired URL. Legitimate will collect analytics data before redirecting.
The URL parameters can then be used to call the tag related APIs.
Each time an NFC tag is scanned, a new set of verification parameters will be generated. Therefore, if you are intending to use the Tag URL Redirect features, it is extremely important to note that . This is meant to protect the connected products from counterfeit and ensure that each scan is unique.
To configure the redirect URL, please login to the , open the configuration page for the desired SKU, and set the Redirect URL field.
User taps the tag with their phone and opens the link popup
The browser opens
The uid, ctr, and cmac is used to verify the tag's authenticity and get information about the content for the tag.
The browser is then redirected to your own page with the same parameters https://www.yourdomain.com/page/name?uid=XXXXXXXXXXXXXX&ctr=YYYYYY&cmac=ZZZZZZZZZZZZ
Your own page must now call our APIs to verify the digital signature payload that is present in the query parameters.
Please reference our Getting Started guide to see how to implement this verification via a simple JS snippet
Alternatively, you can implement this verification yourself using our API Resources to create a more robust user-experience.

https://verify.legitimate.tech/?uid=XXXXXXXXXXXXXXX&ctr=YYYYYY&cmac=ZZZZZZZZZZZZZZZZhttps://www.yourdomain.com/experience/?uid=XXXXXXXXXXXXXX&ctr=YYYYYY&cmac=ZZZZZZZZZZZZZ<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Script Test</title>
<script src="verify-sdk-v1.js"></script>
<script src="https://cdn.tailwindcss.com"></script>
</head>
<body class="min-h-screen bg-gray-50">
<main class="container mx-auto px-4 py-8">
<h1 class="text-4xl font-bold text-gray-900 mb-4">Main Page Content</h1>
<p class="text-lg text-gray-600">If the API is valid, you'll see this content.</p>
</main>
<!-- Custom Error Message -->
<div id="legitimate-custom-error-message" class="hidden">
<div class="min-h-screen flex items-center justify-center bg-gray-50">
<div class="max-w-md w-full p-6 bg-white rounded-lg shadow-lg">
<h1 class="text-3xl font-bold text-red-600 mb-4">Custom Error!</h1>
<p class="text-gray-600">This content failed to load. Please contact support.</p>
</div>
</div>
</div>
<!-- Expired CMAC Error Message -->
<div id="legitimate-expired-cmac-message" class="hidden">
<div class="min-h-screen flex items-center justify-center bg-gray-50">
<div class="max-w-md w-full p-6 bg-white rounded-lg shadow-lg">
<h1 class="text-3xl font-bold text-red-600 mb-4">Please Scan the Tag Again</h1>
<p class="text-gray-600">The tag verification has expired. Please scan the tag again.</p>
</div>
</div>
</div>
</body>
</html>(function() {
// Inject CSS to hide body and error container
const style = document.createElement('style');
style.innerHTML = `
body { display: none !important; }
`;
document.head.appendChild(style);
const API_URL = 'https://api.legitimate.tech/external/v1/tags/verify';
document.addEventListener('DOMContentLoaded', () => {
console.log('DOM loaded, making API request');
fetch(API_URL, {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(Object.fromEntries(new URLSearchParams(window.location.search)))
}).then(async res => {
const data = await res.json();
if (!res.ok) {
if (res.status === 422 && data.errors.cmac.indexOf('has expired') !== -1) {
renderErrorMessage('expired_cmac');
} else {
renderErrorMessage();
}
return;
}
if (!data.errors) {
style.innerHTML = `
body { display: block !important; }
#legitimate-custom-error-message { display: none !important; }
#legitimate-expired-cmac-message { display: none !important; }
`;
} else {
renderErrorMessage();
}
})
.catch(() => {
renderErrorMessage();
});
});
function renderErrorMessage(errorType = 'default') {
let errorContainer = document.getElementById('legitimate-error-message-container');
if (!errorContainer) {
console.log('Creating error message container');
errorContainer = document.createElement('div');
errorContainer.id = 'legitimate-error-message-container';
document.body.appendChild(errorContainer);
}
let errorContent = `
<div style="font-family: sans-serif; color: red; padding: 2rem; text-align: center;">
An error occurred. Please try again later.
</div>
`;
if (errorType === 'expired_cmac') {
const expiredCmacErrorEl = document.getElementById('legitimate-expired-cmac-message');
if (expiredCmacErrorEl) {
console.log('Using expired cmac error message');
errorContent = expiredCmacErrorEl.innerHTML;
}
} else {
const customErrorEl = document.getElementById('legitimate-custom-error-message');
if (customErrorEl) {
console.log('Using custom error message');
errorContent = customErrorEl.innerHTML;
}
}
errorContainer.innerHTML = errorContent;
style.innerHTML = `
body { display: block !important; }
body > *:not(#legitimate-error-message-container) { display: none !important; }
`;
}
})();