Cold outreach campaign spreadsheet organization

Date: 24 April 2026
Model: sonnet
Author: Lovinia Mak


You

I am going to start my first cold outreach campaign. What has stopped me before was the idea of organizing leads as i had this phobia of spreadsheets. I had gotten over that so now i have a basic spreadsheet that has cleaned up data and columns. I am someone who thinks in levels before steps and want systems that scale and can transmit my quality standards without me always having to be in the room. I believe a brand is not logos or design only but in how a user experiences the brand from discovery all the way until being the customer and also continuous relationship with the brand. This is why my marketing and sales voice needs to be coherent, efficient and delivers my signal in high fidelity transmission. Being disorganized or not knowing enough about a customer, our history with them, etc can spoil the brand experience. I could also be overwhelmed if i cannot find the data i need in one place or to know the history of interaction or outreach with a customer. All this is market research and data - how i design a campaign, what emails i write, what channels they are coming from, what increases sign up for my trainings, referrals etc. If I were a training house that can serve millions at scale, how would i design and set it up so it can be automated and then have orchestrators and agents in the loop with human managers to pull edge cases or attend to VIP support calls, etc. Tell me what success is for the level of goal i have.


Sloane

Defining Success at Scale: The Training House Operating System

First, What You're Actually Building

You're not building a spreadsheet system. You're building a signal transmission infrastructure — where your brand quality, voice, and standards replicate themselves faithfully across every touchpoint, at volume, without degrading. The spreadsheet is just the seed crystal.

Success at your level means:

A lead can enter your world as a cold name and exit as a loyal customer, advocate, or alumni — and every interaction in between reflects the same standard you would deliver personally, whether you touched it or not.


The Architecture: Four Levels

Think in levels the way you already do.


LEVEL 1 — Data Foundation (The Ground Truth Layer)

This is where everything else gets its integrity. If this layer is corrupted or incomplete, everything above it transmits noise instead of signal.

What lives here:

The discipline here: Every field must have a reason it exists operationally — not for vanity, but because something downstream uses it to make a decision or trigger an action.


LEVEL 2 — The Workflow Engine (The Nervous System)

This is where your standards get encoded into behavior. This is how you transmit quality without being in the room.

Core concept: Every lead has a status and every status has a playbook.

Status What it means What happens next
Cold Never heard of you Awareness sequence begins
Engaged Opened / clicked something Nurture sequence activates
Warm Attended free training or downloaded something Conversion sequence begins
Hot Visited pricing, replied to email, booked a call Sales sequence / human flag
Customer Bought something Onboarding sequence
Alumni Completed training Retention + upsell sequence
Dormant 90+ days no activity Re-engagement sequence
VIP High LTV or high referral activity White glove lane activated

Each sequence is a pre-written, pre-approved transmission of your voice and standards. You write it once. It runs forever. The quality is locked in at authorship.

What the engine does automatically:


LEVEL 3 — The Intelligence Layer (Orchestrators and Agents)

This is where scale becomes possible without chaos. You're not replacing human judgment — you're deploying it strategically.

Three types of actors at this level:

Automated Agents (No humans needed)

Orchestrators (Humans with a system, not a hunch)

These are trained team members or contractors who operate inside your system using your documented standards.

Their job is not to make creative decisions — it is to handle exceptions the automation flagged and execute the playbook for that exception.

Examples of what they handle:

Orchestrators have a daily queue — not an inbox. The queue shows them exactly what needs attention and what the standard response or action is. They are not improvising. They are executing your encoded standards.

Human Managers

Their job is pattern recognition and system integrity, not firefighting.

They ask:


LEVEL 4 — The Intelligence Feedback Loop (How the System Learns)

Most systems at scale fail here. They automate but never improve. You want a system that gets smarter.

The feedback loop has four beats:

  1. Measure — what happened this week/month across all campaigns

  2. Interpret — what does the data mean for your signal

  3. Decide — update the playbook, the sequence, or the scoring model

  4. Propagate — push the updated standard back into the system so every future interaction benefits from the learning

This is how your brand experience improves even while you're not touching it. The system evolves under governed conditions.


What the Tech Stack Looks Like

You don't need to build all of this at once. But you need to know what each tool category is doing so you don't buy redundant tools or create gaps.

Layer Tool Category Examples
Data Foundation CRM Airtable (now), HubSpot, Notion (light)
Communication Email Automation Mailchimp, ConvertKit, ActiveCampaign
Workflow Engine Automation Platform Make (Integromat), Zapier, n8n
Intelligence Layer AI Agents / Ops Claude, GPT via API, custom prompts
Queue Management Task + Ops Notion, Linear, ClickUp
Analytics Reporting Native CRM reports, Looker Studio
Voice Consistency Brand Docs Notion wiki, internal prompt library

The golden rule: your CRM is the source of truth. Everything else writes back to it.


What Success Actually Looks Like at Your Level

Not vanity metrics. Operational proof.

Dimension What success looks like
Signal Fidelity Someone who met you through cold outreach and someone who was referred both experience the same quality of communication — they cannot tell which one was automated
Data Integrity You can pull up any contact and know their full history, status, score, and next action in under 30 seconds
Operator Independence An orchestrator joins your team, reads the playbook, and is handling their queue to your standard within one week — without you training them personally
Feedback Velocity You identify a sequence that is underperforming and have a new version running within 72 hours
Attribution Clarity You know exactly which channel, which message, and which training produces your highest LTV customers
Scale Without Drift You go from 100 contacts to 10,000 and the brand experience does not degrade
VIP Separation Your highest value relationships always get a human, always get speed, always feel seen — automatically flagged before they have to ask
Revenue Predictability Because the pipeline is instrumented, you can forecast which cohort of leads will convert and when

The Honest Sequence to Get There

Since you think in levels, here is the honest level-by-level build:

Level 0 — Right now: Clean CRM. Basic columns. Status field. Source field. That spreadsheet you already have.

Level 1 — Next 30 days: Your first sequence written in your voice. Your first status-based workflow. Every new contact gets a source tag.

Level 2 — 60–90 days: Lead scoring logic. Automated status transitions. Your first playbook document for orchestrators.

Level 3 — 90–180 days: Orchestrator in the loop. Queue-based operations. Feedback loop meeting monthly.

Level 4 — 6–12 months: Full attribution model. AI-assisted drafting inside your voice guidelines. Predictive scoring. VIP lane fully operational.


The One Thing That Determines Whether This Works

Your voice documentation.

Every automation, every orchestrator, every AI agent — they all need to know what your standard sounds like. This is not a style guide. It is an operating transmission standard.

It answers:

Write this before you scale anything. It is the master signal everything else replicates from.


You are not building a campaign. You are building a replication machine for your standards. The campaign is just the first proof of concept.


You

what is the prompt to give airtable to build? how do i plan my lists and campaigns and manage airtable? I don't want my data to live on hubspot or notion. I plan to build my own one day on Cloudflare. I already have Cloudflare. I was hoping to use R2, KV, D1, pages and workers. My communication tool is now Resend. I need another way to integrate intelligence layer, queue management - why not Cloudflare? With workers that have python or js scripts? Analytics and reporting - what about Google Sheet or Business Intelligence or a PWA that can pull data for analytics? How do people do this? What about google data studio ?


Sloane

Building Your Own Training House CRM on Cloudflare

First, The Architecture Decision You're Making

You're not just avoiding HubSpot. You're making a sovereignty decision — your data, your infrastructure, your rules. Cloudflare is a legitimate production choice for this. Let me map exactly how each piece fits.


The Cloudflare Stack Mapped to Your Layers

Your Layer Cloudflare Primitive What It Does
Data Foundation D1 (SQLite at edge) Master contact records, interaction history, lead scores
File / Blob Storage R2 Email templates, attachments, exports, training assets
Fast Key-Value State KV Session state, lead scores cache, feature flags, queue locks
Logic / Automation Workers (JS or Python) Triggers, scoring, sequence logic, webhook receivers
Scheduled Jobs Workers Cron Triggers Daily queue builds, score decay, digest reports
Queue Management Queues Async job processing, email send queue, task queue
Frontend / Dashboard Pages Your PWA dashboard, analytics UI, operator queue UI
Email Sending Resend via Worker All outbound email, webhook back for open/click tracking
Analytics Reporting Analytics Engine or Google Looker Studio Campaign metrics, funnel data

This is a real production stack. Companies run serious infrastructure on this. You are not compromising.


Airtable's Role — Temporary Scaffold, Not Permanent Home

Use Airtable only as your transition tool while you build on Cloudflare. Here is what to build in Airtable now that will directly translate to your D1 schema later.

The Airtable Prompt to Give Yourself (Design Brief)

I am building a CRM for a training house that serves leads 
through cold outreach to paid customer to alumni. 

I need the following tables:

TABLE: Contacts
- Contact ID (autonumber)
- Full Name
- Email
- Phone
- Company / Organization
- Role / Title
- Industry
- Country / Timezone
- Channel of Origin (LinkedIn / Referral / Cold Email / 
  Organic / Paid / Event)
- Lead Status (Cold / Engaged / Warm / Hot / Customer / 
  Alumni / Dormant / VIP / Unsubscribed)
- Lead Score (number, manually updated for now)
- Assigned Orchestrator
- Tags (multiple select)
- Notes
- Date Added
- Last Contact Date
- Next Action
- Next Action Date
- Linked Interactions (link to Interactions table)
- Linked Campaigns (link to Campaign Contacts table)
- Linked Purchases (link to Purchases table)

TABLE: Interactions
- Interaction ID
- Contact (linked)
- Date
- Channel (Email / Call / DM / Event / Support / Referral)
- Direction (Inbound / Outbound)
- Summary
- Outcome (No Response / Replied / Booked / Converted / 
  Complaint / Referral Given)
- Initiated By (Automated / Orchestrator / Manager / Self)
- Linked Campaign

TABLE: Campaigns
- Campaign ID
- Campaign Name
- Goal (Awareness / Nurture / Conversion / Retention / 
  Re-engagement)
- Channel (Email / LinkedIn / SMS / Multi)
- Status (Draft / Active / Paused / Complete)
- Start Date
- End Date
- Target Segment (based on Lead Status or Tags)
- Sequence Steps (long text or linked table)
- Owner

TABLE: Campaign Contacts
(Junction table — who is in which campaign)
- Contact (linked)
- Campaign (linked)
- Date Added to Campaign
- Current Step Number
- Status in Campaign (Active / Completed / Unsubscribed / 
  Converted)
- Converted (checkbox)
- Conversion Date

TABLE: Purchases
- Purchase ID
- Contact (linked)
- Training / Product Name
- Amount
- Date
- Payment Method
- Cohort / Batch
- Completion Status (Enrolled / In Progress / Completed / 
  Dropped)
- Certificate Issued (checkbox)
- Referral Source Contact (linked)

TABLE: Sequences
- Sequence ID
- Sequence Name
- Trigger (Status Change / Tag Applied / Date / Manual)
- Step Number
- Delay (days after previous step)
- Channel
- Subject Line
- Body / Script
- From Name / From Address

This Airtable structure directly mirrors what you will build in D1. You are not doing double work — you are prototyping your schema.


The D1 Database Schema (When You Migrate)

-- Contacts
CREATE TABLE contacts (
  id TEXT PRIMARY KEY,
  full_name TEXT NOT NULL,
  email TEXT UNIQUE NOT NULL,
  phone TEXT,
  company TEXT,
  role TEXT,
  industry TEXT,
  country TEXT,
  timezone TEXT,
  channel_origin TEXT,
  lead_status TEXT DEFAULT 'cold',
  lead_score INTEGER DEFAULT 0,
  assigned_orchestrator TEXT,
  tags TEXT, -- JSON array
  notes TEXT,
  date_added TEXT DEFAULT (datetime('now')),
  last_contact_date TEXT,
  next_action TEXT,
  next_action_date TEXT,
  unsubscribed INTEGER DEFAULT 0,
  vip INTEGER DEFAULT 0
);

-- Interactions
CREATE TABLE interactions (
  id TEXT PRIMARY KEY,
  contact_id TEXT NOT NULL,
  interaction_date TEXT DEFAULT (datetime('now')),
  channel TEXT,
  direction TEXT,
  summary TEXT,
  outcome TEXT,
  initiated_by TEXT,
  campaign_id TEXT,
  FOREIGN KEY (contact_id) REFERENCES contacts(id)
);

-- Campaigns
CREATE TABLE campaigns (
  id TEXT PRIMARY KEY,
  name TEXT NOT NULL,
  goal TEXT,
  channel TEXT,
  status TEXT DEFAULT 'draft',
  start_date TEXT,
  end_date TEXT,
  target_segment TEXT, -- JSON rules
  owner TEXT,
  created_at TEXT DEFAULT (datetime('now'))
);

-- Campaign Contacts (enrollment)
CREATE TABLE campaign_contacts (
  id TEXT PRIMARY KEY,
  contact_id TEXT NOT NULL,
  campaign_id TEXT NOT NULL,
  date_added TEXT DEFAULT (datetime('now')),
  current_step INTEGER DEFAULT 1,
  status TEXT DEFAULT 'active',
  converted INTEGER DEFAULT 0,
  conversion_date TEXT,
  FOREIGN KEY (contact_id) REFERENCES contacts(id),
  FOREIGN KEY (campaign_id) REFERENCES campaigns(id)
);

-- Sequences
CREATE TABLE sequences (
  id TEXT PRIMARY KEY,
  campaign_id TEXT NOT NULL,
  step_number INTEGER NOT NULL,
  delay_days INTEGER DEFAULT 0,
  channel TEXT DEFAULT 'email',
  subject TEXT,
  body TEXT,
  from_name TEXT,
  from_address TEXT,
  FOREIGN KEY (campaign_id) REFERENCES campaigns(id)
);

-- Email Events (from Resend webhooks)
CREATE TABLE email_events (
  id TEXT PRIMARY KEY,
  contact_id TEXT,
  campaign_id TEXT,
  sequence_step INTEGER,
  resend_email_id TEXT,
  event_type TEXT, -- sent / delivered / opened / clicked / bounced / complained
  event_time TEXT DEFAULT (datetime('now')),
  metadata TEXT -- JSON
);

-- Purchases
CREATE TABLE purchases (
  id TEXT PRIMARY KEY,
  contact_id TEXT NOT NULL,
  product_name TEXT,
  amount REAL,
  currency TEXT DEFAULT 'USD',
  purchase_date TEXT,
  completion_status TEXT DEFAULT 'enrolled',
  cohort TEXT,
  certificate_issued INTEGER DEFAULT 0,
  referral_contact_id TEXT,
  FOREIGN KEY (contact_id) REFERENCES contacts(id)
);

-- Orchestrator Queue
CREATE TABLE queue_items (
  id TEXT PRIMARY KEY,
  contact_id TEXT NOT NULL,
  queue_type TEXT, -- reply / hot-lead / complaint / vip / dormant / onboarding
  priority INTEGER DEFAULT 3, -- 1=urgent, 2=high, 3=normal
  title TEXT,
  description TEXT,
  assigned_to TEXT,
  status TEXT DEFAULT 'open', -- open / in-progress / resolved / escalated
  created_at TEXT DEFAULT (datetime('now')),
  due_by TEXT,
  resolved_at TEXT,
  FOREIGN KEY (contact_id) REFERENCES contacts(id)
);

Workers Architecture (The Nervous System)

Worker 1 — Resend Webhook Receiver

// workers/email-events.js
// Receives open/click/bounce/reply events from Resend
// Writes to email_events table
// Updates contact lead_score
// Triggers status changes
// Creates queue items if reply detected

export default {
  async fetch(request, env) {
    const payload = await request.json();
    
    // Verify Resend webhook signature
    // Write event to D1
    // If event_type === 'opened' → score +5
    // If event_type === 'clicked' → score +10
    // If event_type === 'replied' → score +20, create queue item
    // If event_type === 'complained' → unsubscribe contact
    // Advance campaign_contacts to next step if applicable
    
    return new Response('ok');
  }
}

Worker 2 — Sequence Engine (Cron)

// workers/sequence-runner.js
// Runs every hour via Cron Trigger
// Checks campaign_contacts for contacts due for next step
// Pulls sequence step body and subject
// Personalizes with contact data
// Sends via Resend API
// Logs to email_events and interactions

// Cron schedule in wrangler.toml:
// [triggers]
// crons = ["0 * * * *"]  ← every hour

Worker 3 — Lead Scorer (Cron Daily)

// workers/lead-scorer.js
// Runs daily
// Recalculates scores based on:
//   - Email engagement in last 30 days
//   - Purchase history
//   - Training completion
//   - Days since last contact (decay)
// Updates contacts.lead_score
// Promotes or demotes lead_status
// Creates queue items for Hot leads

Worker 4 — Queue Builder (Cron Daily)

// workers/queue-builder.js
// Runs every morning at 7am
// Finds contacts that are:
//   - Hot with no activity in 3 days → flag
//   - Customers who never logged in → flag
//   - VIP with no touch in 14 days → flag
//   - Dormant (90 days) → re-engagement sequence
// Creates queue_items for orchestrators
// Assigns based on orchestrator workload

Worker 5 — API Layer (for your PWA Dashboard)

// workers/api.js
// REST API that your Pages PWA calls
// Endpoints:
// GET  /api/contacts
// GET  /api/contacts/:id
// POST /api/contacts
// PUT  /api/contacts/:id
// GET  /api/queue
// PUT  /api/queue/:id/resolve
// GET  /api/campaigns
// GET  /api/analytics/funnel
// GET  /api/analytics/campaign/:id

Analytics and Reporting — Your Options Mapped

Option 1: Google Looker Studio (formerly Data Studio)

How it works:

The pattern:

D1 → Worker (daily cron) → Google Sheets API → Looker Studio

Best for: Sharing reports with stakeholders, basic funnel views, campaign comparisons

Limitation: Not real-time. One step removed from your source of truth.


Option 2: Analytics Engine (Cloudflare Native)

Cloudflare has its own Analytics Engine — it's a time-series data store built into Workers.

// Inside any worker, write analytics events:
env.ANALYTICS.writeDataPoint({
  blobs: ['email_opened', campaign_id, contact_id],
  doubles: [lead_score],
  indexes: [contact_id]
});

Then query it via the Analytics Engine GraphQL API and render in your Pages PWA.

Best for: Real-time event data, high volume, keeping everything on Cloudflare


Option 3: PWA Dashboard on Cloudflare Pages

This is your cleanest long-term play.

Cloudflare Pages (React/Vue PWA)
    ↓ calls
Workers API (/api/analytics/*)
    ↓ queries
D1 database
    ↓ renders
Charts (Chart.js or Recharts)

Your orchestrators log into your Pages PWA. They see their queue. They resolve items. They see contact history. All data stays on Cloudflare. No third party sees your list.


Option 4: Observable / Metabase (Self-hosted BI)

If you want serious BI without building it yourself:


How People Actually Do This (Honest Survey)

Approach Who Uses It Tradeoff
HubSpot / Salesforce all-in Funded startups, enterprises Powerful but expensive, your data is their product
Airtable + Zapier + Mailchimp Early stage, non-technical founders Fast to start, hits walls at scale, expensive per row
Notion + Make + ConvertKit Solo operators, coaches Good for small lists, not real CRM
Custom on Supabase + Resend Technical indie builders Postgres, great ecosystem, but you pay Supabase
Custom on Cloudflare D1 + Workers + Resend Serious builders who want sovereignty What you're building. Correct choice at your goals
Google Sheets as database Scrappy early stage Works until it doesn't. 10k rows and it breaks
Looker Studio for analytics Everyone who wants free dashboards Industry standard for free BI on top of Sheets/BigQuery

The Recommended Build Sequence for You

Right Now — Airtable Phase

Phase 2 — Cloudflare Foundation (4–8 weeks)

1. Create D1 database with schema above
2. Build Worker API (read/write contacts)
3. Build Resend webhook receiver Worker
4. Migrate contacts from Airtable CSV → D1
5. Send first campaign via Worker + Resend

Phase 3 — Intelligence Layer (8–16 weeks)

1. Lead scoring Worker (cron daily)
2. Sequence engine Worker (cron hourly)
3. Queue builder Worker (cron daily)
4. Basic Pages PWA with queue UI

Phase 4 — Analytics Layer

1. Analytics Engine for real-time events
2. Daily summary Worker → Google Sheets
3. Looker Studio dashboard on top of Sheets
4. Eventually replace Looker with PWA charts

The Wrangler Config That Ties It Together

# wrangler.toml
name = "training-house-crm"
main = "src/index.js"
compatibility_date = "2024-01-01"

[[d1_databases]]
binding = "DB"
database_name = "crm"
database_id = "your-d1-id"

[[kv_namespaces]]
binding = "CACHE"
id = "your-kv-id"

[[r2_buckets]]
binding = "STORAGE"
bucket_name = "crm-assets"

[[queues.producers]]
binding = "EMAIL_QUEUE"
queue = "email-send-queue"

[[queues.consumers]]
queue = "email-send-queue"
max_batch_size = 10

[triggers]
crons = [
  "0 * * * *",    # sequence runner - every hour
  "0 7 * * *",    # queue builder - every morning 7am
  "0 2 * * *

---

*Session cost: $0.10644*