Instantly debug bundle
425 plugins, 2,810 skills, 200 agents for Claude Code. Open-source marketplace at tonsofskills.com with the ccpi CLI package manager.
npx -y skills add jeremylongshore/claude-code-plugins-plus-skills --skill instantly-debug-bundleAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
What its author says it does
Copied from the file, not written here
'Collect Instantly.ai debug evidence for support tickets and troubleshooting.
The file declares its own license as MIT. That is the author’s claim about this one file, and it is not the same thing as the license GitHub reports for the repository, which is listed with the other numbers below.
SKILL.md
7.9 KB, as published. Nobody here has run it
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
instantly-install-authsetup - API key with
all:readscope (or individual read scopes for each resource)
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
instantly-debug-{timestamp}.json— full debug bundle- Console summary with campaign/account/webhook counts
- Broken account identification with SMTP/IMAP status
- Errors collected during diagnostic
Error Handling
| Error | Cause | Solution |
|---|---|---|
403 on workspace endpoint | Key missing workspace scope | Add all:read scope to API key |
| Empty warmup analytics | No accounts have warmup enabled | Enable warmup first |
| Partial bundle | Some endpoints failed | Check errors array in bundle output |
| Large bundle (>10MB) | 100+ campaigns and accounts | Reduce limits or collect per-campaign |
Resources
- Instantly Help Center
- Instantly API v2 Docs
- Background Jobs API
Next Steps
For error resolution patterns, see instantly-common-errors.