MarkTag API
The MarkTag endpoints allow you to generate and verify tracking implementations for merchant domains.
Endpoints
Generate MarkTag
Generate tracking implementation for a merchant. Choose from three types based on your specific needs:
Choosing the Right MarkTag Type
Quick Decision Guide:
Need tracking NOW? → Use client-side
Merchant wants their own domain? → Use server-side
Integrating many merchants on your platform? → Use preverifiedMarkTag Type Comparison
| Type | Setup Time | DNS Required | Domain Used | Best For |
|---|---|---|---|---|
| client-side | Instant | No | mtag.markopolo.ai | Quick starts, testing, non-technical merchants |
| server-side | 5-30 min | Yes (merchant's) | Merchant's custom | Enterprise, domain control, ad blocker resistance |
| preverified | Instant | No (uses yours) | Your partner domain | Platform merchants, white-label, bulk onboarding |
Detailed Type Descriptions
client-side 🚀
- JavaScript-based tracking using
mtag.markopolo.ai - No DNS configuration ever required
- Works instantly after generation
- Perfect for immediate tracking needs
server-side 🏢
- DNS-based tracking on merchant's custom domain
- Merchant must configure CNAME record
- Requires verification before activation
- Best for enterprise requirements
preverified 🎯
- DNS-based tracking on your pre-configured partner domain
- Uses CNAME you set up during onboarding
- Activates instantly without merchant DNS setup
- Ideal for platform-integrated merchants
Endpoint: POST /v1/partners/marktag/generate
Headers:
Authorization: Bearer mp_live_YOUR_TOKEN
Content-Type: application/jsonRequest Body:
{
"merchantId": "01d1f5db-848d-4410-bb38-7e2c5b084ec8",
"type": "server-side",
"domain": "example.com" // Only required for server-side type
}Request Body Parameters:
| Field | Type | Required | Description | Validation |
|---|---|---|---|---|
merchantId | string | Yes | Merchant identifier | Valid UUID format |
type | string | Yes | Type of marktag to generate | Must be: "server-side", "client-side", or "preverified" |
domain | string | Conditional | Root domain name only | Required for "server-side" type only. Must be valid domain without protocol or www prefix. Optional for "preverified" (auto-derived from partner config) |
Type-Specific Requirements:
| Type | Domain Field | DNS Setup | Verification | Time to Active |
|---|---|---|---|---|
client-side | Not needed | Never | No | Instant |
server-side | Required | Merchant configures | Yes | 5-30 minutes |
preverified | Optional | Pre-configured by you | No | Instant |
Decision Flow
Domain Validation Rules (for server-side):
- Domain must be a root domain (e.g., "example.com")
- No protocol prefix (http:// or https://)
- No www prefix
- Must be a valid domain format
- Cannot be a preverified partner domain
- Pattern:
^(?!.*:\/\/)(?!www\.)([a-zA-Z0-9-]+\.)+[a-zA-Z]{2,}$
Example Requests:
Client-Side MarkTag (No DNS Required):
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": "01d1f5db-848d-4410-bb38-7e2c5b084ec8",
"type": "client-side"
}'Server-Side MarkTag (Custom Domain):
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": "01d1f5db-848d-4410-bb38-7e2c5b084ec8",
"type": "server-side",
"domain": "example.com"
}'Preverified MarkTag (Partner Domain):
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": "01d1f5db-848d-4410-bb38-7e2c5b084ec8",
"type": "preverified"
}'Success Responses (200 OK):
Client-Side Response:
{
"tagId": "client-abc123",
"status": "active",
"message": "New tag created successfully",
"type": "client-side"
}Server-Side Response:
{
"tagId": "server-xyz789",
"record": {
"type": "CNAME",
"name": "mtag-h7k9",
"value": "mts1.markopolo.ai",
"ttl": 300
},
"status": "inactive",
"message": "New tag created successfully",
"type": "server-side"
}Preverified Response:
{
"tagId": "server-def456",
"record": {
"type": "CNAME",
"name": "mtag-k3m7",
"value": "mts1.markopolo.ai",
"ttl": 300
},
"status": "active",
"message": "New tag created successfully",
"type": "preverified"
}Response Fields:
| Field | Type | Description | Present For |
|---|---|---|---|
tagId | string | Unique identifier for the generated MarkTag | All types |
type | string | Type of marktag ("client-side", "server-side", or "preverified") | All types |
status | string | Current status ("active" or "inactive") | All types |
message | string | Status message ("New tag created successfully" or "Existing tag retrieved") | All types |
record | object | DNS CNAME record to be added to domain | server-side, preverified only |
record.type | string | DNS record type (always "CNAME") | server-side, preverified only |
record.name | string | Subdomain name for the CNAME record | server-side, preverified only |
record.value | string | Target value for the CNAME record | server-side, preverified only |
record.ttl | number | Time-to-live in seconds | server-side, preverified only |
Status Field Reference:
Understanding the status field helps you manage marktag lifecycle:
| Type | Initial Status | Becomes Active | Action Required |
|---|---|---|---|
| client-side | active | Immediately | None |
| server-side | inactive | After DNS verification | Call verify endpoint |
| preverified | active | Immediately | None |
Error Responses:
| HTTP Status | Error Code | Description |
|---|---|---|
| 400 | VALIDATION_ERROR | Invalid request parameters (missing merchantId, invalid type, missing/invalid domain for server-side, server-side attempting to use preverified domain) |
| 401 | AUTHENTICATION_ERROR | Missing or invalid Bearer token |
| 403 | FORBIDDEN | Access denied - merchant doesn't belong to partner |
| 404 | NOT_FOUND | Merchant doesn't exist |
| 409 | VALIDATION_ERROR | Domain already registered |
| 500 | SERVICE_ERROR | Unable to process request |
For detailed error handling, see the Error Handling Guide.
Important Notes:
Progressive Enhancement Strategy:
- Start with
client-sidefor immediate tracking (always available) - Add
server-sidewhen merchant configures their domain (always available) - Use
preverifiedfor platform-integrated features (requires prior setup) - Each merchant can have one marktag of each type
Availability:
- Client-side & Server-side: Available to all partners immediately
- Preverified: Requires setup process with Markopolo (contact partners@markopolo.ai)
DNS Configuration:
- Client-side: No DNS ever required - works with JavaScript
- Server-side: Merchant adds CNAME to their domain
- Preverified: You configured CNAME once during onboarding
Activation Timeline:
- Client-side: Active immediately, no verification needed
- Server-side: Active after DNS propagation and verification
- Preverified: Active immediately using your pre-configured domain
Common Use Cases:
- Testing/Development: Use client-side for instant results
- Enterprise Merchants: Use server-side for domain control
- SaaS Platforms: Use preverified for seamless integration
- Mixed Approach: Start with client-side, add others as needed
Verify MarkTag
Verify DNS configuration for server-side marktags. This endpoint activates tracking after DNS setup.
Verification Requirements by Type
| MarkTag Type | Verification Required | Reason |
|---|---|---|
| client-side | ❌ Never | No DNS involved |
| server-side | ✅ Always | Must verify merchant's DNS |
| preverified | ❌ Never | Uses pre-verified partner domain |
When to use this endpoint:
- Only for server-side marktags
- After merchant adds CNAME to their domain
- After waiting for DNS propagation (5-30 minutes)
- To activate tracking on merchant's custom domain
Skip this endpoint for:
- Client-side marktags - They're active immediately
- Preverified marktags - They use your pre-configured domain
Endpoint: POST /v1/partners/marktag/verify
Headers:
Authorization: Bearer mp_live_YOUR_TOKEN
Content-Type: application/jsonRequest Body:
{
"tagId": "4d00dcfa-fb3d-4495-88bc-9112aedb2046",
"subdomain": "mtag-h7k9.example.com"
}Request Body Parameters:
| Field | Type | Required | Description | Validation |
|---|---|---|---|---|
tagId | string | Yes | The ID of the marktag to verify | Valid UUID format |
subdomain | string | Yes | Subdomain to verify | Valid subdomain without protocol |
Subdomain Validation Rules:
- Must not include protocol (http:// or https://)
- Can include multiple subdomain levels (e.g., "api.shop.example.com")
- Must be a valid domain format
- Pattern:
^(?!.*:\/\/)([a-zA-Z0-9-]+\.)*[a-zA-Z0-9-]+\.[a-zA-Z]{2,}$
Example Request:
curl -X POST "https://api-alpha.markopolo.ai/v1/partners/marktag/verify" \
-H "Authorization: Bearer mp_live_YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"tagId": "4d00dcfa-fb3d-4495-88bc-9112aedb2046",
"subdomain": "mtag-h7k9.example.com"
}'Success Response (200 OK):
{
"verified": true
}Response Fields:
| Field | Type | Description |
|---|---|---|
verified | boolean | Whether the MarkTag installation was successfully verified |
Error Responses:
| HTTP Status | Error Code | Description |
|---|---|---|
| 400 | VALIDATION_ERROR | Invalid subdomain format or DNS configuration error |
| 401 | AUTHENTICATION_ERROR | Missing or invalid Bearer token |
| 403 | FORBIDDEN | Access denied - tag doesn't belong to partner |
| 404 | NOT_FOUND | Tag doesn't exist |
| 422 | VALIDATION_ERROR | DNS verification pending - allow time for DNS propagation |
| 500 | SERVICE_ERROR | Unable to process request |
Important DNS Verification States:
- 422 Status: DNS records have been added but haven't propagated yet. This is a temporary state - retry after waiting for DNS propagation (typically 5-30 minutes).
- 400 Status: DNS records are either missing or incorrectly configured. Check the CNAME record configuration.
- 200 Status: DNS is properly configured and verified.
Example 422 Response (DNS Pending):
{
"success": false,
"error": {
"code": "VALIDATION_ERROR",
"message": "DNS verification pending. Please allow time for DNS propagation and try again",
"statusCode": 422,
"timestamp": "2026-02-16T08:15:31.482Z",
"path": "/v1/partners/marktag/verify",
"method": "POST"
}
}For detailed error handling, see the Error Handling Guide.
Verification Process:
- The system extracts the root domain from the subdomain
- Verifies ownership of the merchant associated with the tag
- Calls external service to verify DNS configuration
- Returns different status codes based on DNS state:
- 200: DNS verified successfully - tag activated
- 422: DNS pending propagation - retry later
- 400: DNS misconfigured - check CNAME setup
- Updates tag status to 'waiting_for_events' upon successful verification
- Updates both
isConnectedandisVerifiedflags
Implementation Guide
Complete MarkTag Setup Flow by Type
Client-Side MarkTag (Simplest)
- Generate MarkTag - Create with
type: "client-side"(no domain needed) - Install Tracking Code - Add JavaScript to merchant's website using
mtag.markopolo.ai - Start Collecting Data - Immediately begins tracking events
Server-Side MarkTag (Custom Domain)
- Generate MarkTag - Create with
type: "server-side"and merchant's domain - Configure DNS - Merchant adds the provided CNAME record to their domain's DNS settings
- Wait for Propagation - DNS changes typically take 5-30 minutes to propagate
- Verify Installation - Use the verify endpoint to confirm DNS configuration
- Install Tracking Code - Add tracking code to merchant's website
- Start Collecting Data - Once verified, MarkTag begins tracking events
Preverified MarkTag (Partner Domain)
- Generate MarkTag - Create with
type: "preverified"(domain auto-derived) - Install Tracking Code - Add tracking code using your partner domain
- Start Collecting Data - Immediately begins tracking events
DNS Configuration Guide
Partner Domain Setup (One-time during onboarding)
During onboarding with partners@markopolo.ai, you'll receive a CNAME record to add to your domain. This enables all preverified marktags under your domain.
Custom Merchant Domain Setup
For merchants using their own domains, they'll need to add CNAME records after you generate their MarkTag:
Example DNS Record
Type: CNAME
Name: mtag
Value: mtag.markopolo.ai
TTL: 300Common DNS Providers
Cloudflare:
- Log in to Cloudflare dashboard
- Select your domain
- Go to DNS section
- Click "Add record"
- Select Type: CNAME
- Enter Name: mtag
- Enter Target: mtag.markopolo.ai
- Set TTL: Auto or 5 minutes
- Save
GoDaddy:
- Log in to GoDaddy account
- Go to Domain Settings
- Select DNS Management
- Add new CNAME record
- Host: mtag
- Points to: mtag.markopolo.ai
- TTL: 600 seconds
- Save
Route 53 (AWS):
- Open Route 53 console
- Select your hosted zone
- Create Record
- Record type: CNAME
- Record name: mtag
- Value: mtag.markopolo.ai
- TTL: 300
- Create records
DNS Propagation
- DNS changes typically propagate within 5-30 minutes
- Maximum propagation time can be up to 48 hours
- Use online DNS checkers to verify propagation status
- The verify endpoint will confirm when DNS is properly configured
Quick Reference: Choosing MarkTag Types
Decision Matrix
| Scenario | Recommended Type | Why |
|---|---|---|
| Need tracking right now | client-side | No DNS wait, instant activation |
| Testing the integration | client-side | Quick setup, no infrastructure |
| Enterprise with IT team | server-side | Full domain control, first-party |
| Many merchants on your platform | preverified | No merchant DNS, your domain |
| Non-technical merchants | client-side or preverified | No DNS knowledge required |
| Concerned about ad blockers | server-side or preverified | First-party domain tracking |
| White-label solution needed | preverified | Uses your branded domain |
| Progressive rollout | Start client-side, add others | Immediate tracking, enhance later |
Setup Complexity
| Type | Merchant Effort | Partner Effort | Time to Live |
|---|---|---|---|
| client-side | Quick merchant onboarding, testing, small merchants | Instant | None - just add JavaScript |
| server-side | Enterprise merchants, custom domains, full control | 5-30 min (DNS) | DNS access, domain ownership |
| preverified | Merchants on your platform, seamless integration | Instant | Uses your partner domain |
Best Practices
Domain Validation
Always validate domain format before making API calls:
- For generate endpoint: Use root domain only (e.g.,
example.com) - For verify endpoint: Use full subdomain (e.g.,
shop.example.com) - No protocol prefixes (http:// or https://)
- No www prefix for root domains
Error Handling
Implement specific error handling for different scenarios:
- 400 VALIDATION_ERROR: Invalid parameters or DNS misconfiguration
- 401 AUTHENTICATION_ERROR: Authentication issues
- 403 FORBIDDEN: Access denied to resource
- 404 NOT_FOUND: Merchant or tag not found
- 422 VALIDATION_ERROR: DNS pending propagation (retry after waiting)
- 500 SERVICE_ERROR: Server errors requiring retry
Handling DNS Verification States:
async function verifyMarkTag(tagId, subdomain) {
try {
const response = await fetch('/v1/partners/marktag/verify', {
method: 'POST',
headers: {
'Authorization': `Bearer ${token}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({ tagId, subdomain })
});
if (response.status === 200) {
console.log('✓ DNS verified successfully');
return { verified: true };
}
const error = await response.json();
if (response.status === 422) {
console.log('⏳ DNS propagation pending, retry in a few minutes');
// Implement retry logic with delay
return { verified: false, pending: true };
}
if (response.status === 400) {
console.error('❌ DNS configuration error - check CNAME records');
return { verified: false, pending: false };
}
throw error;
} catch (error) {
console.error('Verification failed:', error);
throw error;
}
}For comprehensive error handling examples and best practices, see the Error Handling Guide.
Next Steps
After verifying your MarkTag:
- MarkTag will begin collecting event data
- Retrieve events using the Events API
- Monitor tag status through the merchant endpoints