Agent skill
instantly-reference-architecture
Implement Instantly.ai reference architecture with best-practice project layout. Use when designing new Instantly integrations, planning multi-campaign systems, or building an outreach automation platform. Trigger with phrases like "instantly architecture", "instantly project structure", "instantly reference design", "instantly system design", "instantly integration layout".
Install this agent skill to your Project
npx add-skill https://github.com/jeremylongshore/claude-code-plugins-plus-skills/tree/main/plugins/saas-packs/instantly-pack/skills/instantly-reference-architecture
SKILL.md
Instantly Reference Architecture
Overview
Reference architecture for production Instantly.ai integrations. Covers project layout, API client design, event-driven webhook processing, campaign management, lead pipeline, and analytics dashboard. Designed for teams building outreach automation on top of Instantly API v2.
Architecture Diagram
Instantly API v2
(api.instantly.ai)
|
┌─────────────────────┼─────────────────────┐
| | |
Campaign Mgmt Lead Pipeline Account Mgmt
(create/launch/ (import/move/ (warmup/
pause/analytics) enrich/block) vitals/pause)
| | |
└─────────┬───────────┘ |
| |
┌─────────┴─────────┐ |
| Your Backend |◄────────────────────┘
| (Node/Python) |
└────────┬──────────┘
|
┌────────┴──────────┐
| Webhook Receiver |◄──── Instantly Webhooks
| (Cloud Run / | (reply_received,
| Vercel / Fly) | email_bounced, etc.)
└────────┬──────────┘
|
┌─────────────┼─────────────┐
| | |
CRM Sync Slack Alerts Analytics DB
Project Layout
instantly-integration/
├── src/
│ ├── instantly/
│ │ ├── client.ts # API client wrapper with retry + auth
│ │ ├── types.ts # TypeScript interfaces for API schemas
│ │ ├── pagination.ts # Cursor-based pagination helpers
│ │ └── cache.ts # Analytics caching layer
│ ├── campaigns/
│ │ ├── create.ts # Campaign creation with sequences
│ │ ├── launch.ts # Campaign activation workflow
│ │ ├── analytics.ts # Campaign performance tracking
│ │ └── templates.ts # Email sequence templates
│ ├── leads/
│ │ ├── import.ts # Lead import from CSV/CRM
│ │ ├── lists.ts # Lead list management
│ │ ├── enrich.ts # Lead enrichment pipeline
│ │ └── blocklist.ts # Block list management
│ ├── accounts/
│ │ ├── warmup.ts # Warmup enable/disable/monitor
│ │ ├── health.ts # Account vitals testing
│ │ └── rotation.ts # Account assignment to campaigns
│ ├── webhooks/
│ │ ├── server.ts # Express webhook receiver
│ │ ├── handlers.ts # Event type handlers
│ │ └── validation.ts # Payload validation
│ └── config.ts # Environment config
├── tests/
│ ├── unit/ # Unit tests (mocked API)
│ ├── integration/ # Integration tests (mock server)
│ └── e2e/ # End-to-end (live API, read-only)
├── scripts/
│ ├── seed-leads.ts # Seed campaign with test leads
│ ├── audit.ts # Workspace audit script
│ └── migrate-v1-to-v2.ts # API migration helper
├── .env.example
├── .github/workflows/ci.yml
├── Dockerfile
├── package.json
└── tsconfig.json
Core Module Implementation
API Client (src/instantly/client.ts)
import "dotenv/config";
export class InstantlyClient {
constructor(
private apiKey = process.env.INSTANTLY_API_KEY!,
private baseUrl = "https://api.instantly.ai/api/v2"
) {}
async request<T>(path: string, init: RequestInit = {}): Promise<T> {
const res = await fetch(`${this.baseUrl}${path}`, {
...init,
headers: {
"Content-Type": "application/json",
Authorization: `Bearer ${this.apiKey}`,
...init.headers,
},
});
if (res.status === 429) {
await new Promise((r) => setTimeout(r, 2000));
return this.request<T>(path, init);
}
if (!res.ok) {
throw new InstantlyApiError(res.status, path, await res.text());
}
return res.json() as Promise<T>;
}
// Campaign operations
campaigns = {
list: (limit = 50) => this.request<Campaign[]>(`/campaigns?limit=${limit}`),
get: (id: string) => this.request<Campaign>(`/campaigns/${id}`),
create: (data: CreateCampaignInput) =>
this.request<Campaign>("/campaigns", { method: "POST", body: JSON.stringify(data) }),
activate: (id: string) =>
this.request<void>(`/campaigns/${id}/activate`, { method: "POST" }),
pause: (id: string) =>
this.request<void>(`/campaigns/${id}/pause`, { method: "POST" }),
analytics: (id: string) =>
this.request<CampaignAnalytics>(`/campaigns/analytics?id=${id}`),
analyticsDaily: (id: string, start: string, end: string) =>
this.request(`/campaigns/analytics/daily?campaign_id=${id}&start_date=${start}&end_date=${end}`),
};
// Lead operations
leads = {
create: (data: CreateLeadInput) =>
this.request<Lead>("/leads", { method: "POST", body: JSON.stringify(data) }),
list: (filter: ListLeadsInput) =>
this.request<Lead[]>("/leads/list", { method: "POST", body: JSON.stringify(filter) }),
get: (id: string) => this.request<Lead>(`/leads/${id}`),
delete: (id: string) => this.request(`/leads/${id}`, { method: "DELETE" }),
updateInterest: (email: string, campaignId: string, value: number) =>
this.request("/leads/update-interest-status", {
method: "POST",
body: JSON.stringify({ lead_email: email, campaign_id: campaignId, interest_value: value }),
}),
};
// Account operations
accounts = {
list: (limit = 50) => this.request<Account[]>(`/accounts?limit=${limit}`),
get: (email: string) => this.request<Account>(`/accounts/${encodeURIComponent(email)}`),
enableWarmup: (emails: string[]) =>
this.request("/accounts/warmup/enable", { method: "POST", body: JSON.stringify({ emails }) }),
warmupAnalytics: (emails: string[]) =>
this.request("/accounts/warmup-analytics", { method: "POST", body: JSON.stringify({ emails }) }),
testVitals: (emails: string[]) =>
this.request("/accounts/test/vitals", { method: "POST", body: JSON.stringify({ accounts: emails }) }),
pause: (email: string) =>
this.request(`/accounts/${encodeURIComponent(email)}/pause`, { method: "POST" }),
resume: (email: string) =>
this.request(`/accounts/${encodeURIComponent(email)}/resume`, { method: "POST" }),
};
// Webhook operations
webhooks = {
list: () => this.request<Webhook[]>("/webhooks?limit=50"),
create: (data: CreateWebhookInput) =>
this.request<Webhook>("/webhooks", { method: "POST", body: JSON.stringify(data) }),
test: (id: string) => this.request(`/webhooks/${id}/test`, { method: "POST" }),
delete: (id: string) => this.request(`/webhooks/${id}`, { method: "DELETE" }),
};
}
Campaign Template System (src/campaigns/templates.ts)
export const SEQUENCE_TEMPLATES = {
"3-step-cold": {
name: "3-Step Cold Outreach",
sequences: [{
steps: [
{ type: "email" as const, delay: 0, variants: [
{ subject: "{{firstName}}, quick question about {{companyName}}", body: "..." },
]},
{ type: "email" as const, delay: 3, delay_unit: "days" as const, variants: [
{ subject: "Re: {{firstName}}, quick question", body: "..." },
]},
{ type: "email" as const, delay: 5, delay_unit: "days" as const, variants: [
{ subject: "Re: {{firstName}}, quick question", body: "..." },
]},
],
}],
defaults: {
daily_limit: 50,
stop_on_reply: true,
email_gap: 120,
link_tracking: false,
open_tracking: true,
},
},
"meeting-request": {
name: "Meeting Request",
sequences: [{
steps: [
{ type: "email" as const, delay: 0, variants: [
{ subject: "15 min chat, {{firstName}}?", body: "..." },
]},
{ type: "email" as const, delay: 2, delay_unit: "days" as const, variants: [
{ subject: "Re: 15 min chat", body: "..." },
]},
],
}],
defaults: {
daily_limit: 30,
stop_on_reply: true,
email_gap: 180,
},
},
};
Data Flow Summary
Lead CSV/CRM → import.ts → POST /leads → Campaign
↓
POST /campaigns/{id}/activate
↓
Instantly sends emails
↓
Webhook events fire
↓
handlers.ts routes events
↓
┌─────────┬─────────┬───────────┐
CRM Slack Analytics Block List
Error Handling
| Error | Cause | Solution |
|---|---|---|
| Client constructor fails | Missing INSTANTLY_API_KEY |
Check .env file |
| Namespace methods fail | API scope mismatch | Verify key has correct scopes |
| Import fails midway | Network/rate limit | Batch with retry (see instantly-performance-tuning) |
| Webhook events missing | Webhook not registered | Register after deploy (see instantly-webhooks-events) |
Resources
Next Steps
For multi-environment setup, see instantly-multi-env-setup.
Recommended Agent Skills
Expand your agent's capabilities with these related and highly-rated skills.
dockerfile-generator
Dockerfile Generator - Auto-activating skill for DevOps Basics. Triggers on: dockerfile generator, dockerfile generator Part of the DevOps Basics skill category.
branch-naming-helper
Branch Naming Helper - Auto-activating skill for DevOps Basics. Triggers on: branch naming helper, branch naming helper Part of the DevOps Basics skill category.
readme-generator
Readme Generator - Auto-activating skill for DevOps Basics. Triggers on: readme generator, readme generator Part of the DevOps Basics skill category.
makefile-generator
Makefile Generator - Auto-activating skill for DevOps Basics. Triggers on: makefile generator, makefile generator Part of the DevOps Basics skill category.
gitignore-generator
Gitignore Generator - Auto-activating skill for DevOps Basics. Triggers on: gitignore generator, gitignore generator Part of the DevOps Basics skill category.
pre-commit-hook-setup
Pre Commit Hook Setup - Auto-activating skill for DevOps Basics. Triggers on: pre commit hook setup, pre commit hook setup Part of the DevOps Basics skill category.
Didn't find tool you were looking for?