LIVE SYSTEM · IN PRODUCTION

An AI outbound engine that finds, qualifies, and reaches out to leads automatically.

Designed, built and operated by one engineer. It scans job boards, scores every prospect against a strict ideal-client profile, writes each email from the company’s verified tech stack — and follows up on its own.

Work with me See how it works

Pipelines are data, not code.
This is one of them.

A pipeline is a graph of steps assembled from a node registry — discovery, guards, enrichment, branching, actions — each one configured rather than written. The flow below is a real one: a new audience means a new graph, not a new codebase. It mixes autonomous tool-using agents where judgment is needed with deterministic steps where consistency and auditability matter more.

Execution role

Runs before the per-lead phase and stamps every row it creates with the pipeline id, so throughput and send caps stay attributable. Skipped entirely when the trigger already supplied lead ids.

Context payload
{ "leadIds": ["8f2c…", "b104…"],
  "source": "apify_google",
  "inserted": 42, "deduped": 7 }
Execution role

Resolves the lead to an identity — email address, optionally company domain — across every lead row, not just this one. Two pipelines sharing an ICP will otherwise both email the same person imported twice under two ids. Placed first because a lead that must not be contacted should never have been researched either.

Context payload
{ "dedupe": { "passed": false,
    "reason": "cooldown",
    "matched_on": "domain",
    "last_contacted_at": "2026-08-14" } }
Execution role

The deep-diver is a real multi-turn loop: it fetches a page, decides what to read next, and repeats under a page budget. It is confined to the lead’s own hostname — an agent free to follow outbound links will quietly start auditing somebody else’s site on your token budget.

Context payload
{ "enrichment": { "email_risk": "low" },
  "audit_points": [
    { "area": "capture", "severity": "high",
      "finding": "No enquiry form on /services" } ] }
Execution role

Context exists only for the duration of one run. This node merges it under a namespace inside raw_data — never replacing the original import payload — and writes mapped values onto real columns through a whitelist, so a config edited in the builder can never reach unsubscribed or pipeline_id.

Context payload
{ "crm_write": {
    "fields_written": ["company", "website"],
    "context_keys": ["research", "audit_points"] } }
Execution role

Branches are generic field / operator / value tests against the accumulated context, evaluated top to bottom with first match winning. Nothing about scoring is special-cased — any numeric or boolean a step writes can route a lead with no schema change.

Context payload
{ "qualification": { "score": 8,
    "passed": true,
    "reasons": ["WordPress 5.4, unpatched",
                "hiring 2 sales roles"] } }
SCORE ≥ 7
Execution role

Takes the angle from step config rather than a hardcoded campaign switch, which is what lets one registry node serve a web-dev pipeline and a logistics pipeline without a fork.

Context payload
{ "personalization": {
    "subject": "the /services form on …",
    "opening_line": "Noticed your quote form …" } }
Execution role

The cap is fail-closed: if the count query errors it reports the day as full. An unknown send count read as “nothing sent yet” is how a whole batch escapes on an already-full day.

Context payload
{ "sent": true, "message_id": "re_9f…",
  "cap_remaining": 11 }
Execution role

Holding a lead in process memory for three days assumes a process that lives three days; this one sleeps on a free tier. The lead is parked with resume_at and the step it should resume at, and a sweep re-enters the pipeline for it once the time passes.

Context payload
{ "wait": { "resume_at": "2026-09-04T09:00Z",
    "delay_minutes": 4320 } }
Execution role

Where the channel cannot be automated, the pipeline stops being an autopilot and becomes a queue: a Slack card with the drafted note, under its own daily cap, because silently flooding human work is the expensive failure here.

Context payload
{ "sentiment": { "category": "interested",
    "confidence": 0.82 } }
Path A: qualified leads continue to outreach and follow-up
SCORE < 7
Execution role

An explicit early exit, kept distinct from a failure in the step contract. A correctly-rejected lead is the pipeline working; routing it down the failure path would misreport the run and bury real errors.

Context payload
{ "status": "stopped",
  "stop_reason": "score 4 below threshold 7" }
Path B: unqualified leads are marked cold and the run ends for them
DiscoveryGuardEnrichmentStorageBranchingAI AgentActionTerminal hover a node for its execution role

A real morning run, replayed.

pipeline — live log
0
composable pipeline nodes
assembled into graphs, not forked
~$0/mo
AI operating cost
prompt-cached Claude calls
0+
leads processed
scored, filtered, deduplicated
0+
autonomous AI decisions
every one logged with cost + latency
Claude APINext.jsNode.jsSupabaseApifyResendFramer Motion

Every score explained.
Every email accountable.

The portal shows the full funnel — who was found, why they scored what they scored, what was written, when it was opened. Rejection is a feature: leads that don’t fit the profile are disqualified with a stated reason and never emailed.

→ real interface · live data · details redacted

Qualified Leads
client data redacted
20
qualified
31%
apollo pass rate
0
sent to bad fits
9
HOT
8
WARM
7
WARM
3
DQ

Need systems like this built?

I design and ship AI agent systems, custom WordPress / WooCommerce engineering, and modern web platforms — end to end, as one engineer.

Hire me on Upwork Contact Me