Jetrack

Jetrack

API Reference

API Keys

Generate and manage API keys for programmatic access to your analytics

API keys provide secure, programmatic access to your Jetrack analytics data. Use them to build integrations, automate reports, or sync data with your internal tools.

What Are API Keys?

An API key is a unique identifier that authenticates your requests to the Jetrack API. Unlike session-based authentication, API keys are designed for server-to-server communication and long-running integrations.

Use cases:

  • Building custom dashboards
  • Automating analytics reports
  • Integrating with internal tools (Slack, Discord, etc.)
  • Syncing data with data warehouses
  • Creating monitoring and alerting systems

API Key Format

Jetrack API keys follow a specific format for easy identification:

bj_live_a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6q7r8s9t0u1v2w3x4y5z6a7b8c9d0e1f2
  • Prefix: bj_live_ (8 characters)
  • Key body: 64 hexadecimal characters
  • Total length: 72 characters

The bj_live_ prefix makes it easy to identify Jetrack API keys in your codebase and helps prevent accidental exposure in logs.

Getting Your API Key

Step 1: Navigate to Settings

Log in to your Jetrack dashboard and click on your profile icon in the top navigation bar. Select API Keys from the dropdown menu to go to the Settings page.

Step 2: Generate Your Key

On the Settings page, you'll see the API key management interface. If you don't have an API key yet:

  1. Optionally enter a name for your key (e.g., "Production Server", "Analytics Dashboard")
  2. Click Generate API Key

Your API key will be displayed only once. Make sure to copy it immediately.

Step 3: Store It Securely

After copying your key, store it in a secure location:

  • Use environment variables (recommended)
  • Store in a secrets manager (AWS Secrets Manager, HashiCorp Vault, etc.)
  • Never commit API keys to version control

Using Your API Key

You can authenticate API requests using either of these methods:

Include your API key in the X-API-Key header:

curl -X GET "https://analytics.brandjet.ai/api/v1/account" \
  -H "X-API-Key: bj_live_your_api_key_here"

Method 2: Authorization Bearer Header

Alternatively, use the standard Authorization header with a Bearer token:

curl -X GET "https://analytics.brandjet.ai/api/v1/account" \
  -H "Authorization: Bearer bj_live_your_api_key_here"

Both methods are equally secure. Choose whichever fits your existing codebase better.

Code Examples

cURL

# Get account info
curl -X GET "https://analytics.brandjet.ai/api/v1/account" \
  -H "X-API-Key: bj_live_your_api_key_here"

# List all websites
curl -X GET "https://analytics.brandjet.ai/api/v1/websites" \
  -H "X-API-Key: bj_live_your_api_key_here"

# Get analytics for a website
curl -X GET "https://analytics.brandjet.ai/api/v1/websites/{id}/stats/main?from=2025-01-01&to=2025-01-31" \
  -H "X-API-Key: bj_live_your_api_key_here"

JavaScript / Node.js

Using the Fetch API:

const API_KEY = process.env.JETRACK_API_KEY;
const BASE_URL = 'https://analytics.brandjet.ai/api/v1';

async function getWebsites() {
  const response = await fetch(`${BASE_URL}/websites`, {
    headers: {
      'X-API-Key': API_KEY,
    },
  });

  if (!response.ok) {
    throw new Error(`API error: ${response.status}`);
  }

  return response.json();
}

async function getStats(websiteId, from, to) {
  const params = new URLSearchParams({ from, to });
  const response = await fetch(
    `${BASE_URL}/websites/${websiteId}/stats/main?${params}`,
    {
      headers: {
        'X-API-Key': API_KEY,
      },
    }
  );

  if (!response.ok) {
    throw new Error(`API error: ${response.status}`);
  }

  return response.json();
}

// Usage
const websites = await getWebsites();
console.log('My websites:', websites);

const stats = await getStats(websites[0].id, '2025-01-01', '2025-01-31');
console.log('Analytics:', stats);

Using Axios:

import axios from 'axios';

const api = axios.create({
  baseURL: 'https://analytics.brandjet.ai/api/v1',
  headers: {
    'X-API-Key': process.env.JETRACK_API_KEY,
  },
});

// Get account info
const { data: account } = await api.get('/account');

// List websites
const { data: websites } = await api.get('/websites');

// Get analytics
const { data: stats } = await api.get(`/websites/${websiteId}/stats/main`, {
  params: {
    from: '2025-01-01',
    to: '2025-01-31',
  },
});

Python

Using the requests library:

import os
import requests

API_KEY = os.environ.get('JETRACK_API_KEY')
BASE_URL = 'https://analytics.brandjet.ai/api/v1'

headers = {
    'X-API-Key': API_KEY
}

def get_account():
    """Get account information."""
    response = requests.get(f'{BASE_URL}/account', headers=headers)
    response.raise_for_status()
    return response.json()

def get_websites():
    """List all websites."""
    response = requests.get(f'{BASE_URL}/websites', headers=headers)
    response.raise_for_status()
    return response.json()

def get_stats(website_id, from_date, to_date):
    """Get analytics for a website."""
    params = {
        'from': from_date,
        'to': to_date
    }
    response = requests.get(
        f'{BASE_URL}/websites/{website_id}/stats/main',
        headers=headers,
        params=params
    )
    response.raise_for_status()
    return response.json()

# Usage
account = get_account()
print(f"Account: {account['data']['email']}")

websites = get_websites()
print(f"Found {len(websites['data'])} websites")

if websites['data']:
    website_id = websites['data'][0]['id']
    stats = get_stats(website_id, '2025-01-01', '2025-01-31')
    print(f"Visitors: {stats['data']['uniqueVisitors']}")

TypeScript

With type definitions:

interface ApiResponse<T> {
  success: boolean;
  data: T;
  meta: {
    status: number;
    message?: string;
    errors?: string[];
  };
}

interface Website {
  id: string;
  name: string;
  domain: string;
  createdAt: string;
}

interface MainAnalytics {
  uniqueVisitors: number;
  totalPageviews: number;
  avgSessionDuration: number;
  bounceRate: number;
}

const API_KEY = process.env.JETRACK_API_KEY!;
const BASE_URL = 'https://analytics.brandjet.ai/api/v1';

async function fetchApi<T>(endpoint: string, params?: Record<string, string>): Promise<T> {
  const url = new URL(`${BASE_URL}${endpoint}`);
  if (params) {
    Object.entries(params).forEach(([key, value]) => {
      url.searchParams.append(key, value);
    });
  }

  const response = await fetch(url.toString(), {
    headers: {
      'X-API-Key': API_KEY,
    },
  });

  if (!response.ok) {
    throw new Error(`API error: ${response.status}`);
  }

  const json: ApiResponse<T> = await response.json();
  return json.data;
}

// Usage
const websites = await fetchApi<Website[]>('/websites');
const stats = await fetchApi<MainAnalytics>(
  `/websites/${websites[0].id}/stats/main`,
  { from: '2025-01-01', to: '2025-01-31' }
);

Managing Your API Key

View Key Information

On the Settings page, you can see your API key's:

  • Key prefix - The first 12 characters (e.g., bj_live_a1b2)
  • Name - The label you assigned (if any)
  • Created date - When the key was generated
  • Last used - When the key was last used for authentication

The full key is never displayed after creation for security reasons.

Regenerate Key

If your API key is compromised or you need a new one:

  1. Go to Settings
  2. Click Regenerate Key
  3. Confirm the action

Important: Regenerating immediately invalidates your old key. Any integrations using the old key will stop working until you update them with the new key.

Revoke Key

To permanently delete your API key:

  1. Go to Settings
  2. Click Revoke API Key in the Danger Zone
  3. Confirm the action

This is irreversible. You'll need to generate a new key if you want to use the API again.

Security Best Practices

Store Keys in Environment Variables

Never hardcode API keys in your source code:

# .env file (never commit this!)
JETRACK_API_KEY=bj_live_your_api_key_here
// Access via environment variable
const apiKey = process.env.JETRACK_API_KEY;

Keep Keys Server-Side Only

API keys should only be used in server-side code. Never expose them in:

  • Browser JavaScript
  • Mobile app code
  • Client-side configuration files
  • Public repositories

Use Secrets Management

For production environments, consider using a secrets manager:

  • AWS Secrets Manager
  • HashiCorp Vault
  • Google Cloud Secret Manager
  • Azure Key Vault
  • Doppler

Rotate Keys Periodically

Even without a security incident, it's good practice to regenerate your API key periodically (e.g., every 90 days).

Monitor Usage

Check the "Last used" timestamp regularly to detect unauthorized usage. If you see unexpected activity, regenerate your key immediately.

Troubleshooting

401 Unauthorized

Possible causes:

  • Missing API key header
  • Invalid or revoked API key
  • Typo in the key

Solution:

  • Verify the header name is correct (X-API-Key or Authorization: Bearer)
  • Check that the full key is included (72 characters)
  • Ensure the key hasn't been regenerated or revoked
  • Try regenerating a new key

403 Forbidden

Possible causes:

  • Trying to access a resource you don't own
  • Website belongs to another account

Solution:

  • Verify you're using the correct website ID
  • Check that the resource belongs to your account

Rate Limiting (429)

Possible causes:

  • Too many requests in a short period

Solution:

  • Implement exponential backoff
  • Cache responses where appropriate
  • Batch requests when possible
async function fetchWithRetry(url, options, maxRetries = 3) {
  for (let i = 0; i < maxRetries; i++) {
    const response = await fetch(url, options);

    if (response.status === 429) {
      const delay = Math.pow(2, i) * 1000; // Exponential backoff
      await new Promise(resolve => setTimeout(resolve, delay));
      continue;
    }

    return response;
  }
  throw new Error('Max retries exceeded');
}

Next Steps

On this page