Claude-code-plugins-plus-skills instantly-debug-bundle
install
source · Clone the upstream repo
git clone https://github.com/jeremylongshore/claude-code-plugins-plus-skills
Claude Code · Install into ~/.claude/skills/
T=$(mktemp -d) && git clone --depth=1 https://github.com/jeremylongshore/claude-code-plugins-plus-skills "$T" && mkdir -p ~/.claude/skills && cp -r "$T/plugins/saas-packs/instantly-pack/skills/instantly-debug-bundle" ~/.claude/skills/jeremylongshore-claude-code-plugins-plus-skills-instantly-debug-bundle && rm -rf "$T"
manifest:
plugins/saas-packs/instantly-pack/skills/instantly-debug-bundle/SKILL.mdsource content
Instantly Debug Bundle
Overview
Collect a comprehensive debug bundle from your Instantly workspace: campaign state, account health, warmup metrics, lead stats, webhook delivery status, and recent errors. Output is a JSON report suitable for support tickets or internal audits.
Prerequisites
- Completed
setupinstantly-install-auth - API key with
scope (or individual read scopes for each resource)all:read
Instructions
Step 1: Collect Full Debug Bundle
import { instantly } from "./src/instantly"; import { writeFileSync } from "fs"; interface DebugBundle { timestamp: string; workspace: unknown; campaigns: unknown[]; accounts: unknown[]; warmup_analytics: unknown[]; webhooks: unknown[]; webhook_event_summary: unknown; background_jobs: unknown[]; lead_count_by_campaign: Record<string, number>; errors: string[]; } async function collectDebugBundle(): Promise<DebugBundle> { const bundle: DebugBundle = { timestamp: new Date().toISOString(), workspace: null, campaigns: [], accounts: [], warmup_analytics: [], webhooks: [], webhook_event_summary: null, background_jobs: [], lead_count_by_campaign: {}, errors: [], }; // Workspace info try { bundle.workspace = await instantly("/workspaces/current"); } catch (e: any) { bundle.errors.push(`workspace: ${e.message}`); } // All campaigns with status try { bundle.campaigns = await instantly("/campaigns?limit=100"); } catch (e: any) { bundle.errors.push(`campaigns: ${e.message}`); } // All email accounts try { bundle.accounts = await instantly("/accounts?limit=100"); } catch (e: any) { bundle.errors.push(`accounts: ${e.message}`); } // Warmup analytics for all accounts try { const accounts = bundle.accounts as Array<{ email: string }>; if (accounts.length > 0) { bundle.warmup_analytics = await instantly("/accounts/warmup-analytics", { method: "POST", body: JSON.stringify({ emails: accounts.map((a) => a.email) }), }); } } catch (e: any) { bundle.errors.push(`warmup_analytics: ${e.message}`); } // Webhooks try { bundle.webhooks = await instantly("/webhooks?limit=50"); } catch (e: any) { bundle.errors.push(`webhooks: ${e.message}`); } // Webhook event delivery summary try { bundle.webhook_event_summary = await instantly("/webhook-events/summary"); } catch (e: any) { bundle.errors.push(`webhook_events: ${e.message}`); } // Recent background jobs try { bundle.background_jobs = await instantly("/background-jobs?limit=20"); } catch (e: any) { bundle.errors.push(`background_jobs: ${e.message}`); } // Lead counts per campaign for (const c of (bundle.campaigns as Array<{ id: string; name: string }>).slice(0, 10)) { try { const analytics = await instantly<{ total_leads: number }>( `/campaigns/analytics?id=${c.id}` ); bundle.lead_count_by_campaign[c.name] = analytics.total_leads; } catch { bundle.lead_count_by_campaign[c.name] = -1; // error } } return bundle; }
Step 2: Save and Analyze
async function main() { console.log("Collecting Instantly debug bundle...\n"); const bundle = await collectDebugBundle(); // Save to file const filename = `instantly-debug-${Date.now()}.json`; writeFileSync(filename, JSON.stringify(bundle, null, 2)); console.log(`Saved debug bundle to ${filename}`); // Print summary const campaigns = bundle.campaigns as Array<{ name: string; status: number }>; const accounts = bundle.accounts as Array<{ email: string; status: number }>; console.log("\n=== Debug Summary ==="); console.log(`Campaigns: ${campaigns.length}`); console.log(` Active: ${campaigns.filter((c) => c.status === 1).length}`); console.log(` Paused: ${campaigns.filter((c) => c.status === 2).length}`); console.log(` Unhealthy: ${campaigns.filter((c) => c.status === -1).length}`); console.log(` Bounce Protected: ${campaigns.filter((c) => c.status === -2).length}`); console.log(`\nAccounts: ${accounts.length}`); console.log(`Webhooks: ${(bundle.webhooks as any[]).length}`); console.log(`Background Jobs: ${(bundle.background_jobs as any[]).length}`); if (bundle.errors.length > 0) { console.log(`\nErrors during collection:`); bundle.errors.forEach((e) => console.log(` - ${e}`)); } } main().catch(console.error);
Step 3: Account Vitals Deep Dive
async function accountVitalsDiagnostic() { const accounts = await instantly<Array<{ email: string }>>( "/accounts?limit=100" ); const vitals = await instantly("/accounts/test/vitals", { method: "POST", body: JSON.stringify({ accounts: accounts.map((a) => a.email) }), }) as Array<{ email: string; smtp_status: string; imap_status: string; dns_status: string }>; console.log("\n=== Account Vitals ==="); const broken = vitals.filter((v) => v.smtp_status !== "ok" || v.imap_status !== "ok"); const healthy = vitals.filter((v) => v.smtp_status === "ok" && v.imap_status === "ok"); console.log(`Healthy: ${healthy.length} | Broken: ${broken.length}`); for (const v of broken) { console.log(` BROKEN: ${v.email} — SMTP=${v.smtp_status} IMAP=${v.imap_status} DNS=${v.dns_status}`); } }
Step 4: Curl-Based Quick Diagnostic
set -euo pipefail echo "=== Instantly Quick Diagnostic ===" echo "Timestamp: $(date -u +%Y-%m-%dT%H:%M:%SZ)" echo -e "\n--- Campaigns ---" curl -s https://api.instantly.ai/api/v2/campaigns?limit=100 \ -H "Authorization: Bearer $INSTANTLY_API_KEY" | \ jq '[.[] | {name, status, id}] | length as $total | {total: $total, active: [.[] | select(.status==1)] | length, paused: [.[] | select(.status==2)] | length, unhealthy: [.[] | select(.status==-1)] | length}' echo -e "\n--- Accounts ---" curl -s https://api.instantly.ai/api/v2/accounts?limit=100 \ -H "Authorization: Bearer $INSTANTLY_API_KEY" | \ jq 'length as $total | {total: $total, accounts: [.[:5][] | {email, status}]}' echo -e "\n--- Webhooks ---" curl -s https://api.instantly.ai/api/v2/webhooks?limit=50 \ -H "Authorization: Bearer $INSTANTLY_API_KEY" | \ jq '[.[] | {name, event_type, target_hook_url}]' echo -e "\n--- Recent Background Jobs ---" curl -s https://api.instantly.ai/api/v2/background-jobs?limit=5 \ -H "Authorization: Bearer $INSTANTLY_API_KEY" | \ jq '[.[] | {id, status, timestamp_created}]'
Output
— full debug bundleinstantly-debug-{timestamp}.json- Console summary with campaign/account/webhook counts
- Broken account identification with SMTP/IMAP status
- Errors collected during diagnostic
Error Handling
| Error | Cause | Solution |
|---|---|---|
on workspace endpoint | Key missing workspace scope | Add scope to API key |
| Empty warmup analytics | No accounts have warmup enabled | Enable warmup first |
| Partial bundle | Some endpoints failed | Check array in bundle output |
| Large bundle (>10MB) | 100+ campaigns and accounts | Reduce limits or collect per-campaign |
Resources
Next Steps
For error resolution patterns, see
instantly-common-errors.