Preverified MarkTag Implementation
Complete implementation guide for preverified MarkTag - white-label tracking solution for platform providers.
Overview
Preverified MarkTag allows platform providers to offer instant tracking to their merchants without requiring merchant-side DNS configuration. Tracking runs under your platform's domain, providing a seamless white-label solution.
Best for:
- Platform-hosted merchants
- White-label tracking solutions
- Bulk merchant onboarding
- Non-technical merchants
Setup time: Instant (after one-time platform setup)
Prerequisites
One-Time Platform Setup (Required First)
Before you can use preverified MarkTags, you must complete a one-time setup:
- Contact Markopolo - Email partners@markopolo.ai to request preverified access
- Receive CNAME Target - Get your unique target (e.g.,
partner-xyz.tracking.markopolo.ai) - Configure Your DNS - Add CNAME record for your chosen subdomain
- Verification - Markopolo confirms your setup
- Access Granted - You can now create preverified MarkTags
⚠️ Important: This setup must be completed before following this guide.
After Setup Prerequisites
- Partners API token (
mp_live_...) - Preverified access enabled
- Your platform domain configured (e.g.,
tracking.yourplatform.com) - Access to merchant websites or platform templates
One-Time Platform Setup Process
Step 1: Request Preverified Access
Send an email to partners@markopolo.ai:
Subject: Preverified MarkTag Setup Request
Partner Name: [Your Platform Name]
API Token: mp_live_[YOUR_TOKEN_ID] // Just the ID portion for verification
Proposed Domain: tracking.yourplatform.com
Expected Merchant Volume: [Number of merchants]
Platform Type: [E-commerce/Website Builder/etc.]
Use Case: [Brief description of how you'll use preverified MarkTags]Step 2: Receive Configuration from Markopolo
You'll receive configuration details:
{
"partnerId": "ptr_abc123...",
"cnameConfiguration": {
"type": "CNAME",
"hostname": "tracking.yourplatform.com",
"target": "partner-xyz.tracking.markopolo.ai",
"ttl": 3600
},
"verificationEndpoint": "https://tracking.yourplatform.com/verify",
"estimatedSetupTime": "5-30 minutes for DNS propagation"
}Step 3: Configure Your Platform DNS
Add the CNAME record to your platform's DNS:
| Field | Value |
|---|---|
| Type | CNAME |
| Name | tracking |
| Target | partner-xyz.tracking.markopolo.ai |
| TTL | 3600 |
Note: The target is unique to your partnership, not the generic tracking.markopolo.ai.
Step 4: Verify DNS Configuration
Check that your DNS is configured correctly:
# Verify CNAME record
dig tracking.yourplatform.com CNAME +short
# Should return:
# partner-xyz.tracking.markopolo.ai.Step 5: Notify Markopolo for Activation
Reply to the setup email:
DNS configuration complete.
Domain: tracking.yourplatform.com
CNAME Target: partner-xyz.tracking.markopolo.ai
Please verify and activate preverified access.Step 6: Receive Confirmation
Markopolo will verify and confirm:
{
"status": "active",
"domain": "tracking.yourplatform.com",
"preverifiedEnabled": true,
"activatedAt": "2024-01-15T10:00:00Z",
"message": "Preverified access enabled. You can now generate preverified MarkTags."
}Complete Implementation Flow
Once preverified access is enabled, follow these steps for each merchant:
Step 1: Create Merchant Account
Create a merchant account on your platform.
Request:
curl -X POST https://api-alpha.markopolo.ai/v1/partners/merchant \
-H "Authorization: Bearer mp_live_YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"name": "Platform Merchant Store",
"domain": "merchant.yourplatform.com"
}'Response:
{
"merchantId": "mch_5f6g7h8i-9j0k-1l2m-3n4o-5p6q7r8s9t0u",
"name": "Platform Merchant Store",
"domain": "merchant.yourplatform.com",
"createdAt": "2024-01-15T12:00:00Z"
}Step 2: Generate Preverified MarkTag
Generate a preverified MarkTag for instant activation.
Request:
curl -X POST https://api-alpha.markopolo.ai/v1/partners/marktag/generate \
-H "Authorization: Bearer mp_live_YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"merchantId": "mch_5f6g7h8i-9j0k-1l2m-3n4o-5p6q7r8s9t0u",
"type": "preverified"
}'Response:
{
"tagId": "server-def456",
"record": {
"type": "CNAME",
"name": "mtag",
"value": "mtag.markopolo.ai",
"ttl": 300
},
"status": "active",
"message": "New tag created successfully",
"type": "preverified"
}Key differences from other types:
- status: Immediately
active(no DNS wait) - record: Shows the DNS configuration you set up during onboarding
- Works immediately with your pre-configured domain
Step 3: Install the Tracking Script
No DNS wait needed! Install immediately.
Extract TAG_ID
From the response:
- tagId:
server-def456 - Your tracking domain:
tracking.yourplatform.com(configured during onboarding)
The tracking implementation requires two script tags:
Installation Methods
Method A: Direct Template Injection
For platform-controlled templates:
<!-- In your platform's merchant template -->
<!DOCTYPE html>
<html>
<head>
<!-- Preverified MarkTag Initialization (Your Platform Analytics) -->
<script>
window.mtrem = window.mtrem || [];
function mtag() {
mtrem.push(arguments);
}
mtag("init", "https://tracking.yourplatform.com?tagId=server-def456", {
consent: true,
});
</script>
<!-- Preverified MarkTag Loader -->
<script async src="https://tracking.yourplatform.com/script"></script>
<!-- Rest of merchant's head content -->
{{ merchant.head_content }}
</head>
<body>
{{ merchant.body_content }}
</body>
</html>Method B: Automatic Injection System
class PlatformAnalytics {
constructor(apiToken, platformDomain) {
this.apiToken = apiToken;
this.platformDomain = platformDomain;
this.apiBase = 'https://api-alpha.markopolo.ai/v1/partners';
}
async enableAnalyticsForMerchant(merchantData) {
// Step 1: Create or get merchant
const merchant = await this.createMerchant(merchantData);
// Step 2: Generate preverified marktag
const marktag = await this.generatePreverifiedMarkTag(merchant.merchantId);
// Step 3: Inject into merchant's site automatically
await this.injectTrackingScript(merchant.merchantId, marktag.tagId);
return {
success: true,
merchantId: merchant.merchantId,
tagId: marktag.tagId,
trackingActive: true,
initUrl: `https://${this.platformDomain}?tagId=${marktag.tagId}`,
scriptUrl: `https://${this.platformDomain}/script`
};
}
async createMerchant(data) {
const response = await fetch(`${this.apiBase}/merchant`, {
method: 'POST',
headers: {
'Authorization': `Bearer ${this.apiToken}`,
'Content-Type': 'application/json'
},
body: JSON.stringify(data)
});
return response.json();
}
async generatePreverifiedMarkTag(merchantId) {
const response = await fetch(`${this.apiBase}/marktag`, {
method: 'POST',
headers: {
'Authorization': `Bearer ${this.apiToken}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({
merchantId,
type: 'preverified'
})
});
return response.json();
}
async injectTrackingScript(merchantId, tagId) {
// Your platform-specific injection logic
const scripts = `
<script>
window.mtrem = window.mtrem || [];
function mtag() {
mtrem.push(arguments);
}
mtag("init", "https://${this.platformDomain}?tagId=${tagId}", {
consent: true,
});
</script>
<script async src="https://${this.platformDomain}/script"></script>
`;
// Example: Update merchant template in database
await database.updateMerchantTemplate(merchantId, {
headScripts: scripts
});
// Or inject via your template engine
await templateEngine.addToHead(merchantId, scripts);
}
}
// Usage
const analytics = new PlatformAnalytics('mp_live_YOUR_TOKEN', 'tracking.yourplatform.com');
// When merchant enables analytics in your platform
const result = await analytics.enableAnalyticsForMerchant({
name: 'New Merchant Store',
domain: 'newstore.yourplatform.com'
});
console.log('Analytics enabled:', result);Step 4: Verify Tracking
Confirm events are being received immediately.
Request:
curl -X GET "https://api-alpha.markopolo.ai/v1/partners/events?merchantId=mch_5f6g7h8i-9j0k-1l2m-3n4o-5p6q7r8s9t0u&limit=5" \
-H "Authorization: Bearer mp_live_YOUR_TOKEN"Expected Response:
{
"events": [
{
"eventId": "evt_345678",
"type": "pageview",
"url": "https://merchant.yourplatform.com/",
"timestamp": "2024-01-15T12:02:00Z",
"domain": "tracking.yourplatform.com",
"merchantId": "mch_5f6g7h8i-9j0k-1l2m-3n4o-5p6q7r8s9t0u"
}
],
"pagination": {
"currentPage": 1,
"totalItems": 1
}
}✅ Success! Events appear immediately with no DNS configuration by merchant.
Platform Integration Patterns
Pattern 1: Bulk Merchant Onboarding
class BulkOnboarding {
constructor(apiToken, platformDomain) {
this.apiToken = apiToken;
this.platformDomain = platformDomain;
}
async onboardMerchants(merchants) {
const results = [];
for (const merchantData of merchants) {
try {
// Create merchant
const merchant = await this.createMerchant(merchantData);
// Generate preverified marktag
const marktag = await this.generateMarkTag(merchant.merchantId);
// Store tracking info
await this.storeTrackingInfo(merchant.merchantId, marktag);
results.push({
merchantId: merchant.merchantId,
tagId: marktag.tagId,
status: 'success',
initUrl: `https://${this.platformDomain}?tagId=${marktag.tagId}`,
scriptUrl: `https://${this.platformDomain}/script`
});
} catch (error) {
results.push({
merchantName: merchantData.name,
status: 'failed',
error: error.message
});
}
}
return results;
}
async createMerchant(data) {
// API call to create merchant
}
async generateMarkTag(merchantId) {
// API call to generate preverified marktag
}
async storeTrackingInfo(merchantId, marktag) {
// Store in your database for later use
await database.saveTrackingInfo({
merchantId,
tagId: marktag.tagId,
initUrl: `https://${this.platformDomain}?tagId=${marktag.tagId}`,
scriptUrl: `https://${this.platformDomain}/script`
});
}
}
// Bulk onboard merchants
const onboarding = new BulkOnboarding('mp_live_YOUR_TOKEN', 'tracking.yourplatform.com');
const results = await onboarding.onboardMerchants([
{ name: 'Store 1', domain: 'store1.platform.com' },
{ name: 'Store 2', domain: 'store2.platform.com' },
{ name: 'Store 3', domain: 'store3.platform.com' }
]);Pattern 2: Dashboard Integration
// React component for merchant dashboard
import React, { useState } from 'react';
function AnalyticsSettings({ merchantId }) {
const [analyticsEnabled, setAnalyticsEnabled] = useState(false);
const [loading, setLoading] = useState(false);
const [tagId, setTagId] = useState(null);
const enableAnalytics = async () => {
setLoading(true);
try {
// Call your backend to generate preverified marktag
const response = await fetch('/api/analytics/enable', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ merchantId })
});
const data = await response.json();
// Analytics is instantly active
setAnalyticsEnabled(true);
setTagId(data.tagId);
// Show success message
alert('Analytics enabled! Tracking will begin immediately.');
} catch (error) {
alert('Failed to enable analytics: ' + error.message);
} finally {
setLoading(false);
}
};
return (
<div className="analytics-settings">
<h2>Analytics Settings</h2>
{!analyticsEnabled ? (
<div>
<p>Enable analytics to track visitor behavior and conversions.</p>
<button onClick={enableAnalytics} disabled={loading}>
{loading ? 'Enabling...' : 'Enable Analytics (Instant)'}
</button>
<p className="note">
✨ No technical setup required - activates immediately!
</p>
</div>
) : (
<div>
<p>✅ Analytics is active and tracking</p>
<p>Tag ID: {tagId}</p>
<a href="/analytics/dashboard">View Analytics Dashboard →</a>
</div>
)}
</div>
);
}Pattern 3: Multi-Tenant SaaS Platform
# Python/Django example for SaaS platform
from django.db import models
import requests
class MerchantAnalytics:
API_TOKEN = 'mp_live_YOUR_TOKEN'
API_BASE = 'https://api-alpha.markopolo.ai/v1/partners'
TRACKING_DOMAIN = 'tracking.yourplatform.com'
@classmethod
def enable_for_tenant(cls, tenant):
"""Enable analytics for a tenant/merchant"""
# Step 1: Create merchant in Markopolo
merchant_response = requests.post(
f'{cls.API_BASE}/merchant',
headers={'Authorization': f'Bearer {cls.API_TOKEN}'},
json={
'name': tenant.name,
'domain': tenant.domain
}
)
merchant = merchant_response.json()
# Step 2: Generate preverified marktag
marktag_response = requests.post(
f'{cls.API_BASE}/marktag',
headers={'Authorization': f'Bearer {cls.API_TOKEN}'},
json={
'merchantId': merchant['merchantId'],
'type': 'preverified'
}
)
marktag = marktag_response.json()
# Step 3: Save to database
tenant.analytics_enabled = True
tenant.tag_id = marktag['tagId']
tenant.tracking_script = f"""
<script>
window.mtrem = window.mtrem || [];
function mtag() {{
mtrem.push(arguments);
}}
mtag("init", "https://{cls.TRACKING_DOMAIN}?tagId={marktag['tagId']}", {{
consent: true,
}});
</script>
<script async src="https://{cls.TRACKING_DOMAIN}/script"></script>
"""
tenant.save()
# Step 4: Inject into tenant's template
cls.inject_tracking_script(tenant)
return marktag
@classmethod
def inject_tracking_script(cls, tenant):
"""Inject tracking script into tenant's site template"""
# Your platform-specific injection logic
# This could update a template, modify HTML, or use a middleware
pass
# Usage in view
def enable_analytics_view(request):
tenant = request.tenant # Your tenant detection logic
marktag = MerchantAnalytics.enable_for_tenant(tenant)
return JsonResponse({
'success': True,
'message': 'Analytics enabled instantly',
'tagId': marktag['tagId']
})White-Label Customization
Custom Analytics Branding
Since tracking runs under your domain, you can:
Brand as Your Analytics
html<!-- Presented to merchants as your platform's analytics --> <!-- YourPlatform Analytics --> <script> window.mtrem = window.mtrem || []; function mtag() { mtrem.push(arguments); } mtag("init", "https://tracking.yourplatform.com?tagId=server-def456", { consent: true, }); </script> <script async src="https://tracking.yourplatform.com/script"></script>Custom Documentation Create your own analytics documentation referring to your domain
Integrated Dashboards Build analytics dashboards using the Events API
API Wrapper for White-Label
class YourPlatformAnalytics {
constructor() {
// Hide Markopolo implementation details
this.platformDomain = 'tracking.yourplatform.com';
}
getTrackingCode(merchantId) {
// Return branded tracking code
const tagId = this.getTagIdForMerchant(merchantId);
return {
scripts: `
<script>
window.mtrem = window.mtrem || [];
function mtag() {
mtrem.push(arguments);
}
mtag("init", "https://${this.trackingDomain}?tagId=${tagId}", {
consent: true,
});
</script>
<script async src="https://${this.trackingDomain}/script"></script>`,
instructions: 'Add this YourPlatform Analytics code to your website'
};
}
async getAnalytics(merchantId, dateRange) {
// Fetch from Markopolo API but present as your analytics
const events = await this.fetchEvents(merchantId, dateRange);
return this.formatAsYourAnalytics(events);
}
}Migration Scenarios
From Client-Side to Preverified
async function migrateToPreverified(merchantId) {
// Step 1: Generate preverified marktag
const preverifiedMarkTag = await generatePreverifiedMarkTag(merchantId);
// Step 2: Update merchant's template
// Replace old client-side scripts with preverified
const oldScripts = `
<script>
window.mtrem = window.mtrem || [];
function mtag() {
mtrem.push(arguments);
}
mtag("init", "https://mtag.markopolo.ai?tagId=OLD_TAG_ID", {
consent: true,
});
</script>
<script async src="https://mtag.markopolo.ai/script"></script>`;
const newScripts = `
<script>
window.mtrem = window.mtrem || [];
function mtag() {
mtrem.push(arguments);
}
mtag("init", "https://tracking.yourplatform.com?tagId=${preverifiedMarkTag.tagId}", {
consent: true,
});
</script>
<script async src="https://tracking.yourplatform.com/script"></script>`;
await updateMerchantTemplate(merchantId, {
find: oldScripts,
replace: newScripts
});
// Step 3: Optionally disable old marktag
await disableOldMarkTag(oldMarkTagId);
return {
success: true,
newTagId: preverifiedMarkTag.tagId
};
}From External Analytics
async function migrateFromGoogleAnalytics(merchantId) {
// Step 1: Generate preverified marktag
const marktag = await generatePreverifiedMarkTag(merchantId);
// Step 2: Add alongside GA initially
const dualTracking = `
<!-- Google Analytics -->
<script async src="https://www.googletagmanager.com/gtag/js?id=GA_ID"></script>
<script>
window.dataLayer = window.dataLayer || [];
function gtag(){dataLayer.push(arguments);}
gtag('js', new Date());
gtag('config', 'GA_ID');
</script>
<!-- YourPlatform Analytics (Powered by Markopolo) -->
<script>
window.mtrem = window.mtrem || [];
function mtag() {
mtrem.push(arguments);
}
mtag("init", "https://tracking.yourplatform.com?tagId=${marktag.tagId}", {
consent: true,
});
</script>
<script async src="https://tracking.yourplatform.com/script"></script>
`;
// Step 3: Run both in parallel for testing period
// Step 4: Remove GA once confident
}Troubleshooting
Issue: "Preverified not enabled for partner"
Cause: Trying to generate preverified marktag before setup
Solution:
- Complete one-time setup with Markopolo
- Wait for confirmation email
- Verify your platform DNS is configured
Check:
curl -X POST https://api-alpha.markopolo.ai/v1/partners/marktag \
-H "Authorization: Bearer mp_live_YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"merchantId": "TEST_MERCHANT_ID",
"type": "preverified"
}'Issue: Scripts not loading
Diagnostic:
# Check your platform domain is resolving
dig tracking.yourplatform.com CNAME
# Test script endpoint
curl -I https://tracking.yourplatform.com/script?tagId=server-def456Solutions:
- Verify platform DNS is still configured correctly
- Check CNAME hasn't been accidentally removed
- Ensure SSL certificate is valid
Issue: Events not appearing
Check merchant configuration:
# Get merchant details
curl -X GET "https://api-alpha.markopolo.ai/v1/partners/merchant/MERCHANT_ID" \
-H "Authorization: Bearer mp_live_YOUR_TOKEN"
# Check marktag status
curl -X GET "https://api-alpha.markopolo.ai/v1/partners/marktag/MARKTAG_ID" \
-H "Authorization: Bearer mp_live_YOUR_TOKEN"Best Practices
- Automatic Injection - Inject scripts automatically when merchants enable analytics
- Bulk Operations - Use batch APIs for multiple merchant setup
- Monitor Platform DNS - Set up monitoring for your tracking domain
- Version Control - Track which merchants have which TAG_IDs
- Gradual Rollout - Test with a few merchants before platform-wide deployment
- Documentation - Create merchant-facing docs using your branding
API Reference
Generate Preverified MarkTag
POST /v1/partners/marktagRequest Body:
{
"merchantId": "string",
"type": "preverified"
}Response:
{
"tagId": "string",
"record": {
"type": "CNAME",
"name": "mtag",
"value": "mtag.markopolo.ai",
"ttl": 300
},
"status": "active",
"message": "New tag created successfully",
"type": "preverified"
}Check Preverified Status
GET /v1/partners/configResponse:
{
"partnerId": "string",
"preverifiedEnabled": true,
"preverifiedDomain": "tracking.yourplatform.com",
"features": {
"preverified": true,
"clientSide": true,
"serverSide": true
}
}