Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/vemetric/vemetric/llms.txt

Use this file to discover all available pages before exploring further.

Error Response Format

All API errors follow a consistent JSON structure:
{
  "error": {
    "code": "ERROR_CODE",
    "message": "Human-readable error message",
    "details": [
      // Optional: additional error details for validation errors
    ]
  }
}

HTTP Status Codes

The Vemetric API uses standard HTTP status codes:
Status CodeDescription
200Success
400Bad Request - Invalid request payload or parameters
401Unauthorized - Invalid or missing API key
403Forbidden - Plan limits exceeded or insufficient permissions
404Not Found - Route or resource not found
429Too Many Requests - Rate limit exceeded
500Internal Server Error - Unexpected server error

Error Codes

Authentication Errors (401)

UNAUTHORIZED

The request is not properly authenticated. Common causes:
  • Missing Authorization header
  • Malformed Authorization header (not using Bearer scheme)
  • Invalid API key format
  • Invalid or revoked API key
Example responses:
{
  "error": {
    "code": "UNAUTHORIZED",
    "message": "Missing API key. Use Authorization: Bearer <key>"
  }
}
How to fix:
  1. Ensure you’re including the Authorization header
  2. Use the Bearer scheme: Authorization: Bearer vem_your_api_key
  3. Verify your API key is correct and hasn’t been revoked
  4. Check that your API key starts with vem_ and is 36 characters long

Validation Errors (400)

VALIDATION_ERROR

The request payload contains invalid parameters. Example response:
{
  "error": {
    "code": "VALIDATION_ERROR",
    "message": "Invalid request parameters",
    "details": [
      {
        "field": "date_range.0",
        "message": "Start date must be before or equal to end date"
      },
      {
        "field": "metrics.0",
        "message": "Invalid enum value. Expected 'users' | 'pageviews' | 'events' | 'bounce_rate' | 'visit_duration', received 'invalid_metric'"
      }
    ]
  }
}
Common validation errors:
{
  "field": "date_range.0",
  "message": "Start date must be before or equal to end date"
}
Fix: Ensure the start date comes before the end date.
{
  "field": "group_by",
  "message": "group_by can include max one item in v1"
}
Fix: The current API version only supports grouping by one field. Remove extra items from the group_by array.
{
  "field": "order_by.0.0",
  "message": "Sort metric must be included in metrics"
}
Fix: If you’re sorting by a metric, ensure it’s included in the metrics array.
{
  "field": "limit",
  "message": "Number must be less than or equal to 1000"
}
Fix: The maximum limit is 1000. Reduce the limit value.
{
  "field": "filters.0.type",
  "message": "Required"
}
Fix: All filters must have a type field. See the Analytics documentation for valid filter types.
How to fix:
  1. Review the details array to identify which fields have validation errors
  2. Check the field path (e.g., "date_range.0" refers to the first element of the date_range array)
  3. Fix the invalid values according to the error messages
  4. Consult the Analytics API documentation for valid parameter formats

Rate Limiting Errors (429)

RATE_LIMIT_EXCEEDED

You’ve exceeded the rate limit for your project. Example response:
{
  "error": {
    "code": "RATE_LIMIT_EXCEEDED",
    "message": "Rate limit exceeded. Try again shortly."
  }
}
Rate limit details:
  • Limit: 100 requests per 60 seconds
  • Window: Sliding 60-second window
  • Scope: Per project (based on API key)
Response headers:
X-RateLimit-Limit: 100
X-RateLimit-Remaining: 0
X-RateLimit-Reset: 1709582460
How to fix:
  1. Implement exponential backoff in your retry logic
  2. Check the X-RateLimit-Reset header to know when to retry
  3. Reduce request frequency
  4. Consider caching responses
  5. Batch multiple queries if possible
Example retry logic:
async function queryWithRetry(url, options, maxRetries = 3) {
  for (let i = 0; i < maxRetries; i++) {
    const response = await fetch(url, options);
    
    if (response.status === 429) {
      const resetTime = response.headers.get('X-RateLimit-Reset');
      const waitTime = (parseInt(resetTime) * 1000) - Date.now();
      
      console.log(`Rate limited. Waiting ${waitTime}ms...`);
      await new Promise(resolve => setTimeout(resolve, waitTime));
      continue;
    }
    
    return response;
  }
  
  throw new Error('Max retries exceeded');
}

Plan Limit Errors (403)

PLAN_LIMIT_EXCEEDED

The requested operation exceeds your plan’s limits. Common causes:
  • Requesting data beyond your plan’s retention period
  • Attempting to access premium features not available on your plan
Example responses:
{
  "error": {
    "code": "PLAN_LIMIT_EXCEEDED",
    "message": "Your current plan limits data retention to 90 days. Please upgrade to access historical data beyond this period."
  }
}
How to fix:
  1. Reduce the date range to fit within your plan’s retention period
  2. Upgrade your plan to access more historical data
  3. Contact support if you need custom retention periods

Not Found Errors (404)

NOT_FOUND

The requested route does not exist. Example response:
{
  "error": {
    "code": "NOT_FOUND",
    "message": "Route not found. See https://vemetric.com/docs/api"
  }
}
How to fix:
  1. Check the request URL for typos
  2. Ensure you’re using the correct API version (/v1/)
  3. Review the API documentation for valid endpoints

Server Errors (500)

INTERNAL_SERVER_ERROR

An unexpected error occurred on the server. Example response:
{
  "error": {
    "code": "INTERNAL_SERVER_ERROR",
    "message": "An unexpected error occurred"
  }
}
How to fix:
  1. Retry the request (the error may be temporary)
  2. If the error persists, check the Vemetric status page
  3. Contact support if the issue continues

INTERNAL_ERROR

Similar to INTERNAL_SERVER_ERROR, used in some error handling contexts. Example response:
{
  "error": {
    "code": "INTERNAL_ERROR",
    "message": "An unexpected error occurred"
  }
}

Error Handling Best Practices

Always check status codes - Don’t assume requests succeeded. Check response.ok or the status code
Parse error responses - Extract the error.code and error.message for logging and debugging
Implement retry logic - Handle transient errors (500, 429) with exponential backoff
Log error details - For validation errors, log the details array to identify problematic fields
Don’t retry validation errors - 400 and 401 errors won’t be fixed by retrying. Fix the request instead
Don’t ignore rate limits - Respect the X-RateLimit-* headers to avoid being blocked

Example Error Handling

JavaScript/TypeScript

async function queryAnalytics(payload) {
  const response = await fetch('https://api.vemetric.com/v1/analytics/query', {
    method: 'POST',
    headers: {
      'Authorization': `Bearer ${API_KEY}`,
      'Content-Type': 'application/json'
    },
    body: JSON.stringify(payload)
  });
  
  if (!response.ok) {
    const error = await response.json();
    
    switch (error.error.code) {
      case 'UNAUTHORIZED':
        throw new Error('Invalid API key. Please check your credentials.');
      
      case 'VALIDATION_ERROR':
        console.error('Validation errors:', error.error.details);
        throw new Error('Invalid request parameters. See console for details.');
      
      case 'RATE_LIMIT_EXCEEDED':
        const resetTime = response.headers.get('X-RateLimit-Reset');
        throw new Error(`Rate limited. Retry after ${new Date(resetTime * 1000)}`);
      
      case 'PLAN_LIMIT_EXCEEDED':
        throw new Error('Plan limit exceeded. Please upgrade your plan.');
      
      default:
        throw new Error(`API error: ${error.error.message}`);
    }
  }
  
  return response.json();
}

Python

import requests
import time

def query_analytics(payload, api_key):
    response = requests.post(
        'https://api.vemetric.com/v1/analytics/query',
        headers={
            'Authorization': f'Bearer {api_key}',
            'Content-Type': 'application/json'
        },
        json=payload
    )
    
    if not response.ok:
        error = response.json()['error']
        
        if error['code'] == 'UNAUTHORIZED':
            raise Exception('Invalid API key')
        
        elif error['code'] == 'VALIDATION_ERROR':
            print('Validation errors:', error.get('details', []))
            raise Exception('Invalid request parameters')
        
        elif error['code'] == 'RATE_LIMIT_EXCEEDED':
            reset_time = int(response.headers.get('X-RateLimit-Reset', 0))
            wait_seconds = reset_time - int(time.time())
            raise Exception(f'Rate limited. Wait {wait_seconds}s')
        
        elif error['code'] == 'PLAN_LIMIT_EXCEEDED':
            raise Exception('Plan limit exceeded')
        
        else:
            raise Exception(f"API error: {error['message']}")
    
    return response.json()

Getting Help

If you encounter an error you don’t understand:
  1. Check this error reference
  2. Review the API documentation
  3. Search GitHub issues
  4. Contact support at support@vemetric.com

API Overview

Learn about the Vemetric API basics

Authentication

Troubleshoot authentication issues