apollo-debug-bundle

Collect Apollo.io debug evidence for support. Use when preparing support tickets, documenting issues, or gathering diagnostic information for Apollo problems. Trigger with phrases like "apollo debug", "apollo support bundle", "collect apollo diagnostics", "apollo troubleshooting info".

claude-codecodexopenclaw
3 Tools
apollo-pack Plugin
saas packs Category

Allowed Tools

ReadGrepBash(curl:*)

Provided by Plugin

apollo-pack

Claude Code skill pack for Apollo.io sales intelligence platform (24 skills)

saas packs v1.0.0
View Plugin

Installation

This skill is included in the apollo-pack plugin:

/plugin install apollo-pack@claude-code-plugins-plus

Click to copy

Instructions

Apollo Debug Bundle

Current State

!node --version 2>/dev/null || echo 'N/A'

!python3 --version 2>/dev/null || echo 'N/A'

!uname -a

Overview

Collect comprehensive debug information for Apollo.io API issues. Generates a JSON diagnostic bundle with environment info, connectivity tests, rate limit status, key type verification, and sanitized request/response logs.

Prerequisites

  • APOLLOAPIKEY environment variable set
  • Node.js 18+ or Python 3.10+

Instructions

Step 1: Create the Debug Bundle Collector


// src/scripts/debug-bundle.ts
import axios from 'axios';
import os from 'os';

const BASE_URL = 'https://api.apollo.io/api/v1';

interface DebugBundle {
  timestamp: string;
  environment: Record<string, string>;
  connectivity: { reachable: boolean; latencyMs: number; statusCode?: number };
  keyType: 'master' | 'standard' | 'invalid' | 'unknown';
  rateLimits: { limit?: string; remaining?: string; window?: string };
  endpointTests: Array<{ endpoint: string; status: number | string; ok: boolean }>;
  systemInfo: Record<string, string>;
}

async function collectDebugBundle(): Promise<DebugBundle> {
  const headers = {
    'Content-Type': 'application/json',
    'x-api-key': process.env.APOLLO_API_KEY ?? '',
  };

  const bundle: DebugBundle = {
    timestamp: new Date().toISOString(),
    environment: {
      nodeVersion: process.version,
      platform: os.platform(),
      arch: os.arch(),
      apiKeySet: process.env.APOLLO_API_KEY ? 'yes (redacted)' : 'NOT SET',
      apiKeyLength: String(process.env.APOLLO_API_KEY?.length ?? 0),
      apiKeyPrefix: process.env.APOLLO_API_KEY?.slice(0, 4) + '...' ?? 'N/A',
    },
    connectivity: { reachable: false, latencyMs: 0 },
    keyType: 'unknown',
    rateLimits: {},
    endpointTests: [],
    systemInfo: {},
  };

  return bundle;
}

Step 2: Test Connectivity and Key Type


async function testConnectivity(bundle: DebugBundle) {
  const headers = { 'Content-Type': 'application/json', 'x-api-key': process.env.APOLLO_API_KEY! };

  // Test basic auth
  const start = Date.now();
  try {
    const resp = await axios.get(`${BASE_URL}/auth/health`, { headers, timeout: 10_000 });
    bundle.connectivity = { reachable: true, latencyMs: Date.now() - start, statusCode: resp.status };
    bundle.keyType = resp.data.is_logged_in ? 'standard' : 'invalid';  // at minimum standard
  } catch (err: any) {
    bundle.connectivity = { reachable: false, latencyMs: Date.now() - start, statusCode: err.response?.status };
    return;
  }

  // Test master key access
  try {
    await axios.post(`${BASE_URL}/contacts/search`, { per_page: 1 }, { headers, timeout: 10_000 });
    bundle.keyType = 'master';
  } catch (err: any) {
    if (err.response?.status === 403) bundle.keyType = 'standard';
  }
}

Step 3: Test Key Endpoints


async function testEndpoints(bundle: DebugBundle) {
  const headers = { 'Content-Type': 'application/json', 'x-api-key': process.env.APOLLO_API_KEY! };

  const tests = [
    { name: 'Auth Health', method: 'GET', url: `${BASE_URL}/auth/health` },
    { name: 'People Search', method: 'POST', url: `${BASE_URL}/mixed_people/api_search`,
      body: { per_page: 1, q_organization_domains_list: ['apollo.io'] } },
    { name: 'Org Enrichment', method: 'GET', url: `${BASE_URL}/organizations/enrich?domain=apollo.io` },
    { name: 'Contacts Search', method: 'POST', url: `${BASE_URL}/contacts/search`, body: { per_page: 1 } },
    { name: 'Sequences Search', method: 'POST', url: `${BASE_URL}/emailer_campaigns/search`, body: { per_page: 1 } },
    { name: 'Email Accounts', method: 'GET', url: `${BASE_URL}/email_accounts` },
  ];

  for (const test of tests) {
    try {
      const resp = await axios({ method: test.method as any, url: test.url, data: test.body, headers, timeout: 10_000 });
      bundle.endpointTests.push({ endpoint: test.name, status: resp.status, ok: true });

      // Capture rate limit headers from any successful response
      if (resp.headers['x-rate-limit-limit']) {
        bundle.rateLimits = {
          limit: resp.headers['x-rate-limit-limit'],
          remaining: resp.headers['x-rate-limit-remaining'],
          window: resp.headers['x-rate-limit-window'],
        };
      }
    } catch (err: any) {
      bundle.endpointTests.push({
        endpoint: test.name,
        status: err.response?.status ?? err.code ?? err.message,
        ok: false,
      });
    }
  }
}

Step 4: Generate and Output


async function main() {
  console.log('Collecting Apollo debug bundle...\n');
  const bundle = await collectDebugBundle();
  await testConnectivity(bundle);
  await testEndpoints(bundle);

  // System info
  bundle.systemInfo = {
    hostname: os.hostname(),
    platform: `${os.platform()} ${os.release()}`,
    memory: `${Math.round(os.freemem() / 1024 / 1024)}MB free / ${Math.round(os.totalmem() / 1024 / 1024)}MB total`,
  };

  // Write to file
  const fs = await import('fs');
  const filename = `apollo-debug-${Date.now()}.json`;
  fs.writeFileSync(filename, JSON.stringify(bundle, null, 2));

  // Print summary
  console.log('=== Apollo Debug Summary ===');
  console.log(`API Key:     ${bundle.environment.apiKeySet} (${bundle.environment.apiKeyLength} chars)`);
  console.log(`Key Type:    ${bundle.keyType}`);
  console.log(`Reachable:   ${bundle.connectivity.reachable} (${bundle.connectivity.latencyMs}ms)`);
  console.log(`Rate Limit:  ${bundle.rateLimits.remaining ?? '?'}/${bundle.rateLimits.limit ?? '?'} remaining`);
  console.log(`Endpoints:`);
  for (const t of bundle.endpointTests) {
    console.log(`  ${t.ok ? 'OK' : 'FAIL'}  ${t.endpoint}: ${t.status}`);
  }
  console.log(`\nBundle saved: ${filename}`);
}

main().catch(console.error);

Output

  • JSON debug bundle with environment, connectivity, key type, rate limits, and endpoint results
  • Key type detection (master vs standard vs invalid)
  • Endpoint-by-endpoint health check (auth, search, enrichment, contacts, sequences)
  • Rate limit header capture
  • Ready-to-attach file for Apollo support tickets

Error Handling

Issue Debug Step
Connection timeout Check network/firewall, verify DNS for api.apollo.io
Key type = invalid Key was revoked — regenerate in Apollo dashboard
Key type = standard Master key needed — check which endpoints fail with 403
All endpoints fail Check status.apollo.io for outages

Examples

Quick CLI Diagnostic


# One-liner: test auth + connectivity
curl -s -w "\nHTTP %{http_code} in %{time_total}s\n" \
  -H "x-api-key: $APOLLO_API_KEY" \
  "https://api.apollo.io/api/v1/auth/health"

# Test rate limit headers
curl -s -D - -o /dev/null \
  -H "Content-Type: application/json" -H "x-api-key: $APOLLO_API_KEY" \
  -X POST -d '{"per_page":1,"q_organization_domains_list":["apollo.io"]}' \
  "https://api.apollo.io/api/v1/mixed_people/api_search" 2>/dev/null | grep -i "x-rate"

Resources

Next Steps

Proceed to apollo-rate-limits for rate limiting implementation.

Ready to use apollo-pack?