Install any skill in seconds. Free to start, no credit card required.
Get Started Free →Execute Apollo.io production deployment checklist. Use when preparing to deploy Apollo integrations to production, doing pre-launch verification, or auditing production readiness. Trigger with phrases like "apollo production checklist", "deploy apollo", "apollo go-live", "apollo production ready", "apollo launch checklist".
.claude/skills/jeremylongshore-apollo-prod-checklist/SKILL.md| Model | Eval pass | Runs |
|---|---|---|
| gemini-3.6-flash | 79% | 15 |
| Test case | Without → With | Effect | Δ tokens | Δ turns |
|---|---|---|---|---|
| case-02 | ✗→✓ | ▲ Improved | 49% | 0% |
| case-09 | ✗→✓ | ▲ Improved | 18% | 0% |
| case-04 | ✗→✓ | ▲ Improved | 61% | 0% |
| case-05 | ✗→✓ | ▲ Improved | 59% | 0% |
| case-08 | ✗→✓ | ▲ Improved | 46% | 0% |
Comprehensive pre-production checklist for Apollo.io integrations with automated validation scripts. Covers authentication, resilience, observability, compliance, and credit management.
apollo-install-auth setuptypescript// src/scripts/prod-checklist.ts import axios from 'axios'; interface Check { category: string; name: string; pass: boolean; detail: string; } const results: Check[] = []; // 1.1 API key is set (not hardcoded) results.push({ category: 'Auth', name: 'API key from env/secrets', pass: !!process.env.APOLLO_API_KEY, detail: process.env.APOLLO_API_KEY ? 'Loaded from env' : 'NOT SET', }); // 1.2 Using x-api-key header (not query param) const { execSync } = await import('child_process'); let usesHeader = true; try { execSync('grep -rn "params.*api_key" src/ --include="*.ts"', { stdio: 'pipe' }); usesHeader = false; } catch {} results.push({ category: 'Auth', name: 'x-api-key header auth', pass: usesHeader, detail: usesHeader ? 'OK' : 'Switch to x-api-key header' }); // 1.3 API key is valid try { const resp = await axios.get('https://api.apollo.io/api/v1/auth/health', { headers: { 'x-api-key': process.env.APOLLO_API_KEY! }, }); results.push({ category: 'Auth', name: 'Key valid', pass: resp.data.is_logged_in, detail: resp.data.is_logged_in ? 'OK' : 'Invalid key' }); } catch (err: any) { results.push({ category: 'Auth', name: 'Key valid', pass: false, detail: `HTTP ${err.response?.status}` }); } // 1.4 .env gitignored const gitIgnored = execSync('git check-ignore .env 2>/dev/null || echo NOT').toString().trim(); results.push({ category: 'Auth', name: '.env gitignored', pass: gitIgnored !== 'NOT', detail: gitIgnored !== 'NOT' ? 'OK' : 'Add .env to .gitignore' });
typescriptasync function fileContains(dir: string, pattern: string): Promise<boolean> { try { execSync(`grep -r "${pattern}" ${dir} --include="*.ts" -l`, { stdio: 'pipe' }); return true; } catch { return false; } } results.push({ category: 'Resilience', name: 'Rate limiting', pass: await fileContains('src/', 'rate-limiter\\|SlidingWindow\\|RateLimit'), detail: 'Rate limiter implementation' }); results.push({ category: 'Resilience', name: 'Retry logic', pass: await fileContains('src/', 'withRetry\\|withBackoff\\|exponential'), detail: 'Exponential backoff for 429/5xx' }); results.push({ category: 'Resilience', name: 'Error categorization', pass: await fileContains('src/', 'categorizeError\\|ApolloApiError'), detail: 'Typed error handling' }); results.push({ category: 'Resilience', name: 'Timeout configured', pass: await fileContains('src/', 'timeout.*\\d'), detail: 'Request timeout set' });
typescriptresults.push({ category: 'Observability', name: 'PII redaction', pass: await fileContains('src/', 'redact'), detail: 'PII redaction in logs' }); results.push({ category: 'Observability', name: 'Structured logging', pass: await fileContains('src/', 'pino\\|winston\\|console\\.log.*Apollo'), detail: 'Logger with Apollo context' }); results.push({ category: 'Observability', name: 'Health endpoint', pass: await fileContains('src/', '/health'), detail: '/health endpoint checking Apollo connectivity' });
typescriptresults.push({ category: 'Credits', name: 'Credit tracking', pass: await fileContains('src/', 'credit\\|CreditTracker'), detail: 'Track enrichment credit usage' }); results.push({ category: 'Credits', name: 'Deduplication', pass: await fileContains('src/', 'dedup\\|isAlreadyEnriched'), detail: 'Prevent duplicate enrichment charges' }); results.push({ category: 'Credits', name: 'Budget controls', pass: await fileContains('src/', 'budget\\|isOverBudget'), detail: 'Daily credit budget enforcement' });
typescriptfunction generateReport(results: Check[]) { const categories = [...new Set(results.map((r) => r.category))]; let allPass = true; console.log('\n Apollo Production Readiness Checklist\n'); for (const cat of categories) { console.log(`-- ${cat} --`); for (const r of results.filter((r) => r.category === cat)) { console.log(` ${r.pass ? 'PASS' : 'FAIL'} ${r.name}: ${r.detail}`); if (!r.pass) allPass = false; } console.log(''); } const passCount = results.filter((r) => r.pass).length; console.log(`Score: ${passCount}/${results.length} checks passed`); console.log(`Status: ${allPass ? 'READY FOR PRODUCTION' : 'BLOCKED — fix failing checks'}`); process.exit(allPass ? 0 : 1); } generateReport(results);
| Issue | Resolution | |-------|------------| | Auth checks fail | Verify APOLLO_API_KEY env var, switch to x-api-key header | | Missing rate limiting | Add apollo-rate-limits skill patterns | | No credit tracking | Add apollo-cost-tuning skill patterns | | Post-deploy failures | Run checklist in CI as a deployment gate |
json{ "scripts": { "prod:checklist": "tsx src/scripts/prod-checklist.ts" } }
bashnpm run prod:checklist && npm run deploy
Proceed to apollo-upgrade-migration for API upgrade procedures.
| Case | Status | Duration (ms) | Turns | Tokens | Tool calls | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Without | With | Δ | Without | With | Δ | Without | With | Δ | Without | With | Δ | ||
case-01 | fail→fail | 26,344 | 25,557 | -3% | 1 | 1 | 0% | 6,218 | 7,955 | +28% | 0 | 0 | — |
case-02 | fail→pass | 19,987 | 20,652 | +3% | 1 | 1 | 0% | 4,398 | 6,535 | +49% | 0 | 0 | — |
case-03 | pass→pass | 21,691 | 17,889 | -18% | 1 | 1 | 0% | 4,895 | 6,156 | +26% | 0 | 0 | — |
case-09 | fail→pass | 11,311 | 4,660 | -59% | 1 | 1 | 0% | 2,181 | 2,574 | +18% | 0 | 0 | — |
case-04 | fail→pass | 7,962 | 7,622 | -4% | 1 | 1 | 0% | 1,529 | 2,467 | +61% | 0 | 0 | — |
case-05 | fail→pass | 14,249 | 13,176 | -8% | 1 | 1 | 0% | 2,741 | 4,369 | +59% | 0 | 0 | — |
case-06 | pass→pass | 20,299 | 13,784 | -32% | 1 | 1 | 0% | 3,657 | 4,315 | +18% | 0 | 0 | — |
case-07 | pass→pass | 16,349 | 13,025 | -20% | 1 | 1 | 0% | 2,955 | 4,365 | +48% | 0 | 0 | — |
case-08 | fail→pass | 17,530 | 14,232 | -19% | 1 | 1 | 0% | 3,076 | 4,486 | +46% | 0 | 0 | — |
case-10 | pass→pass | 12,148 | 4,603 | -62% | 1 | 1 | 0% | 2,159 | 2,632 | +22% | 0 | 0 | — |
case-11 | pass→pass | 19,798 | 11,094 | -44% | 1 | 1 | 0% | 3,722 | 3,938 | +6% | 0 | 0 | — |
case-12 | pass→pass | 12,825 | 5,296 | -59% | 1 | 1 | 0% | 2,022 | 2,717 | +34% | 0 | 0 | — |
case-13 | fail→pass | 11,308 | 2,693 | -76% | 1 | 1 | 0% | 1,850 | 2,134 | +15% | 0 | 0 | — |
case-14 | pass→pass | 7,458 | 2,371 | -68% | 1 | 1 | 0% | 1,335 | 2,172 | +63% | 0 | 0 | — |
case-15 | fail→pass | 9,540 | 2,141 | -78% | 1 | 1 | 0% | 1,671 | 2,116 | +27% | 0 | 0 | — |
case-16 | fail→pass | 10,687 | 3,645 | -66% | 1 | 1 | 0% | 1,990 | 2,354 | +18% | 0 | 0 | — |
case-17 | pass→pass | 15,165 | 8,535 | -44% | 1 | 1 | 0% | 2,684 | 3,399 | +27% | 0 | 0 | — |
case-18 | pass→pass | 11,023 | 5,937 | -46% | 1 | 1 | 0% | 1,943 | 2,492 | +28% | 0 | 0 | — |
case-19 | fail→pass | 11,181 | 8,800 | -21% | 1 | 1 | 0% | 1,648 | 3,119 | +89% | 0 | 0 | — |
case-20 | pass→pass | 34,208 | 12,469 | -64% | 1 | 1 | 0% | 3,644 | 4,659 | +28% | 0 | 0 | — |
case-21 | pass→pass | 19,100 | 14,563 | -24% | 1 | 1 | 0% | 4,153 | 4,998 | +20% | 0 | 0 | — |
case-22 | pass→pass | 18,855 | 19,382 | +3% | 1 | 1 | 0% | 3,757 | 5,851 | +56% | 0 | 0 | — |
DecimalAI ran this skill against gemini-3.6-flash twice over the same eval suite — once with the skill loaded and once without — and compared the two runs case by case. 22 cases were attempted. The headline lift of +41 percentage points is the difference between those two pass rates over the 22 comparable cases.
Without the skill loaded, the model failed this case. With it loaded, the same prompt on the same model passed. This is one improved case from the latest verified run; every case, including any that regressed, is in the table above.
Other measured skills in the registry, with their headline benchmark lift.