Third-Party API Issues | Blue Frog Docs

Third-Party API Issues

Diagnose and fix third-party API integration problems affecting analytics and marketing tools

Third-Party API Issues

Third-party API issues affect integrations with analytics platforms, marketing tools, and external services. These problems can break data collection and automation workflows.

What This Means

Third-party API issues occur when:

  • API versions are deprecated
  • Response formats change unexpectedly
  • Connection timeouts occur
  • Rate limits are exceeded
  • Service outages happen

Impact:

  • Missing analytics data
  • Failed marketing automation
  • Broken conversion tracking
  • Delayed reporting

How to Diagnose

Check API Status

Monitor vendor status pages:

Review API Responses

Log API responses:

async function apiRequest(url, options) {
  const startTime = Date.now();

  try {
    const response = await fetch(url, options);
    const data = await response.json();

    console.log({
      url,
      status: response.status,
      duration: Date.now() - startTime,
      success: response.ok,
      responseSize: JSON.stringify(data).length
    });

    return data;
  } catch (error) {
    console.error({
      url,
      error: error.message,
      duration: Date.now() - startTime
    });
    throw error;
  }
}

Check API Version

Verify you're using the correct API version:

# Check API version in response headers
curl -I https://api.example.com/v1/endpoint | grep -i version

General Fixes

1. Handle API Version Changes

Version-aware requests:

const API_VERSION = 'v4';

async function makeApiCall(endpoint, params) {
  const url = `https://api.example.com/${API_VERSION}/${endpoint}`;

  try {
    return await fetch(url, params);
  } catch (error) {
    // Fallback to previous version if available
    if (error.message.includes('deprecated')) {
      const fallbackUrl = url.replace(API_VERSION, 'v3');
      return await fetch(fallbackUrl, params);
    }
    throw error;
  }
}

2. Implement Robust Error Handling

Handle different error types:

async function handleApiResponse(response) {
  if (response.ok) {
    return response.json();
  }

  switch (response.status) {
    case 400:
      throw new Error('Bad Request: Check parameters');
    case 401:
      throw new Error('Unauthorized: Check credentials');
    case 403:
      throw new Error('Forbidden: Check permissions');
    case 404:
      throw new Error('Not Found: Check endpoint URL');
    case 429:
      const retryAfter = response.headers.get('Retry-After') || 60;
      throw new RateLimitError(retryAfter);
    case 500:
    case 502:
    case 503:
    case 504:
      throw new ServerError('Service unavailable, retry later');
    default:
      throw new Error(`API Error: ${response.status}`);
  }
}

3. Handle Timeouts

Set appropriate timeouts:

async function fetchWithTimeout(url, options, timeout = 10000) {
  const controller = new AbortController();
  const timeoutId = setTimeout(() => controller.abort(), timeout);

  try {
    const response = await fetch(url, {
      ...options,
      signal: controller.signal
    });
    clearTimeout(timeoutId);
    return response;
  } catch (error) {
    clearTimeout(timeoutId);

    if (error.name === 'AbortError') {
      throw new Error(`Request timeout after ${timeout}ms`);
    }
    throw error;
  }
}

4. Implement Circuit Breaker

Prevent cascade failures:

class CircuitBreaker {
  constructor(threshold = 5, resetTimeout = 30000) {
    this.failures = 0;
    this.threshold = threshold;
    this.resetTimeout = resetTimeout;
    this.state = 'CLOSED';
    this.nextAttempt = Date.now();
  }

  async execute(fn) {
    if (this.state === 'OPEN') {
      if (Date.now() > this.nextAttempt) {
        this.state = 'HALF-OPEN';
      } else {
        throw new Error('Circuit breaker is OPEN');
      }
    }

    try {
      const result = await fn();
      this.onSuccess();
      return result;
    } catch (error) {
      this.onFailure();
      throw error;
    }
  }

  onSuccess() {
    this.failures = 0;
    this.state = 'CLOSED';
  }

  onFailure() {
    this.failures++;
    if (this.failures >= this.threshold) {
      this.state = 'OPEN';
      this.nextAttempt = Date.now() + this.resetTimeout;
    }
  }
}

const apiCircuitBreaker = new CircuitBreaker();

async function safeApiCall(fn) {
  return apiCircuitBreaker.execute(fn);
}

5. Handle Response Format Changes

Validate response structure:

function validateApiResponse(data, expectedSchema) {
  const requiredFields = Object.keys(expectedSchema);

  for (const field of requiredFields) {
    if (!(field in data)) {
      console.warn(`Missing field in API response: ${field}`);
      data[field] = expectedSchema[field]; // Use default
    }
  }

  return data;
}

// Usage
const expectedSchema = {
  id: null,
  name: '',
  value: 0
};

const data = validateApiResponse(apiResponse, expectedSchema);

6. Implement Caching

Cache API responses:

const cache = new Map();
const CACHE_TTL = 5 * 60 * 1000; // 5 minutes

async function cachedApiCall(key, fetchFn) {
  const cached = cache.get(key);

  if (cached && Date.now() < cached.expiry) {
    return cached.data;
  }

  const data = await fetchFn();

  cache.set(key, {
    data,
    expiry: Date.now() + CACHE_TTL
  });

  return data;
}

Platform-Specific Fixes

Google Analytics 4 API

Handle quota limits:

// GA4 Data API has daily quotas
async function ga4DataRequest(property, request) {
  try {
    return await analyticsData.properties.runReport({
      property: `properties/${property}`,
      requestBody: request
    });
  } catch (error) {
    if (error.code === 429) {
      // Quota exceeded, try smaller date range
      console.log('Quota exceeded, reducing date range');
      request.dateRanges = [{ startDate: '7daysAgo', endDate: 'today' }];
      return await analyticsData.properties.runReport({
        property: `properties/${property}`,
        requestBody: request
      });
    }
    throw error;
  }
}

Meta Marketing API

Handle API version deprecation:

const META_API_VERSION = 'v18.0';

async function metaApiCall(endpoint, params) {
  const response = await fetch(
    `https://graph.facebook.com/${META_API_VERSION}/${endpoint}`,
    params
  );

  const data = await response.json();

  // Check for deprecation warnings
  if (data.__fb_trace_id__) {
    console.log('Meta API request traced:', data.__fb_trace_id__);
  }

  return data;
}

Shopify API

Handle version updates:

const SHOPIFY_API_VERSION = '2024-01';

async function shopifyApiCall(shop, endpoint) {
  const response = await fetch(
    `https://${shop}.myshopify.com/admin/api/${SHOPIFY_API_VERSION}/${endpoint}`,
    {
      headers: {
        'X-Shopify-Access-Token': process.env.SHOPIFY_TOKEN,
        'Content-Type': 'application/json'
      }
    }
  );

  // Check for deprecation header
  const deprecation = response.headers.get('X-Shopify-API-Deprecated-Reason');
  if (deprecation) {
    console.warn('Shopify API deprecation:', deprecation);
  }

  return response.json();
}

Monitoring Third-Party APIs

Track API Health

const apiHealthMetrics = {
  requests: 0,
  errors: 0,
  avgLatency: 0,
  lastSuccess: null,
  lastError: null
};

function trackApiMetrics(success, latency, error = null) {
  apiHealthMetrics.requests++;
  apiHealthMetrics.avgLatency =
    (apiHealthMetrics.avgLatency * (apiHealthMetrics.requests - 1) + latency) /
    apiHealthMetrics.requests;

  if (success) {
    apiHealthMetrics.lastSuccess = new Date();
  } else {
    apiHealthMetrics.errors++;
    apiHealthMetrics.lastError = { date: new Date(), message: error };
  }
}

Set Up Alerts

Alert on:

  • Error rate > 10%
  • Latency > 5 seconds
  • Consecutive failures > 3
  • API deprecation warnings

Verification

After fixing issues:

  1. Test all API endpoints used by your application
  2. Verify data flows correctly to destination
  3. Check error logs for new issues
  4. Monitor metrics for 24 hours

Checklist

  • API version is current and supported
  • Error handling covers all status codes
  • Timeouts are configured appropriately
  • Circuit breaker prevents cascade failures
  • Response validation handles format changes
  • Caching reduces API load
  • Monitoring tracks API health
  • Alerts configured for failures
// SYS.FOOTER