# B2B Cold Email Sequence Writer — AI Multi-Touch Cadence (`fuze/b2b-cold-outreach-sequencer`) Actor

Give it target domains, what you sell and your sender identity. For each company AI writes a complete multi-touch cold-email sequence — subjects, bodies, timing and a breakup email, grounded in a real fact. Drafts only; never sends.

- **URL**: https://apify.com/fuze/b2b-cold-outreach-sequencer.md
- **Developed by:** [Fredrik Hansson](https://apify.com/fuze) (community)
- **Categories:** Lead generation, AI
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $88.00 / 1,000 sequence generateds

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

## B2B Cold Email Sequence Writer — AI Multi-Touch Cadence

**Stop writing one email at a time. Give it a list of target companies and it writes the whole cold-email sequence for each — subject lines, bodies, timing, and a breakup email — personalized and grounded in a real fact about that company. Drafts only. You review and send from your own tool.**

A single opener gets you one shot. Deals come from the *follow-up*. This Actor turns target company domains + what you sell + who you are into a complete multi-touch **outbound cadence** per company: each email personalized, spaced out over days, each with its own angle, ending in a polite last-attempt email. It never sends anything — it hands you ready-to-paste drafts.

![B2B Cold Email Sequence Writer — AI Multi-Touch Cadence — input and sample output](https://datatools-hub.vercel.app/actor-shots/b2b-cold-outreach-sequencer.png)

### 🔗 Chain it after your scraper

Already building prospect lists with **[Google Maps Scraper (`compass/crawler-google-places`)](https://apify.com/compass/crawler-google-places)**, **[Google Maps Email Extractor (`lukaskrivka/google-maps-with-contact-details`)](https://apify.com/lukaskrivka/google-maps-with-contact-details)** or **[LinkedIn Profile Search Scraper (`harvestapi/linkedin-profile-search`)](https://apify.com/harvestapi/linkedin-profile-search)**? Pipe the dataset straight in — paste its dataset ID (via the Integrations tab) and get a full, personalized multi-touch cold-email cadence per company, ready to paste into your sending tool. Works with any Maps, LinkedIn or company scraper's output.

### Quick start

1. **Fill in the input** — set the fields in the input tab (prefilled with a working example).
2. **Click Start** — the Actor runs and writes one record per item to the dataset.
3. **Get your data** — export to **JSON, CSV or Excel**, or pull it via the API.

***

### The flow

```
  domains + what you sell          enrich each company            AI writes an N-touch cadence          finished drafts
  + sender identity          →     (real firmographics,      →    (intro · proof · case study ·   →    per company: subjects,
                                    ICP fit — optional)            breakup) grounded in a fact          bodies, timing, plain text
```

1. **You give it** target company domains, a one-line description of your offer, and your sender name + company.
2. **It (optionally) enriches** each company via [`fuze/ai-company-enrichment`](https://apify.com/fuze/ai-company-enrichment) so personalization is grounded in a real, verifiable firmographic fact and an ICP-fit read — not a guess.
3. **AI writes the full cadence** for each company: a personalized intro, varied middle touches (social proof, a relevant use case / mini case study, a light follow-up), and a polite **breakup** email, with sensible day-by-day timing.
4. **You get drafts** — one complete sequence per company, as structured `touches` *and* as clean copy-paste plain text. Nothing is sent.

***

### What you get per company

For every company, the Actor returns:

1. **`touches`** — the whole cadence as an array (one object per email), each with:
   - `step` — 1-based position in the sequence.
   - `dayOffset` — cumulative days from day 0 (e.g. `0, 3, 7, 12`), so you know exactly when to send each.
   - `channel` — always `"email"`.
   - `subject` — a short, specific, non-spammy subject line.
   - `body` — a 50–125 word email with one clear call to action, no hype.
   - `purpose` — the touch's job (e.g. `"intro + value"`, `"social proof"`, `"case study"`, `"breakup"`).
2. **The last touch is always a polite breakup / last-attempt email** that closes the loop gracefully.
3. **`personalizationBasis`** — the single real fact the cadence is anchored on (or `"generic — no enrichment data"` when none was available).
4. **`icpFitNote`** — one sentence on why they're a fit (from the enrichment ICP read), or `null`.
5. **`sequencePlain`** — the entire cadence as clean plain text, ready to copy into your sequencing tool, with no markdown fluff.
6. **`enrichmentUsed`** — whether real firmographics actually informed this sequence.

The model only uses facts it's given — it will **not invent** specifics about a company.

***

### Three ways people use it

- **SDRs & outbound sales teams** — generate a whole **multi-touch campaign** for a target account list in one run: personalized **sales follow-up emails** with built-in timing, ready to load into Instantly, Smartlead, Lemlist, Clay, Apollo or HubSpot. Personalization **at scale**, without writing each **cold email sequence** by hand.
- **Founders doing their own outbound** — paste the ten accounts you actually want, get a complete **outbound cadence** for each, grounded in something real about them, and spend your time replying instead of drafting.
- **Agencies running cold email for clients** — spin up a fresh, on-brand cadence per client offer across hundreds of prospects. Consistent structure, varied angles, and a clean breakup email every time — **drafts only, so you (and the client) stay in control** of what actually goes out.

***

### Input

| Field | Type | Default | Notes |
|---|---|---|---|
| `domains` | `string[]` | `["stripe.com","notion.so"]` | Target company domains, URLs or emails (one per line). |
| `offering` | `string` | — **(required)** | What you sell — drives every touch. |
| `senderName` | `string` | — **(required)** | Your name, used to sign the emails. |
| `senderCompany` | `string` | — **(required)** | The company you're reaching out on behalf of. |
| `numberOfTouches` | `integer` | `4` | Emails in the cadence (min 2, max 7). Last one is always the breakup. |
| `tone` | `string` | `friendly, concise, no hype` | Email tone. |
| `outputLanguage` | `string` | `en` | Language for all subjects and bodies. |
| `useEnrichment` | `boolean` | `true` | Ground personalization in real firmographics + ICP fit. |
| `maxResults` | `integer` | `50` | Max companies (one charge each). Max 1000. |
| `maxConcurrency` | `integer` | `4` | Companies written in parallel. Max 15. |
| `model` | `string` | `gpt-4o-mini` | OpenAI model. |

#### Minimal input example

```json
{
  "domains": ["stripe.com", "notion.so"],
  "offering": "We sell a SOC2 compliance automation platform for SaaS companies.",
  "senderName": "Fredrik Hansson",
  "senderCompany": "Fuze",
  "numberOfTouches": 4
}
```

***

### Output example

```json
{
  "domain": "stripe.com",
  "companyName": "Stripe",
  "personalizationBasis": "Stripe sells payments infrastructure to internet businesses, so audited security posture is core to its customers.",
  "icpFitNote": "A large payments platform whose customers demand strong, continuously-audited compliance — a natural fit for compliance automation.",
  "enrichmentUsed": true,
  "touches": [
    {
      "step": 1,
      "dayOffset": 0,
      "channel": "email",
      "subject": "SOC2 evidence, minus the screenshots",
      "body": "Hi — Stripe's customers lean hard on your security posture, which usually means a lot of manual evidence-gathering at audit time. We automate SOC2 evidence collection and control monitoring so teams stop screenshotting. Worth a quick look to see if it saves your team a week each cycle?\n\nBest,\nFredrik Hansson, Fuze",
      "purpose": "intro + value"
    },
    {
      "step": 2,
      "dayOffset": 3,
      "channel": "email",
      "subject": "How teams your size cut audit prep",
      "body": "Following up — teams running continuous compliance usually cut audit prep from weeks to days once evidence is collected automatically. Happy to share how a similar platform team set it up. Open to a 15-minute walkthrough next week?\n\nFredrik",
      "purpose": "social proof"
    },
    {
      "step": 3,
      "dayOffset": 7,
      "channel": "email",
      "subject": "A quick before/after",
      "body": "One more useful data point: a SaaS team we work with went from manual quarterly evidence pulls to always-on monitoring, and passed their renewal with zero last-minute scramble. If that's a pain for your team, I can send the short write-up. Want it?\n\nFredrik",
      "purpose": "case study"
    },
    {
      "step": 4,
      "dayOffset": 12,
      "channel": "email",
      "subject": "Should I close the loop?",
      "body": "I don't want to crowd your inbox, so this is my last note. If automating SOC2 evidence isn't a priority right now, no problem at all — just let me know and I'll step back. If timing changes down the line, I'm easy to reach.\n\nThanks for reading,\nFredrik Hansson, Fuze",
      "purpose": "breakup"
    }
  ],
  "sequencePlain": "Day 0 — Subject: SOC2 evidence, minus the screenshots\nHi — Stripe's customers lean hard on your security posture... \n\nDay 3 — Subject: How teams your size cut audit prep\nFollowing up — teams running continuous compliance... \n\nDay 7 — Subject: A quick before/after\nOne more useful data point... \n\nDay 12 — Subject: Should I close the loop?\nI don't want to crowd your inbox, so this is my last note..."
}
```

***

### Pay-per-event pricing

This Actor uses **pay-per-event** billing with a single event:

| Event | Price | Charged when |
|---|---|---|
| `sequence-generated` | **$0.20** | Once per company turned into a complete personalized multi-touch cold-email sequence. Covers the optional enrichment and the AI drafting of every touch. |

The Actor logs its OpenAI token usage and estimated AI cost at the end of every run, so the event price always stays safely above the model cost.

***

### Setup

The AI layer calls the OpenAI API. Set the environment variable / secret **`OPENAI_API_KEY`** on the Actor. Without it, the run stops with a clear error.

***

### Compliance

This Actor **generates drafts only — it never sends any email.** You review every sequence and send it from your own outreach tool, so you remain in control of consent, sending volume, local anti-spam law (GDPR / CAN-SPAM / PECR) and deliverability. Treat the output as a first draft to edit, not a send button.

***

### Use it from an AI agent (Apify MCP server)

This Actor is available through the [Apify MCP server](https://mcp.apify.com), so AI agents (Claude, ChatGPT, or anything that speaks MCP) can call it as a tool — hand it `domains`, `offering` and your sender identity, and read back a complete cold-email cadence per company — with no custom integration code.

***

### Run it locally

```bash
npm install
## put your input in storage/key_value_stores/default/INPUT.json
export OPENAI_API_KEY=sk-...   # required — powers the cadence writing
apify run -p
```

***

### Related actors

- [AI Cold Email Personalizer](https://apify.com/fuze/ai-cold-email-personalizer) — the single-opener sibling: one personalized hook, subject and draft per prospect.
- [AI Company Enrichment](https://apify.com/fuze/ai-company-enrichment) — turn domains into structured firmographics, contacts and ICP fit (the enrichment layer this Actor uses).
- [B2B Intent Radar](https://apify.com/fuze/b2b-intent-radar) — surface accounts showing buying intent before you reach out.
- [Email Finder](https://apify.com/fuze/email-finder-scraper) — find the addresses to send your finished sequence to.

# Actor input Schema

## `domains` (type: `array`):

Company domains, website URLs or emails (the domain is extracted). One per line.

## `offering` (type: `string`):

Describe what you offer, so every touch connects to each prospect. Required.

## `senderName` (type: `string`):

Your name, used to sign the emails. Required.

## `senderCompany` (type: `string`):

The company you are reaching out on behalf of. Required.

## `datasetId` (type: `string`):

Optional. Read the domains from a previous Actor run's dataset — for no-code chaining via the Integrations tab.

## `datasetField` (type: `string`):

Which dataset field holds the domain/URL. Leave blank to auto-detect (domain, website, companyDomain, url, companyUrl).

## `numberOfTouches` (type: `integer`):

How many emails in the cadence. The last one is always a polite breakup / last-attempt email.

## `tone` (type: `string`):

e.g. friendly, direct, formal.

## `outputLanguage` (type: `string`):

Language for all subjects and bodies (e.g. en, sv, de).

## `useEnrichment` (type: `boolean`):

If on, enrich each company first (via fuze/ai-company-enrichment) so personalization is grounded in a real company fact + ICP fit.

## `maxResults` (type: `integer`):

Max companies to turn into sequences. One pay-per-event charge per company.

## `maxConcurrency` (type: `integer`):

How many companies to write sequences for in parallel.

## `model` (type: `string`):

Override the model (default gpt-4o-mini).

## Actor input object example

```json
{
  "domains": [
    "stripe.com",
    "notion.so"
  ],
  "offering": "We sell a SOC2 compliance automation platform for SaaS companies.",
  "senderName": "Fredrik Hansson",
  "senderCompany": "Fuze",
  "numberOfTouches": 4,
  "tone": "friendly, concise, no hype",
  "outputLanguage": "en",
  "useEnrichment": true,
  "maxResults": 50,
  "maxConcurrency": 4,
  "model": "gpt-4o-mini"
}
```

# Actor output Schema

## `sequences` (type: `string`):

All generated cold-email sequences in the default dataset.

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "domains": [
        "stripe.com",
        "notion.so"
    ],
    "offering": "We sell a SOC2 compliance automation platform for SaaS companies.",
    "senderName": "Fredrik Hansson",
    "senderCompany": "Fuze"
};

// Run the Actor and wait for it to finish
const run = await client.actor("fuze/b2b-cold-outreach-sequencer").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = {
    "domains": [
        "stripe.com",
        "notion.so",
    ],
    "offering": "We sell a SOC2 compliance automation platform for SaaS companies.",
    "senderName": "Fredrik Hansson",
    "senderCompany": "Fuze",
}

# Run the Actor and wait for it to finish
run = client.actor("fuze/b2b-cold-outreach-sequencer").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "domains": [
    "stripe.com",
    "notion.so"
  ],
  "offering": "We sell a SOC2 compliance automation platform for SaaS companies.",
  "senderName": "Fredrik Hansson",
  "senderCompany": "Fuze"
}' |
apify call fuze/b2b-cold-outreach-sequencer --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,fuze/b2b-cold-outreach-sequencer"
        }
    }
}
```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/AqIVPl2VPcSkiSDbp/builds/u3yeUrvtWuVEJ4BXH/openapi.json
