apollo-common-errors
Installation
SKILL.md
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
// 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
// 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:
- Using
api_keyquery parameter instead ofx-api-keyheader - Key was revoked or regenerated in the dashboard
- 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_idsPOST /opportunities(deals)POST /tasks(tasks)DELETE /contacts/{id}
// 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
// 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
// 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
// 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 |
| ECONNREFUSED | Network/firewall | Allow outbound HTTPS to api.apollo.io:443 |
Examples
Quick cURL Diagnostic
# 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
Resources
Next Steps
Proceed to apollo-debug-bundle for collecting debug evidence.
Weekly Installs
29
Repository
jeremylongshore…s-skillsGitHub Stars
2.1K
First Seen
Jan 25, 2026
Security Audits