Skip to content

Error Handling

The Partners API uses a standardized error handling approach to provide consistent, secure error responses without exposing internal system details.

Error Response Format

All API errors follow a consistent JSON structure:

json
{
  "message": "Human-readable error message",
  "code": "ERROR_CODE",
  "statusCode": 400
}

Response Fields

FieldTypeDescription
messagestringHuman-readable error description
codestringStandardized error code for programmatic handling
statusCodeintegerHTTP status code

Standard Error Codes

The API uses these standardized error codes across all endpoints:

CodeMessageHTTP StatusDescription
VALIDATION_ERROR"Invalid request parameters"400Invalid input data or failed validation
AUTHENTICATION_ERROR"Authentication required"401Missing or invalid Bearer token
FORBIDDEN"Access denied"403Attempting to access resources not owned by partner
NOT_FOUND"Resource not found"404Merchant, tag, or resource doesn't exist
VALIDATION_ERROR"DNS verification pending..."422DNS records not yet propagated (verification endpoint)
SERVICE_ERROR"Unable to process request"500Database errors or internal failures

Authentication Errors

Authentication failures always return a consistent response to prevent information leakage:

json
{
  "message": "Authentication required",
  "code": "AUTHENTICATION_ERROR",
  "statusCode": 401
}

Common Authentication Issues

  • Missing Authorization header
  • Invalid Bearer token format (must be Bearer mp_live_...)
  • Revoked or expired token
  • Malformed token structure

Validation Errors

The API validates all request parameters using strict DTOs. Validation failures return:

json
{
  "message": "Invalid request parameters",
  "code": "VALIDATION_ERROR",
  "statusCode": 400
}

Common Validation Issues

  • Missing required fields
  • Invalid UUID format for IDs
  • Invalid domain format (e.g., including protocol or www prefix)
  • Out-of-range pagination values (page < 1 or limit > 100)
  • Invalid data types

Resource Access Errors

Resource Not Found

When a requested resource doesn't exist:

json
{
  "message": "Resource not found",
  "code": "NOT_FOUND",
  "statusCode": 404
}

Access Denied

When attempting to access another partner's resources:

json
{
  "message": "Access denied",
  "code": "FORBIDDEN",
  "statusCode": 403
}

Special Error Cases

Some operations have specific error scenarios:

Domain Already Registered

When attempting to register a domain that's already in use:

json
{
  "message": "Domain already registered",
  "code": "VALIDATION_ERROR",
  "statusCode": 409
}

DNS Verification Pending

When DNS records haven't propagated yet during verification:

json
{
  "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"
  }
}

DNS Verification Failed

When DNS record exists but points to an incorrect domain:

json
{
  "message": "Tag verification failed. Please check your DNS configuration",
  "code": "VALIDATION_ERROR",
  "statusCode": 400
}

Internal Server Errors

All database errors, external service failures, and unexpected errors return a generic response to prevent information leakage:

json
{
  "message": "Unable to process request",
  "code": "SERVICE_ERROR",
  "statusCode": 500
}

This includes:

  • Database connection errors
  • External service timeouts
  • Unexpected application errors
  • Configuration issues

Error Handling Best Practices

1. Use Error Codes for Logic

Always check the code field rather than parsing error messages:

javascript
// Good ✅
if (error.code === "AUTHENTICATION_ERROR") {
  await refreshToken();
}

// Bad ❌
if (error.message.includes("Authentication")) {
  await refreshToken();
}

2. Implement Retry Logic

For transient failures, implement exponential backoff:

javascript
async function apiCallWithRetry(url, options, maxRetries = 3) {
  for (let i = 0; i < maxRetries; i++) {
    try {
      const response = await fetch(url, options);

      if (response.ok) return response;

      const error = await response.json();

      // Only retry on server errors
      if (error.code === "SERVICE_ERROR" && i < maxRetries - 1) {
        await new Promise((resolve) =>
          setTimeout(resolve, Math.pow(2, i) * 1000),
        );
        continue;
      }

      throw error;
    } catch (error) {
      if (i === maxRetries - 1) throw error;
    }
  }
}

Common Error Scenarios

Creating a Merchant

ScenarioError CodeResolution
Missing merchant nameVALIDATION_ERRORProvide a valid merchant name
Database issueSERVICE_ERRORRetry the request

Generating MarkTag

ScenarioError CodeResolution
Invalid domain formatVALIDATION_ERRORUse format: example.com (no protocol/www)
Merchant doesn't existNOT_FOUNDCreate merchant first
Domain already registeredVALIDATION_ERRORDomain is already in use by another partner
Partner domain mismatchVALIDATION_ERRORUse your assigned partner domain for preverified tags

Verifying MarkTag

ScenarioError CodeHTTP StatusResolution
Tag doesn't existNOT_FOUND404Check tag ID is correct
DNS not propagatedVALIDATION_ERROR422Wait for DNS propagation (5-30 minutes typical)
DNS misconfiguredVALIDATION_ERROR400Check CNAME record configuration
Not your tagFORBIDDEN403Can only verify tags you created
Server errorSERVICE_ERROR500Retry with exponential backoff

Retrieving Events

ScenarioError CodeResolution
Invalid date rangeVALIDATION_ERRORUse valid ISO 8601 date format
Page out of rangeVALIDATION_ERRORUse page number within valid range
Merchant not foundNOT_FOUNDCheck merchant ID exists

Troubleshooting Common Issues

MarkTag Not Tracking

Client-Side MarkTag

  • Verify tagId is correct: Check the tagId matches what was returned from the API
  • Check browser console: Look for JavaScript errors or blocked requests
  • Ensure script placement: Script should be in the <head> section of the page
  • Check for ad blockers: Some ad blockers may block tracking scripts

Server-Side MarkTag

  • DNS verification fails: Confirm CNAME record is added correctly to merchant's DNS
  • DNS propagation delay: Wait for full DNS propagation (typically 5-30 minutes, up to 48 hours in rare cases)
  • Verify DNS setup: Use nslookup mtag.domain.com to check DNS configuration
  • 422 error during verification: This is normal - DNS is still propagating, wait and retry

Preverified MarkTag

  • Verify partner domain: Ensure your partner domain CNAME is properly configured
  • Check domain usage: Confirm you're using the correct partner domain in tracking code
  • Match tagId: Ensure tagId in tracking code matches the generated value

Event Collection Issues

  • No events appearing: Verify the tracking script is loaded (check typeof mtag === 'function' in console)
  • Delayed events: Events may take a few seconds to appear in the API
  • Missing events: Check that events are being fired on the correct pages/actions

Support

If you encounter persistent errors or need assistance:

  • Check your API token is valid and not expired
  • Verify your request format matches the documentation
  • Ensure DNS records are properly configured for domain verification
  • Contact partners@markopolo.ai for technical support