Skip to content
Back to skills

Apollo Common Errors

BSecurity

'Diagnose and fix common Apollo.io API errors.

  • 2,719 stars
  • 0 votes
  • 0 copies
  • 2 views
  • Added September 21, 2026
ai-agentstypescriptpythongobashnodedebuggingapi

Works with

  • claude code
  • cli
  • api

Security analysis

B88/100
  • criticalDownloads and executes remote scripts — classic supply chain attack

Pro scans all 3 files and shows the line behind each finding

Scanned September 21, 2026

npx -y skills add jeremylongshore/claude-code-plugins-plus --skill apollo-common-errors --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Apollo Common Errors?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Apollo Common Errors
[![Security: B — Skills Directory](https://www.skillsdirectory.com/api/skills/jeremylongshore-apollo-common-errors-82baa831/badge)](https://www.skillsdirectory.com/skills/jeremylongshore-apollo-common-errors-82baa831)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: apollo-common-errors
description: 'Diagnose and fix common Apollo.io API errors.

  Use when encountering Apollo API errors, debugging integration issues,

  or troubleshooting failed requests.

  Trigger with phrases like "apollo error", "apollo api error",

  "debug apollo", "apollo 401", "apollo 429", "apollo troubleshoot".

  '
allowed-tools: Read, Grep, Bash(curl:*)
version: 1.13.0
license: MIT
author: Jeremy Longshore <jeremy@intentsolutions.io>
tags:
- saas
- apollo
- api
- debugging
compatibility: Designed for Claude Code
---
# Apollo Common Errors

## Overview

Comprehensive guide to diagnosing and fixing Apollo.io API errors. Apollo uses `x-api-key` header authentication and the base URL `https://api.apollo.io/api/v1/`. Apollo distinguishes between **master** and **standard** API keys — many endpoints require master keys.

## Prerequisites

- Valid Apollo.io API credentials
- Node.js 18+ or Python 3.10+

## Instructions

### Step 1: Identify the Error Category

```typescript
// src/apollo/error-handler.ts
import { AxiosError } from 'axios';

type ErrorCategory = 'auth' | 'permission' | 'rate_limit' | 'validation' | 'server' | 'network';

function categorizeError(err: AxiosError): ErrorCategory {
  if (!err.response) return 'network';
  switch (err.response.status) {
    case 401: return 'auth';
    case 403: return 'permission';
    case 429: return 'rate_limit';
    case 400: case 422: return 'validation';
    default: return err.response.status >= 500 ? 'server' : 'validation';
  }
}
```

### Step 2: Handle 401 — Invalid API Key

```typescript
// Most common cause: missing x-api-key header or wrong key format
async function diagnoseAuth() {
  try {
    const response = await fetch('https://api.apollo.io/api/v1/auth/health', {
      headers: { 'x-api-key': process.env.APOLLO_API_KEY! },
    });
    const data = await response.json();
    if (data.is_logged_in) {
      console.log('API key is valid');
    } else {
      console.error('API key is invalid or expired');
      console.error('  Generate a new one at: Apollo > Settings > Integrations > API Keys');
    }
  } catch (err: any) {
    console.error('Cannot reach Apollo API:', err.message);
  }
}
```

**Common 401 causes:**

1. Using `api_key` query parameter instead of `x-api-key` header
2. Key was revoked or regenerated in the dashboard
3. Key has trailing whitespace (check with `echo -n "$APOLLO_API_KEY" | wc -c`)

### Step 3: Handle 403 — Wrong Key Type

```
Standard API key: search + enrichment only
Master API key:   full access (contacts, sequences, deals, tasks)
```

Endpoints that **require a master key**:

- `POST /contacts` (create/update)
- `POST /emailer_campaigns/search` (sequences)
- `POST /emailer_campaigns/{id}/add_contact_ids`
- `POST /opportunities` (deals)
- `POST /tasks` (tasks)
- `DELETE /contacts/{id}`

```typescript
// Diagnose: test a master-key-only endpoint
async function diagnoseMasterKey() {
  try {
    await client.post('/contacts/search', { per_page: 1 });
    console.log('Master API key confirmed');
  } catch (err: any) {
    if (err.response?.status === 403) {
      console.error('Your API key is a standard key. Master key required.');
      console.error('  Go to Apollo > Settings > Integrations > API Keys');
      console.error('  Generate a new key with "Master Key" type');
    }
  }
}
```

### Step 4: Handle 429 — Rate Limiting

Apollo uses fixed-window rate limiting per endpoint category:

```
Endpoint Category         | Limit      | Window  | Burst
--------------------------+------------+---------+------
People Search             | 100/min    | 1 min   | 10/sec
People Enrichment         | 100/min    | 1 min   | 10/sec
Bulk People Enrichment    | 10/min     | 1 min   | 2/sec
Organization Enrichment   | 100/min    | 1 min   | 10/sec
Contacts (CRUD)           | 100/min    | 1 min   | 10/sec
Sequences                 | 100/min    | 1 min   | 10/sec
```

```typescript
// Respect Retry-After header
async function handleRateLimit<T>(fn: () => Promise<T>): Promise<T> {
  try {
    return await fn();
  } catch (err: any) {
    if (err.response?.status === 429) {
      const retryAfter = parseInt(err.response.headers['retry-after'] ?? '60', 10);
      console.warn(`Rate limited. Waiting ${retryAfter}s...`);
      await new Promise((r) => setTimeout(r, retryAfter * 1000));
      return fn();
    }
    throw err;
  }
}
```

### Step 5: Handle 422 — Validation Errors

```typescript
// Common 422 causes:
//   - per_page > 100 on search endpoints
//   - Missing required fields on /contacts POST (first_name, last_name)
//   - Invalid email format on /people/match
//   - page > 500 on /mixed_people/api_search (50,000 record limit)

function logValidationError(err: AxiosError) {
  const body = err.response?.data as any;
  console.error('Validation error:', {
    status: err.response?.status,
    message: body?.message ?? body?.error,
    errors: body?.errors,
    url: err.config?.url,
    body: typeof err.config?.data === 'string' ? JSON.parse(err.config.data) : err.config?.data,
  });
}
```

### Step 6: Build Comprehensive Error Middleware

```typescript
// src/apollo/error-middleware.ts
import { AxiosError, AxiosInstance } from 'axios';

export function attachErrorHandler(client: AxiosInstance) {
  client.interceptors.response.use(
    (response) => response,
    (err: AxiosError) => {
      const status = err.response?.status;
      const body = err.response?.data as any;
      const endpoint = err.config?.url ?? 'unknown';

      const info = {
        status,
        endpoint,
        message: body?.message ?? err.message,
        timestamp: new Date().toISOString(),
      };

      switch (categorizeError(err)) {
        case 'auth':
          console.error('[APOLLO AUTH] Invalid x-api-key header', info);
          break;
        case 'permission':
          console.error('[APOLLO PERMISSION] Master key required for this endpoint', info);
          break;
        case 'rate_limit':
          console.warn('[APOLLO RATE LIMIT]', info);
          break;
        case 'validation':
          console.error('[APOLLO VALIDATION]', info);
          break;
        case 'server':
          console.error('[APOLLO SERVER] Check status.apollo.io', info);
          break;
        case 'network':
          console.error('[APOLLO NETWORK] Cannot reach api.apollo.io', info);
          break;
      }

      return Promise.reject(err);
    },
  );
}
```

## Error Reference

| Code | Meaning | Fix |
|------|---------|-----|
| 401 | Invalid or missing `x-api-key` header | Verify key in dashboard, check header name |
| 403 | Standard key used for master-only endpoint | Generate master API key |
| 422 | Bad request body | Check field names, per_page <= 100, page <= 500 |
| 429 | Rate limit exceeded | Read `Retry-After` header, implement backoff |
| 500 | Apollo server error | Retry with backoff, check [status.apollo.io](https://status.apollo.io) |
| ECONNREFUSED | Network/firewall | Allow outbound HTTPS to `api.apollo.io:443` |

## Output

- A classified error record containing the HTTP status, affected endpoint, and
  a redacted provider message suitable for the incident timeline
- A bounded recovery decision: rotate or correct credentials, request the
  required key type, retry within the server-provided window, or stop the job
- A reproducible diagnostic that uses a minimal request and never writes an
  Apollo key, raw contact data, or full request body to shared logs

## Examples

### Quick cURL Diagnostic

```bash
# Test auth (should return is_logged_in: true)
curl -s -H "x-api-key: $APOLLO_API_KEY" \
  https://api.apollo.io/api/v1/auth/health | python3 -m json.tool

# Test master key (returns contacts or 403)
curl -s -X POST -H "Content-Type: application/json" -H "x-api-key: $APOLLO_API_KEY" \
  -d '{"per_page":1}' https://api.apollo.io/api/v1/contacts/search | python3 -m json.tool
```

## Error Handling

Treat a `401` as a credential configuration failure: redact the value, verify
the secret binding, and rotate only through the approved credential owner. A
`403` means the workflow must stop until the correct authorized key type is
available; do not widen a standard key's permissions in a debug branch. For a
`429`, honor `Retry-After`, cap retries, and preserve the unfinished work for a
later run. For `5xx` or network failures, record the redacted request context,
check the provider status page, and fail the batch rather than replaying writes
whose outcome is unknown.

## Resources

- [Apollo API Error Reference](https://docs.apollo.io/reference/rate-limits)
- [Apollo Status Page](https://status.apollo.io)
- [Create API Keys](https://docs.apollo.io/docs/create-api-key)
- [API Usage Stats](https://docs.apollo.io/reference/view-api-usage-stats)

## Next Steps

Proceed to `apollo-debug-bundle` for collecting debug evidence.

Files in this skill

  • SKILL.md8.7 KB
  • references/implementation-guide.md7.2 KB
  • references/implementation.md3.6 KB

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.