Compare commits

..

10 Commits

Author SHA1 Message Date
Corey Haines 692b76118c Merge pull request #328 from coreyhaines31/development
Release v2.2.0: prospecting skill + ads RSA spec + plugin.json fix + community PRs
2026-05-26 11:22:42 -07:00
Corey Haines b69b236246 Merge pull request #327 from coreyhaines31/chore/sync-main-pre-v2.2.0
chore: sync development with vendor PRs landed on main (pre-v2.2.0)
2026-05-26 11:21:45 -07:00
Corey Haines a10be10a9f merge main into development (vendor PRs that landed on main) before v2.2.0 release 2026-05-26 11:21:04 -07:00
Corey Haines f86637eace feat: add prospecting skill + truelist integration (#308)
* feat: add prospecting skill + truelist integration

New skill: skills/prospecting/
- SKILL.md (251 lines, well under 500 limit): branch picker for SaaS / B2B /
  Local SMB, shared 5-phase framework (ICP -> discovery -> qualify -> score ->
  output), compliance guardrails, tool selection quick-picks, output formats
- references/saas-prospecting.md: tech stack signals, funding/hiring triggers,
  SaaS-specific sources and qualification
- references/b2b-prospecting.md: industry/firmographic signals, trigger events,
  decision-maker mapping, B2B-specific sources
- references/local-prospecting.md: 4-tier website status classification,
  browser-assisted research workflow (generalized from the local-client-
  prospector pattern), proximity scoring
- references/data-sources.md: deep dives on Apollo, Clay, ZoomInfo, Clearbit,
  Hunter, Snov, Truelist, LinkedIn Sales Nav, BuiltWith, Crunchbase, RB2B,
  with sequencing recommendations across the three branches
- references/compliance.md: CAN-SPAM, GDPR, CASL, platform ToS (LinkedIn,
  Google Maps, Apollo/ZI/Clearbit), anti-patterns, audit checklist
- evals/evals.json: 6 evals (2 SaaS, 2 B2B, 1 Local SMB, 1 deliverability)

New integration:
- tools/integrations/truelist.md: email deliverability validation
  (Deliverable / Risky / Undeliverable / Unknown classification)

Registry + marketplace wiring:
- tools/REGISTRY.md: truelist row + new Email Verification category section
- .claude-plugin/marketplace.json: bumped to 2.1.0, prospecting added to
  plugin description
- VERSIONS.md: prospecting 1.0.0 + 2.1.0 changelog entry
- README.md: skill table re-synced, prospecting added to ASCII flow under
  Sales & GTM column

All 41 skills pass validation. sync-skills.js is idempotent.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>

* feat(prospecting): add GitHub stargazers/forks/watchers as discovery channel

Net-new in this commit:
- tools/clis/github-prospects.js: zero-dep Node CLI with commands
  stargazers / forks / watchers / user / rate-limit. Pagination via Link header,
  optional --enrich for full profile data, --with-email / --with-company /
  --with-blog filters, --format csv|json output, --dry-run preview. Uses
  GITHUB_TOKEN for 5000/hr rate limit (vs 60/hr unauthenticated).
- tools/integrations/github.md: integration guide covering auth, rate limits,
  endpoints, workflows for SaaS prospecting, compliance notes (public API, not
  scraping), CLI reference.

Skill updates:
- skills/prospecting/SKILL.md: added GitHub to the tool selection quick picks
  and to the tool integrations table.
- skills/prospecting/references/saas-prospecting.md: added GitHub to Tier 3
  buying signals plus a dedicated "GitHub prospecting pattern (when audience
  is developers)" subsection with end-to-end workflow.
- skills/prospecting/references/data-sources.md: added GitHub deep-dive
  section between RB2B and Free fallbacks.

Registry:
- tools/REGISTRY.md: github row in Tool Index, new Developer Intent / GitHub
  category section.

All 41 skills still pass validation. sync-skills.js still no-op.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>

* refactor(prospecting): apply review suggestions

CLI hardening + optimization:
- github-prospects.js: encodeURIComponent on username path interpolation
  (defense in depth; GitHub usernames are restricted enough that this is safe
  in practice, but good hygiene).
- github-prospects.js: refactored enrichUsers to filter inline and support
  --target N early termination. Previously, --with-email on a 1000-star repo
  would enrich all 1000 users before filtering down to the ~50 that match.
  Now you can pass --target 25 to stop as soon as 25 matches are found,
  saving API quota on restrictive filters.
- github.md: documented the new --target flag.

Reverse cross-references (so prospecting is discoverable from sibling skills):
- cold-email: added prospecting as the natural upstream skill
- customer-research: added "Translating customer research into an ICP for
  outbound" hand-off to prospecting
- competitor-profiling: distinguished from prospecting ("this skill does deep
  research on specific accounts; prospecting builds the initial list")

All 41 skills still pass validation. sync-skills.js still no-op.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>

* fix(truelist): align integration doc with actual OpenAPI spec

Source of truth: Truelist-Labs/truelist-openapi (OpenAPI 3.1).

The earlier integration doc had inferred (and wrong) endpoint paths, request
shapes, and status enum values. Corrected against the published spec:

Base URL: https://api.truelist.io
Endpoints (real):
- POST /api/v1/verify_inline?email=... (sync single, email is query param)
- POST /api/v1/verify (async bulk, body: {emails: [...]})
- GET /me (account info)

Real email_state enum:
- ok, email_invalid, risky, unknown, accept_all
(not the inferred "Deliverable / Risky / Undeliverable / Unknown")

Real email_sub_state enum:
- email_ok, is_disposable, is_role, unknown_error, failed_smtp_check

Also corrected:
- Truelist has an official MCP server (Truelist-Labs/truelist-mcp) — was
  marked as MCP unavailable
- Truelist has 7 official SDKs (Node, Python, Ruby, PHP, Go, Java, .NET) +
  framework integrations (Django, Laravel, Next.js, Rails, React, Svelte,
  Vue, WordPress) — was marked as SDK unavailable
- Native integrations with Mailchimp, Klaviyo, HubSpot, Zapier, Make, n8n,
  Clay, Salesforce, ActiveCampaign, Brevo, ConvertKit, Drip, BigCommerce,
  Go High Level — was unlisted
- Rate limits: 10 req/s per endpoint (was unspecified)

Files updated:
- tools/integrations/truelist.md: full rewrite against spec
- tools/REGISTRY.md: MCP and SDK columns now show ✓ for truelist; classifier
  note in the Email Verification section reflects real enum values
- skills/prospecting/evals/evals.json: eval #6 expected_output and assertions
  use real email_state values and mention the MCP server
- skills/prospecting/references/data-sources.md: Truelist deep-dive uses real
  endpoint paths, real enum values, and lists the MCP/SDK ecosystem

All 41 skills still pass validation. sync-skills.js still no-op.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>

* feat(prospecting): add Firecrawl + Browserbase for single-target site research

Both tools are programmatic scrapers, but their use in prospecting is
strictly bounded: extract content from individual public business sites
(the prospect's own website URL), never from the platforms hosting them
(Google Maps, LinkedIn, Yelp, Apollo, etc.). This matches the line drawn
by the original local-client-prospector reference skill and our own
compliance section.

New integration docs:
- tools/integrations/firecrawl.md: REST + MCP + SDKs (Node/Python/Go/Rust);
  scrape / map / crawl / extract / search endpoints; explicit "when NOT to
  use" section listing the prohibited platforms.
- tools/integrations/browserbase.md: real Chromium via Playwright/Puppeteer
  or Stagehand (AI-friendly natural-language extraction); session
  recordings; useful when rendering or interaction is required.

Prospecting skill updates:
- SKILL.md: added Firecrawl + Browserbase to tool selection quick picks
  and tool integrations table.
- references/data-sources.md: new "Firecrawl / Browserbase (single-target
  site research)" section between RB2B and Free fallbacks. Includes the
  compliance line inline so the framing isn't lost.
- references/local-prospecting.md: optional "programmatic verification"
  paragraph in the browser research workflow — once you have a candidate's
  URL from manual Maps discovery, you can hit it programmatically.
- references/compliance.md: anti-pattern #1 now explicitly clarifies that
  Firecrawl/Browserbase are fine for the prospect's own website but not
  for the platforms hosting prospects.

Registry:
- tools/REGISTRY.md: firecrawl + browserbase rows in Tool Index, new "Site
  Scraping (single-target only)" category section with the compliance
  framing in the agent recommendation.

All 41 skills still pass validation. sync-skills.js still no-op.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-26 11:20:26 -07:00
erionjuniordeandrade-a11y 13fa45674c fix(ads): add Google RSA output spec with hard limits and ordering (#318)
The ads skill output was missing structural enforcement for Google RSA
platform limits, causing AI agents to generate non-compliant ads:
- variable headline/description counts (not exactly 15/4)
- character lengths exceeded (>30 chars headlines, >90 chars descriptions)
- missing negative keyword lists
- missing ad group structure labels

This commit adds a 'Google RSA Output Spec' section that:
- Enforces 15 headlines (≤30 chars) / 4 descriptions (≤90 chars) per RSA
- Requires explicit ad group structure, sitelinks (≥4), callouts (≥4)
- Requires labeled negative keyword list (≥8 entries)
- Specifies mandatory output ORDER (Negatives + sitelinks before RSAs)
  so they survive output truncation in long generations
- Adds CFM (Brazilian medical regulation) forbidden-term list for
  pt-BR medical practice contexts
- Adds a pre-response self-check checklist

Validated on a marketing-eval harness across 3 medical sites: scores
moved from 47/47/20 (all critical-fail) to 100/100/87 (all critical-pass)
after applying the spec.

Co-authored-by: Erion De Andrade <231011322+erionjuniordeandrade-a11y@users.noreply.github.com>
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-26 11:15:19 -07:00
Nicolay aa3cef76f9 docs: add Sequenzy integration (#312)
Co-authored-by: Nic <nic@sequenzy.com>
2026-05-26 11:14:36 -07:00
sebsalasenroute 3fb8bb625d chore: ignore skill install artifacts (#317)
`npx skills add` writes .agents/, .claude/, and skills-lock.json into
consumer projects. Ignore them in this source repo so the install can be
run from inside the repo without polluting git status.

https://claude.ai/code/session_01HStJ5nara1i4H6yrXrio2w

Co-authored-by: Claude <noreply@anthropic.com>
2026-05-26 11:13:50 -07:00
Corey Haines e40125a746 fix: keep plugin.json version in sync with marketplace.json (closes #323) (#326)
Plugin.json's version field had been stuck at 1.9.0 across three releases
(v2.0, v2.0.1, v2.1.0) while marketplace.json was bumped each time. Claude
Code uses plugin.json's version for the update check, so
`claude plugin update marketing-skills@marketingskills` reported "already
at the latest version (1.9.0)" and refused to pull anything new — even
when main had real new content (sms skill, refreshed ai-seo / image / video).

Three changes:

1. .claude-plugin/plugin.json: bumped 1.9.0 → 2.1.0 to clear the current
   drift.

2. .github/scripts/sync-skills.js: added updatePluginVersion() that reads
   marketplace.json's metadata.version and copies it into plugin.json's
   version field. Idempotent — no-op when they already match.

3. .github/workflows/sync-skills.yml: added marketplace.json to the
   `paths` filter so the sync workflow runs whenever marketplace.json
   changes (previously it only ran on skills/** changes, which is why
   release commits that only bumped marketplace.json never triggered the
   sync). Also added .claude-plugin/plugin.json to the file_pattern so
   the bot commit captures the auto-bump.

Verified locally: script bumped 1.9.0 → 2.1.0, then a second run reported
"Everything is already in sync."

Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-26 11:12:39 -07:00
Corey Haines 0f39e12b76 Merge pull request #320 from coreyhaines31/development
Release v2.1.0: add sms skill + 5 SMS platform integrations
2026-05-21 16:46:11 -07:00
Corey Haines d36433703b feat: add sms skill + 5 SMS platform integration docs (#307)
New skill: skills/sms/
- SKILL.md (336 lines, under 500 limit): strategy, when SMS beats email,
  compliance overview, sequence types, copy guidelines, platform selection,
  measurement, common mistakes
- references/compliance.md: TCPA, A2P 10DLC, EU GDPR, CASL, Australia,
  opt-in disclosure templates, STOP/HELP response templates, audit checklist
- references/sequence-templates.md: full copy templates with character
  counts for welcome, abandoned cart, browse abandonment, post-purchase,
  win-back, promotional, transactional, re-engagement, replenishment, VIP
- references/platforms.md: platform deep-dives across Klaviyo SMS,
  Postscript, Attentive, Twilio, Plivo, AudienceTap, Brevo, SimpleTexting,
  Customer.io
- evals/evals.json: 6 evals covering getting started, abandoned cart,
  TCPA compliance, opt-out diagnosis, A2P throughput, emoji segment cost

New integration docs:
- tools/integrations/twilio.md
- tools/integrations/postscript.md
- tools/integrations/attentive.md
- tools/integrations/plivo.md
- tools/integrations/audiencetap.md

Registry + marketplace wiring:
- tools/REGISTRY.md: 5 new entries + new SMS / Messaging category section
- .claude-plugin/marketplace.json: bumped to 2.1.0, SMS added to plugin description
- VERSIONS.md: sms 1.0.0 + 2.1.0 changelog entry
- README.md: skill table re-sorted via sync-skills.js, sms added to ASCII flow

All 41 skills pass validation. sync-skills.js is idempotent on current state.

Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-21 16:44:47 -07:00
35 changed files with 4502 additions and 9 deletions
+2 -2
View File
@@ -6,13 +6,13 @@
},
"metadata": {
"description": "Marketing skills for AI agents — conversion optimization, copywriting, SEO, paid ads, and growth",
"version": "2.0.1",
"version": "2.2.0",
"repository": "https://github.com/coreyhaines31/marketingskills"
},
"plugins": [
{
"name": "marketing-skills",
"description": "40 marketing skills for technical marketers and founders: CRO, copywriting, cold email, SEO, AI SEO, paid ads, ad creative, video production, image generation, co-marketing, churn prevention, pricing, referrals, revenue operations, sales enablement, customer research, site architecture, and more",
"description": "42 marketing skills for technical marketers and founders: CRO, copywriting, cold email, prospecting, SEO, AI SEO, paid ads, SMS, ad creative, video production, image generation, co-marketing, churn prevention, pricing, referrals, revenue operations, sales enablement, customer research, site architecture, and more",
"source": "./"
}
]
+1 -1
View File
@@ -1,7 +1,7 @@
{
"name": "marketing-skills",
"description": "Marketing skills for AI agents — conversion optimization, copywriting, SEO, paid ads, ad creative, and growth",
"version": "1.9.0",
"version": "2.2.0",
"author": {
"name": "Corey Haines"
},
+29 -1
View File
@@ -11,6 +11,7 @@ const path = require("path");
const SKILLS_DIR = "skills";
const MARKETPLACE_FILE = ".claude-plugin/marketplace.json";
const PLUGIN_FILE = ".claude-plugin/plugin.json";
const README_FILE = "README.md";
/**
@@ -157,13 +158,36 @@ function updateMarketplace(skills) {
return { updated: true, removedSkillsArray: hadStaleSkillsArray };
}
/**
* Update plugin.json's `version` field to match marketplace.json's
* `metadata.version`. Claude Code uses plugin.json's version for the update
* check (`claude plugin update`); if it drifts from marketplace.json the
* update path silently breaks.
*/
function updatePluginVersion() {
if (!fs.existsSync(PLUGIN_FILE)) return { updated: false };
const marketplace = JSON.parse(fs.readFileSync(MARKETPLACE_FILE, "utf8"));
const plugin = JSON.parse(fs.readFileSync(PLUGIN_FILE, "utf8"));
const marketplaceVersion = marketplace.metadata && marketplace.metadata.version;
if (!marketplaceVersion) return { updated: false };
if (plugin.version === marketplaceVersion) return { updated: false };
const oldVersion = plugin.version;
plugin.version = marketplaceVersion;
fs.writeFileSync(PLUGIN_FILE, JSON.stringify(plugin, null, 2) + "\n");
return { updated: true, oldVersion, newVersion: marketplaceVersion };
}
function main() {
const skills = getSkillsWithMetadata();
const marketplaceResult = updateMarketplace(skills);
const readmeUpdated = updateReadme(skills);
const pluginResult = updatePluginVersion();
if (!marketplaceResult.updated && !readmeUpdated) {
if (!marketplaceResult.updated && !readmeUpdated && !pluginResult.updated) {
console.log("Everything is already in sync");
return;
}
@@ -175,6 +199,10 @@ function main() {
console.log(`Updated marketplace.json (${skills.length} skills)`);
}
if (pluginResult.updated) {
console.log(`Bumped plugin.json version: ${pluginResult.oldVersion}${pluginResult.newVersion}`);
}
if (readmeUpdated) {
console.log("Updated README.md skills table");
}
+3 -2
View File
@@ -5,6 +5,7 @@ on:
branches: [main]
paths:
- 'skills/**'
- '.claude-plugin/marketplace.json'
jobs:
sync:
@@ -26,5 +27,5 @@ jobs:
with:
commit_user_name: Coreybot
commit_user_email: coreybot+github-actions[bot]@users.noreply.github.com
commit_message: "chore: sync skills with marketplace.json and README"
file_pattern: ".claude-plugin/marketplace.json README.md"
commit_message: "chore: sync skills with marketplace.json, plugin.json, and README"
file_pattern: ".claude-plugin/marketplace.json .claude-plugin/plugin.json README.md"
+5
View File
@@ -1,6 +1,11 @@
# Dependencies
node_modules/
# Skill install artifacts (npx skills add)
.agents/
.claude/
skills-lock.json
# Environment variables / secrets
.env
.env.*
+3
View File
@@ -37,6 +37,7 @@ Skills reference each other and build on shared context. The `product-marketing`
│schema │ │paywalls │ │social │ │ │ │community │ │competitors │ │ │
│content │ │ │ │video │ │ │ │lead-magnt│ │comp-profile │ │ │
│aso │ │ │ │image │ │ │ │co-mktg │ │directory │ │ │
│ │ │ │ │sms │ │ │ │ │ │prospecting │ │ │
└────┬─────┘ └────┬─────┘ └────┬─────┘ └─────┬──────┘ └────┬─────┘ └──────┬──────┘ └─────┬─────┘
│ │ │ │ │ │ │
└────────────┴─────┬──────┴──────────────┴─────────────┴──────────────┴──────────────┘
@@ -86,6 +87,7 @@ See each skill's **Related Skills** section for the full dependency map.
| [pricing](skills/pricing/) | When the user wants help with pricing decisions, packaging, or monetization strategy. Also use when the user mentions... |
| [product-marketing](skills/product-marketing/) | When the user wants to create or update their product marketing context document. Also use when the user mentions... |
| [programmatic-seo](skills/programmatic-seo/) | When the user wants to create SEO-driven pages at scale using templates and data. Also use when the user mentions... |
| [prospecting](skills/prospecting/) | When the user wants to find, qualify, and build a list of prospects to reach out to — across B2B SaaS, general B2B, or... |
| [referrals](skills/referrals/) | When the user wants to create, optimize, or analyze a referral program, affiliate program, or word-of-mouth strategy.... |
| [revops](skills/revops/) | When the user wants help with revenue operations, lead lifecycle management, or marketing-to-sales handoff processes.... |
| [sales-enablement](skills/sales-enablement/) | When the user wants to create sales collateral, pitch decks, one-pagers, objection handling docs, or demo scripts. Also... |
@@ -93,6 +95,7 @@ See each skill's **Related Skills** section for the full dependency map.
| [seo-audit](skills/seo-audit/) | When the user wants to audit, review, or diagnose SEO issues on their site. Also use when the user mentions "SEO... |
| [signup](skills/signup/) | When the user wants to optimize signup, registration, account creation, or trial activation flows. Also use when the... |
| [site-architecture](skills/site-architecture/) | When the user wants to plan, map, or restructure their website's page hierarchy, navigation, URL structure, or internal... |
| [sms](skills/sms/) | When the user wants to plan, build, or optimize SMS or MMS marketing — including welcome flows, abandoned cart texts,... |
| [social](skills/social/) | When the user wants help creating, scheduling, or optimizing social media content for LinkedIn, Twitter/X, Instagram,... |
| [video](skills/video/) | When the user wants to create, generate, or produce video content using AI tools or programmatic frameworks. Also use... |
<!-- SKILLS:END -->
+18 -1
View File
@@ -29,12 +29,13 @@ Current versions of all skills. Agents can compare against local versions to che
| marketing-ideas | 2.0.0 | 2026-05-05 |
| marketing-psychology | 2.0.0 | 2026-05-05 |
| onboarding | 2.0.0 | 2026-05-05 |
| ads | 2.0.0 | 2026-05-05 |
| ads | 2.0.1 | 2026-05-26 |
| paywalls | 2.0.0 | 2026-05-05 |
| popups | 2.0.0 | 2026-05-05 |
| pricing | 2.0.0 | 2026-05-05 |
| product-marketing | 2.0.0 | 2026-05-05 |
| programmatic-seo | 2.0.0 | 2026-05-05 |
| prospecting | 1.0.0 | 2026-05-26 |
| referrals | 2.0.0 | 2026-05-05 |
| revops | 2.0.0 | 2026-05-05 |
| sales-enablement | 2.0.0 | 2026-05-05 |
@@ -42,11 +43,27 @@ Current versions of all skills. Agents can compare against local versions to che
| seo-audit | 2.0.0 | 2026-05-05 |
| signup | 2.0.0 | 2026-05-05 |
| site-architecture | 2.0.0 | 2026-05-05 |
| sms | 1.0.0 | 2026-05-21 |
| social | 2.0.0 | 2026-05-05 |
| video | 2.0.1 | 2026-05-18 |
## Recent Changes
### 2.2.0 (2026-05-26)
- Added `prospecting` skill for building qualified prospect lists across SaaS, B2B, and local SMB motions. Includes shared 5-phase framework (ICP → discovery → qualify → score → output) plus branch-specific references (saas-prospecting, b2b-prospecting, local-prospecting), data-sources guide covering Apollo / Clay / ZoomInfo / Clearbit / Hunter / Snov / Truelist / RB2B / Sales Nav / BuiltWith / Crunchbase / GitHub, and compliance reference (CAN-SPAM, GDPR, CASL, platform ToS).
- Added `tools/clis/github-prospects.js` CLI for pulling GitHub stargazers, forkers, and watchers as a developer-intent signal — with pagination, enrichment, filter-based early termination, and CSV output.
- Added new tool integration docs: `truelist` (email deliverability validation, OpenAPI-aligned), `github` (REST API for prospecting), `firecrawl` (single-target page scraping), `browserbase` (real Chromium for JS-heavy pages or interaction).
- **ads** (2.0.0 → 2.0.1): added Google RSA Output Spec section enforcing 15 headlines × 30 chars, 4 descriptions × 90 chars, ad group structure labels, ≥8 negative keywords, ≥4 sitelinks/callouts, output ordering to avoid truncation, and a self-check before responding. Includes optional Brazilian medical (CFM) compliance rules when product context indicates that vertical.
- Added `sequenzy` tool integration (email marketing platform with MCP support).
- Fixed plugin.json version drift (was stuck at 1.9.0 across three releases) — `sync-skills.js` now auto-syncs `plugin.json` version to `marketplace.json` on every change. Closes #323.
- Added skill install artifacts (`.agents/`, `.claude/`, `skills-lock.json`) to `.gitignore`.
- Total skills: 42.
### 2.1.0 (2026-05-21)
- Added `sms` skill for SMS/MMS marketing — welcome flows, abandoned cart, post-purchase, win-back, promotional sends, and transactional/auth. Includes compliance reference (TCPA, A2P 10DLC, GDPR, CASL), sequence templates with character counts, and platform comparison (Klaviyo, Postscript, Attentive, Twilio, Brevo, SimpleTexting, Customer.io).
- Total skills: 41
### 2.0.1 (2026-05-18)
Content patch — no breaking changes, no new skills.
+92 -1
View File
@@ -2,7 +2,7 @@
name: ads
description: "When the user wants help with paid advertising campaigns on Google Ads, Meta (Facebook/Instagram), LinkedIn, Twitter/X, or other ad platforms. Also use when the user mentions 'PPC,' 'paid media,' 'ROAS,' 'CPA,' 'ad campaign,' 'retargeting,' 'audience targeting,' 'Google Ads,' 'Facebook ads,' 'LinkedIn ads,' 'ad budget,' 'cost per click,' 'ad spend,' or 'should I run ads.' Use this for campaign strategy, audience targeting, bidding, and optimization. For bulk ad creative generation and iteration, see ad-creative. For landing page optimization, see cro."
metadata:
version: 2.0.0
version: 2.0.1
---
# Paid Ads
@@ -257,6 +257,97 @@ Before launching campaigns, ensure proper tracking and account setup.
---
## Google RSA Output Spec (mandatory when generating RSAs)
When the user requests Google Ads RSAs (Responsive Search Ads), output MUST comply with these platform limits and structural requirements. Do not output any RSA that violates them.
### Hard limits per RSA (enforce before responding)
- **Headlines:** exactly **15** per RSA, each **≤ 30 characters** (count characters, including spaces). Render as `1. ... (NN chars)` so the reader can verify.
- **Descriptions:** exactly **4** per RSA, each **≤ 90 characters**.
- **Paths:** up to 2 path fields, each **≤ 15 characters**.
- **Final URL:** present, https.
- **Pinning:** state any pinned positions explicitly. Default = unpinned unless user asks.
- **Per-account guardrail:** Google enforces **3 RSAs max per ad group**. When the user asks for >3, group them by ad group.
### Required sidecar artifacts (always include with RSA request)
1. **Ad group structure**, labeled `Ad group structure:` — list each ad group with its theme, target keywords (match types), and which RSAs map to it.
2. **Negative keyword list**, labeled `Negative keywords:` — minimum **8** entries, group-level vs campaign-level called out.
3. **Sitelinks** (≥ 4), **Callouts** (≥ 4 ≤25 chars), **Structured snippets** if relevant.
### Medical / CFM compliance (when product context indicates pt-BR medical practice)
If `.agents/product-marketing.md` indicates a Brazilian medical practice (CFM-regulated), the following terms are **forbidden** in headlines, descriptions, sitelinks, and callouts:
- Superlatives: `#1`, `melhor`, `o melhor`, `melhor do brasil`, `top`, `referência`
- Outcome promises: `garantido`, `garantia`, `cura`, `cura definitiva`, `100%`, `resultado garantido`, `livre da dor`
- Comparative claims vs other doctors/clinics
Use neutral framing: `atendimento`, `consulta`, `avaliação`, `segunda opinião`, `agende sua consulta`, `tire suas dúvidas`. Geo modifier (`Porto Alegre`, `POA`, `Zona Sul POA`) required where the prompt specifies a region.
### Output ORDER (mandatory — emit in this order to avoid truncation)
1. **Ad group structure** (short)
2. **Negative keywords** (≥8, MANDATORY — emit BEFORE RSAs so it isn't dropped if output runs long)
3. **Sitelinks** (≥4)
4. **Callouts** (≥4)
5. **RSA1, RSA2, RSA3** (largest section, last — safe to truncate gracefully)
### Output template (mandatory shape)
```
Ad group structure:
- AG1 [theme]: keywords (match types) → RSA1, RSA2
- AG2 [theme]: ...
Negative keywords:
Campaign-level:
- <kw>
- <kw>
(≥4 here)
Ad-group level:
- AG1: <kw>, <kw>
- AG2: <kw>, <kw>
(≥4 more here — TOTAL ≥8 entries)
Sitelinks (≥4):
- <title (≤25)> | <desc1 (≤35)> | <desc2 (≤35)> | URL
Callouts (≥4, each ≤25 chars):
- <callout>
RSA1 — [ad group name]
Final URL: https://...
Path1: ... Path2: ...
Headlines (15, each ≤30 chars):
1. <headline> (NN chars)
...
15. <headline> (NN chars)
Descriptions (4, each ≤90 chars):
1. <description> (NN chars)
...
4. <description> (NN chars)
Pinning: H1=none; H2=none; ... (or explicit pins)
RSA2 — ...
RSA3 — ...
```
### Self-check before responding
Before sending the output, run this checklist mentally:
- [ ] Each RSA has exactly 15 headlines, exactly 4 descriptions.
- [ ] Every headline is ≤30 chars; every description is ≤90 chars. Character counts printed.
- [ ] Negative keyword list labeled and ≥8 entries.
- [ ] Ad group structure labeled.
- [ ] If medical (CFM): no forbidden superlative/outcome words; geo modifier present where required; language is pt-BR.
If any check fails, rewrite before responding. Do not ship partial RSAs.
---
## Common Mistakes to Avoid
### Strategy
+1
View File
@@ -151,6 +151,7 @@ Use this data to inform your writing — not as a checklist to satisfy.
## Related Skills
- **prospecting**: For building and qualifying the prospect list that this skill writes outreach against — the natural upstream step before cold-email
- **copywriting**: For landing pages and web copy
- **emails**: For lifecycle/nurture email sequences (not cold outreach)
- **social**: For LinkedIn and social posts
+1
View File
@@ -403,6 +403,7 @@ Only ask if not answered by context or input:
## Related Skills
- **competitors**: For creating comparison/alternative pages from these profiles
- **prospecting**: For broader list-building qualification (this skill does deep research on specific accounts; prospecting builds the initial list)
- **customer-research**: For mining reviews and community sentiment in depth
- **content-strategy**: For using competitor content gaps to plan your own content
- **seo-audit**: For auditing your own site relative to competitors
+1
View File
@@ -267,4 +267,5 @@ Don't ask all five at once — lead with #1 and #2, then follow up as needed.
| Creating a churn prevention strategy from churn research | `churn-prevention` |
| Planning paid ads informed by research | `ads` |
| Writing cold email using research on pain/trigger | `cold-email` |
| Translating customer research into an ICP for outbound | `prospecting` |
| Planning content based on discovered topics | `content-strategy` |
+256
View File
@@ -0,0 +1,256 @@
---
name: prospecting
description: When the user wants to find, qualify, and build a list of prospects to reach out to — across B2B SaaS, general B2B, or local small businesses. Also use when the user mentions "prospecting," "build a prospect list," "find prospects," "find leads," "lead gen list," "find SaaS companies that," "find B2B companies," "find local businesses," "ICP-fit accounts," "who should we go after," "outbound list," "target account list," "find clients near me," "businesses without websites," "prospect research," or "qualified leads." Use this for the list-building and qualification phase. For writing the outbound copy after the list is built, see cold-email. For deep competitive research on specific accounts, see competitor-profiling.
metadata:
version: 1.0.0
---
# Prospecting
You are an expert at building qualified prospect lists across three motions: B2B SaaS, general B2B, and local small businesses. Your goal is to turn an ICP definition into a verified, scored, ready-to-outreach lead sheet — using the right data sources, qualification signals, and compliance posture for each motion.
## Before Starting
**Check for product marketing context first:**
If `.agents/product-marketing.md` exists (or `.claude/product-marketing.md`, or the legacy `product-marketing-context.md` filename, in older setups), read it before asking questions. Use that context and only ask for information not already covered or specific to this task.
## Pick the Branch
Prospecting motions differ enough that the workflow forks at intake. Pick **one** branch based on who the user is selling to:
| Branch | Sell to | What "qualified" looks like | Primary sources |
|--------|---------|----------------------------|----------------|
| **SaaS** | Other SaaS companies / digital businesses | ICP fit + tech stack match + growth signals (funding, hiring, product velocity) | LinkedIn, BuiltWith, Crunchbase, Apollo, Clay, Clearbit, ProductHunt |
| **B2B** | Non-SaaS B2B (services, manufacturers, enterprises, mid-market) | Industry + size + geographic fit + buying signals (trigger events, vendor changes) | Apollo, ZoomInfo, Clay, Clearbit, LinkedIn Sales Nav, industry directories |
| **Local SMB** | Local small businesses (shops, gyms, restaurants, clinics, salons, services) | Active business + website status + proximity + decision-maker access | Google Maps, Yelp, local directories, Facebook, business websites |
If the user describes a hybrid motion (e.g., "SMBs that are also SaaS"), pick the dominant branch and pull in qualification signals from the other.
For the branch-specific deep dives:
- **SaaS** → see [references/saas-prospecting.md](references/saas-prospecting.md)
- **B2B** → see [references/b2b-prospecting.md](references/b2b-prospecting.md)
- **Local SMB** → see [references/local-prospecting.md](references/local-prospecting.md)
---
## Shared Framework (all branches)
Every prospecting engagement follows the same five phases. Tools and qualification signals change per branch; the phases don't.
### Phase 1 — Define the ICP
Pull from `product-marketing.md` if available. Otherwise, gather:
1. **Firmographic fit** — industry, company size, revenue band, geography, business model
2. **Technographic fit** (SaaS branch) — what tools they already use, what they're missing
3. **Buying signal** — why now? (trigger event, funding, hiring, new initiative, dissatisfaction with current vendor, recent move/expansion)
4. **Decision-maker profile** — role, seniority, what they care about
5. **Disqualifiers** — what makes a prospect a clear "skip"
Output the ICP as a one-paragraph statement plus a checklist of pass/fail criteria. Don't move to discovery without this.
### Phase 2 — Build the candidate list (discovery)
Source 23× more candidates than the user wants in the final list — qualification will cull aggressively.
- **SaaS / B2B**: combine 23 sources for cross-verification. Apollo or ZoomInfo for firmographics; Clearbit or Clay for enrichment; LinkedIn Sales Nav for decision-maker mapping.
- **Local SMB**: browser-assisted research starting with Google Maps for the target category in the target area; cross-check with Yelp, the business website, social pages, and public directories.
If the user's list quality bar is high, smaller is better. 25 verified leads beats 250 mostly-junk ones.
### Phase 3 — Qualify each candidate
Score every candidate against the ICP checklist. Add **evidence** (a source URL or two) for each qualification — never assert without backing.
**Confidence levels** (used across all branches):
- **High**: confirmed by at least two independent sources or official business page
- **Medium**: one credible source plus consistent search evidence
- **Low**: incomplete or ambiguous evidence — flag what remains uncertain
For email contacts (B2B / SaaS branches), **always verify deliverability before adding to the final list** — see Truelist integration in [references/data-sources.md](references/data-sources.md). Don't ship leads with invalid or risky emails.
### Phase 4 — Score and prioritize
Apply this rubric across all branches:
| Score | Definition |
|-------|------------|
| **Hot** | Strong ICP fit + clear buying signal + decision-maker accessible + verified contact |
| **Warm** | ICP fit + softer or older signal + contact verifiable |
| **Cold** | Loose ICP fit OR no clear signal OR contact unverified |
| **Skip** | Disqualifier hit (out of ICP, closed business, duplicate, irrelevant, low confidence) |
Branch-specific signals refine the scoring — see each reference file. Default ratio target: ~20% Hot, ~30% Warm, rest Cold/Skip.
### Phase 5 — Output the lead sheet
Default to a markdown table in chat. Switch to CSV when the list is >25 rows or the user explicitly asks for a file.
After the table, always add **"Top outreach targets"** — the top 35 hot leads with one sentence each on why this lead should be reached out to first.
Columns vary by branch (see reference files), but every lead sheet includes:
- score, business/company name, contact (where applicable), why-it's-a-prospect, source(s), confidence, last verified date
---
## Compliance Guardrails
These apply to every branch. **Read first, every engagement.**
1. **No bulk scraping** of LinkedIn, Google Maps, paywalled sites, or rate-limited APIs. Browser is an assisted research tool, not a scraper.
2. **No CAPTCHA, login wall, or bot protection bypass.** If a site requires it, work with what's publicly visible.
3. **Public business contact channels only.** Use info@, hello@, contact@, and named-role emails (founder, owner) where they're published on the business's own site. Personal/private emails require a lawful basis (existing relationship, opt-in, etc.).
4. **GDPR / CAN-SPAM / CASL aware.** Capture and retain the source URL and date for every contact you add to a list — required for downstream outreach compliance.
5. **No reselling extracted data** from Google Maps, LinkedIn, or any platform whose terms prohibit it. List building for the user's own outreach is fine; productizing the list to sell is not.
6. **Rate limit yourself.** Even on public sources, space requests. Don't fingerprint as a bot.
For the full compliance reference (GDPR, CAN-SPAM, CASL, LinkedIn ToS, Google Maps ToS, Clay/Apollo/ZoomInfo use restrictions): see [references/compliance.md](references/compliance.md).
---
## Inputs to Collect
If missing, ask once, then infer reasonable defaults and continue:
- **Branch** (SaaS / B2B / Local SMB) — usually inferable from context
- **ICP description** — pull from `product-marketing.md` if present
- **Target count** — default 25 for SaaS / B2B, 15 for Local SMB
- **Geography** (essential for Local SMB; useful for B2B; less critical for SaaS)
- **Tools the user has access to** — Apollo? Clay? ZoomInfo? Hunter? Truelist? Defaults to what's free + browser
- **Output format** — chat table (default) or CSV
- **Buying signal preference** — what triggers should they prioritize? (funding rounds, hiring, recent move, etc.)
---
## Tool Selection Quick Picks
Full breakdown in [references/data-sources.md](references/data-sources.md). Quick picks:
| If the user has access to... | Use it for |
|------------------------------|------------|
| **Apollo** | B2B / SaaS firmographic + contact discovery |
| **Clay** | Multi-source enrichment, waterfall lookups, custom scoring |
| **Clearbit** | Email-to-company and company enrichment |
| **ZoomInfo** | Enterprise B2B contact + intent data |
| **Hunter or Snov** | Email pattern guessing and verification |
| **Truelist** | Email deliverability validation (before adding to outreach list) |
| **LinkedIn Sales Navigator** | Decision-maker mapping (manual, no scraping) |
| **BuiltWith / Wappalyzer** | Tech stack qualification (SaaS branch) |
| **Crunchbase** | Funding signals (SaaS branch) |
| **GitHub** | Stargazers / forks of competitor or adjacent repos (dev-tool SaaS branch) |
| **Google Maps + browser** | Local SMB discovery |
| **Firecrawl / Browserbase** | Programmatic extraction from individual prospect websites — never from platforms |
**If the user has no enrichment tools**: lean on browser-assisted research with public sources — company website, About page, LinkedIn company page, news mentions. Slower but works.
---
## Output Formats
### Default — chat table
For SaaS / B2B (≤25 rows):
```
| Score | Company | Industry | Size | Signal | Contact | Email status | Source | Confidence |
| --- | --- | --- | --- | --- | --- | --- | --- | --- |
```
For Local SMB (≤15 rows) — port from the local-prospector reference:
```
| Score | Business | Category | Area | Website status | Website/Social | Phone | Why it's a prospect | Confidence |
| --- | --- | --- | --- | --- | --- | --- | --- | --- |
```
### CSV — when >25 rows or user requests a file
SaaS / B2B columns:
```csv
score,company,domain,industry,size_band,country,signal,contact_name,contact_title,contact_email,email_status,linkedin,source_urls,why_prospect,confidence,verified_date,notes
```
Local SMB columns:
```csv
score,business,category,area,distance_km,website_status,website_url,social_urls,phone,email,source_urls,why_prospect,confidence,verified_date,notes
```
### Always include after the table
- **Top outreach targets**: top 35 hot leads with one-sentence outreach rationale each
- **Search parameters**: branch, ICP, location/radius, target count, date generated
- **Open questions**: anything you couldn't verify and the user should look at
---
## Quality Checks (before finalizing)
- [ ] Remove duplicates (by domain for SaaS/B2B, by business + address for Local SMB)
- [ ] Every "Hot" lead has a verified contact + at least one source URL
- [ ] No lead has an email that failed Truelist (or your validator) verification — move to a separate "invalid" bucket and flag for the user
- [ ] No lead labeled "Hot" lacks a clear buying signal
- [ ] Confidence levels honest — "High" requires 2 independent sources, not just two of your own searches
- [ ] No leads sourced from prohibited scraping (LinkedIn at scale, Google Maps bulk extract, etc.)
- [ ] Source URL + date captured for every contact (GDPR / CAN-SPAM lineage)
- [ ] Final count matches user's request, or you've explained why it's smaller (quality bar)
---
## Common Mistakes
1. **Starting discovery without an ICP**. Build candidates against vague criteria and you'll qualify the wrong things.
2. **Treating data sources as authoritative without cross-checks**. Apollo and ZoomInfo are out of date often; verify before scoring as "Hot."
3. **Adding contacts without email verification**. Cold email reputation tanks fast with bounces — always validate.
4. **Bulk scraping LinkedIn or Google Maps**. Real risk: account suspension + ToS violation. Browser as an assisted tool only.
5. **Mixing branches**. Don't apply Local SMB scoring (website status) to a B2B SaaS prospect, or vice versa.
6. **"Hot" labels without buying signals**. ICP fit alone is not enough — the signal is what makes the timing right.
7. **No source URLs**. Every claim should be traceable to a public source. Future outreach depends on this lineage.
8. **Ignoring quiet hours / time zone** when scheduling the downstream outreach (handoff to cold-email).
9. **Forgetting to retain consent / lineage records**. Required for GDPR DSARs and CAN-SPAM audits.
---
## Task-Specific Questions
1. Which branch — SaaS, B2B, or Local SMB?
2. What's your ICP? (Or: should I pull from your product-marketing context?)
3. How many qualified leads do you want?
4. What tools do you have access to (Apollo / Clay / ZoomInfo / Hunter / Truelist / browser only)?
5. What's the triggering buying signal you care most about?
6. Geography or radius (Local SMB / B2B)?
7. Chat table or CSV?
---
## Tool Integrations
For implementation, see the [tools registry](../../tools/REGISTRY.md). Key prospecting tools:
| Tool | Best For | MCP | Guide |
|------|----------|:---:|-------|
| **Apollo** | B2B / SaaS firmographic + contact discovery | - | [apollo.md](../../tools/integrations/apollo.md) |
| **Clay** | Multi-source enrichment + waterfall | ✓ | [clay.md](../../tools/integrations/clay.md) |
| **Clearbit** | Email-to-company enrichment | - | [clearbit.md](../../tools/integrations/clearbit.md) |
| **ZoomInfo** | Enterprise B2B contact + intent | ✓ | [zoominfo.md](../../tools/integrations/zoominfo.md) |
| **Hunter** | Email pattern + verification | - | [hunter.md](../../tools/integrations/hunter.md) |
| **Snov** | Email finder + verifier | - | [snov.md](../../tools/integrations/snov.md) |
| **Truelist** | Email deliverability validation | - | [truelist.md](../../tools/integrations/truelist.md) |
| **Outreach** | Sales engagement (post-list) | ✓ | [outreach.md](../../tools/integrations/outreach.md) |
| **RB2B** | Visitor identification (warm intent) | - | [rb2b.md](../../tools/integrations/rb2b.md) |
| **GitHub** | Stargazers/forks/watchers as developer-intent signal | - | [github.md](../../tools/integrations/github.md) |
| **Firecrawl** | Single-target site extraction (prospect's own website) | ✓ | [firecrawl.md](../../tools/integrations/firecrawl.md) |
| **Browserbase** | Real-browser site research when rendering or interaction needed | ✓ | [browserbase.md](../../tools/integrations/browserbase.md) |
---
## Related Skills
- **cold-email**: For writing outbound sequences against the qualified list (the natural next step after prospecting)
- **customer-research**: For understanding why current customers buy — informs the ICP definition
- **competitor-profiling**: For deeper research on individual accounts (different from list-building qualification)
- **revops**: For lead routing, lifecycle, and CRM handoff after prospecting
- **sales-enablement**: For battle cards and one-pagers used in the outreach
- **directory-submissions**: For inbound discovery surfaces (the prospects might find you back)
- **product-marketing**: For the ICP definition that anchors every prospecting engagement
+107
View File
@@ -0,0 +1,107 @@
{
"skill_name": "prospecting",
"evals": [
{
"id": 1,
"prompt": "We're a B2B SaaS selling RevOps tooling at $30K ACV. Build me a list of 25 prospects.",
"expected_output": "Should check for product-marketing.md first. Should identify this as the SaaS branch. Should run Phase 1 ICP definition pulling from product-marketing context or asking targeted questions (target industry, headcount range, tech stack signals, funding stage). Should propose discovery sources appropriate for SaaS at $30K ACV: Apollo for breadth, Clay for waterfall enrichment, Crunchbase for funding signals, BuiltWith/Wappalyzer for tech stack, LinkedIn Sales Nav for decision-mapping (manual). Should ask about user's tool access before assuming. Should source 50-75 candidates (2-3x target) before qualifying. Should flag that email validation via Truelist or similar is non-negotiable before final list. Should output SaaS-branch chat table columns (Score | Company | Industry | Size | Signal | Contact | Email status | Confidence) followed by top 3-5 hot leads with one-sentence rationale each. Should reference references/saas-prospecting.md.",
"assertions": [
"Checks for product-marketing.md",
"Identifies SaaS branch",
"Runs Phase 1 ICP definition",
"Recommends multi-source discovery (Apollo, Clay, Crunchbase, BuiltWith)",
"Asks about user's tool access",
"Sources 2-3x candidates before qualifying",
"Requires email validation before final list",
"Outputs SaaS-branch chat table columns",
"Includes top 3-5 outreach targets with rationale",
"References saas-prospecting.md"
],
"files": []
},
{
"id": 2,
"prompt": "Find me 25 SaaS companies that just raised a Series B in the last 60 days and use HubSpot.",
"expected_output": "Should recognize this as a SaaS branch prospecting task with very specific signals. Should identify the trigger event (Series B in last 60 days) and the technographic filter (uses HubSpot). Should recommend a workflow: (1) Crunchbase or Pitchbook for funding signal filter (Series B + date), (2) BuiltWith or Clay's waterfall for tech stack verification (uses HubSpot), (3) cross-check via business websites and LinkedIn. Should note this is a tight ICP that should yield high-confidence matches if data sources are current. Should flag freshness concerns: Crunchbase data depends on self-reporting, BuiltWith refresh cycles aren't real-time. Should recommend cross-source verification for the funding date specifically. Should output a SaaS-branch chat table with the funding round + date in the Signal column. Should include verified email validation before delivering.",
"assertions": [
"Identifies as SaaS branch",
"Identifies funding signal + tech stack filter",
"Recommends Crunchbase or Pitchbook for funding",
"Recommends BuiltWith or Clay for HubSpot verification",
"Notes data freshness concerns",
"Recommends cross-source verification",
"Outputs signal column showing round + date",
"Requires email validation"
],
"files": []
},
{
"id": 3,
"prompt": "I run a marketing agency. Find me 25 mid-market manufacturers in the Midwest US who recently hired a new CMO.",
"expected_output": "Should identify this as the B2B branch (manufacturers, not SaaS). Should run Phase 1 ICP definition: industry (manufacturing, with NAICS code if precision matters), size (mid-market = typically 200-2000 employees), geography (Midwest US states), trigger event (CMO hire in last 90-180 days). Should propose discovery: Apollo or ZoomInfo for firmographic filter, LinkedIn Sales Nav for CMO hire detection (job changes), Google Alerts on press releases for trigger events. Should warn that CMO hires aren't always in public databases — LinkedIn Sales Nav alerts on job changes is the most reliable source. Should output B2B-branch chat table with the CMO trigger as the signal. Should reference references/b2b-prospecting.md. Should mention compliance: GDPR less likely (US-only), CAN-SPAM applies, capture source URL + date for every contact.",
"assertions": [
"Identifies B2B branch (not SaaS)",
"Runs Phase 1 ICP definition with NAICS or industry classification",
"Specifies mid-market size band",
"Specifies Midwest US geography",
"Identifies trigger event (CMO hire)",
"Recommends Apollo/ZoomInfo + LinkedIn Sales Nav",
"Notes CMO hires often only on LinkedIn",
"Outputs B2B-branch chat table",
"Mentions CAN-SPAM and source URL capture",
"References b2b-prospecting.md"
],
"files": []
},
{
"id": 4,
"prompt": "We sell to industrial distributors. Build a list of 25 prospects.",
"expected_output": "Should identify this as the B2B branch. Should run Phase 1 ICP definition asking targeted questions: distributor size, geography, vertical specialty, buying patterns. Should propose discovery: Apollo or ZoomInfo for firmographic depth, industry-specific directories (e.g., NAW for wholesale distributors, ISA for industrial sales agencies), trade show exhibitor lists. Should note state business registries and Chamber of Commerce as verification sources. Should propose trigger events: new location, recent acquisition, leadership change, posting RFPs. Should warn that industrial distributor data is often spotty in major databases — cross-check with company website + LinkedIn for size and ownership signals. Should output B2B-branch chat table. Should note ICP fit precision matters more than initial volume for this kind of niche prospecting.",
"assertions": [
"Identifies B2B branch",
"Runs Phase 1 ICP definition asking targeted questions",
"Recommends industry-specific directories beyond Apollo/ZoomInfo",
"Mentions trade show exhibitor lists",
"Identifies relevant trigger events",
"Warns about data spottiness for industrial",
"Recommends cross-verification with business websites + LinkedIn",
"Notes ICP fit precision over volume"
],
"files": []
},
{
"id": 5,
"prompt": "I build websites for local businesses. Find me 15 prospects near Austin, TX who don't have a website.",
"expected_output": "Should identify as Local SMB branch. Should run Phase 1 ICP definition: business category (ask user — gyms, restaurants, salons, etc. matter), radius (default 20 km from Austin), target count (15). Should run the browser research workflow: search Google Maps for category + Austin, build candidate list from visible results, cross-check via business name + city web search to verify website status. Should apply the 4-tier website status classification (No site found / Social only / Weak site / Has site) — prioritize No site + Social only as Hot. Should score: Hot (no site + active + phone + within radius), Warm (weak site), Cold (has site), Skip (closed/duplicate/out of scope). Should output Local SMB chat table (Score | Business | Category | Area | Distance | Website status | Website/Social | Phone | Why prospect | Confidence). Should add 'Best first outreach targets' top 3 with reasoning. Should reference references/local-prospecting.md. Should warn against bulk-scraping Google Maps (ToS violation) — browser-assisted research only.",
"assertions": [
"Identifies Local SMB branch",
"Asks about business category if not specified",
"Defaults radius to 20km",
"Runs browser research workflow",
"Applies 4-tier website status classification",
"Uses Hot/Warm/Cold/Skip scoring",
"Outputs Local SMB chat table columns",
"Adds top 3 outreach targets",
"References local-prospecting.md",
"Warns against bulk-scraping Google Maps"
],
"files": []
},
{
"id": 6,
"prompt": "I have a list of 200 prospect emails from Apollo. How do I know which ones are deliverable before I start outreach?",
"expected_output": "Should explain the deliverability validation step in Phase 3. Should recommend Truelist (the integration in this pack) for bulk validation. Should explain the email_state classification output: ok (deliverable), email_invalid (bounces, exclude), risky (deliverable with risk like role or disposable, include cautiously), unknown (couldn't determine, skip or re-verify), accept_all (catch-all domain, include cautiously). Should warn that Apollo data accuracy is typically 60-80% — sending without validation will tank sender reputation (bounce rate >2% triggers ISP throttling and reputation damage). Should recommend the workflow: bulk POST to /api/v1/verify or CSV upload → keep ok, include risky/accept_all cautiously, exclude email_invalid, re-verify unknown → hand off to outreach. Should note Truelist also has an official MCP server for agent-driven validation. Should note cold email reputation is hard to recover once damaged — validation is non-negotiable, not optional. Should mention Hunter and Snov as alternatives with built-in verification. Should reference truelist.md integration guide.",
"assertions": [
"Recommends Truelist for bulk validation",
"Explains email_state values (ok, email_invalid, risky, unknown, accept_all)",
"Warns Apollo accuracy is 60-80%",
"Cites 2% bounce rate threshold for reputation damage",
"Recommends workflow: validate, keep ok, exclude email_invalid",
"Mentions Truelist MCP server for agent workflows",
"Mentions cold email reputation is hard to recover",
"References truelist.md or data-sources.md"
],
"files": []
}
]
}
@@ -0,0 +1,106 @@
# B2B Prospecting Reference
For when the user sells to non-SaaS B2B — services, agencies, manufacturers, mid-market and enterprise companies, professional services firms.
---
## ICP Signals That Matter (B2B branch)
### Firmographic signals
- **Industry / vertical** — NAICS or SIC codes if precision matters
- **Company size** — headcount band, revenue band, location count
- **Geography** — relevant for time zones, regulations, on-site requirements
- **Business model** — service vs product vs distribution; B2B vs B2B2C
- **Ownership** — independent, PE-backed, public, family-owned — affects buying motion
### Buying signals
- **Trigger events**: new C-level hire, recent acquisition or divestiture, IPO/funding, opening a new location, recent rebrand, expansion announcement
- **Vendor signals**: posting RFPs publicly, switching costs in last quarterly report, contract renewal windows
- **Operational signals**: recent layoffs (cost pressure) or rapid hiring (capacity pressure)
- **News mentions**: launching new initiative, entering new market, regulatory change forcing action
- **PR / press**: anything that signals "this company is changing right now"
### Decay signals
- Multiple bankruptcies or PE-stripped operations
- Negative growth + cost-cutting headlines
- Ownership stagnation (small family-owned, no growth incentive)
- Buyer turnover (3+ Marketing Directors in 2 years)
---
## Discovery Sources (B2B branch)
### Tier 1 — primary discovery
- **Apollo**: best general B2B firmographic + contact discovery
- **ZoomInfo**: enterprise B2B + intent signals (mid-market+)
- **LinkedIn Sales Navigator**: industry + role + signal search; the gold standard for decision-maker mapping (manual)
- **Clay**: when you need custom waterfall lookups (e.g., enrich Apollo records with Hunter + Clearbit)
### Tier 2 — industry-specific directories
- **Crunchbase / Pitchbook**: funded businesses
- **D&B Hoovers**: large traditional B2B firmographics
- **State / national business registries**: for verified incorporation data
- **Industry association membership rosters**: trade groups often publish member lists
- **Trade show exhibitor lists**: signals active participation in a vertical
- **Procurement databases** (Procore for construction, e.g.): vertical-specific signals
### Tier 3 — trigger event monitoring
- **Google Alerts / Feedly**: trigger keywords ("acquired," "hires," "expansion," "raises," "announces")
- **PR Newswire / Business Wire**: company-controlled announcements
- **SEC filings** (public companies): material change disclosures
- **State filings**: new entity formation, dissolution
---
## Qualification Checklist (B2B branch)
- [ ] Industry / vertical matches ICP (use a recognized classification if possible)
- [ ] Company size within range (employees or revenue)
- [ ] Geography fits
- [ ] At least one trigger event in last 90180 days
- [ ] Decision-maker role exists (CEO, COO, VP Operations, Director of X — match buyer profile)
- [ ] Email contact verifiable (named role > info@ catchall)
- [ ] Source URLs captured for firmographic claims
- [ ] No disqualifiers (closed, acquired-paused, multi-bankrupt, off-ICP)
---
## Output Columns (B2B branch)
Recommended CSV columns:
```csv
score,company,domain,industry,naics_code,size_band,revenue_band,country,city,trigger_event,trigger_date,contact_name,contact_title,contact_email,email_status,linkedin_url,source_urls,why_prospect,confidence,verified_date,notes
```
For chat table, condense to: Score | Company | Industry | Size | Trigger | Contact | Email status | Confidence.
---
## Top Outreach Targets Selection (B2B)
Prioritize for the top 35 hot leads:
1. **Trigger event recency** — 30 days beats 6 months
2. **Trigger event specificity** — new CMO hire in your buyer's role beats "company in the news"
3. **Decision-maker access** — named contact with verified email + LinkedIn beats role-only
4. **Vertical fit precision** — exact NAICS match beats "adjacent industry"
Each top target rationale names the trigger and decision-maker: "Hired new VP of Marketing 14 days ago; verified email; mid-market manufacturer matching ICP."
---
## Common Mistakes (B2B)
1. **Treating B2B like SaaS** — funding rounds matter less; PE ownership and acquisition activity matter more.
2. **Trying to verify private company revenue precisely** — most public databases approximate. Use size bands, not point estimates.
3. **Ignoring procurement complexity** at enterprise scale — your prospect contact list may not include the actual approver.
4. **Cold-emailing executive assistants** — they're not the buyer and they will flag your outreach as spam.
5. **Source URL hygiene** — without source lineage, you can't defend a contact under GDPR DSAR or CAN-SPAM challenge.
6. **Stopping at one source** — Apollo can be 60% accurate on small businesses. Cross-verify with LinkedIn or the business website.
+123
View File
@@ -0,0 +1,123 @@
# Prospecting Compliance Reference
The legal and platform-ToS constraints that apply to prospect list building. Read first, every engagement.
> Operational guidance, not legal advice. For high-volume programs or programs touching EU/UK residents, run your setup past a privacy attorney.
---
## United States — CAN-SPAM (downstream)
CAN-SPAM regulates the cold email **send**, not the list build. But the list build matters because:
- You must be able to identify the source of every email address you contact (required if challenged)
- The "from" line and email content rules apply at send time — but you can't lie about how you got the contact
- Opt-out requests must be honored within 10 business days and tracked
**For prospecting specifically**: capture and retain the source URL + date for every contact you add to a list. CAN-SPAM doesn't require it explicitly, but defending your sender practices does.
---
## EU / UK — GDPR
The strictest applicable framework. Triggers when:
- Your prospect resides in EU/UK
- You're processing personal data (any identifiable info, including business emails tied to a named person)
### Lawful bases for cold B2B outreach
You have three credible options:
1. **Legitimate interest** (most common for B2B). Requires:
- The contact is in a business role likely to be interested in your offer
- The data was collected from a public, business-context source
- You provide a clear opt-out
- You can articulate the legitimate interest test in writing
2. **Consent** — typically not feasible for cold outreach (you don't have consent before first contact)
3. **Existing customer relationship** — only applies to current customers, not prospects
### What you must do
- Capture **source + date + lawful basis** for every contact
- Honor data subject access requests (DSARs) — you must be able to disclose, correct, or delete on request
- Include a privacy notice / opt-out in the first outreach
- Don't store personal data longer than necessary for the legitimate interest
### What disqualifies a list
- Bulk-scraped LinkedIn data — explicit ToS violation + GDPR risk
- Email addresses purchased from a list broker without source provenance
- "Anyone @ this domain" guessed emails sent without verification (multiplies risk + bounces)
---
## Canada — CASL
Stricter than CAN-SPAM. Cold B2B outreach requires:
- **Express consent** (explicit opt-in) — typically not present for cold prospecting
- **OR implied consent** — existing business relationship within 24 months, OR business address publicly published on the company's own site for the purpose of receiving such communications
**Practical implication for Canadian prospects**: relying on the publicly-published-address exception is the most defensible cold prospecting basis in Canada. You must include sender identification, mailing address, and an unsubscribe mechanism in every message.
---
## Platform Terms of Service
### LinkedIn
- **Sales Navigator** as a research tool: fine
- **Scraping LinkedIn at any scale**: explicit ToS violation. Banned accounts are permanent. Don't.
- **Apollo, Clay, and ZoomInfo** claim LinkedIn-overlap data through various legitimate channels — verify their data sources before assuming compliance
- **InMail and Connection Requests**: governed by LinkedIn's own messaging rules, not by CAN-SPAM/GDPR (because LinkedIn-internal)
### Google Maps
- ToS prohibits bulk extraction or productizing Maps data
- Browser-assisted research as a discovery aid: acceptable
- Storing Place IDs or large structured Maps data in your CRM: explicit ToS prohibition
- Use Maps to **find** local businesses, then cross-source from the business's own site for the data you retain
### Apollo / ZoomInfo / Clearbit
- All have their own ToS limiting reselling, downstream sharing, and use cases
- Read your contract — typically you can use the data for your own outreach but not productize it
- Don't share extracts publicly (e.g., on a leaderboard, in a public report)
### Crunchbase
- Free tier is read-only for personal use
- Paid tier permits broader use within contractual scope
- API access requires paid Pro+ tier
---
## Anti-Patterns (Don't Do These)
1. **Bulk-scraping LinkedIn / Google Maps / Yelp**. Browser-assisted research is OK; automated scrapers pointed at these platforms are not. **Firecrawl and Browserbase are fine for an individual prospect's own website** (the URL you found through manual discovery) — not for the platforms hosting prospects.
2. **Buying lists from random vendors** without source provenance. You inherit their legal exposure.
3. **Guessing emails and sending unverified**. Bounce rates over 2% destroy sender reputation; legally, you can't claim a "legitimate interest" basis for an email you fabricated.
4. **Harvesting personal email addresses** (Gmail, personal Outlook, etc.) from public profiles. Personal addresses raise GDPR risk significantly.
5. **Storing data you don't need**. Minimize retention. Don't keep prospect lists forever — GDPR right to deletion applies.
6. **Skipping the lawful basis documentation**. If challenged, you need to show your work. Capture source URL + collection date for every contact.
7. **Reselling prospect lists**. You may not have the right to share them downstream. Read your data provider contracts.
8. **CAPTCHA bypass / login wall bypass**. Even if technically possible, this signals bot behavior and violates virtually every ToS.
---
## Quick Audit Checklist
Before shipping a list to the user (or downstream to cold-email):
- [ ] Every contact has a source URL + collection date
- [ ] No contacts sourced from scraped LinkedIn data
- [ ] No Google Maps Place IDs or large Maps-structured data retained
- [ ] Lawful basis documented (legitimate interest test for B2B, or relevant alternative)
- [ ] Email addresses validated (deliverability check before outreach)
- [ ] Personal addresses (Gmail, etc.) flagged or excluded
- [ ] Source provider contracts permit the intended use case
- [ ] Retention plan documented (when to delete)
- [ ] First outreach will include unsubscribe + privacy notice (downstream concern for cold-email skill, but mention it now)
@@ -0,0 +1,287 @@
# Prospecting Data Sources
Tool selection guide for prospecting across all three branches.
---
## Tool selection by goal
| Goal | Primary tools | Notes |
|------|--------------|-------|
| **Build initial firmographic list (B2B / SaaS)** | Apollo, ZoomInfo, Clay | Apollo for breadth, ZoomInfo for enterprise + intent, Clay for custom workflows |
| **Decision-maker mapping** | LinkedIn Sales Navigator (manual), Apollo, ZoomInfo | Sales Nav is the gold standard. Never bulk scrape it. |
| **Tech stack qualification (SaaS)** | BuiltWith, Wappalyzer | BuiltWith has wider coverage + paid plans for bulk; Wappalyzer is lighter + free for small use |
| **Funding signals (SaaS)** | Crunchbase, Pitchbook | Crunchbase free tier sufficient for early signals; Pitchbook for deeper investor data |
| **Email pattern discovery** | Hunter, Snov, Apollo | Pattern guessing — followed by verification |
| **Email deliverability verification** | Truelist, Hunter, NeverBounce, ZeroBounce | Always verify before adding to outreach lists |
| **Visitor identification (warm intent)** | RB2B, Clearbit Reveal | Anonymous traffic → company identification |
| **Intent data** | ZoomInfo Intent, 6sense, Bombora | Pre-warmed signals; mid-market+ pricing |
| **Trigger event monitoring** | Google Alerts, Feedly, LinkedIn Sales Nav alerts | Free options are sufficient for most |
| **Local business discovery** | Google Maps (manual), Yelp, Facebook Pages | Browser-assisted, not bulk-extracted |
---
## Apollo
**Use for**: General B2B / SaaS firmographic + contact data. Best starting point if you don't already have a list.
**Strengths**:
- Large database (>200M contacts, >60M companies)
- Strong filtering UI (industry, size, technologies, signals)
- Integrated email + LinkedIn finder
- Pay-as-you-go and tiered plans
**Watch out for**:
- Data freshness varies — re-verify before scoring as "Hot"
- Email accuracy ~6080% — always validate
- Bulk export limits apply
**Integration**: see [apollo.md](../../../tools/integrations/apollo.md)
---
## Clay
**Use for**: Multi-source enrichment, waterfall lookups, custom scoring logic. When list quality matters more than list size.
**Strengths**:
- Waterfall logic: try Apollo first → fallback to ZoomInfo → fallback to Clearbit
- 100+ data provider integrations
- AI-powered enrichment (LLM-driven extraction from URLs)
- Custom columns + scoring formulas
- Native MCP server
**Watch out for**:
- Per-credit pricing can spike on large lists
- Complexity overhead — easy to over-engineer workflows
**Integration**: see [clay.md](../../../tools/integrations/clay.md)
---
## ZoomInfo
**Use for**: Enterprise B2B + intent data. Mid-market+ buyer profiles.
**Strengths**:
- Enterprise-grade firmographic depth
- Intent signals (companies searching topics relevant to your offer)
- Best-in-class for >$50K ACV B2B sales
- Native MCP server
**Watch out for**:
- Expensive ($15K+/yr starter)
- Overkill for SMB prospecting
- Locked into multi-year contracts typically
**Integration**: see [zoominfo.md](../../../tools/integrations/zoominfo.md)
---
## Clearbit
**Use for**: Email → company enrichment, anonymous visitor identification (Clearbit Reveal).
**Strengths**:
- Strong company enrichment (industry, size, funding, tech stack)
- Email lookup by domain
- Reveal: identify anonymous site visitors at company level
- API-first
**Watch out for**:
- HubSpot acquisition (2023) — bundled into HubSpot Breeze Intelligence now
- Standalone API still available but pricing/access depends on tier
**Integration**: see [clearbit.md](../../../tools/integrations/clearbit.md)
---
## Hunter / Snov
**Use for**: Email pattern discovery + lightweight verification on small lists.
**Hunter strengths**:
- Domain-based email discovery
- Built-in deliverability verification
- Free tier reasonable for occasional use
**Snov strengths**:
- Email finder + drip campaigns (overlap with outreach tooling)
- Bulk verification
- Cheaper than Hunter at scale
**Watch out for**:
- Both are pattern-guessing tools — accuracy depends on the target company's email pattern being inferable
- Always run results through a dedicated validator (Truelist or similar) before outreach
**Integrations**: see [hunter.md](../../../tools/integrations/hunter.md), [snov.md](../../../tools/integrations/snov.md)
---
## Truelist
**Use for**: Email deliverability validation before adding contacts to outreach lists. Critical safety step.
**Strengths**:
- Single-email sync verification (`/api/v1/verify_inline`) + bulk async (`/api/v1/verify`)
- Returns `email_state` (ok / email_invalid / risky / unknown / accept_all) + `email_sub_state` (email_ok / is_disposable / is_role / unknown_error / failed_smtp_check) + did-you-mean typo suggestions
- Catches catch-all domains, role accounts, spam traps, disposable providers
- Official MCP server for agent-driven workflows (Claude, Cursor, VS Code)
- Official SDKs in 7 languages + framework integrations (Django, Laravel, Next.js, Rails, React, Svelte, Vue, WordPress)
- Native integrations with Mailchimp, Klaviyo, HubSpot, Zapier, Make, n8n, Clay, Salesforce, more
- Pay-per-email pricing
**Why this matters**: Cold email reputation craters when bounce rates exceed 2%. Validating before sending is non-negotiable. Apollo/ZoomInfo/Hunter data is often 6080% accurate — Truelist catches the rest.
**Integration**: see [truelist.md](../../../tools/integrations/truelist.md)
---
## LinkedIn Sales Navigator
**Use for**: Manual decision-maker discovery. The gold standard for B2B / SaaS prospecting but only when used as a research tool.
**Strengths**:
- Most accurate decision-maker data in the industry
- Real-time job changes, posts, signals
- Lead lists, alerts, saved searches
- Inmail credits (separate channel from cold email)
**Hard rules**:
- **Never bulk scrape**. LinkedIn aggressively bans scrapers. Account ban risk is real and permanent.
- Use Sales Nav as a research interface — open profiles, read, take notes, capture key data manually.
- Apollo and other tools claim LinkedIn data via partnerships / public mirroring — verify the source legitimacy before assuming compliance.
**Integration**: no MCP or API access at consumer level. Manual research only.
---
## BuiltWith / Wappalyzer
**Use for**: Tech stack qualification (SaaS branch).
**BuiltWith**:
- ~50K+ technologies tracked
- API + bulk lookups (paid)
- Historical data (when stack changed)
**Wappalyzer**:
- Free browser extension; paid API
- Lighter coverage than BuiltWith
- Faster for one-off lookups
Cross-reference both for high-confidence tech stack signals.
---
## Crunchbase
**Use for**: Funding signals (SaaS branch).
**Strengths**:
- Free tier shows recent funding events
- Paid (Pro / Enterprise) unlocks alerts and deep history
- API access for paid users
**Watch out for**:
- Coverage is best for VC-backed companies; bootstrapped + small businesses underrepresented
- Self-reported data — verify funding amounts independently
---
## GitHub (stargazers / forks / watchers)
**Use for**: Developer-intent prospecting. Especially powerful for dev-tool SaaS — stargazers of competitor or category-defining repos are in-market signal.
**Strengths**:
- Public API, no scraping concerns
- High signal quality (a starred repo = explicit interest)
- Forks are an even stronger signal (intent to modify, not just bookmark)
- Bundled `github-prospects.js` CLI handles pagination + enrichment + CSV output
- Free with 5,000 req/hr authenticated rate limit
**Watch out for**:
- Only ~520% of users publish email — pair with Apollo/Clay/Hunter for enrichment
- Very-popular repos (100K+ stars) are mostly noise; smaller targeted repos (5K25K) give better signal density
- Most prospects are individuals, not company contacts directly — need to figure out their company from `company` field or LinkedIn
**Integration**: see [github.md](../../../tools/integrations/github.md)
---
## Firecrawl / Browserbase (single-target site research)
**Use for**: Programmatically extracting content from a **prospect's own website** that you already found via discovery on platforms like Google Maps, Yelp, or LinkedIn. Not for scraping those platforms themselves.
### Firecrawl
- **Best for**: "Just give me the page as markdown" — Local SMB website status checks, B2B company about/team page extraction, structured field extraction
- **Strengths**: Low overhead, returns clean LLM-ready markdown, handles most JS-rendered sites, has an MCP server
- **API + MCP + SDKs**: Node, Python, Go, Rust
### Browserbase
- **Best for**: When you need real Chromium — JS-heavy pages, cookie consent dialogs, form submission to reach a contact page, session state
- **Strengths**: Full browser control via Playwright/Puppeteer; Stagehand provides AI-friendly natural-language extraction; session recordings for debugging
- **API + MCP (Stagehand) + SDKs**: Node, Python
### Critical compliance line
Both tools can technically point at any URL. The hard rule:
-**OK**: extracting content from a single business's own website (`joescoffeeshop.com`) that you found through manual discovery
-**NOT OK**: pointing them at `google.com/maps`, LinkedIn search results, Yelp listings, or any platform whose ToS prohibits bulk extraction
Discovery happens on platforms (manual browser-assisted research). Extraction happens on individual public business sites.
**Integrations**: see [firecrawl.md](../../../tools/integrations/firecrawl.md), [browserbase.md](../../../tools/integrations/browserbase.md)
---
## RB2B / Clearbit Reveal
**Use for**: Identifying anonymous site visitors as warm intent signals.
**Strengths**:
- Pixel-based visitor → company identification
- High-intent: they came to your site, they're already in research mode
- Slack / email alerts on key visits
**Watch out for**:
- Privacy/GDPR considerations — verify your privacy policy disclosures
- Person-level identification raises higher concerns than company-level
**Integration**: see [rb2b.md](../../../tools/integrations/rb2b.md)
---
## Free / browser-only fallbacks
When the user has no paid tools, lean on:
- **Google Search** — exact business name + city + role searches
- **LinkedIn** (manual, no scraping) — company pages, employee lookups
- **Crunchbase free tier** — funding events
- **Wappalyzer browser extension** — tech stack at a glance
- **Hunter.io free tier** — 25 lookups/month
- **Google Maps** — for Local SMB discovery
- **Business websites + About pages** — primary source for any claim
- **News sites + press releases** — trigger event monitoring via Google Alerts
Slower than tooled-up workflows, but produces high-quality smaller lists if the user is willing to do the work.
---
## Sequencing recommendations
A typical full-stack prospecting workflow:
1. **Define ICP** from product-marketing context (no tools needed)
2. **Initial list** from Apollo or ZoomInfo (firmographic filter)
3. **Enrich** with Clay (waterfall: tech stack, funding, trigger events)
4. **Decision-maker mapping** in LinkedIn Sales Nav (manual)
5. **Email pattern discovery** with Hunter or Apollo's built-in
6. **Email validation** with Truelist before final list
7. **Hand off** to cold-email skill for outreach copy
Adapt this sequence based on which tools the user actually has.
@@ -0,0 +1,165 @@
# Local SMB Prospecting Reference
For when the user sells to local small businesses — shops, gyms, restaurants, salons, clinics, professional services, contractors, real estate, fitness studios, dental practices.
Adapted from and generalized beyond the local-client-prospector pattern (browser-assisted discovery + website status classification + proximity scoring).
---
## ICP Signals That Matter (Local SMB branch)
### Operational signals
- **Active business** — Google Business Profile updated, recent reviews, recent hours updates
- **Recent activity** — open right now, regular hours posted, recent photos uploaded by owner
- **Customer engagement** — owner responding to reviews, posts on social, active calendar (for service businesses)
### Online presence signals (the core SMB qualification axis)
The reference local-client-prospector skill uses **website status** as the primary qualification — port this directly. Four classifications:
| Status | Definition | Typical outcome |
|--------|-----------|-----------------|
| **No site found** | No credible standalone website after cross-checked search | **Hot prospect** for web/marketing service |
| **Social only** | Facebook, Instagram, WhatsApp, Linktree, booking portal, marketplace page only — no standalone site | **Hot prospect** for web/marketing service |
| **Weak site** | Standalone site exists but outdated, broken, very thin, non-mobile-friendly, or missing clear contact/conversion flow | **Warm prospect** for refresh / rebuild service |
| **Has site** | Credible, modern standalone site exists | **Low prospect** unless other signals apply (e.g., poor SEO, weak conversion design) |
### Proximity signals
- **Distance** from the user's location or service area
- **Density** — clusters of similar businesses in one area = neighborhood targeting opportunity
- **Travel time** — useful when in-person discovery, install, or service delivery is required
### Decay signals
- Closed permanently (Google Maps banner)
- Reviews paused or business listing reported as closed
- Last activity (review, post) >12 months ago
---
## Discovery Sources (Local SMB branch)
### Primary
- **Google Maps** (browser, manual) — search "category near [location]" and walk the visible results. Cross-check details. Don't bulk-extract.
- **Yelp** — secondary verification; complementary categories
- **Bing Local / Apple Maps** — different coverage on smaller businesses
- **Facebook Pages search** — many SMBs are Facebook-only
### Cross-verification
- **Business's own website** (if any)
- **Industry directories** (e.g., Healthgrades for medical, OpenTable for restaurants, Avvo for legal)
- **Local Chamber of Commerce listings**
- **State business registries** for incorporation status
- **Search results for "[business name] [city]"** to discover non-Maps presence
---
## Browser Research Workflow
1. Open a browser and search Google Maps for the category near `base_location`
2. Build a candidate list from visible local results, search results, and public directories
3. For each candidate, inspect public sources to fill required fields
4. Search the exact business name plus city/town to check whether a standalone website exists
5. Classify website status per the table above
6. Mark confidence: High (2+ sources), Medium (1 source + consistent evidence), Low (incomplete/ambiguous)
When the user explicitly asks for subagents AND subagents are available, split candidates into non-overlapping batches and ask each subagent to verify only website/social/contact status. Don't use subagents for the primary search if it slows progress.
### Optional: programmatic verification with Firecrawl or Browserbase
Once you have a candidate's website URL (found via manual Maps/Yelp discovery), you can speed up website-status classification by hitting the URL programmatically:
- **Firecrawl** for simple "is this site live, modern, mobile-friendly, conversion-flow-equipped" reads — returns clean markdown you can inspect
- **Browserbase** when the candidate site requires JS rendering, has a cookie consent dialog, or you need session state
**Strict line**: use these on the individual business's URL. **Don't** point them at Google Maps, Yelp, or any platform whose ToS prohibits bulk extraction — discovery stays manual.
See [data-sources.md](data-sources.md) for setup details.
---
## Qualification Checklist (Local SMB branch)
- [ ] Business is active (recent reviews or activity in last 6 months)
- [ ] Category matches user's service offering
- [ ] Distance / proximity within target radius
- [ ] Website status classified
- [ ] Phone or contact channel verified
- [ ] At least one cross-source confirms business operates at the listed address
- [ ] Not a duplicate / chain location / out-of-scope category
- [ ] Not closed permanently
---
## Lead Scoring (Local SMB)
Use this simple rubric (matches local-client-prospector pattern):
| Score | Criteria |
|-------|----------|
| **Hot** | No site found OR social-only + phone present + active business + within target radius |
| **Warm** | Weak site, poor online presentation, or marketplace/booking-page only |
| **Cold** | Good website already present OR low confidence |
| **Skip** | Closed, duplicate, outside radius, irrelevant category, or not a business prospect |
---
## Output Columns (Local SMB branch)
Chat table (≤15 rows):
```
| Score | Business | Category | Area | Distance | Website status | Website/Social | Phone | Why it's a prospect | Confidence |
```
CSV:
```csv
score,business,category,area,distance_km,website_status,website_url,social_urls,phone,email,source_urls,why_prospect,confidence,verified_date,notes
```
Rules:
- Keep "Why it's a prospect" short and actionable
- Use `Not found` instead of leaving blank fields
- Include source links sparingly, not all of them
- After the table, add **Best first outreach targets** with the top 3 leads and one practical reason each
- If confidence is low, state exactly what remains uncertain
---
## Top Outreach Targets Selection (Local SMB)
Prioritize for the top 3 hot leads:
1. **No site / social only + phone present** = clearest service opportunity
2. **High review count** = active, established business with real customers
3. **Owner-responded reviews** = engaged owner = more likely to evaluate a vendor
4. **Industry alignment with your service specialty** beats generic category match
Each top target rationale should be one sentence naming the gap and the signal: "No standalone website (cross-checked); 80+ Google reviews with owner replies; 2 km from target area."
---
## Compliance Notes (Local SMB-specific)
The local branch is the most scraping-sensitive of the three motions. Specifically:
- **Google Maps Terms of Service** prohibit bulk extraction. Treat browser visits as research, not as data acquisition.
- **Don't store full Google Maps Place IDs in your CRM** — the ToS limits storage of Maps data.
- **Public business contact channels only**: published phone, contact form, info@ email. Don't reach individual employees through their personal channels.
- **Owner/operator name when published on the business's own site** is OK to use. If you only got it from LinkedIn, mark the source.
---
## Common Mistakes (Local SMB)
1. **Bulk-scraping Google Maps** — fastest way to violate ToS and lose the research channel.
2. **Treating Google Maps data as truth** — listings go stale. Cross-check hours, status, and reviews.
3. **Skipping the website status cross-check** — finding "no site" on Maps doesn't mean no site exists; do an exact-name web search before classifying.
4. **Targeting only the largest businesses** — they're already covered by other providers. The 25 employee SMBs are the under-served opportunity.
5. **Generic outreach to all hot leads** — local SMBs respond better to outreach that names their specific gap ("I noticed your menu isn't visible on mobile") than generic pitches.
6. **Ignoring chains and franchises** as Skip — sometimes the franchisee is the buyer and they have local marketing authority. Verify before skipping.
@@ -0,0 +1,123 @@
# SaaS Prospecting Reference
For when the user sells SaaS or digital services to other SaaS companies / digital businesses.
---
## ICP Signals That Matter (SaaS branch)
Beyond standard firmographics (industry, size, geography), SaaS prospects are qualified by:
### Technographic signals
- **Tech stack** — do they use complementary tools (your integration target) or competing tools (a switch opportunity)?
- **Recent stack changes** — adding/removing tools signals active vendor evaluation
- **Custom-built vs off-the-shelf** — DIY tooling often means a buyer who'd benefit from your product
- **Free/freemium plan signals** — using a free competitor means they may be ready to upgrade
### Growth signals
- **Funding round** — Series A / B / C in last 6 months = budget + new hires + tool needs
- **Headcount growth** — 10%+ growth in last quarter signals scaling pressure
- **Hiring signals** — specific role openings (e.g., "Head of RevOps" → ICP for revops tooling)
- **Product velocity** — frequent shipping, new features, blog posts = healthy growth motion
- **Open positions for your buyer's role** — if you sell to Marketing Ops and they're hiring one, that's a signal
### Decay signals (downgrade scoring)
- Layoffs in target department
- Funding round >2 years ago with no follow-up
- Product hasn't shipped in 6+ months
- Team page shows founders only (very early — may not have budget)
---
## Discovery Sources (SaaS branch)
Combine 2+ sources for cross-verification.
### Tier 1 — primary discovery
- **Apollo**: firmographic + technographic + contact data. Good for building large initial lists.
- **Clay**: waterfall enrichment, custom scoring, multi-source merges. Best for high-quality smaller lists.
- **ZoomInfo**: enterprise-grade firmographic + intent signals. Expensive; mid-market+.
- **LinkedIn Sales Navigator**: decision-maker mapping. Use manually, never bulk scrape.
### Tier 2 — technographic / growth signals
- **BuiltWith**: tech stack lookups, find sites using specific tools
- **Wappalyzer**: free browser extension + API; lighter tech stack signal
- **Crunchbase**: funding rounds, headcount, founders
- **Pitchbook**: deeper investor data (enterprise/paid)
- **ProductHunt**: recent launches, builder audience
- **Hacker News / Show HN**: technical builders launching products
### Tier 3 — buying signals
- **Job boards** (LinkedIn Jobs, Indeed, AngelList): role openings as signals
- **RB2B / Clearbit Reveal**: visitor identification (warm anonymous traffic)
- **GitHub stars/forks of competitor or adjacent repos**: developer-level intent signal (see `tools/integrations/github.md` and the `github-prospects.js` CLI). Especially strong for dev-tool SaaS — a developer who starred `vercel/next.js` last week is in-market for adjacent Next.js infrastructure.
- **Recent blog posts / changelog**: product direction signals
- **G2 reviews mentioning competitor switches**: explicit dissatisfaction signal
#### GitHub prospecting pattern (when audience is developers)
For dev-tool SaaS, GitHub is one of the highest-quality discovery channels:
1. Identify 35 "anchor" repos: your direct competitors, your category leader, complementary tools your buyer uses
2. Pull stargazers (or forks for stronger intent) via `node tools/clis/github-prospects.js stargazers <owner/repo> --enrich --with-company --format csv`
3. Filter to users with `company` set — these are the easiest to enrich downstream
4. Pair with Apollo/Clay/Hunter to lookup email by name + company
5. Validate with Truelist before adding to outreach list
Tradeoffs: GitHub yields email for only ~520% of users directly. The strength is the signal quality — a stargazer of a niche dev tool is genuinely in-market in a way Apollo firmographics alone can't tell you.
---
## Qualification Checklist (SaaS branch)
For each candidate, verify:
- [ ] Industry vertical matches ICP
- [ ] Company size (headcount) within range
- [ ] Tech stack includes (or notably excludes) a target technology
- [ ] Funding stage matches buyer maturity
- [ ] At least one growth signal in last 90 days (funding, hiring, product velocity)
- [ ] Decision-maker role exists at the company (named or inferable from job listings)
- [ ] Email contact verifiable
- [ ] No disqualifiers (closed, acquired-and-paused, layoffs, ICP miss)
---
## Output Columns (SaaS branch)
Recommended CSV columns:
```csv
score,company,domain,industry,size_band,country,funding_stage,last_round_date,tech_stack_match,signal,signal_date,contact_name,contact_title,contact_email,email_status,linkedin_url,source_urls,why_prospect,confidence,verified_date,notes
```
For chat table, condense to: Score | Company | Industry | Size | Signal | Contact | Email status | Confidence.
---
## Top Outreach Targets Selection (SaaS)
Prioritize for the top 35 hot leads:
1. **Strongest signal recency** — funding 30 days ago beats funding 9 months ago
2. **Tech stack match strength** — known integration partner beats inferred fit
3. **Decision-maker named with verified email** — beats role-pattern-guessed email
4. **Multi-source confidence** — both Apollo + Crunchbase agree beats one source
Each top target gets a one-sentence outreach rationale that names the specific signal: "Raised Series B 30 days ago; hiring Head of RevOps; verified VP of Ops email."
---
## Common Mistakes (SaaS)
1. **Buying lists from Apollo wholesale** without re-verifying email and re-checking firmographics. Stale data is the norm.
2. **Treating tech stack data as 100% accurate**. BuiltWith and Wappalyzer miss things; Clay's waterfalls miss things. Cross-check.
3. **Targeting Series C+ for early-stage SaaS sellers**. The buyer profile is wrong — too many procurement hoops, too much red tape.
4. **Targeting Series Pre-Seed seed** for products requiring meaningful budget. They have neither budget nor evaluator bandwidth.
5. **Ignoring intent data when it exists** (ZoomInfo Intent, 6sense, etc.) — pre-warm signals beat cold every time.
+338
View File
@@ -0,0 +1,338 @@
---
name: sms
description: When the user wants to plan, build, or optimize SMS or MMS marketing — including welcome flows, abandoned cart texts, post-purchase, win-back, promotional sends, or transactional/auth SMS. Also use when the user mentions "SMS marketing," "text message campaigns," "SMS sequence," "SMS automation," "abandoned cart text," "post-purchase SMS," "Klaviyo SMS," "Postscript," "Attentive," "Twilio," "A2P 10DLC," "TCPA," "SMS compliance," "short code," "toll-free SMS," "MMS campaign," "should I do SMS," or "SMS vs email." For email sequences, see emails. For SMS copy framing, see copywriting. For opt-in popups that capture phone numbers, see popups.
metadata:
version: 1.0.0
---
# SMS Marketing
You are an expert in SMS and MMS marketing for direct-to-consumer brands, mobile apps, and SaaS products with high-engagement use cases. Your goal is to help plan, build, and optimize SMS programs that drive measurable revenue or activation while staying fully compliant with TCPA and carrier rules.
## Before Starting
**Check for product marketing context first:**
If `.agents/product-marketing.md` exists (or `.claude/product-marketing.md`, or the legacy `product-marketing-context.md` filename, in older setups), read it before asking questions. Use that context and only ask for information not already covered or specific to this task.
Gather this context (ask if not provided):
### 1. Business Type
- B2C ecom / DTC, B2B SaaS, mobile app, services, fintech
- Order volume or list size (SMS economics depend on scale)
- Geographic mix (US, EU, both — compliance differs dramatically)
### 2. Current State
- Existing SMS program (platform, list size, opt-in rate, opt-out rate, revenue/send)
- Email program (SMS works best as a layer on top, not a replacement)
- Phone number type: short code, toll-free, long code (10DLC)
### 3. Compliance Posture
- US: A2P 10DLC registration complete? (Required since 2022 — without it, your messages get filtered)
- Opt-in mechanism in use? (Checkbox, keyword opt-in, double opt-in)
- Privacy policy + terms include SMS disclosures?
### 4. Goal
- Drive revenue (promotional, cart recovery, post-purchase)
- Drive activation (welcome, onboarding, milestone nudges)
- Transactional (order updates, auth codes, alerts)
---
## When SMS Beats Email
SMS is not "another email." Use it where the channel's properties win:
| Use Case | SMS or Email? | Why |
|----------|---------------|-----|
| Abandoned cart recovery | **SMS first** | 98% open rate within 3 min vs 20% for email in 24h |
| Order/shipping updates | **SMS** | Customers want it now, on their phone |
| Flash sale / limited drop | **SMS** | Urgency channel; immediate read |
| Auth codes / 2FA | **SMS** (or app) | Latency-sensitive, must arrive in seconds |
| Welcome series | **Email primary, SMS layer** | Email carries the long-form content |
| Educational nurture | **Email** | Too much text for SMS, costs add up |
| Newsletter | **Email** | Wrong channel for SMS |
| Win-back lapsed customers | **Both** | SMS for the strong nudge, email for the offer detail |
| Post-purchase upsell | **SMS** | High open rate, ride the purchase momentum |
**General rule**: SMS earns the right to interrupt because of opt-in. Use it for messages that genuinely benefit from immediacy. If it could wait 24 hours, send it via email.
---
## Compliance — Read First
**Compliance is the foundation, not an afterthought.** A single TCPA class-action settlement runs $5M$40M. The basics:
### US — TCPA (Telephone Consumer Protection Act)
1. **Express written consent** required for marketing SMS. Implied consent doesn't count.
2. **Clear disclosure at opt-in** must include: program name, frequency expectation ("up to 4 msgs/month"), STOP/HELP instructions, "Msg & data rates may apply," link to terms.
3. **Honor STOP/UNSUBSCRIBE within seconds**, every time, no exceptions, on every keyword variant (STOP, END, CANCEL, UNSUBSCRIBE, QUIT).
4. **Honor HELP** with a response containing brand name + STOP info + support contact.
5. **Quiet hours**: no marketing sends before 8am or after 9pm in the recipient's local time. Carrier rules and state laws (e.g., Florida, Oklahoma, Washington) are stricter than federal — default to 9am8pm recipient-local.
6. **Keep written consent records** with timestamp, opt-in source, and exact disclosure text shown. Auditable.
### US — A2P 10DLC Registration (required since 2022)
Application-to-Person 10-digit long codes must be registered through The Campaign Registry (TCR) via your SMS platform. Without registration:
- Throughput is throttled (or zero)
- Carriers filter your messages
- You'll see "delivered" status but recipients won't get them
**Registration covers**: brand identity verification, campaign use case (marketing, account notification, OTP, etc.), sample messages, opt-in mechanism, opt-out language. Sample message text from registration must match what you actually send.
### EU/UK — GDPR-derived consent
- Explicit opt-in required (no pre-checked boxes)
- Right to withdraw consent must be as easy as giving it
- Data subject access requests apply to SMS records
- ePrivacy Directive layered on top of GDPR
### Canada — CASL
- Express consent + sender identification + unsubscribe in every message
- Implied consent allowed for existing business relationships within 24 months
- Penalties up to CAD $10M per violation
**For full compliance details, edge cases, opt-in copy templates, and STOP/HELP response templates**: see [references/compliance.md](references/compliance.md).
---
## Phone Number Types (US)
| Type | Throughput | Cost | Use Case | Trust |
|------|-----------|------|----------|-------|
| **Short code (5-6 digit)** | 100+ msg/sec | $500$1,000/mo + setup | High-volume marketing | Highest (carrier-vetted) |
| **Toll-free (1-8XX)** | ~3 msg/sec | $10$30/mo | Mid-volume, B2C support | Medium-high (carrier-verified) |
| **10DLC (regular long code)** | 1250 msg/sec | $2$10/mo | SMB, conversational, transactional | Medium (requires A2P 10DLC reg) |
**Rule of thumb**: list <10K = 10DLC. List 10K100K = toll-free. List 100K+ = short code.
---
## Core Principles
### 1. Every send has a real cost
SMS isn't free. At $0.0075$0.04 per send + carrier fees, a 100K send costs $750$4,000. This forces relevance — you can't "blast." Segment hard.
### 2. Opt-in is your most valuable asset
Opt-in rate from email → SMS is typically 525%. A high-quality SMS list of 10K beats a low-quality list of 100K. Optimize opt-in quality, not volume.
### 3. Each message must justify itself
The recipient gave you their phone number. Every send should pass: "would I be glad I got this text?" If no, don't send.
### 4. Brevity + clarity
160 GSM-7 characters = 1 SMS segment. 161+ chars = 2 segments (you're billed for 2). Emojis force UCS-2 encoding (70 chars per segment). Plan for segment count.
### 5. One CTA, one link
Short links are mandatory (`klvy.co`, `txt.attn.tv`, branded short domain). Track UTM params on every link.
### 6. Sender identity, every send
"From [Brand]:" or branded short code at the start of every message. Even on automated flows. Recipients can't see "from" address — they need it inline.
---
## SMS Sequence Types
### Welcome / Opt-In Confirmation (immediate)
Send 1: Confirmation + reward (immediate)
> From Acme: Thanks for joining! Here's 10% off: ACME10. Use at checkout: acme.co/sale. Reply STOP to opt out.
Optional Send 2 (24h later): Reminder + best-seller showcase
### Abandoned Cart (highest-ROI flow for ecom)
- Send 1 (30 min after abandon): "Forget something? Your cart's still here: [short link]"
- Send 2 (4 hours later): Soft urgency + social proof
- Send 3 (24 hours later, optional): Discount offer (only if margin allows)
**Note**: Discount on first message trains customers to abandon. Reserve discount for Send 2 or 3.
### Browse Abandonment
- Send 1 (1 hour after browse): Product + "Thinking it over?" + link
### Post-Purchase
- Send 1 (immediate): Order confirmation + delivery ETA (transactional, separate consent OK)
- Send 2 (after delivery + 2 days): "How are you liking [product]?" + review prompt + cross-sell
### Win-Back (lapsed)
- Send 1 (6090 days after last purchase): "We miss you" + curated picks
- Send 2 (14 days later): Discount offer
- Send 3 (final, 14 days later): Opt-out warning + last chance
### Promotional / Campaign Sends
- Flash sales, drops, launches, BFCM
- 12 sends max per campaign
- Stack against email send schedule to avoid same-day double-tap
### Transactional (separate compliance bucket)
- Order updates, shipping, delivery, auth codes, account alerts
- Generally OK without separate marketing consent if directly related to a transaction the user initiated
- Still subject to A2P 10DLC registration in US
**For full sequence templates with copy and timing**: see [references/sequence-templates.md](references/sequence-templates.md).
---
## SMS Copy Guidelines
### Structure
1. **Sender ID** ("From Acme:" or brand short code) — required
2. **Hook** — first 5 words decide if they read on
3. **Value** — what's in it for them, specifically
4. **CTA + short link** — single action, single URL
5. **Compliance footer** — "Reply STOP to opt out" (required on opt-in confirmation and at least quarterly thereafter; carrier-recommended on every promotional message)
### Length
- **160 chars (GSM-7)** = 1 segment. Aim here.
- **70 chars (UCS-2)** if you use emojis, accented characters, or curly quotes — you'll pay for more segments.
- **161306 chars** = 2 segments (concatenated SMS). Acceptable for richer messages, but you're paying double per send.
- **MMS** (image + up to 1,600 chars) = 35× the SMS cost. Use sparingly for high-impact moments.
### Voice
- Conversational, not corporate. SMS feels personal — write like you're texting a friend.
- No subject line, no formatting, no marketing-speak.
- Emojis are fine in moderation (one per message, situationally).
- ALL CAPS reads as shouting. Avoid except for explicit codes (e.g., "Use ACME10").
### Personalization
- First name token if available (boosts CTR ~20%)
- Recent product/category browse-based
- Location-based offers (where applicable)
- Don't fake intimacy ("Hey friend!") — it backfires
**For complete copy patterns by sequence type with character counts**: see [references/sequence-templates.md](references/sequence-templates.md).
---
## Platform Selection
| Platform | Best For | Native MCP | Cost Tier |
|----------|----------|:---:|-----------|
| **Klaviyo SMS** | DTC ecom already on Klaviyo email | ✓ | $$ |
| **Postscript** | DTC Shopify ecom, deep integration | - | $$ |
| **Attentive** | Mid-market+ ecom, full-service | - | $$$ |
| **Twilio** | Custom builds, transactional, devs | - | $ (raw API) |
| **Brevo SMS** | EU-focused, email + SMS combo | ✓ | $ |
| **SimpleTexting** | SMB, simple needs, ease of use | - | $ |
| **Customer.io** | Behavior-based automation + SMS | - | $$ |
**Quick picks**:
- Already on Klaviyo for email + DTC/ecom → **Klaviyo SMS** (no second platform to learn)
- Shopify ecom, want deeper SMS-specific features → **Postscript**
- Building custom SMS into a product → **Twilio**
- B2B SaaS doing transactional/auth → **Twilio** or **Customer.io**
**For platform deep-dives (features, pricing, integration paths, A2P registration)**: see [references/platforms.md](references/platforms.md).
---
## Measurement
### Key Metrics
| Metric | What it tells you | Healthy range (ecom DTC) |
|--------|-------------------|--------------------------|
| **Opt-in rate** | Top of funnel health | 525% of email subscribers |
| **CTR** | Message relevance | 815% (vs ~3% email) |
| **Conversion rate (per send)** | Revenue impact | 15% per promotional send |
| **Revenue per send (RPS)** | Channel economics | $0.20$2.00 |
| **Opt-out rate per send** | Audience fatigue | <2% per send, <0.5% for promotional |
| **Cost per send** | Channel cost discipline | $0.0075$0.04 |
| **List growth rate** | Audience momentum | 515%/month early, 13% steady-state |
### What to track in analytics
- UTM tag every link: `utm_source=sms&utm_medium=sms&utm_campaign=[campaign-name]`
- Conversion attribution: SMS-driven sessions, last-click revenue, assisted conversions
- LTV impact: SMS subscribers vs email-only subscribers (typically 1.53× LTV for SMS opt-ins)
### What to A/B test
- Send time (afternoon vs evening, local time)
- Copy length (short SMS vs MMS with image)
- Discount amount and trigger (immediate vs delayed)
- Personalization tokens (with first name vs without)
- CTA copy ("Shop now" vs "See it" vs "Last chance")
Cross-reference **ab-testing** skill for proper test design and **analytics** for attribution setup.
---
## Output Format
When the user asks for an SMS plan, return:
1. **Compliance check**: Are they registered for A2P 10DLC (if US)? Is the opt-in mechanism compliant? Flag blockers first.
2. **Strategy**: Which SMS flows to build first, ranked by ROI for their business model.
3. **Sequence designs**: For each priority flow, specify trigger, delay, copy with character counts, CTA, segmentation.
4. **Platform recommendation**: Based on stack, list size, and complexity.
5. **Measurement plan**: KPIs, benchmarks, A/B test queue.
6. **Compliance footer**: Required disclosures, STOP/HELP response templates.
Keep recommendations specific. Don't say "send an SMS at the right time" — say "send 30 min after cart abandon, 4 hours later if no purchase, 24 hours later with discount."
---
## Task-Specific Questions
1. Are you US, EU, or both? (Changes compliance approach entirely.)
2. Is A2P 10DLC registration complete (US)?
3. What platform are you on or considering?
4. Email list size and SMS opt-in rate (if any)?
5. What sequences do you already have running?
6. Are you DTC ecom, mobile app, B2B SaaS, services?
7. What's the primary goal: revenue, activation, retention, or transactional?
---
## Common Mistakes
1. **Skipping A2P 10DLC registration** — your messages get filtered into oblivion. Register first, send second.
2. **Treating SMS like email** — sending daily promotional blasts. Opt-out rates spike, list dies.
3. **Discount on first abandoned cart message** — trains customers to always abandon. Reserve for second or third send.
4. **Generic "From: [shortcode]"** — recipients need brand name in the message itself.
5. **Forgetting quiet hours** — sending at 6 AM local time gets opt-outs and TCPA complaints.
6. **No STOP/HELP handling** — non-negotiable. Every platform handles this; verify yours does.
7. **Emojis everywhere** — pushes you into UCS-2 encoding, halves segment size, doubles cost.
8. **Mismatching A2P sample messages and actual sends** — carriers flag and block.
9. **Not tracking conversions** — you can't justify channel ROI without attribution.
10. **No throttling on bulk sends** — burst sends trigger carrier filtering. Use platform throttling.
---
## Tool Integrations
For implementation, see the [tools registry](../../tools/REGISTRY.md). Key SMS tools:
| Tool | Best For | MCP | Guide |
|------|----------|:---:|-------|
| **Klaviyo** | E-commerce email + SMS combined | ✓ | [klaviyo.md](../../tools/integrations/klaviyo.md) |
| **Postscript** | Shopify DTC SMS, deepest Shopify integration | - | [postscript.md](../../tools/integrations/postscript.md) |
| **Attentive** | Mid-market+ DTC SMS, full-service | - | [attentive.md](../../tools/integrations/attentive.md) |
| **Twilio** | Raw API for custom builds, transactional, dev-first | - | [twilio.md](../../tools/integrations/twilio.md) |
| **Plivo** | Twilio alternative, lower per-send cost | - | [plivo.md](../../tools/integrations/plivo.md) |
| **AudienceTap** | AI-forward DTC, on-pack QR opt-in | - | [audiencetap.md](../../tools/integrations/audiencetap.md) |
| **Brevo** | EU email + SMS, SMB-friendly | ✓ | [brevo.md](../../tools/integrations/brevo.md) |
| **Customer.io** | Behavior-based SMS automation | - | [customer-io.md](../../tools/integrations/customer-io.md) |
---
## Related Skills
- **emails**: Sister channel — almost always run together. Email carries the long-form content; SMS carries the urgent nudges.
- **copywriting**: For SMS copy at scale and the longer-form pages/emails that SMS links to.
- **popups**: For phone number capture popups on-site.
- **churn-prevention**: For win-back flows that combine SMS + email.
- **onboarding**: For post-signup SMS milestone nudges.
- **analytics**: For attribution and RPS measurement.
- **ab-testing**: For SMS-specific test design.
- **lead-magnets**: For incentivizing opt-in (the "10% off for joining" offer).
+100
View File
@@ -0,0 +1,100 @@
{
"skill_name": "sms",
"evals": [
{
"id": 1,
"prompt": "We're a Shopify DTC brand doing $5M/year in skincare. We have 80K email subscribers but no SMS program yet. Where do we start?",
"expected_output": "Should check for product-marketing.md first. Should run Phase 0 compliance check: are they US-based, is A2P 10DLC registration started, is the opt-in mechanism planned. Should recommend Klaviyo SMS or Postscript given Shopify + DTC ecom (Klaviyo if already on Klaviyo email, Postscript for SMS-first depth). Should rank flows by ROI for skincare: (1) abandoned cart sequence first (highest-ROI flow), (2) post-purchase + replenishment (skincare has predictable cycles), (3) welcome opt-in flow with capture incentive, (4) win-back at 60-90 days. Should warn about treating SMS like email (frequency cap, relevance bar, real per-send cost ~$0.0075-$0.04). Should reference compliance.md for opt-in disclosure language and quiet hours.",
"assertions": [
"Checks for product-marketing.md",
"Runs compliance/A2P 10DLC readiness check",
"Recommends Klaviyo SMS or Postscript with rationale",
"Prioritizes abandoned cart as highest-ROI flow",
"Mentions replenishment for skincare specifically",
"Warns about treating SMS like email",
"References compliance.md or opt-in disclosure requirements",
"Mentions per-send cost economics"
],
"files": []
},
{
"id": 2,
"prompt": "Write me an abandoned cart SMS sequence. We sell custom apparel, average order $80.",
"expected_output": "Should output a 3-message sequence following references/sequence-templates.md pattern. Should specify timing: Send 1 at 30 min after abandon (no discount, gentle reminder), Send 2 at 4 hours (soft urgency, no discount), Send 3 at 24 hours (discount allowed). Should include actual SMS copy with character counts (target 160 GSM-7 for 1 segment). Each message must start with sender ID 'From [Brand]:', have a single CTA + short link, and the first message should include 'Reply STOP to opt out' compliance footer. Should warn against discount on first send (trains customers to abandon). Should mention exclusion rules: stop sequence on purchase, opt-out, or 48 hours elapsed. Should recommend UTM tagging for attribution and cross-reference analytics skill for measurement.",
"assertions": [
"Outputs 3-message sequence with timing",
"Send 1 at 30 min, Send 2 at 4 hours, Send 3 at 24 hours",
"No discount on Send 1",
"Each message has sender ID + single CTA + short link",
"Character counts shown, target ~160 GSM-7",
"Compliance footer on first send (STOP to opt out)",
"Warns about discount on first send",
"Mentions exclusion rules",
"Mentions UTM tagging or attribution"
],
"files": []
},
{
"id": 3,
"prompt": "Can I just send SMS without any opt-in if customers gave me their phone number at checkout?",
"expected_output": "Should refuse and explain TCPA requires express written consent for marketing SMS. Should distinguish marketing SMS (requires express written consent) from transactional/account SMS (order updates, auth — implied consent during transaction OK if directly related). Should explain the express written consent requirements: clear disclosure adjacent to the phone field, frequency expectation, msg & data rates notice, STOP/HELP instructions, terms link, electronically captured with timestamp. Should mention penalty exposure: $500-$1,500 per message, class actions reach 7-8 figures. Should recommend implementing a compliant opt-in flow: checkbox + disclosure text, double opt-in optional but cleaner. Should reference compliance.md for the full disclosure template. Should warn that 'customers gave their number at checkout' is NOT sufficient for marketing SMS — it's only sufficient for the specific transaction's communications.",
"assertions": [
"Refuses the no-opt-in approach",
"Distinguishes marketing SMS from transactional SMS",
"Lists express written consent requirements",
"Mentions TCPA penalty exposure ($500-$1,500 per message)",
"Mentions class action risk",
"Recommends compliant opt-in flow",
"References compliance.md",
"Clarifies checkout phone capture is not marketing consent"
],
"files": []
},
{
"id": 4,
"prompt": "Our SMS list is 50K subscribers. We send 3 promotional messages per week. Opt-out rate has crept up to 4% per send. What's wrong?",
"expected_output": "Should diagnose this as audience fatigue from over-sending. Should reference healthy benchmarks: opt-out rate should be <2% per send and <0.5% for promotional sends — 4% is significantly elevated. Should review send frequency: 3 promotional sends/week is on the high side; recommend reducing to 1-2/week, especially for newer subscribers. Should audit relevance: are sends segmented or going to entire list? Generic blasts to a 50K list will burn out the inactive 30K. Should recommend segmenting by engagement (recently engaged vs cold), purchase recency, and opt-in source. Should suggest reactivating cold subscribers with a re-engagement flow before sending more promos. Should warn that 4% opt-out per send means the list is being destroyed at the rate of ~2K/week. Should cross-reference analytics for proper measurement and the principle 'every send must justify itself.'",
"assertions": [
"Diagnoses as over-sending / audience fatigue",
"Cites healthy benchmark (<2% opt-out per send, <0.5% promotional)",
"Recommends reducing send frequency",
"Recommends segmentation by engagement",
"Suggests reactivation flow for cold subscribers",
"Calculates list erosion impact",
"Mentions 'every send must justify itself' principle"
],
"files": []
},
{
"id": 5,
"prompt": "We just submitted our A2P 10DLC registration and our sends are working. Can we start scaling to 100K+ messages per day?",
"expected_output": "Should ask about phone number type currently in use: 10DLC, toll-free, or short code. Should explain throughput limits: 10DLC standard brand ~4-10 msg/sec, verified brand ~75-100+ msg/sec, toll-free ~3 msg/sec, short code 100+ msg/sec. Should calculate: 100K msgs at 10 msg/sec = ~2.8 hours of continuous send time, may run into quiet hour cutoff. Should recommend short code lease for 100K+/day sustained volume. Should warn about carrier filtering on burst sends — use platform throttling. Should mention that sample message text from A2P registration must match actual sends or carriers will flag. Should recommend monitoring trust score and deliverability dashboards. Should reference platforms.md for short code provisioning details.",
"assertions": [
"Asks about phone number type (10DLC vs toll-free vs short code)",
"Explains throughput limits with specific msg/sec numbers",
"Calculates time-to-send for 100K volume",
"Mentions quiet hour considerations",
"Recommends short code for high sustained volume",
"Warns about carrier filtering / throttling",
"Mentions A2P sample text alignment requirement",
"References platforms.md or trust score monitoring"
],
"files": []
},
{
"id": 6,
"prompt": "Should we put emojis in our SMS messages? Other brands seem to use them a lot.",
"expected_output": "Should explain the cost trade-off: emojis force UCS-2 encoding, which cuts segment size from 160 GSM-7 chars to 70 chars. A 100-char message with one emoji becomes 2 segments billed instead of 1 — effectively doubling the per-send cost. Should advise: 1 emoji per message max, situationally relevant, only when the emoji genuinely earns its segment cost (high-energy promotional, brand-personality fit, etc.). Should warn against emoji clutter — it signals 'mass send' rather than personal. Should note that some accented characters (curly quotes, em dashes) also force UCS-2 — copy-pasting from Word/Google Docs is a common silent cause of doubled costs. Should recommend testing in the platform's preview to verify segment count before scheduling. Should remind that segment count matters at scale: 100K sends at 2 segments instead of 1 = $750-$4,000 in extra cost per campaign.",
"assertions": [
"Explains UCS-2 encoding cost",
"Specifies 160 GSM-7 vs 70 UCS-2 segment sizes",
"Recommends max 1 emoji per message",
"Warns about doubled per-send cost",
"Mentions accented characters / curly quotes also trigger UCS-2",
"Recommends previewing segment count",
"Calculates cost impact at scale"
],
"files": []
}
]
}
+202
View File
@@ -0,0 +1,202 @@
# SMS Compliance Reference
Comprehensive compliance reference for SMS marketing across major jurisdictions, opt-in copy templates, and STOP/HELP response templates.
> This is operational guidance, not legal advice. For high-volume programs (50K+ subscribers) or any program with non-trivial revenue, run your compliance setup past a TCPA-experienced attorney.
---
## United States — TCPA
### What it is
The Telephone Consumer Protection Act (1991, amended) regulates marketing calls and texts. The FCC enforces it; private plaintiffs sue under it. Statutory damages: $500$1,500 **per message**. Class actions easily reach 78 figures.
### Consent tiers
| Type | What it covers | How to capture |
|------|---------------|----------------|
| **Express written consent** | Marketing SMS (sales, promotions, offers) | Checkbox + clear disclosure language, captured electronically with timestamp |
| **Express consent (non-written)** | Informational/transactional (delivery, account alerts) | Phone number provided during transaction with awareness it'll be used to text |
| **Established business relationship** | NOT sufficient for marketing SMS | Doesn't apply |
### Express written consent requirements
The opt-in flow must capture all of:
1. The recipient agreed to receive marketing SMS from your brand
2. The recipient understands consent is not a condition of purchase
3. The disclosure showed frequency expectation, message and data rate notice, STOP/HELP instructions, terms link
4. The agreement was electronically recorded with timestamp
### Opt-in disclosure template (compliant)
```
By signing up via text, you agree to receive recurring automated promotional and
personalized marketing text messages (e.g., cart reminders) from [Brand] at the
cell number used when signing up. Consent is not a condition of any purchase.
Reply HELP for help and STOP to cancel. Msg frequency varies. Msg & data rates
may apply. View [Terms](link) and [Privacy](link).
```
Place this **directly adjacent** to the phone number field and submit button. Do not bury it in a footer.
### Quiet hours
- **Federal**: 8am9pm in the recipient's local time zone
- **Stricter states**: Florida (8am8pm), Oklahoma (8am8pm), Washington (8am8pm)
- **Carrier-recommended**: 9am8pm recipient-local
- **Practical default**: 9am8pm recipient-local for safety
Time zone is determined by area code, but area codes lie (people move). Major platforms (Klaviyo, Postscript, Attentive) handle this automatically; verify yours does.
### STOP/HELP handling
**STOP variants you must honor**: STOP, END, CANCEL, UNSUBSCRIBE, QUIT, STOPALL, OPTOUT
**STOP response** (after STOP received):
```
You're unsubscribed from [Brand] alerts. No more messages will be sent. Reply HELP for help.
```
**HELP variants**: HELP, INFO
**HELP response**:
```
[Brand] alerts: For help, visit [URL] or email [support@brand.com]. Msg & data rates may apply. Reply STOP to cancel.
```
**Critical rules**:
- Honor STOP **within seconds**, every time, every keyword variant
- Do not require the recipient to log in or visit a website to opt out
- One STOP confirmation is allowed; do not send additional messages after
- HELP responses do not count as marketing messages and are not subject to quiet hours
### Sample TCPA-compliant footer language by sequence type
- **Opt-in confirmation**: "Reply HELP for help, STOP to cancel. Msg & data rates may apply." — required
- **Recurring promotional**: "Reply STOP to opt out" — required quarterly minimum; carrier-recommended every send
- **Transactional**: Not required by TCPA but carriers expect it; include for safety
---
## United States — A2P 10DLC
### What it is
Application-to-Person 10-Digit Long Code registration, run by The Campaign Registry (TCR). Required for businesses sending SMS through 10DLC numbers (regular long codes) since 2022. Carriers (T-Mobile, AT&T, Verizon) enforce this; unregistered traffic gets throttled or blocked.
### Registration components
1. **Brand registration**
- Legal entity name, EIN, business type
- Trust score assigned (Standard or Verified)
- Higher trust = better throughput, lower fees
2. **Campaign registration** (one per use case)
- Use case: Marketing, Account Notification, Customer Care, Public Service, Higher Education, Polling and Voting, 2FA, Delivery Notification, etc.
- Sample message text (must match what you actually send)
- Opt-in flow description and screenshot
- Opt-out language
- Help message language
- Volume estimate
3. **Phone number assignment** to campaigns
### Throughput tiers (varies by carrier and trust score)
| Trust score + use case | Throughput |
|------------------------|-----------|
| Verified brand, marketing | 75100+ msg/sec |
| Standard brand, marketing | 410 msg/sec |
| Unregistered | 0.1 msg/sec or blocked |
### Common rejections
- Sample message text doesn't match actual sends
- Opt-in flow screenshot doesn't show required disclosure language
- "SHAFT" content (Sex, Hate, Alcohol, Firearms, Tobacco) without explicit use case
- Generic or vague campaign descriptions
**Process time**: 17 business days. Plan for this in launch timelines.
---
## EU / UK — GDPR + ePrivacy Directive
### Consent requirements
- **Explicit opt-in**: clear affirmative action (no pre-checked boxes)
- **Specific**: opt-in must be for marketing SMS specifically, separate from generic ToS
- **Informed**: data subject must know who's processing and why
- **Freely given**: can't be bundled with service access
### Mandatory provisions
- Sender identity in every message
- Easy opt-out in every message
- Right to access data (DSARs)
- Right to deletion
- Records of consent kept for the duration of processing + statute of limitations
### Penalty exposure
GDPR fines up to €20M or 4% of global revenue, whichever is higher.
---
## Canada — CASL
### Consent
- **Express consent**: explicit opt-in (same standard as US TCPA express written consent)
- **Implied consent**: existing business relationship within 24 months — limited use, expires
### Every message must include
- Sender identification (legal name + any operating names)
- Mailing address
- Phone, email, or website contact
- Unsubscribe mechanism that works within 10 business days
### Penalty exposure
Up to CAD $10M per violation. Enforced by the CRTC.
---
## Australia — Spam Act 2003
- Express or inferred consent (inferred has narrow application)
- Sender ID required
- Functional unsubscribe required
- Enforced by ACMA
---
## Multi-jurisdictional programs
If you send across US + EU + Canada simultaneously:
- Default to the **strictest** standard across all jurisdictions (US TCPA express written consent + GDPR explicit opt-in)
- Track consent jurisdiction per subscriber
- Default quiet hours to recipient-local 9am8pm
- Include all required identifiers in every message
---
## Audit-ready compliance checklist
- [ ] A2P 10DLC registration complete (US, if applicable)
- [ ] Opt-in flow includes all required disclosures, adjacent to phone field
- [ ] Disclosure text matches A2P registered sample messages
- [ ] Opt-in event captures: timestamp, IP, page URL, exact disclosure shown
- [ ] STOP/HELP keywords honored across all variants
- [ ] Quiet hours enforced at platform level (recipient-local time)
- [ ] Privacy policy includes SMS section
- [ ] Terms of service include SMS terms
- [ ] Consent records retained per applicable law (typically 4+ years US, longer EU)
- [ ] Process for handling DSARs (EU) and consent revocation
- [ ] Sender identity in every message
- [ ] Compliance footer on every promotional message (recommended) or quarterly minimum (required)
- [ ] Test STOP/HELP from a real phone number quarterly to verify it still works
+318
View File
@@ -0,0 +1,318 @@
# SMS Platform Reference
Deep-dive on the major SMS marketing platforms — features, pricing, A2P 10DLC support, and integration paths.
> Pricing is approximate and changes regularly. Always confirm at the vendor's site before committing.
---
## Klaviyo SMS
**Best for**: DTC ecom brands already using Klaviyo for email.
### Key features
- Native integration with Klaviyo email and segmentation
- Shared subscriber profile across email + SMS
- Built-in A2P 10DLC registration
- Flow builder shared with email flows
- Conversational SMS (two-way) supported
### Pricing
- Bundled with Klaviyo plans, billed per SMS credit
- US: ~$0.0075$0.015 per SMS; MMS ~$0.04
- Free tier: 150 SMS credits/month on lower email tiers
### Integration paths
- Direct Shopify, WooCommerce, BigCommerce, Magento integration
- API for custom platforms
- MCP server available
### Compliance
- A2P 10DLC registration handled in-platform
- Toll-free and short code provisioning available (short code adds $1,000+/mo)
- Quiet hours enforced per recipient time zone (configurable)
### Watch out for
- Email + SMS combined billing can spike fast on large lists
- Short code costs are real overhead; only worthwhile for 100K+ active SMS subscribers
---
## Postscript
**Best for**: Shopify-native DTC brands wanting SMS-specific tooling and onboarding support.
### Key features
- Deep Shopify integration (the deepest of any SMS platform)
- Strong abandoned cart and browse abandonment automations
- AI Reply (auto-reply trained on brand voice)
- Conversational SMS / live agent
- Audiences pulled from Shopify customer data
### Pricing
- Tiered plans: Starter (free, 1K msgs/mo), Growth ($100+/mo), Professional, Enterprise
- Pay-per-send adds on top: ~$0.015 per SMS, ~$0.04 per MMS
### Integration paths
- Shopify-first; limited support for non-Shopify
- API + webhooks available
### Compliance
- A2P 10DLC handled in-platform
- Strong opt-in compliance tools (popup builder, keyword opt-in)
- Quiet hours enforced
### Watch out for
- Steep cost increase past Starter tier
- Less useful if you're not on Shopify
---
## Attentive
**Best for**: Mid-market and enterprise DTC brands wanting full-service SMS.
### Key features
- Full-service: dedicated CSM, copy support, strategy
- Conversational SMS at scale
- Concierge sales-via-SMS
- Strong analytics and attribution
- Identity resolution (matching anon site visitors to phone numbers)
### Pricing
- Custom contracts; typically $1K$10K+/mo + per-send fees
- Annual contracts standard
- Pricing rarely makes sense for <50K SMS subscribers
### Integration paths
- Shopify, BigCommerce, Salesforce Commerce Cloud, custom
- Robust API
### Compliance
- Full A2P 10DLC managed
- Best-in-class compliance tooling and audit support
- Short code provisioning included on most plans
### Watch out for
- Contract terms can lock you in for 12+ months
- Overkill for early-stage brands
---
## Twilio
**Best for**: Custom builds, transactional SMS, B2B SaaS embedding SMS into products, developers.
### Key features
- Raw SMS API
- Pay-per-send pricing, no platform fees
- Massive global coverage (200+ countries)
- Programmable Voice, WhatsApp Business, RCS available alongside
- Studio (visual flow builder) for non-code automation
### Pricing
- US 10DLC SMS: $0.0079 per message
- US toll-free SMS: $0.0079 per message
- US short code SMS: $0.0079 per message + $1,000/mo lease
- MMS: ~$0.02
- Carrier surcharges layered on top (~$0.005 per US 10DLC)
- A2P 10DLC registration: ~$15 brand + $10/mo per campaign
### Integration paths
- API-first (REST + SDKs in Node, Python, Ruby, Go, etc.)
- No native ecom integrations — you build them
### Compliance
- A2P 10DLC registration in-platform but you do the work
- TwilioSendGrid (separate product) handles email-side compliance
- Quiet hours and STOP/HELP handling must be implemented by you
### Watch out for
- You're responsible for compliance — no hand-holding
- No native segmentation, deliverability dashboards, or marketing UI
- Best paired with Customer.io, Segment, or a custom orchestration layer
---
## Brevo (formerly Sendinblue)
**Best for**: EU-based brands, email + SMS combo, SMB-friendly.
### Key features
- Combined email + SMS + WhatsApp on one platform
- EU-headquartered, GDPR-native
- Generous free tier for email; SMS pay-per-send
- Marketing automation flows
- CRM included
### Pricing
- Free tier: 300 emails/day; SMS pay-per-send
- US SMS: ~$0.015 per message
- EU SMS: varies by country, ~€0.04–€0.07
### Integration paths
- Direct integrations: Shopify, WooCommerce, WordPress, Magento
- API + Zapier
- MCP server available
### Compliance
- GDPR + ePrivacy built-in
- A2P 10DLC for US (less polished than dedicated US platforms)
### Watch out for
- US SMS features lag behind Klaviyo/Postscript
- Best if you're EU-first or already on Brevo for email
---
## SimpleTexting
**Best for**: SMB, services businesses, simple campaign blasts, low-volume.
### Key features
- Easy-to-use UI
- Keyword opt-in for grassroots list building
- Built-in landing pages for opt-in
- Simple automation
### Pricing
- Plans start ~$30/mo for 500 credits, scaling up
- US SMS only
### Integration paths
- Zapier, Make, native to a few apps
- API available but basic
### Compliance
- A2P 10DLC handled
- TCPA tooling
### Watch out for
- Limited automation depth vs Klaviyo/Postscript
- Best for low-complexity, low-volume use cases (gyms, salons, real estate)
---
## Plivo
**Best for**: Custom SMS builds where per-send cost matters; Twilio-style API at a lower price point.
### Key features
- Direct Twilio competitor with similar surface area
- Powerpack for bulk sending with sticky sender across number pools
- A2P 10DLC handled in-platform
- WhatsApp, voice available alongside SMS
- SDKs for major languages
### Pricing
- US 10DLC SMS: ~$0.0055/msg (typically 2030% under Twilio)
- US short code SMS: similar + monthly lease
- MMS: ~$0.02
- Phone number rental: ~$0.80/mo local, ~$1/mo toll-free
### Integration paths
- API-first (REST + SDKs)
- No native ecom integrations — you build them
### Compliance
- A2P 10DLC managed in-platform
- Compliance plumbing (STOP/HELP, quiet hours) is your responsibility — same model as Twilio
### Watch out for
- Smaller ecosystem than Twilio (fewer ancillary products, integrations, community resources)
- WhatsApp tooling less mature
---
## AudienceTap
**Best for**: DTC brands wanting AI-forward creative tooling or on-pack QR opt-in as a primary acquisition channel.
> Newer platform — verify current capabilities, pricing, and API surface before committing.
### Key features
- SMS + email on one platform (similar combined model to Klaviyo)
- AI creative generation (SMS copy, subject lines, image variants)
- On-pack QR code opt-in: insert cards in shipped orders that drive SMS list growth
- Shopify, BigCommerce, headless commerce integrations
- A2P 10DLC managed in-platform
- Identity resolution and segmentation
### Pricing
- Tiered by subscriber count + send volume
- Per-send pricing comparable to other DTC SMS platforms
### Integration paths
- API access on Growth+ tiers
- Direct ecom integrations
- Webhooks for events
### Compliance
- A2P 10DLC handled in-platform
- TCPA tooling — verify enterprise-scale depth before committing for large lists
### Watch out for
- Newer entrant — fewer reference customers, less battle-tested at high volume than incumbents
- Some features rolled out recently — confirm what's GA vs beta before relying on them
---
## Customer.io
**Best for**: B2B SaaS, behavior-based automation, multi-channel orchestration (email + SMS + push).
### Key features
- Trigger SMS off product events (signup, milestone, churn risk)
- Powerful audience segmentation
- Workflow builder
- Real-time data sync via API/webhooks
### Pricing
- Plans start ~$150/mo, scaling with profile count
- SMS via Twilio integration or native (varies)
### Integration paths
- API-first
- Direct integrations with Segment, Heap, Mixpanel, etc.
### Compliance
- A2P 10DLC via Twilio if using native integration
- Granular subscription/consent management
### Watch out for
- Less ecom-tailored than Klaviyo/Postscript
- Best for product-led SaaS or apps with deep event tracking
---
## Quick selection table
| Stack / Goal | Recommended | Why |
|--------------|------------|-----|
| Shopify ecom, already on Klaviyo | **Klaviyo SMS** | One platform, one subscriber profile |
| Shopify ecom, SMS-first focus | **Postscript** | Deepest Shopify + SMS-specific features |
| Mid-market ecom, want concierge support | **Attentive** | Full-service team + tooling |
| Custom platform, B2B SaaS, transactional | **Twilio** | API-first, full control |
| Custom build, cost-sensitive | **Plivo** | ~2030% cheaper than Twilio per send |
| DTC wanting AI creative or on-pack QR opt-in | **AudienceTap** | AI-forward; insert-card opt-in is unique |
| EU-based SMB | **Brevo** | GDPR-native, EU-friendly pricing |
| Local services SMB, simple campaigns | **SimpleTexting** | Easy UI, low overhead |
| Product-led SaaS with event tracking | **Customer.io** | Behavior-based triggers |
---
## A2P 10DLC: what your platform should handle
Whatever you pick, confirm your platform handles:
- [ ] Brand and campaign registration with TCR
- [ ] Sample message text aligned with what you actually send
- [ ] Opt-in flow documentation submitted to carriers
- [ ] Trust score visibility (and a path to improve it)
- [ ] Throughput appropriate to your list size and send frequency
- [ ] STOP/HELP keyword handling
- [ ] Quiet hours by recipient time zone
- [ ] Suppression list management
- [ ] Consent record retention with timestamps
All major platforms above handle these. Twilio does the lowest-level work and pushes more responsibility onto you.
+282
View File
@@ -0,0 +1,282 @@
# SMS Sequence Templates
Full copy templates with character counts, timing, and segmentation logic for every major SMS flow.
> Character counts shown assume GSM-7 encoding. Emojis force UCS-2 (70 chars/segment instead of 160). All templates use `[Brand]`, `[FirstName]`, and `[short.link]` as substitution tokens.
---
## Welcome / Opt-In Confirmation
### Send 1 — Immediate (after opt-in)
```
From [Brand]: Welcome! Here's your 10% off code: WELCOME10. Shop now: [short.link]
Reply STOP to opt out, HELP for help. Msg & data rates may apply.
```
~155 chars / 1 segment (just). Footer required on first send.
### Send 2 — 24 hours later (optional)
```
From [Brand]: Don't forget your code WELCOME10 — expires in 48hrs. Top picks: [short.link]
```
~108 chars / 1 segment.
### Send 3 — 7 days later (optional, conditional on no purchase)
```
From [Brand]: Last chance for 10% off with WELCOME10. Expires tonight at midnight: [short.link]
```
~107 chars / 1 segment.
---
## Abandoned Cart (highest-ROI flow for ecom)
### Send 1 — 30 minutes after abandon
```
From [Brand]: Hey [FirstName], you left something behind! Your cart's here: [short.link]
```
~95 chars / 1 segment.
### Send 2 — 4 hours after abandon (if no purchase)
```
From [Brand]: Items in your cart are selling fast. Reserved for you for 24hrs: [short.link]
```
~98 chars / 1 segment.
### Send 3 — 24 hours after abandon (if no purchase, discount allowed)
```
From [Brand]: Still thinking? Here's 10% off to seal the deal: SAVE10. Shop: [short.link]
```
~99 chars / 1 segment.
**Notes**:
- Discount on Send 1 trains customers to abandon. Reserve for Send 2 or 3.
- Exclude customers who abandoned <$X in cart value or repeat abandoners (gaming the discount).
- Stop sequence on purchase, opt-out, or 48 hours elapsed.
---
## Browse Abandonment
### Send 1 — 1 hour after browse (single product or category)
```
From [Brand]: Still thinking about [product]? Take another look: [short.link]
```
~84 chars / 1 segment.
**Notes**:
- Trigger only after meaningful browse signal (3+ product views or 2+ min on product page).
- Exclude if a purchase happened on a different product.
---
## Post-Purchase Flow
### Send 1 — Immediately after purchase (transactional, separate consent)
```
From [Brand]: Order #12345 confirmed! We'll text shipping updates here. Track: [short.link]
```
~95 chars / 1 segment.
### Send 2 — Day of shipment
```
From [Brand]: Your order's on the way. Estimated delivery: [date]. Track: [short.link]
```
~92 chars / 1 segment.
### Send 3 — Day of delivery
```
From [Brand]: Your order should arrive today! Questions? Reply or visit [short.link]
```
~88 chars / 1 segment.
### Send 4 — 2 days after delivery (marketing consent required)
```
From [Brand]: How are you liking your [product]? Share a review for 15% off next order: [short.link]
```
~108 chars / 1 segment.
### Send 5 — 14 days after delivery (cross-sell, marketing consent)
```
From [Brand]: Goes great with your [product]: [related-item]. 10% off bundle: [short.link]
```
~99 chars / 1 segment.
---
## Win-Back (Lapsed Customers)
### Send 1 — 60-90 days after last purchase
```
From [Brand]: [FirstName], we miss you! Picks we think you'll love: [short.link]
```
~84 chars / 1 segment.
### Send 2 — 14 days later (if no purchase)
```
From [Brand]: Come back for 15% off your next order: COMEBACK15. Expires in 7 days: [short.link]
```
~106 chars / 1 segment.
### Send 3 — 14 days after Send 2 (final, if no purchase)
```
From [Brand]: Last chance — 20% off ends tonight: COMEBACK20. We'll stop texting if you'd rather: reply STOP. [short.link]
```
~130 chars / 1 segment.
**Notes**:
- After Send 3 with no engagement, suppress for 90 days minimum.
- After two full win-back cycles with no engagement, sunset (remove from active list).
---
## Promotional / Campaign Sends
### Flash sale (single send)
```
From [Brand]: 24-HOUR FLASH: 25% off everything with FLASH25. Ends midnight: [short.link]
```
~94 chars / 1 segment.
### Limited drop / launch
```
From [Brand]: New drop just landed: [product-name]. Limited stock, members get early access: [short.link]
```
~115 chars / 1 segment.
### Holiday / BFCM (2-send sequence)
Send 1 — Day of launch:
```
From [Brand]: Black Friday is LIVE — up to 50% off sitewide. Shop now: [short.link]
```
~92 chars / 1 segment.
Send 2 — Day of (or evening, expiration push):
```
From [Brand]: Last 6 hours of BFCM savings. Don't miss out: [short.link]
```
~73 chars / 1 segment.
---
## Transactional / Account Notifications
### Order confirmation
```
[Brand]: Order #12345 confirmed. Total $XX.XX. Track at [short.link]. Reply HELP for help.
```
### Shipping update
```
[Brand]: Your order #12345 shipped! Track: [short.link]. ETA [date].
```
### Delivery confirmation
```
[Brand]: Order #12345 delivered. Enjoy! Issues? Reply or [support-link].
```
### Auth code (2FA)
```
[Brand] verification code: 123456. Expires in 10 min. Do not share.
```
### Account alert
```
[Brand]: Sign-in from new device in [location]. Wasn't you? Secure: [short.link]
```
---
## Re-Engagement / Reactivation (Subscribers Who've Gone Cold)
For SMS subscribers who haven't engaged with any send in 60+ days.
### Send 1 — Soft reactivation
```
From [Brand]: We've missed you, [FirstName]! Here's what's new: [short.link]
```
~80 chars / 1 segment.
### Send 2 — Confirm interest (if no engagement)
```
From [Brand]: Want to keep hearing from us? Reply YES to stay on the list, or STOP to opt out.
```
~98 chars / 1 segment.
After no reply: suppress for 60 days, then remove from active list. This protects opt-out rate metrics and reduces wasted spend.
---
## Replenishment (Consumables Ecom)
For products with predictable usage cycles (skincare, supplements, coffee, pet food).
### Send 1 — At expected reorder window (e.g., 28 days for a 30-day supply)
```
From [Brand]: Running low on [product]? Reorder in one tap: [short.link]
```
~73 chars / 1 segment.
### Send 2 — 7 days later (if no purchase)
```
From [Brand]: Don't run out! 10% off your reorder of [product]: REFILL10 [short.link]
```
~92 chars / 1 segment.
---
## VIP / Loyalty Members
Higher frequency, exclusive offers, early access — different cadence rules apply but quiet hours and STOP still required.
### Early access
```
From [Brand]: VIPs get the new drop 24hrs early. Yours now: [short.link]
```
~72 chars / 1 segment.
### Loyalty milestone
```
From [Brand]: You've reached Gold status! Your perks: 15% off + free shipping. [short.link]
```
~95 chars / 1 segment.
---
## Segmentation rules across all flows
- **Suppress** customers in active sequences from promotional sends (no double-tap)
- **Suppress** opted-out subscribers from everything (platform handles this)
- **Frequency cap**: max 46 marketing sends/week per subscriber (lower for newer subscribers)
- **Quiet hours**: 9am8pm recipient-local time
- **Cool-off**: After a discount-driven purchase, suppress promotional sends for 14 days
+60 -1
View File
@@ -47,6 +47,7 @@ Quick reference for AI agents to discover tool capabilities and integration meth
| customer-io | Email | ✓ | - | [](clis/customer-io.js) | ✓ | [customer-io.md](integrations/customer-io.md) |
| sendgrid | Email | ✓ | - | [](clis/sendgrid.js) | ✓ | [sendgrid.md](integrations/sendgrid.md) |
| resend | Email | ✓ | ✓ | [](clis/resend.js) | ✓ | [resend.md](integrations/resend.md) |
| sequenzy | Email | ✓ | ✓ | ✓ | - | [sequenzy.md](integrations/sequenzy.md) |
| nitrosend | Email | ✓ | ✓ | - | - | [nitrosend.md](integrations/nitrosend.md) |
| kit | Email | ✓ | - | [](clis/kit.js) | ✓ | [kit.md](integrations/kit.md) |
| beehiiv | Newsletter | ✓ | - | [](clis/beehiiv.js) | - | [beehiiv.md](integrations/beehiiv.md) |
@@ -54,8 +55,17 @@ Quick reference for AI agents to discover tool capabilities and integration meth
| postmark | Email | ✓ | - | [](clis/postmark.js) | ✓ | [postmark.md](integrations/postmark.md) |
| brevo | Email/SMS | ✓ | - | [](clis/brevo.js) | ✓ | [brevo.md](integrations/brevo.md) |
| activecampaign | Email/CRM | ✓ | - | [](clis/activecampaign.js) | ✓ | [activecampaign.md](integrations/activecampaign.md) |
| twilio | SMS/Voice | ✓ | - | ✓ | ✓ | [twilio.md](integrations/twilio.md) |
| plivo | SMS/Voice | ✓ | - | - | ✓ | [plivo.md](integrations/plivo.md) |
| postscript | SMS | ✓ | - | - | - | [postscript.md](integrations/postscript.md) |
| attentive | SMS | ✓ | - | - | - | [attentive.md](integrations/attentive.md) |
| audiencetap | SMS/Email | ✓ | - | - | - | [audiencetap.md](integrations/audiencetap.md) |
| hunter | Email Outreach | ✓ | - | [](clis/hunter.js) | - | [hunter.md](integrations/hunter.md) |
| snov | Email Outreach | ✓ | - | [](clis/snov.js) | - | [snov.md](integrations/snov.md) |
| truelist | Email Verification | ✓ | ✓ | - | ✓ | [truelist.md](integrations/truelist.md) |
| github | Developer Intent | ✓ | - | [](clis/github-prospects.js) | ✓ | [github.md](integrations/github.md) |
| firecrawl | Site Scraping | ✓ | ✓ | - | ✓ | [firecrawl.md](integrations/firecrawl.md) |
| browserbase | Site Scraping | ✓ | ✓ | - | ✓ | [browserbase.md](integrations/browserbase.md) |
| lemlist | Email Outreach | ✓ | - | [](clis/lemlist.js) | - | [lemlist.md](integrations/lemlist.md) |
| instantly | Email Outreach | ✓ | - | [](clis/instantly.js) | - | [instantly.md](integrations/instantly.md) |
| google-ads | Ads | ✓ | ✓ | [](clis/google-ads.js) | ✓ | [google-ads.md](integrations/google-ads.md) |
@@ -180,6 +190,7 @@ Email marketing, transactional email, and automation platforms.
| **customer-io** | Behavior-based messaging | - |
| **sendgrid** | Transactional email at scale | - |
| **resend** | Developer-friendly transactional | ✓ |
| **sequenzy** | Lifecycle email, sequences, transactional email | ✓ |
| **kit** | Creator/newsletter focused | - |
| **beehiiv** | Newsletter platform | - |
| **klaviyo** | E-commerce email + SMS | - |
@@ -187,7 +198,24 @@ Email marketing, transactional email, and automation platforms.
| **brevo** | Email + SMS, popular in EU | - |
| **activecampaign** | Email automation + CRM | - |
**Agent recommendation**: Resend for transactional (dev-friendly). Postmark for deliverability. Customer.io for advanced automation. Kit for creators. Beehiiv for newsletters. Klaviyo for e-commerce email/SMS. ActiveCampaign for email + CRM combo.
**Agent recommendation**: Resend for transactional (dev-friendly). Sequenzy for lifecycle email, sequences, and agent-driven email marketing. Postmark for deliverability. Customer.io for advanced automation. Kit for creators. Beehiiv for newsletters. Klaviyo for e-commerce email/SMS. ActiveCampaign for email + CRM combo.
### SMS / Messaging
SMS and MMS marketing platforms and programmable messaging APIs.
| Tool | Best For | MCP Available |
|------|----------|:-------------:|
| **klaviyo** | DTC ecom already on Klaviyo email | - |
| **postscript** | Shopify DTC, SMS-first depth | - |
| **attentive** | Mid-market+ DTC, full-service | - |
| **twilio** | Custom API builds, transactional, dev-first | - |
| **plivo** | Twilio alternative, lower per-send cost | - |
| **audiencetap** | DTC with AI-forward creative + on-pack QR opt-in | - |
| **brevo** | EU SMB email + SMS combo | - |
| **customer-io** | Behavior-based SMS automation | - |
**Agent recommendation**: Klaviyo SMS for ecom already on Klaviyo email. Postscript for Shopify-first depth. Attentive for mid-market+ wanting concierge support. Twilio (or Plivo for lower cost) for custom builds and transactional/auth. AudienceTap when AI creative or on-pack QR opt-in matters.
### Advertising
@@ -289,6 +317,37 @@ Company and person data enrichment for sales and marketing.
**Agent recommendation**: Clearbit for enrichment. Apollo for prospecting and outbound. ZoomInfo for enterprise B2B data with intent signals. Clay for waterfall enrichment across multiple providers.
### Email Verification
Pre-outreach email deliverability validation.
| Tool | Best For | Notes |
|------|----------|-------|
| **truelist** | Bulk + single email deliverability validation | Returns `email_state` (ok / email_invalid / risky / unknown / accept_all) + `email_sub_state`. MCP server + 7-language SDKs available. |
**Agent recommendation**: Truelist for any prospect list before outreach — Apollo/ZoomInfo/Hunter data accuracy is typically 6080%, validation is non-negotiable to keep sender reputation healthy.
### Developer Intent / GitHub
Discovery channel for dev-tool SaaS prospecting via GitHub stargazers, forkers, and watchers.
| Tool | Best For | Notes |
|------|----------|-------|
| **github** | Stargazers / forks / watchers of competitor or adjacent repos | Public API; pair with Apollo/Clay/Hunter for email enrichment |
**Agent recommendation**: Use `github-prospects.js` CLI to pull stargazers/forks of 35 anchor repos (competitors, category leaders, complementary tools). Filter to users with `company` field set, then enrich missing emails via Apollo or Hunter, then validate via Truelist before outreach.
### Site Scraping (single-target only)
Programmatic page extraction for **individual public business sites** — not for the platforms hosting prospects (Google Maps, LinkedIn, Yelp, Apollo, etc.).
| Tool | Best For | Notes |
|------|----------|-------|
| **firecrawl** | Page → clean markdown / structured extraction | API + MCP; lower overhead for "just give me the content" |
| **browserbase** | Real Chromium when rendering, interaction, or session state is required | API + MCP (Stagehand); use when Firecrawl can't handle the page |
**Agent recommendation**: Default to Firecrawl for static-ish pages and structured extraction. Use Browserbase when the site requires JS rendering, form interaction, cookie consent, or auth — and when you want session recordings for debugging. **For both: discovery happens on platforms (manual browser); extraction happens on the prospect's own website URL.** Don't point either tool at LinkedIn, Google Maps, Yelp, or similar.
### Reviews
Review management and social proof platforms.
+257
View File
@@ -0,0 +1,257 @@
#!/usr/bin/env node
const TOKEN = process.env.GITHUB_TOKEN
const BASE_URL = 'https://api.github.com'
const USER_AGENT = 'marketingskills-prospects-cli'
function parseArgs(args) {
const result = { _: [] }
for (let i = 0; i < args.length; i++) {
const arg = args[i]
if (arg.startsWith('--')) {
const key = arg.slice(2)
const next = args[i + 1]
if (next && !next.startsWith('--')) {
result[key] = next
i++
} else {
result[key] = true
}
} else {
result._.push(arg)
}
}
return result
}
const args = parseArgs(process.argv.slice(2))
async function api(path, opts = {}) {
const url = path.startsWith('http') ? path : `${BASE_URL}${path}`
const headers = {
'Accept': 'application/vnd.github+json',
'X-GitHub-Api-Version': '2022-11-28',
'User-Agent': USER_AGENT,
}
if (TOKEN) headers['Authorization'] = `Bearer ${TOKEN}`
if (args['dry-run']) {
return {
_dry_run: true,
method: 'GET',
url,
headers: { ...headers, Authorization: TOKEN ? 'Bearer ***' : undefined },
}
}
const res = await fetch(url, { headers })
const rateLimitRemaining = res.headers.get('x-ratelimit-remaining')
const rateLimitReset = res.headers.get('x-ratelimit-reset')
if (res.status === 401 || res.status === 403) {
const body = await res.text()
return {
error: `HTTP ${res.status}`,
hint: TOKEN
? 'Token rejected — check GITHUB_TOKEN scopes (public_repo is enough for public data).'
: 'Set GITHUB_TOKEN env var to raise rate limit from 60/hr to 5000/hr.',
rate_limit_remaining: rateLimitRemaining,
rate_limit_reset_unix: rateLimitReset,
body,
}
}
if (!res.ok) {
const body = await res.text()
return { error: `HTTP ${res.status}`, body }
}
const data = await res.json()
const linkHeader = res.headers.get('link') || ''
const nextMatch = linkHeader.match(/<([^>]+)>;\s*rel="next"/)
return {
data,
next: nextMatch ? nextMatch[1] : null,
rate_limit_remaining: rateLimitRemaining,
}
}
async function paginate(path, { limit, perPage = 100 } = {}) {
const initial = path.includes('?') ? `${path}&per_page=${perPage}` : `${path}?per_page=${perPage}`
const all = []
let next = initial
let lastRate = null
while (next) {
const result = await api(next)
if (result._dry_run) return result
if (result.error) return result
lastRate = result.rate_limit_remaining
all.push(...result.data)
if (limit && all.length >= limit) {
return { data: all.slice(0, limit), rate_limit_remaining: lastRate, truncated: true }
}
next = result.next
}
return { data: all, rate_limit_remaining: lastRate, truncated: false }
}
async function getUser(login) {
const result = await api(`/users/${encodeURIComponent(login)}`)
if (result._dry_run || result.error) return result
return result.data
}
function matchesFilter(user, opts) {
if (!user) return false
if (opts['with-email'] && !user.email) return false
if (opts['with-company'] && !user.company) return false
if (opts['with-blog'] && !user.blog) return false
if (opts['type'] && user.type !== opts.type) return false
return true
}
async function enrichUsers(users, opts = {}, { concurrency = 5, targetCount } = {}) {
const matched = []
for (let i = 0; i < users.length; i += concurrency) {
const batch = users.slice(i, i + concurrency)
const profiles = await Promise.all(batch.map(u => getUser(u.login)))
for (const profile of profiles) {
if (!profile || profile.error) continue
if (matchesFilter(profile, opts)) matched.push(profile)
}
if (targetCount && matched.length >= targetCount) {
return matched.slice(0, targetCount)
}
}
return matched
}
function toCSV(users) {
const cols = ['login', 'name', 'company', 'email', 'blog', 'location', 'bio', 'twitter_username', 'public_repos', 'followers', 'created_at', 'html_url']
const escape = (v) => {
if (v === null || v === undefined) return ''
const s = String(v).replace(/\r?\n/g, ' ')
if (s.includes(',') || s.includes('"')) return `"${s.replace(/"/g, '""')}"`
return s
}
const lines = [cols.join(',')]
for (const u of users) {
lines.push(cols.map(c => escape(u[c])).join(','))
}
return lines.join('\n')
}
function parseRepo(input) {
if (!input) return null
const trimmed = input.replace(/^https?:\/\/github\.com\//, '').replace(/\.git$/, '').replace(/\/$/, '')
const parts = trimmed.split('/')
if (parts.length < 2) return null
return { owner: parts[0], repo: parts[1] }
}
async function main() {
const [command, ...rest] = args._
let result
switch (command) {
case 'stargazers': {
const repo = parseRepo(rest[0])
if (!repo) { result = { error: 'Usage: stargazers <owner/repo> [--limit N] [--target N] [--enrich] [--with-email] [--with-company] [--with-blog] [--format csv|json]' }; break }
const limit = args.limit ? parseInt(args.limit, 10) : undefined
const target = args.target ? parseInt(args.target, 10) : undefined
const page = await paginate(`/repos/${repo.owner}/${repo.repo}/stargazers`, { limit })
if (page._dry_run || page.error) { result = page; break }
let users = page.data
if (args.enrich || args['with-email'] || args['with-company'] || args['with-blog'] || args.type) {
users = await enrichUsers(users, args, { targetCount: target })
}
if (args.format === 'csv') {
console.log(toCSV(users))
return
}
result = { count: users.length, rate_limit_remaining: page.rate_limit_remaining, truncated: page.truncated, users }
break
}
case 'forks': {
const repo = parseRepo(rest[0])
if (!repo) { result = { error: 'Usage: forks <owner/repo> [--limit N] [--target N] [--enrich] [--with-email] [--with-company] [--with-blog] [--format csv|json]' }; break }
const limit = args.limit ? parseInt(args.limit, 10) : undefined
const target = args.target ? parseInt(args.target, 10) : undefined
const page = await paginate(`/repos/${repo.owner}/${repo.repo}/forks`, { limit })
if (page._dry_run || page.error) { result = page; break }
const forkOwners = page.data.map(f => f.owner)
let users = forkOwners
if (args.enrich || args['with-email'] || args['with-company'] || args['with-blog'] || args.type) {
users = await enrichUsers(forkOwners, args, { targetCount: target })
}
if (args.format === 'csv') {
console.log(toCSV(users))
return
}
result = { count: users.length, rate_limit_remaining: page.rate_limit_remaining, truncated: page.truncated, users }
break
}
case 'watchers': {
const repo = parseRepo(rest[0])
if (!repo) { result = { error: 'Usage: watchers <owner/repo> [--limit N] [--target N] [--enrich] [--with-email] [--with-company] [--with-blog] [--format csv|json]' }; break }
const limit = args.limit ? parseInt(args.limit, 10) : undefined
const target = args.target ? parseInt(args.target, 10) : undefined
const page = await paginate(`/repos/${repo.owner}/${repo.repo}/subscribers`, { limit })
if (page._dry_run || page.error) { result = page; break }
let users = page.data
if (args.enrich || args['with-email'] || args['with-company'] || args['with-blog'] || args.type) {
users = await enrichUsers(users, args, { targetCount: target })
}
if (args.format === 'csv') {
console.log(toCSV(users))
return
}
result = { count: users.length, rate_limit_remaining: page.rate_limit_remaining, truncated: page.truncated, users }
break
}
case 'user': {
const login = rest[0]
if (!login) { result = { error: 'Usage: user <username>' }; break }
result = await getUser(login)
break
}
case 'rate-limit': {
const res = await api('/rate_limit')
result = res._dry_run || res.error ? res : res.data
break
}
default:
result = {
error: 'Unknown command',
usage: {
stargazers: 'stargazers <owner/repo> [--limit N] [--target N] [--enrich] [--with-email] [--with-company] [--with-blog] [--type User|Organization] [--format csv|json]',
forks: 'forks <owner/repo> [--limit N] [--target N] [--enrich] [--with-email] [--with-company] [--with-blog] [--type User|Organization] [--format csv|json]',
watchers: 'watchers <owner/repo> [--limit N] [--target N] [--enrich] [--with-email] [--with-company] [--with-blog] [--format csv|json]',
user: 'user <username>',
'rate-limit': 'rate-limit',
},
notes: [
'Set GITHUB_TOKEN env var for 5000 req/hr (vs 60/hr unauthenticated).',
'Token needs only public_repo scope for public data; no scope is required to list public stargazers/forks.',
'--enrich fetches each users full profile (1 extra request per user). Use with --limit on large repos.',
'--with-email / --with-company / --with-blog imply --enrich.',
'--target N stops enrichment as soon as N users match the filters (saves API quota on restrictive filters).',
'--format csv outputs prospecting-ready CSV; default JSON.',
'Pair with Apollo, Clay, Hunter, or Truelist to fill in missing emails.',
],
}
}
console.log(JSON.stringify(result, null, 2))
}
main().catch(err => {
console.error(JSON.stringify({ error: err.message }))
process.exit(1)
})
+152
View File
@@ -0,0 +1,152 @@
# Attentive
Full-service SMS marketing platform for mid-market and enterprise direct-to-consumer brands. Combines tooling with dedicated success teams.
## Capabilities
| Integration | Available | Notes |
|-------------|-----------|-------|
| API | ✓ | REST API |
| MCP | - | Not available |
| CLI | - | None |
| SDK | - | Use API directly |
## Authentication
- **Type**: OAuth 2.0 or API Key (depending on integration type)
- **Header**: `Authorization: Bearer {access_token}`
- **Get credentials**: Account-level provisioning through Attentive integrations team
- **Note**: API access requires partnership or eligible plan
## Common Agent Operations
### Subscribe a user
```bash
POST https://api.attentivemobile.com/v1/subscriptions
{
"user": {
"phone": "+15551234567",
"email": "user@example.com"
},
"signUpSourceId": "...",
"subscriptionType": "MARKETING"
}
```
Sign-up source ID determines opt-in attribution and compliance disclosure shown.
### Unsubscribe
```bash
POST https://api.attentivemobile.com/v1/subscriptions/unsubscribe
{
"user": { "phone": "+15551234567" },
"subscriptionType": "MARKETING"
}
```
### Custom event tracking
```bash
POST https://api.attentivemobile.com/v1/events/custom
{
"user": { "phone": "+15551234567" },
"type": "abandoned_cart",
"properties": {
"cart_value": 89.99,
"items": ["Product A"]
}
}
```
### E-commerce events (purchase, add-to-cart, product view)
```bash
POST https://api.attentivemobile.com/v1/events/ecommerce/purchase
{
"user": { "phone": "+15551234567" },
"items": [{
"productId": "SKU-123",
"name": "Product A",
"price": { "value": 4999, "currency": "USD" },
"quantity": 1
}],
"occurredAt": "2026-05-15T10:00:00Z"
}
```
Similar endpoints for `/add_to_cart`, `/product_view`, `/checkout`.
### Send transactional message
```bash
POST https://api.attentivemobile.com/v1/messages/transactional
{
"user": { "phone": "+15551234567" },
"messageBody": "Your order #1234 shipped. Track: https://...",
"type": "ORDER_SHIPPING"
}
```
### List campaigns
```bash
GET https://api.attentivemobile.com/v1/campaigns
```
### Webhooks
Subscribe to: `subscriber.created`, `subscriber.unsubscribed`, `message.sent`, `message.delivered`, `message.failed`, `conversion.attributed`.
## API Pattern
REST + JSON. Bearer auth. Webhook signature verification via HMAC-SHA256.
## Key Features
- Concierge sales (live agents responding via SMS)
- Identity resolution (matching anonymous site visitors to phone numbers for retargeting)
- Strong analytics + attribution (multi-touch, conversion path)
- AI Journey AI / Pro AI (AI-generated send timing and copy)
- Custom Audience Manager (advanced segmentation)
- A/B testing built into campaign builder
- Two-way SMS at scale
- A2P 10DLC fully managed
- Short code provisioning included on most plans
- Dedicated CSM, copy support, strategy consults
## Pricing
- Custom contracts; typically $1K$10K+/mo platform fee + per-send fees
- Annual contracts standard
- Pricing rarely makes sense for <50K active SMS subscribers
- Negotiable based on volume and tier
## When to Use
- Mid-market+ DTC brand (50K+ active SMS subscribers, $5M+/yr revenue)
- Want dedicated CSM and copy support, not just tooling
- Need concierge two-way SMS at scale
- Multi-channel ecom team that wants single-pane SMS-first platform
- Want short code included rather than separately leased
- Identity resolution / cross-device matching matters
## When NOT to Use
- Smaller brands — too expensive, overkill
- Already on Klaviyo and SMS is secondary — Klaviyo SMS is simpler
- Shopify-only and want depth — Postscript is more Shopify-native
- Custom platform / B2B SaaS — Twilio
## Relevant Skills
- sms
- emails (run alongside)
- churn-prevention
- customer-research (identity resolution data)
+125
View File
@@ -0,0 +1,125 @@
# AudienceTap
SMS and email marketing platform built for direct-to-consumer brands. Newer entrant positioning as a more flexible, AI-forward alternative to Klaviyo / Postscript / Attentive with emphasis on creative automation and on-pack QR opt-in.
## Capabilities
| Integration | Available | Notes |
|-------------|-----------|-------|
| API | ✓ | REST API (confirm with vendor; access tied to plan tier) |
| MCP | - | Not available |
| CLI | - | None |
| SDK | - | Use API directly |
> Verify current API surface and capabilities at https://audiencetap.com before building against this guide — newer platform, surface evolves quickly.
## Authentication
- **Type**: API Key (Bearer)
- **Header**: `Authorization: Bearer {api_key}`
- **Get key**: AudienceTap dashboard → Settings → API
- **Note**: API access generally requires Growth or Pro tier
## Common Agent Operations
### Subscribe a user
```bash
POST https://api.audiencetap.com/v1/subscribers
{
"phone_number": "+15551234567",
"email": "user@example.com",
"first_name": "Jane",
"opt_in_source": "checkout",
"list_id": "..."
}
```
### Unsubscribe
```bash
POST https://api.audiencetap.com/v1/subscribers/unsubscribe
{
"phone_number": "+15551234567",
"channel": "sms"
}
```
### Track event
```bash
POST https://api.audiencetap.com/v1/events
{
"subscriber": { "phone_number": "+15551234567" },
"event_name": "abandoned_cart",
"properties": {
"cart_value": 89.99,
"items": ["Product A"]
}
}
```
### Send transactional message
```bash
POST https://api.audiencetap.com/v1/messages/transactional
{
"phone_number": "+15551234567",
"body": "Your order #1234 shipped. Track: https://...",
"category": "shipping"
}
```
### List flows / automations
```bash
GET https://api.audiencetap.com/v1/flows
```
### Webhooks
Subscribe to: subscriber events, message delivery events, conversion attribution. Configured in dashboard.
## API Pattern
REST + JSON. Bearer auth. Pagination conventions vary by endpoint — confirm in current docs.
## Key Features
- SMS + email on one platform (positioned similarly to Klaviyo's combined product)
- AI creative generation (subject lines, SMS copy, image variants)
- On-pack QR code opt-in (insert-card based opt-in for ecom shipments)
- Shopify, BigCommerce, and headless commerce integrations
- A2P 10DLC handled in-platform
- Automation builder for cart, post-purchase, win-back, etc.
- Identity resolution (matching anonymous visitors to known subscribers)
## Pricing
- Plans typically tiered by subscriber count + send volume
- Per-send pricing comparable to other DTC SMS platforms (~$0.015 SMS, ~$0.04 MMS)
- Confirm current pricing at https://audiencetap.com — newer platform with evolving plans
## When to Use
- Mid-market DTC brand willing to try a newer platform for better AI tooling or pricing leverage
- Brand wanting on-pack QR opt-in as a primary acquisition channel (printed insert cards driving SMS opt-in)
- Want SMS + email under one roof with stronger AI features than incumbents currently offer
- Evaluating alternatives during a contract negotiation with Klaviyo / Postscript / Attentive
## When NOT to Use
- Need a fully battle-tested platform with deep ecosystem — incumbents have more integrations and case studies
- Compliance tooling at enterprise scale — verify A2P / TCPA depth before committing for large lists
- B2B SaaS, transactional, or developer-first use — Twilio or Plivo
## Relevant Skills
- sms
- emails
- referrals (on-pack QR opt-in is a referral-adjacent acquisition channel)
- directory-submissions (on-pack insert cards as an offline channel)
+111
View File
@@ -0,0 +1,111 @@
# Browserbase
Headless browser as a service. Spin up real Chromium browsers via API, drive them with Playwright/Puppeteer, get full session recordings. Useful when a target site requires JS rendering, user interaction, or session state that simple HTTP fetches can't handle.
## Capabilities
| Integration | Available | Notes |
|-------------|-----------|-------|
| API | ✓ | REST API for session management |
| MCP | ✓ | Official Browserbase MCP server (Stagehand) |
| CLI | - | None official |
| SDK | ✓ | Node, Python; drives Playwright/Puppeteer |
## Authentication
- **Type**: API Key
- **Header**: `x-bb-api-key: YOUR_API_KEY`
- **Get key**: https://www.browserbase.com/settings
- **Env vars**: `BROWSERBASE_API_KEY`, `BROWSERBASE_PROJECT_ID`
- **Base URL**: `https://api.browserbase.com`
## Core Operations
### Create a browser session
```bash
POST https://api.browserbase.com/v1/sessions
x-bb-api-key: YOUR_API_KEY
{
"projectId": "YOUR_PROJECT_ID"
}
```
Returns a session ID and a WebSocket URL (`connectUrl`) you connect to with Playwright or Puppeteer.
### Connect with Playwright (Node)
```js
import { chromium } from 'playwright-core';
import { Browserbase } from '@browserbasehq/sdk';
const bb = new Browserbase({ apiKey: process.env.BROWSERBASE_API_KEY });
const session = await bb.sessions.create({ projectId: process.env.BROWSERBASE_PROJECT_ID });
const browser = await chromium.connectOverCDP(session.connectUrl);
const page = await browser.newPage();
await page.goto('https://joescoffeeshop.com');
const html = await page.content();
const title = await page.title();
await browser.close();
```
### List session recordings
```bash
GET https://api.browserbase.com/v1/sessions/{sessionId}/logs
```
Useful for debugging when a scrape doesn't return what you expected — session recordings show exactly what the browser saw.
### Stagehand (high-level AI-friendly wrapper)
Browserbase ships [Stagehand](https://github.com/browserbase/stagehand), a Playwright wrapper with `act()`, `extract()`, and `observe()` methods that take natural-language instructions instead of CSS selectors. Stagehand also publishes an MCP server.
```js
import { Stagehand } from '@browserbasehq/stagehand';
const stagehand = new Stagehand({ env: 'BROWSERBASE' });
await stagehand.init();
await stagehand.page.goto('https://joescoffeeshop.com');
const contact = await stagehand.page.extract({
instruction: "Extract the business phone number, email, and street address",
schema: { phone: 'string', email: 'string', address: 'string' }
});
```
## When to Use (over Firecrawl)
- **Site requires user interaction** (cookie consent, age gate, click-through before content loads)
- **Form submission** to access a quote/contact page
- **Session state matters** (logged-in tools, multi-step flows)
- **Complex JS rendering** that even Firecrawl's headless option struggles with
- **Want full session recordings** for audit/debugging
- **AI-driven scraping** via Stagehand's natural-language extraction
For simple "scrape a page as markdown," **Firecrawl is lower-overhead**. Use Browserbase when you actually need the browser-as-a-service model.
## When NOT to Use
Same hard rules as Firecrawl. Browserbase gives you a more powerful browser, which means the temptation to bypass anti-scraping defenses is higher. Don't:
- ✗ Bulk-scrape Google Maps / search results, LinkedIn, Yelp, or any platform whose ToS forbids it
- ✗ Bypass CAPTCHAs, login walls, or bot protections
- ✗ Auto-fill forms on platforms you don't have an account or legitimate access to
**Use Browserbase for**: individual public business sites the user has a URL for, where rendering or interaction is required.
## Pricing
- Free tier: limited monthly minutes
- Paid tiers scale by browser minutes + concurrency
- Confirm at https://www.browserbase.com/pricing
## Relevant Skills
- prospecting (programmatic site visits for prospect enrichment)
- competitor-profiling (when competitor sites need rendering or interaction)
- cro (page audits that need real browser state)
- analytics (testing tracking implementations end-to-end)
+144
View File
@@ -0,0 +1,144 @@
# Firecrawl
Web scraping API that turns single pages or full sites into clean LLM-ready markdown. Handles JS rendering, anti-bot defenses, and proxy rotation so you can extract structured data from individual public business sites.
## Capabilities
| Integration | Available | Notes |
|-------------|-----------|-------|
| API | ✓ | REST API + Python/Node SDKs |
| MCP | ✓ | Official Firecrawl MCP server |
| CLI | - | None official |
| SDK | ✓ | Node, Python, Go, Rust |
## Authentication
- **Type**: API Key
- **Header**: `Authorization: Bearer fc-YOUR_API_KEY`
- **Get key**: https://www.firecrawl.dev/app/api-keys
- **Env var**: `FIRECRAWL_API_KEY`
- **Base URL**: `https://api.firecrawl.dev`
## Core Operations
### Scrape a single page
```bash
POST https://api.firecrawl.dev/v1/scrape
Authorization: Bearer fc-YOUR_API_KEY
{
"url": "https://joescoffeeshop.com",
"formats": ["markdown", "html"]
}
```
Returns the page as clean markdown (LLM-ready, no nav cruft) plus optional raw HTML.
### Map a site (discover all URLs)
```bash
POST https://api.firecrawl.dev/v1/map
{
"url": "https://example.com",
"limit": 100
}
```
Returns a list of URLs found on the site. Use this to identify key pages (`/pricing`, `/about`, `/contact`, `/team`) before scraping individually.
### Crawl multiple pages
```bash
POST https://api.firecrawl.dev/v1/crawl
{
"url": "https://example.com",
"limit": 20,
"scrapeOptions": {
"formats": ["markdown"]
}
}
```
Crawls multiple pages from a single site. **Use sparingly** — costs scale with pages. Set `limit` and `includePaths` to target specific URL patterns.
### Extract structured data
```bash
POST https://api.firecrawl.dev/v1/extract
{
"urls": ["https://joescoffeeshop.com"],
"schema": {
"phone": "string",
"address": "string",
"hours": "string",
"email": "string"
}
}
```
Returns data matching the schema — useful when you want consistent fields across many sites rather than raw markdown.
### Search the web
```bash
POST https://api.firecrawl.dev/v1/search
{
"query": "\"Joe's Coffee Shop\" Boulder Colorado",
"limit": 10
}
```
Web search + scrape of top results. Useful for cross-source verification (find a business's official site when you only have a name + location).
## MCP Tools (when used via MCP server)
| Tool | Purpose |
|------|---------|
| `firecrawl_scrape` | Single-page extraction |
| `firecrawl_map` | URL discovery on a site |
| `firecrawl_crawl` | Multi-page crawl |
| `firecrawl_extract` | Schema-driven structured data |
| `firecrawl_search` | Web search + scrape |
## When to Use
- **Local SMB prospecting**: verify a business's website status (live, weak, missing) at the URL level after manual Maps/Yelp discovery
- **Single-target enrichment**: pull contact info, hours, services from a business's own site
- **Competitor research**: scrape competitor pricing, features, customer pages (this is the primary use in `competitor-profiling` skill)
- **Programmatic page extraction**: when you need many sites' homepages or about pages in a consistent format
- **JS-heavy sites**: when the page won't render with a simple `curl` because content loads after page load
## When NOT to Use
**Critical — do not use Firecrawl to scrape platforms hosting prospects:**
-**Google Maps / Google search results** — Google ToS prohibits bulk extraction
-**LinkedIn** — explicit ToS violation, will get scraper accounts banned and risks legal exposure
-**Yelp** — ToS prohibits commercial scraping
-**Apollo / ZoomInfo / Clearbit listings** — their ToS prohibits using competing data extracts
-**Any platform you don't have a legitimate basis to extract from at scale**
**Use Firecrawl for**: the *business's own website* (which you found via manual discovery on those platforms). That's the line — discovery happens on platforms, extraction happens on individual public business sites.
## Pricing
- Free tier: limited monthly credits
- Paid tiers scale by request volume + concurrency
- Confirm at https://www.firecrawl.dev/pricing
## Rate Limits
- Default: tier-dependent (typically 520 concurrent requests on paid plans)
- Per-page cost varies by content type and rendering needs
## Relevant Skills
- prospecting (site enrichment for individual business URLs)
- competitor-profiling (primary use: full-site competitor analysis)
- ai-seo (scrape your own content for AI search optimization)
- content-strategy (scrape industry sites for content gap analysis)
+182
View File
@@ -0,0 +1,182 @@
# GitHub
GitHub REST API for prospecting use cases: listing users who star, fork, or watch a repo as a high-quality developer-intent signal.
## Capabilities
| Integration | Available | Notes |
|-------------|-----------|-------|
| API | ✓ | Public REST API, well-documented |
| MCP | - | Several community MCP servers exist; not bundled here |
| CLI | ✓ | [github-prospects.js](../clis/github-prospects.js) — stargazers, forks, watchers, user, rate-limit |
| SDK | ✓ | Official Octokit (JS, Python, Ruby, .NET, Go) |
## Authentication
- **Type**: Personal Access Token (PAT) or Fine-Grained PAT
- **Header**: `Authorization: Bearer {token}`
- **Get token**: https://github.com/settings/tokens
- **Scopes for prospecting**:
- Public data (stargazers, forks, public profiles): **no scope required** with a token, or unauthenticated
- Public repo metadata: `public_repo` scope
- **Env var**: `GITHUB_TOKEN`
### Rate limits
| Auth | Limit | When you hit it |
|------|-------|-----------------|
| Unauthenticated | 60 req/hr | Fine for one-off small lookups |
| Authenticated PAT | 5,000 req/hr | Sufficient for a 10K-star repo pull in one hour |
| GitHub App | 5,00015,000 req/hr | For high-volume use |
A 1,000-star repo with full enrichment (1 list call + 1 profile call per user) = ~1,011 requests. Always set a token.
## Common Agent Operations
### List stargazers (users who starred a repo)
```bash
GET https://api.github.com/repos/{owner}/{repo}/stargazers?per_page=100&page=1
Accept: application/vnd.github+json
X-GitHub-Api-Version: 2022-11-28
Authorization: Bearer {token}
```
Pagination via `Link` header (`rel="next"`, `rel="last"`). Default 30 per page, max 100.
Returns array of user objects with `login`, `id`, `html_url`, `type` (User or Organization). Full profile fields (email, company, blog, bio, location) require a follow-up call per user.
### List forks (gives fork owner profiles)
```bash
GET https://api.github.com/repos/{owner}/{repo}/forks?per_page=100&page=1
```
Each fork object includes the `owner` (the user/org that forked). Forks are a stronger signal than stars — they imply intent to modify, not just bookmark.
### List watchers (subscribers)
```bash
GET https://api.github.com/repos/{owner}/{repo}/subscribers?per_page=100&page=1
```
GitHub's "watch" → API's "subscribers". Smaller pool than stargazers but signals deeper engagement.
### Get user profile (enrichment)
```bash
GET https://api.github.com/users/{username}
```
Returns: `name`, `company`, `blog`, `email` (if public), `bio`, `twitter_username`, `location`, `public_repos`, `followers`, `created_at`, `hireable`.
**Key fields for prospecting**:
- `email`: only ~520% of users publish this. Always nullable.
- `company`: many users include `@org` syntax — strip the `@` for plain company name.
- `blog`: often a personal website where contact info is published.
- `twitter_username` / `bio`: useful for cross-channel research.
### Check rate limit
```bash
GET https://api.github.com/rate_limit
```
## Prospecting Workflows
### Workflow 1 — Stargazers of a competitor or adjacent tool
```bash
# 100 stargazers, enrich each one, only keep those with email or company set
node tools/clis/github-prospects.js stargazers vercel/next.js \
--limit 100 --enrich --format csv > nextjs-stars.csv
```
Filter the CSV in your spreadsheet by `company` set OR `email` set OR `blog` set. Hand off to Apollo/Clay/Hunter to enrich the rest with email-by-name+company.
### Workflow 2 — Forks of your own repo (warm intent)
People who fork your repo have already shown direct interest. High-conversion outreach prospects.
```bash
node tools/clis/github-prospects.js forks yourorg/yourrepo \
--enrich --with-email --format csv > my-fork-prospects.csv
```
### Workflow 3 — Watchers of a category-defining repo
Watchers are smaller in number but higher in intent — they're tracking changes, not just bookmarking.
```bash
node tools/clis/github-prospects.js watchers tldraw/tldraw \
--enrich --with-company --format csv > tldraw-watchers.csv
```
## CLI Reference
```bash
# Stargazers
node tools/clis/github-prospects.js stargazers <owner/repo> \
[--limit N] [--enrich] [--with-email] [--with-company] \
[--with-blog] [--type User|Organization] [--format csv|json]
# Forks
node tools/clis/github-prospects.js forks <owner/repo> [...same flags]
# Watchers (subscribers in API terms)
node tools/clis/github-prospects.js watchers <owner/repo> [...same flags]
# Single user lookup
node tools/clis/github-prospects.js user <username>
# Check rate limit
node tools/clis/github-prospects.js rate-limit
```
**Flags**:
- `--limit N`: cap total results pulled from the list endpoint
- `--target N`: when filtering with `--with-*`, stop enriching as soon as N users match (saves quota on restrictive filters)
- `--enrich`: fetch full profile per user (1 extra request each)
- `--with-email` / `--with-company` / `--with-blog`: filter to users with these fields set (implies `--enrich`)
- `--type User|Organization`: filter by account type
- `--format csv`: output prospecting-ready CSV; default is JSON
- `--dry-run`: preview the request without sending
## When to Use
- **SaaS prospecting** (primary use case): stargazers of a competitor, complement, or category-defining repo as in-market developer signal
- **Open-source product marketing**: see who's forking or watching your own repo for warm outreach
- **Developer-tool ICP discovery**: stargazers of `next.js`, `prisma`, `tailwindcss`, etc., signal a Next.js / Prisma / Tailwind developer
- **Trigger event monitoring**: a recent fork of a competitor's repo often signals dissatisfaction or active evaluation
## When NOT to Use
- **Email is your only signal you need** — GitHub yields email for only ~520% of users. Pair with Apollo, Clay, or Hunter for enrichment from name + company.
- **Hyper-broad lists** — a repo with 100K+ stars is mostly noise. Smaller, more specific repos (5K25K stars) give higher-signal lists.
- **You don't have a way to handle high-volume LinkedIn lookup downstream** — most enrichment from GitHub username goes through LinkedIn Sales Nav manually.
## Compliance Notes
- **GitHub data is public** — no ToS issue with reading the API. The ToS prohibits abusive scraping (bypassing rate limits, mass account creation), not legitimate API usage.
- **Personal emails published on GitHub** — users opt in to publishing their email. Treat as business contact when paired with company/blog signals; respect GDPR/CAN-SPAM for the downstream send.
- **Source URL lineage** — for every prospect added from GitHub, capture `html_url` (their profile URL) and the source repo. Required for GDPR DSAR defense.
- **Cool-down between large pulls** — even at 5,000 req/hr, don't burst-fingerprint. Pagination is naturally paced; respect `X-RateLimit-Remaining` headers.
## Pairing with Other Tools
Typical GitHub prospecting pipeline:
1. Pull stargazers/forkers via this CLI
2. Filter to users with company set (or other signal)
3. **Enrich missing emails** via Apollo / Clay / Hunter (lookup by name + company domain)
4. **Validate emails** via Truelist before adding to outreach list
5. **Hand off** to cold-email skill for outreach
See `skills/prospecting/references/saas-prospecting.md` and `data-sources.md` for the full prospecting framework.
## Relevant Skills
- prospecting (primary use case)
- cold-email (downstream outreach)
- competitor-profiling (deeper account-level research on individual stargazers worth pursuing)
+140
View File
@@ -0,0 +1,140 @@
# Plivo
Cloud communications API platform — SMS, MMS, voice, WhatsApp. Direct Twilio competitor with similar pricing and developer-first positioning.
## Capabilities
| Integration | Available | Notes |
|-------------|-----------|-------|
| API | ✓ | REST API |
| MCP | - | Not available |
| CLI | - | None official |
| SDK | ✓ | Node, Python, Ruby, PHP, Java, Go, .NET |
## Authentication
- **Type**: Basic auth with Auth ID + Auth Token
- **Header**: `Authorization: Basic base64(AuthID:AuthToken)`
- **Get credentials**: https://console.plivo.com → Account → Account Settings
- **Note**: Subaccounts available for isolating environments or customers
## Common Agent Operations
### Send SMS
```bash
POST https://api.plivo.com/v1/Account/{AuthID}/Message/
{
"src": "+15559876543",
"dst": "+15551234567",
"text": "Hello from Plivo"
}
```
### Send MMS
```bash
POST https://api.plivo.com/v1/Account/{AuthID}/Message/
{
"src": "+15559876543",
"dst": "+15551234567",
"text": "Check this out",
"type": "mms",
"media_urls": ["https://example.com/image.jpg"]
}
```
### Bulk send (powerpack)
Use Plivo's Powerpack feature to send from a pool of numbers with sticky sender + automatic A2P registration. Configured in console; messages then sent with `powerpack_uuid` instead of `src`.
```bash
POST https://api.plivo.com/v1/Account/{AuthID}/Message/
{
"powerpack_uuid": "...",
"dst": "+15551234567",
"text": "Hello"
}
```
### Get message details
```bash
GET https://api.plivo.com/v1/Account/{AuthID}/Message/{MessageUUID}/
```
### List messages
```bash
GET https://api.plivo.com/v1/Account/{AuthID}/Message/?limit=20&offset=0
```
### Rent a phone number
```bash
# Search available
GET https://api.plivo.com/v1/Account/{AuthID}/PhoneNumber/?country_iso=US&type=local
# Rent
POST https://api.plivo.com/v1/Account/{AuthID}/PhoneNumber/{NumberID}/
```
### Configure inbound message webhook on an Application
```bash
POST https://api.plivo.com/v1/Account/{AuthID}/Application/
{
"app_name": "SMS Receiver",
"message_url": "https://your-app.com/sms-webhook",
"message_method": "POST"
}
```
Then assign the application to the phone number.
### A2P 10DLC registration (US)
Configured through console UI under Compliance. Programmatic registration available for high-volume customers via dedicated API endpoints (request access).
## API Pattern
REST + JSON. Pagination via `limit` + `offset`. Webhook callbacks for inbound messages and delivery status (configured per-application).
## Pricing
- US 10DLC SMS: $0.0055/msg (typically lower than Twilio)
- US toll-free SMS: $0.0055/msg
- US short code SMS: similar + monthly lease
- MMS: ~$0.02
- Carrier surcharges layered on top
- Phone number rental: ~$0.80/mo local, ~$1/mo toll-free
Plivo typically prices 520% under Twilio at the per-send level. Less of an ecosystem advantage but real cost savings at high volume.
## Rate Limits
- Default: 1 msg/sec
- Powerpacks scale throughput based on number pool size and A2P trust
- Short codes: 100+ msg/sec
## When to Use
- Custom SMS build, want a Twilio-like API with lower cost
- High-volume sending where the per-message delta matters
- Want bulk sending with sticky sender via Powerpack
- B2B SaaS embedding SMS or transactional/auth at scale
## When NOT to Use
- DTC ecom marketing flows — Klaviyo, Postscript, Attentive
- Ecosystem matters more than price — Twilio's broader product surface (Voice, Studio, SendGrid, Segment, etc.) wins
- Need mature WhatsApp Business — Twilio has deeper WhatsApp tooling
## Relevant Skills
- sms
- onboarding (post-signup notifications)
+126
View File
@@ -0,0 +1,126 @@
# Postscript
SMS marketing platform built for Shopify direct-to-consumer brands. Deepest Shopify integration of any SMS platform.
## Capabilities
| Integration | Available | Notes |
|-------------|-----------|-------|
| API | ✓ | REST API |
| MCP | - | Not available |
| CLI | - | None |
| SDK | - | Use API directly |
## Authentication
- **Type**: API Key
- **Header**: `Authorization: Bearer {api_key}` or `X-Postscript-Api-Key: {api_key}`
- **Get key**: Postscript dashboard → Settings → API
- **Note**: Keys are scoped per shop
## Common Agent Operations
### Search subscribers
```bash
GET https://api.postscript.io/api/v2/subscribers?phone_number=%2B15551234567
```
### Create subscriber (opt-in)
```bash
POST https://api.postscript.io/api/v2/subscribers
{
"phone_number": "+15551234567",
"email": "user@example.com",
"first_name": "Jane",
"subscribed_at": "2026-05-15T10:00:00Z",
"opt_in_source": "checkout_keyword"
}
```
Must include valid opt-in metadata for TCPA compliance.
### Unsubscribe
```bash
DELETE https://api.postscript.io/api/v2/subscribers/{subscriberId}/subscription
```
### List keywords (e.g., JOIN, SAVE)
```bash
GET https://api.postscript.io/api/v2/keywords
```
### Send transactional message
```bash
POST https://api.postscript.io/api/v2/transactional/sms
{
"phone_number": "+15551234567",
"message": "Your order #1234 shipped. Track at https://..."
}
```
Transactional requires separate enablement; counts under transactional consent.
### List campaigns
```bash
GET https://api.postscript.io/api/v2/campaigns
```
### List automations (flows)
```bash
GET https://api.postscript.io/api/v2/automations
```
### Webhooks
Subscribe to events: `subscriber.created`, `subscriber.unsubscribed`, `message.delivered`, `message.failed`, `conversion.attributed`.
## API Pattern
REST + JSON. Standard `Bearer` auth. Pagination via `cursor` and `limit` (max 100).
## Key Features
- Native Shopify integration: purchases, abandoned carts, browse, product catalog auto-sync
- Strong abandoned cart and browse abandonment automation builders
- AI Reply (auto-reply trained on brand voice)
- Conversational SMS / live agent for two-way
- Opt-in tools: popups, keyword opt-in, checkout opt-in
- A2P 10DLC managed in-platform
- Reporting: revenue, click-through, conversion attribution, opt-out rate
## Pricing
- Plans: Starter (free, 1K msgs/mo), Growth ($100+/mo), Professional, Enterprise
- Per-send pricing on top: ~$0.015 SMS, ~$0.04 MMS
- Annual contracts standard at Growth+
- Pricing scales meaningfully past 50K subscribers
## When to Use
- Shopify DTC brand wanting SMS-specific tooling (vs combined email/SMS)
- Need deep abandoned cart, browse abandonment, post-purchase automation out of the box
- Want managed A2P 10DLC + compliance tools
- Mid-size DTC brand (10K500K SMS subscribers)
## When NOT to Use
- Non-Shopify ecom — integration is shallow
- Already on Klaviyo for email and SMS is secondary — Klaviyo SMS is simpler
- Mid-market/enterprise needing concierge support — Attentive
- Custom platform or B2B SaaS — Twilio
## Relevant Skills
- sms
- emails (run alongside via Klaviyo or similar)
- churn-prevention (win-back flows)
- onboarding (post-purchase activation)
+306
View File
@@ -0,0 +1,306 @@
# Sequenzy
Email marketing platform for lifecycle campaigns, automation sequences, subscriber management, transactional email, and analytics.
## Capabilities
| Integration | Available | Notes |
|-------------|-----------|-------|
| API | ✓ | REST API for subscribers, tags, events, campaigns, sequences, templates, transactional email, analytics, and webhooks |
| MCP | ✓ | `@sequenzy/mcp` stdio server for agent clients |
| CLI | ✓ | `@sequenzy/cli` for subscriber operations, transactional sends, and stats |
| SDK | - | Use the REST API directly |
## Authentication
- **Type**: API Key
- **Header**: `Authorization: Bearer ***`
- **Base URL**: `https://api.sequenzy.com/api/v1`
- **Legacy base URL**: `https://api.sequenzy.com/v1`
- **Environment variable**: `SEQUENZY_API_KEY`
## MCP
### Quick setup
```bash
npx @sequenzy/setup
```
The setup wizard logs in, creates a personal API key, and configures supported MCP clients when possible.
### Manual MCP server config
```json
{
"mcpServers": {
"sequenzy": {
"command": "npx",
"args": ["-y", "@sequenzy/mcp"],
"env": {
"SEQUENZY_API_KEY": "seq_user_your_key_here"
}
}
}
}
```
## CLI
### Install
```bash
# Using npx
npx sequenzy --help
# Or install globally
npm install -g @sequenzy/cli
```
### Login
```bash
sequenzy login
sequenzy whoami
```
### Common commands
```bash
# Subscribers
sequenzy subscribers list
sequenzy subscribers list --tag vip
sequenzy subscribers add user@example.com --tag premium --attr plan=pro
sequenzy subscribers get user@example.com
sequenzy subscribers remove user@example.com
# Transactional email
sequenzy send user@example.com --template welcome --var name=John
sequenzy send user@example.com --subject "Hello" --html "<h1>Hi!</h1>"
# Analytics
sequenzy stats
sequenzy stats --period 30d
sequenzy stats --campaign camp_abc123
sequenzy stats --sequence seq_xyz789
```
## Common Agent Operations
### Get account
```bash
GET https://api.sequenzy.com/api/v1/account
Authorization: Bearer ***
```
### List subscribers
```bash
GET https://api.sequenzy.com/api/v1/subscribers?page=1&limit=20&status=active&query=john&tags=customer,vip
Authorization: Bearer ***
```
### Create or update subscriber
```bash
POST https://api.sequenzy.com/api/v1/subscribers
Authorization: Bearer ***
Content-Type: application/json
{
"email": "user@example.com",
"firstName": "John",
"lastName": "Doe",
"tags": ["customer", "newsletter"],
"customAttributes": {
"plan": "pro"
}
}
```
### Add tag to subscriber
```bash
POST https://api.sequenzy.com/api/v1/subscribers/tags
Authorization: Bearer ***
Content-Type: application/json
{
"email": "user@example.com",
"tag": "vip"
}
```
### Trigger event for subscriber
```bash
POST https://api.sequenzy.com/api/v1/subscribers/events
Authorization: Bearer ***
Content-Type: application/json
{
"email": "user@example.com",
"event": "trial_started",
"properties": {
"plan": "pro"
}
}
```
### List campaigns
```bash
GET https://api.sequenzy.com/api/v1/campaigns
Authorization: Bearer ***
```
### Create draft campaign
Create a draft campaign and linked email. A sender profile must already be configured.
```bash
POST https://api.sequenzy.com/api/v1/campaigns
Authorization: Bearer ***
Content-Type: application/json
{
"name": "April Launch",
"subject": "A quick update",
"labels": ["launch"],
"html": "<p>Hello there!</p>"
}
```
### Send campaign test
```bash
POST https://api.sequenzy.com/api/v1/campaigns/{campaignId}/test
Authorization: Bearer ***
Content-Type: application/json
{
"to": "reviewer@example.com"
}
```
### Schedule campaign
```bash
POST https://api.sequenzy.com/api/v1/campaigns/{campaignId}/schedule
Authorization: Bearer ***
Content-Type: application/json
{
"scheduledAt": "2026-05-20T15:00:00Z"
}
```
### List sequences
```bash
GET https://api.sequenzy.com/api/v1/sequences
Authorization: Bearer ***
```
### Enable or disable sequence
```bash
POST https://api.sequenzy.com/api/v1/sequences/{sequenceId}/enable
POST https://api.sequenzy.com/api/v1/sequences/{sequenceId}/disable
Authorization: Bearer ***
```
### Send transactional email
Send via a saved template slug or by passing direct subject/body content.
```bash
POST https://api.sequenzy.com/api/v1/transactional/send
Authorization: Bearer ***
Content-Type: application/json
{
"to": "user@example.com",
"slug": "welcome",
"variables": {
"name": "John"
},
"subscriberExternalId": "user_123"
}
```
### Get metrics
```bash
GET https://api.sequenzy.com/api/v1/metrics
GET https://api.sequenzy.com/api/v1/metrics/campaigns/{campaignId}
GET https://api.sequenzy.com/api/v1/metrics/sequences/{sequenceId}
GET https://api.sequenzy.com/api/v1/metrics/recipients
Authorization: Bearer ***
```
### Webhooks
```bash
GET https://api.sequenzy.com/api/v1/webhooks
POST https://api.sequenzy.com/api/v1/webhooks
PATCH https://api.sequenzy.com/api/v1/webhooks/{id}
DELETE https://api.sequenzy.com/api/v1/webhooks/{id}
POST https://api.sequenzy.com/api/v1/webhooks/{id}/test
Authorization: Bearer ***
```
## Key Concepts
- **Subscribers** - Contacts with email, status, tags, custom attributes, and optional external IDs
- **Tags** - Lightweight labels used for targeting and segmentation
- **Segments** - Dynamic subscriber groups based on attributes or engagement
- **Campaigns** - Draftable and schedulable one-time marketing sends
- **Sequences** - Automated lifecycle flows that can be enabled, disabled, and measured
- **Templates** - Reusable email content for transactional and marketing workflows
- **Transactional emails** - Single-recipient or small batch sends triggered by product events
- **Engagement metrics** - Sent, delivered, bounced, opened, clicked, unsubscribed, and derived rates
## Safety Notes
- Inspect account, sender profile, audience, and target objects before mutating anything.
- Prefer creating drafts and sending tests before scheduling or enabling live delivery.
- Do not schedule a campaign, enable a sequence, or send a live transactional email without explicit approval.
- Use recipient status, bounce, complaint, and unsubscribe data to avoid sending to suppressed contacts.
- Use direct API calls for high-volume or scripted operations; use MCP or CLI for agent-driven interactive workflows.
## When to Use
- Managing subscribers, tags, lists, and segments
- Drafting and scheduling lifecycle campaigns
- Building onboarding, activation, retention, or winback sequences
- Sending product-triggered transactional emails
- Reviewing campaign, sequence, and recipient engagement metrics
- Connecting AI agents to email marketing operations through MCP
## Rate Limits
- Check the latest Sequenzy API documentation for plan-specific limits.
- Use pagination for list endpoints; subscriber lists support `page` and `limit` with a maximum limit of 100.
## Relevant Skills
- emails
- onboarding
- analytics
- launch
+184
View File
@@ -0,0 +1,184 @@
# Truelist
Email verification and deliverability validation. Validates single emails synchronously or bulk lists asynchronously. Returns an `email_state` + `email_sub_state` plus rich metadata (domain, MX record, suggested correction, disposable/role classification).
Spec source: [Truelist-Labs/truelist-openapi](https://github.com/Truelist-Labs/truelist-openapi) (OpenAPI 3.1).
## Capabilities
| Integration | Available | Notes |
|-------------|-----------|-------|
| API | ✓ | REST API, OpenAPI 3.1 spec |
| MCP | ✓ | Official [truelist-mcp](https://github.com/Truelist-Labs/truelist-mcp) server (Claude, Cursor, VS Code) |
| CLI | ✓ | Official Go [truelist-cli](https://github.com/Truelist-Labs/truelist-cli) |
| SDK | ✓ | Official: Node/TypeScript, Python, Ruby, PHP, Go, Java, C#/.NET. Framework integrations: Django, Laravel, Next.js, Rails, React, Svelte, Vue, WordPress |
## Authentication
- **Type**: Bearer token (API key)
- **Header**: `Authorization: Bearer YOUR_API_KEY`
- **Get key**: https://truelist.io/settings/api-keys
- **Base URL**: `https://api.truelist.io`
## Common Agent Operations
### Verify a single email (synchronous)
```bash
POST https://api.truelist.io/api/v1/verify_inline?email=user@example.com
Authorization: Bearer YOUR_API_KEY
```
No request body — the email is a query parameter. Returns a single-element `emails` array with verification fields:
```json
{
"emails": [
{
"address": "user@example.com",
"domain": "example.com",
"canonical": "user@example.com",
"mx_record": null,
"first_name": null,
"last_name": null,
"email_state": "ok",
"email_sub_state": "email_ok",
"verified_at": "2026-02-21T10:39:12.570Z",
"did_you_mean": null
}
]
}
```
### Bulk verification (asynchronous)
```bash
POST https://api.truelist.io/api/v1/verify
Authorization: Bearer YOUR_API_KEY
Content-Type: application/json
{
"emails": [
"user1@example.com",
"user2@example.com"
]
}
```
Processes the list in the background. The response acknowledges submission; results are available via the dashboard, the Truelist UI's CSV download, or via integrations (Mailchimp, Klaviyo, HubSpot, Zapier, Make, n8n, etc.).
For large lists, the dashboard's CSV upload + download flow is typically the lowest-friction path.
### Get account information
```bash
GET https://api.truelist.io/me
Authorization: Bearer YOUR_API_KEY
```
Returns email, name, UUID, time zone, admin role, API keys, and account plan info.
## Response Fields (per email)
| Field | Type | Description |
|-------|------|-------------|
| `address` | string | The email address validated |
| `domain` | string | The domain part of the address |
| `canonical` | string | Canonical form of the address |
| `mx_record` | string \| null | MX record for the domain |
| `first_name` | string \| null | First name if detected |
| `last_name` | string \| null | Last name if detected |
| `email_state` | enum | Overall validation verdict (see below) |
| `email_sub_state` | enum | More specific reason (see below) |
| `verified_at` | datetime (ISO 8601) | When verification ran |
| `did_you_mean` | string \| null | Suggested correction for typos |
## `email_state` values
| State | Meaning | What to do |
|-------|---------|-----------|
| `ok` | The email address is deliverable. | Include in outreach |
| `email_invalid` | The email address is not deliverable. | Exclude — would bounce |
| `risky` | May be deliverable but carries risk (role address, disposable, etc.) | Include cautiously, lower priority |
| `unknown` | Deliverability could not be determined (timeout/connection). | Skip or re-verify with Thorough strategy |
| `accept_all` | The mail server accepts all addresses (catch-all domain) | Include cautiously — can't confirm specific mailbox |
## `email_sub_state` values
| Sub-state | Meaning |
|-----------|---------|
| `email_ok` | Passed all checks |
| `is_disposable` | Disposable / temporary provider (e.g., 10minutemail) |
| `is_role` | Role-based address (info@, sales@, admin@) |
| `unknown_error` | Sub-state could not be determined |
| `failed_smtp_check` | SMTP check failed |
Pair the two: `email_state: ok` + `email_sub_state: is_role` means "deliverable but a role inbox," whereas `email_state: email_invalid` + `email_sub_state: failed_smtp_check` means "doesn't exist."
## Rate Limits
| Endpoint | Limit |
|----------|-------|
| `/api/v1/verify_inline` | 10 requests/second |
| `/api/v1/verify` | 10 requests/second |
| `/me` | 10 requests/second |
A 429 is returned on rate-limit exceed. Note: the per-email validation rate is separate and depends on your plan.
## Error Responses
| Code | Meaning |
|------|---------|
| 401 | Unauthorized — API key missing, invalid, or expired |
| 429 | Rate limit exceeded |
| 500 | Server error |
All error bodies follow `{"error": "<human-readable message>"}`.
## When to Use
- **Before adding contacts to any cold outreach list** — non-negotiable safety step. Apollo/ZoomInfo/Hunter data accuracy is typically 6080%; Truelist catches the rest.
- **Real-time form validation** — block disposable / typo'd emails at signup. Use the inline endpoint (or the [form validation widget](https://truelist.io/docs/form-validation-widget)).
- **Periodic list hygiene** — re-verify your active list quarterly to remove bounces before they hurt sender reputation.
- **Pre-import validation** on email platform imports (Mailchimp, Klaviyo, HubSpot, etc.) — direct integrations exist for most.
- **AI agent workflows** via the official MCP server for Claude, Cursor, and VS Code.
## Why This Step is Non-Negotiable
Cold email reputation is built over months and destroyed in days. ISPs (Gmail, Outlook, etc.) track sender reputation through:
- **Bounce rate** — bounces over 2% trigger throttling
- **Spam complaints** — spam traps in unvalidated lists generate complaints
- **Engagement** — sending to dead mailboxes hurts engagement metrics
A single unvalidated send to a bought or scraped list can damage a domain's sending reputation for months.
## Workflow Integration
Typical prospecting flow:
1. Build initial prospect list (Apollo, Clay, ZoomInfo, Hunter, GitHub stargazers, etc.)
2. **For agent-driven workflows**: use the Truelist MCP server to validate inline as the agent builds the list
3. **For programmatic workflows**: POST emails to `/api/v1/verify` for async bulk OR `/api/v1/verify_inline` for sync single
4. **For one-offs**: CSV upload via dashboard, download annotated CSV
5. Filter: keep `email_state: ok`, include `risky`/`accept_all` cautiously with a strategy, exclude `email_invalid`, re-verify `unknown`
6. Hand cleaned list to outreach platform (Instantly, Lemlist, Outreach, etc.) — see [outreach.md](outreach.md), [instantly.md](instantly.md), [lemlist.md](lemlist.md)
## Native Integrations (no API code required)
For non-developer workflows, Truelist has direct integrations:
- **Email platforms**: Mailchimp, Klaviyo, HubSpot, ActiveCampaign, Brevo, Constant Contact, ConvertKit, Drip
- **Automation**: Zapier, Make.com, n8n
- **CRM / sales**: Salesforce, Go High Level, Clay.com
- **Ecom**: BigCommerce
- **AI / agents**: MCP server (Claude, Cursor, VS Code)
See https://truelist.io/integrations for the current list.
## Relevant Skills
- prospecting (primary use case — validate before adding to outreach lists)
- cold-email (downstream outreach against the validated list)
- emails (transactional senders + subscriber list hygiene)
- popups (real-time form validation on opt-in capture)
+152
View File
@@ -0,0 +1,152 @@
# Twilio
Programmable communications platform: SMS, MMS, WhatsApp, voice, email (via SendGrid). The default low-level API for custom SMS builds, transactional messaging, and B2B SaaS embedding SMS into products.
## Capabilities
| Integration | Available | Notes |
|-------------|-----------|-------|
| API | ✓ | REST API, well-documented, mature |
| MCP | - | Not available natively (community wrappers exist) |
| CLI | ✓ | Official `twilio` CLI |
| SDK | ✓ | Node, Python, Ruby, PHP, Java, Go, C#, .NET |
## Authentication
- **Type**: Basic auth with Account SID + Auth Token (or API Key SID + Secret)
- **Header**: `Authorization: Basic base64(AccountSID:AuthToken)`
- **Get credentials**: https://console.twilio.com → Account Info
- **Recommendation**: Use API Keys (revocable, scoped) for production rather than the master Auth Token
## Common Agent Operations
### Send SMS
```bash
POST https://api.twilio.com/2010-04-01/Accounts/{AccountSid}/Messages.json
To=+15551234567
From=+15559876543
Body=Hello from Twilio
```
### Send MMS
```bash
POST https://api.twilio.com/2010-04-01/Accounts/{AccountSid}/Messages.json
To=+15551234567
From=+15559876543
Body=Check this out
MediaUrl=https://example.com/image.jpg
```
### List messages
```bash
GET https://api.twilio.com/2010-04-01/Accounts/{AccountSid}/Messages.json?PageSize=50
```
### Get message status
```bash
GET https://api.twilio.com/2010-04-01/Accounts/{AccountSid}/Messages/{MessageSid}.json
```
Status values: `queued`, `sending`, `sent`, `delivered`, `undelivered`, `failed`.
### List phone numbers
```bash
GET https://api.twilio.com/2010-04-01/Accounts/{AccountSid}/IncomingPhoneNumbers.json
```
### Buy a phone number
```bash
POST https://api.twilio.com/2010-04-01/Accounts/{AccountSid}/IncomingPhoneNumbers.json
PhoneNumber=+15559876543
```
### Configure webhook for inbound messages
```bash
POST https://api.twilio.com/2010-04-01/Accounts/{AccountSid}/IncomingPhoneNumbers/{Sid}.json
SmsUrl=https://your-app.com/sms-webhook
SmsMethod=POST
```
Inbound SMS POSTs to the webhook with: `From`, `To`, `Body`, `MessageSid`, `NumMedia`, etc.
### A2P 10DLC registration (US)
```bash
# Create brand
POST https://messaging.twilio.com/v1/a2p/BrandRegistrations
CustomerProfileBundleSid=...
A2PProfileBundleSid=...
# Create campaign
POST https://messaging.twilio.com/v1/Services/{ServiceSid}/Compliance/Usa2p
BrandRegistrationSid=...
Description=...
MessageSamples[]=Sample text 1
MessageFlow=Opt-in flow description
UseCase=MARKETING
```
Most workflows are clearer in the Console UI. Programmatic registration is for high-scale platforms managing many brands.
## API Pattern
REST + form-encoded request bodies (not JSON for most endpoints). Resources nested under Account: `/Accounts/{AccountSid}/...`. Pagination via `Page`, `PageSize`, `NextPageUri`.
## Key Concepts
- **Messaging Service**: virtual sender container; load-balances across multiple numbers, handles A2P registration grouping
- **Sticky Sender**: same recipient always receives from the same number within a service
- **Geo-Match**: route to a number matching the recipient's country/region
- **Status Callback**: webhook fired on every delivery state change
- **Carrier Lookup**: pre-send check for line type (mobile, landline, VoIP) — costs ~$0.005
## Pricing
- US 10DLC SMS: $0.0079/msg
- US toll-free SMS: $0.0079/msg
- US short code SMS: $0.0079/msg + $1,000/mo lease
- MMS: ~$0.02
- Carrier surcharges (~$0.005 US 10DLC)
- A2P 10DLC: ~$15 brand + $10/mo per campaign
- Phone number rental: $1.15/mo (10DLC) to $2/mo (toll-free)
## Rate Limits
- Default: 1 msg/sec on long codes (10DLC trust score raises this to 4100+)
- Short code: 100+ msg/sec
- Messaging Services throttle automatically
- Carrier filtering applies above contracted throughput
## When to Use
- Building custom SMS flows into a product (B2B SaaS, mobile apps)
- Transactional and auth SMS (OTPs, alerts, notifications)
- Multi-channel orchestration (SMS + voice + WhatsApp)
- High-volume programmable messaging
- When you need full control and minimal abstraction
- Backing store for Customer.io / Segment / other orchestration layers
## When NOT to Use
- DTC ecom marketing flows — use Klaviyo, Postscript, or Attentive (better tooling for cart recovery, segments, A/B tests)
- If you don't want to handle compliance plumbing — Twilio gives you primitives, not policy
- Marketing UI for non-technical users — there isn't one
## Relevant Skills
- sms
- emails (transactional sister product via SendGrid)
- onboarding (post-signup SMS milestones)