Skip to main content
Pro Plan10 minutesIntermediate

API Connection Errors

Troubleshoot API connection issues, authentication failures, and integration problems. Learn about api in this troubleshooting guide.

apierrorsauthenticationintegrationdebugging
Last updated:

Diagnose and resolve API connection errors, authentication failures, and integration issues.

The Zenovay REST API is available on paid plans (Pro and above). Free-plan keys are rejected with a 403 API_PAID_PLAN_REQUIRED response — upgrade to use API keys.

Authentication Errors

"Invalid API Key" (401)

Common causes:

  1. Wrong key format

    • API key must start with zv_ prefix
    • Keys without this prefix are invalid
    • Check you copied the full key from dashboard
  2. Key revoked

    • Go to Settings → Account → Security & access and open the Personal API keys section
    • Create a new key if the existing one was revoked
  3. Key only saved once

    • The full key is shown only at creation time — only the prefix is stored afterward
    • If you didn't copy it, create a new key

Fix:

// Wrong - invalid format
const key = 'abc123_not_valid...';

// Correct - Zenovay API key
const key = 'zv_xyz789abc...';

"API Key Not Found" (401)

Check header format:

# Wrong
curl -H "Api-Key: zv_..."

# Correct (External API)
curl -H "X-API-Key: zv_..."

"API requires a paid plan" (403)

The REST API is a paid feature. A key created on (or now tied to) a Free-tier team returns:

{
  "error": "The Zenovay API requires a paid plan. Upgrade to Pro or higher to use API keys.",
  "code": "API_PAID_PLAN_REQUIRED"
}

Fix: Upgrade the team to Pro or higher, then create the key under Settings → Account → Security & accessPersonal API keys.

"Access denied to this website" (403)

A personal API key is scoped two ways when you create it:

SettingOptions
PermissionsFull access, or only Read / Write / Admin
Team accessAll teams you belong to, or only selected teams

A key can only reach websites in the teams it's allowed to act on (and only while you're still a member of those teams). If a request returns 403 for a specific website, the team that owns it is likely outside the key's team access, or you no longer belong to that team. Review the key under Settings → Account → Security & accessPersonal API keys, or create a key with the access you need.

Connection Errors

"Connection Refused"

Check endpoint:

Correct: https://api.zenovay.com/api/external/v1/
Wrong:   http://api.zenovay.com/api/external/v1/  (no HTTPS)
Wrong:   https://zenovay.com/api/    (wrong domain)

"Connection Timeout"

Causes:

  • Network issues
  • Firewall blocking
  • DNS resolution failure

Debug steps:

  1. Test connectivity:

    curl -v https://api.zenovay.com/api/external/v1/usage
    
  2. Check DNS:

    nslookup api.zenovay.com
    
  3. Check firewall:

    • Allow outbound HTTPS (443)
    • Allow api.zenovay.com domain

"SSL Certificate Error"

Causes:

  • Outdated root certificates
  • Corporate proxy interference
  • Clock skew on server

Fix:

# Update certificates (Ubuntu)
sudo apt update && sudo apt install ca-certificates

# Check system time
date

# If using Node.js, don't disable verification:
// DON'T DO THIS IN PRODUCTION
// process.env.NODE_TLS_REJECT_UNAUTHORIZED = '0';

Rate Limit Errors

"Rate Limit Exceeded" (429)

Response headers:

X-RateLimit-Limit: 30
X-RateLimit-Remaining: 0
X-RateLimit-Reset: 2026-06-13T12:01:00.000Z
Retry-After: 42

The API also returns your monthly usage on every response:

X-Usage-Monthly: 4231
X-Usage-Limit: 10000

Implement backoff:

async function apiCallWithRetry(fn, maxRetries = 3) {
  for (let i = 0; i < maxRetries; i++) {
    try {
      return await fn();
    } catch (error) {
      if (error.status === 429) {
        const retryAfter = error.headers.get('Retry-After') || 60;
        await sleep(retryAfter * 1000);
        continue;
      }
      throw error;
    }
  }
}

REST API rate limits

The REST API is rate-limited per key, by plan tier — both a per-minute rate and a monthly request quota:

PlanPer minutePer month
Pro30 req/min10,000
Scale60 req/min100,000
Enterprise120 req/min1,000,000

Exceeding the per-minute rate returns 429 with Retry-After. Exceeding the monthly quota returns 429 and resets at the start of the next month (see the X-Usage-Monthly / X-Usage-Limit headers).

Tracking and public endpoint limits

The tracking ingest and other public endpoints are rate-limited per IP (not per plan), independent of REST API key limits:

ContextLimit
Tracking (burst)60 req/10 sec per IP
Tracking (sustained)5,000 req/hour per IP
Public endpoints30 req/min per IP
Auth endpoints30 req/min per IP

Request Errors

"Bad Request" (400)

Common issues:

  1. Invalid JSON:

    // Wrong - trailing comma
    { "name": "Test", }
    
    // Correct
    { "name": "Test" }
    
  2. Missing or malformed query parameters:

    # Wrong - invalid date range
    GET /api/external/v1/analytics/{websiteId}?from=yesterday
    
    # Correct - ISO dates
    GET /api/external/v1/analytics/{websiteId}?from=2026-06-01&to=2026-06-13
    
  3. Wrong data types in a request body:

    // Wrong - string instead of number
    { "page": "1" }
    
    // Correct
    { "page": 1 }
    

"Not Found" (404)

Check:

  • Endpoint URL is correct
  • Resource ID exists
  • Resource belongs to your account
# Verify endpoint (note the /api/external/v1 prefix and plural "websites")
GET /api/external/v1/websites/{websiteId}  # Correct
GET /api/external/v1/website/{websiteId}   # Wrong (singular)

"Unprocessable Entity" (422)

Validation failed. Check response body:

{
  "error": "validation_error",
  "details": {
    "url": "Invalid URL format",
    "name": "Name too long (max 100 characters)"
  }
}

SDK Errors

JavaScript SDK

"Zenovay not defined":

<!-- Ensure script loaded -->
<script src="https://api.zenovay.com/z.js"
        data-tracking-code="YOUR_TRACKING_CODE"></script>

<!-- Check after load -->
<script>
  window.addEventListener('load', () => {
    if (typeof zenovay !== 'undefined') {
      console.log('Zenovay loaded');
    }
  });
</script>

Server-Side API Calls

Connection issues with the tracking endpoint:

// Use fetch with the tracking endpoint - no npm package needed.
// The ingest endpoint validates the payload, so send the full event:
// session_id (min 8 chars), an absolute url, user_agent, and the
// device fields (device_type, browser, os) are all required.
const response = await fetch('https://api.zenovay.com/e/YOUR_TRACKING_CODE', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    event_type: 'pageview',
    url: 'https://example.com/home',
    session_id: 'srv-session-abcdef',
    user_agent: 'MyServer/1.0',
    device_type: 'desktop',
    browser: 'Server',
    os: 'Linux',
  }),
});

if (!response.ok) {
  console.error('Zenovay tracking error:', response.status);
}

Timeout errors:

// Use AbortController for timeout control
const controller = new AbortController();
const timeout = setTimeout(() => controller.abort(), 30000);

const response = await fetch('https://api.zenovay.com/e/YOUR_TRACKING_CODE', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    event_type: 'pageview',
    url: 'https://example.com/home',
    session_id: 'srv-session-abcdef',
    user_agent: 'MyServer/1.0',
    device_type: 'desktop',
    browser: 'Server',
    os: 'Linux',
  }),
  signal: controller.signal,
});

clearTimeout(timeout);

Debugging Tips

Enable Debug Mode

In server-side calls:

// Enable verbose logging for External API calls
const response = await fetch('https://api.zenovay.com/api/external/v1/websites', {
  headers: { 'X-API-Key': 'zv_...' },
});
console.log('Status:', response.status);
console.log('Response:', await response.json());

In tracking script:

<script data-tracking-code="YOUR_TRACKING_CODE"
        data-debug="true"
        src="..."></script>

Check API Status

  1. Visit status.zenovay.com
  2. Check API endpoint status
  3. Review incident history

Check key activity

In the dashboard:

  1. Go to Settings → Account → Security & access and find your Personal API keys
  2. Select a key to open its detail view
  3. Review its activity — accepted-event counts over the last 24 hours, 7 days, and all time, plus when the key was last used

Test with cURL

# Test API key with usage endpoint
curl -H "X-API-Key: zv_..." \
     https://api.zenovay.com/api/external/v1/usage

# List websites
curl -H "X-API-Key: zv_..." \
     https://api.zenovay.com/api/external/v1/websites

# With verbose output
curl -v -H "X-API-Key: zv_..." \
     https://api.zenovay.com/api/external/v1/websites

Common Error Codes

CodeMeaningSolution
400Bad requestCheck request body
401UnauthorizedCheck API key
403ForbiddenCheck permissions
404Not foundCheck endpoint/ID
422Validation failedCheck field values
429Rate limitedImplement backoff
500Server errorRetry, contact support
502Bad gatewayRetry in 1 minute
503UnavailableCheck status page

Contacting Support

When reporting API issues, include:

  1. Request details:

    • Endpoint URL
    • HTTP method
    • Request headers (redact API key)
    • Request body
  2. Response details:

    • Status code
    • Response body
    • Response headers
  3. Context:

    • Timestamp
    • Request ID (from headers)
    • SDK version if applicable

Email: [email protected]

Next Steps

Was this article helpful?