Skip to content

Buying-trigger feed

Each week, the companies in your customer sentence that raised money, posted the role you replace, or dropped the tool you replace.

Kind
Workflow
Price
$1.55 per week
Your time
7 minutes
Approval
Runs on its own
Deepens
Outbound
ICP.track
You, to your agent

Tell me which property managers in my ICP started hiring a leasing coordinator this week, spend up to $2, and show me the plan first.

curl -X POST "https://api.sb/leaseline.app/icps/track?mode=try" \
  -H "Authorization: Bearer $SB_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"goal":"Tell me which property managers in my ICP started hiring a leasing coordinator this week, spend up to $2, and show me the plan first.","budget":{"amount":2,"currency":"USD"}}'
npx startup-builder do ICP.track --try --data '{"goal":"Tell me which property managers in my ICP started hiring a leasing coordinator this week, spend up to $2, and show me the plan first.","budget":{"amount":2,"currency":"USD"}}'
{
  "name": "do",
  "arguments": {
    "mode": "try",
    "code": "return await $.ICP.track({ goal: 'Tell me which property managers in my ICP started hiring a leasing coordinator this week, spend up to $2, and show me the plan first.', budget: { amount: 2, currency: 'USD' } })"
  }
}
import { $ } from 'startup-builder'

const result = await $.try.ICP.track({ goal: 'Tell me which property managers in my ICP started hiring a leasing coordinator this week, spend up to $2, and show me the plan first.', budget: { amount: 2, currency: 'USD' } })
Response
{
  "mode": "try",
  "stored": false,
  "estimate": "About $1.55 a week",
  "sample": {
    "company": "Cedar Hollow Rentals",
    "trigger": "hiring",
    "detail": "Leasing coordinator, posted 2026-10-24",
    "in your ICP": "yes",
    "added": "account Audience"
  }
}
Try mode reads, stores nothing and spends nothingAPI referenceIts Nouns

What you get

  • 1 week · Each week, the companies in your customer sentence that raised money, posted the role you replace, or dropped the tool you replace. · Audience
  • added[] · Each company added this week, with whyNow: the Event and its detail, such as “Leasing coordinator, posted 2026-10-24”.
  • updated[] · Companies already on the Audience with a new trigger; never added twice.
  • skipped · Trigger hits outside your customer sentence, by reason and count.

How long: About 5 minutes.

Trigger

It runs weekly, as three Monitors with change set to funding, hiring and technology.

TypeScript
every('mon 06:00', ($) => $.ICP.track({ icp: 'icps/icp_4', changes: ['funding', 'hiring', 'technology'] }))

Steps

Your agent does these steps, one row per step; each step’s check is part of its row and its price.

StepVerbReturnsPriceApproval
1. Read the week’s funding roundsOrganization.findCompanies in your sentence that announced a round in the last 7 daysAbout 80¢Runs on its own
2. Read the week’s job posts for your rolesOrganization.findCompanies in your sentence that posted the role you replaceAbout 25¢Runs on its own
3. Read what changed at the watched accountsOrganization.enrichTechnology adopted or dropped at 50 accounts, oldest-read firstAbout 50¢Runs on its own
4. Keep the hits that match your sentenceCollection.queryThe hits that pass every filter in your sentence, by a declared ruleFreeRuns on its own
5. Add them to the account Audience with why nowAudience.createRows added or updated, each emitting its Event so a Play’s Trigger can act on itFreeRuns on its own

Calls: Organization.find, then Organization.enrich, then Collection.query, then Audience.create.

About $1.55 a week, each time it runs, capped at $2.00.

Example: give it a goal

Tell me which property managers in my ICP started hiring a leasing coordinator this week, spend up to $2, and show me the plan first.

The plan it shows runs 5 steps, priced before it spends anything; Run it above shows the result it returns.

When something fails

Each failure, and what happens next
WhenThen
A trigger source fails on every routeThat change kind is skipped for the week with a note; the other two still land.
A company already on the Audience fires againIts row is updated with the new whyNow, never added twice.
Fewer than 10 hiring hits match in goal modeThe agent may widen to adjacent titles, such as “assistant property manager”, as a Decision with its cost; it never widens your sentence.
You call it twice in one ISO weekThe second call returns the week’s hits at $0: it is idempotent per ICP, change and week.

Each step retries three times, then falls through to the next route; one item's failure lands in skipped with its reason, never failing the call. Before a step would cross maxCost it stops and returns what it has, with a resume link. Each step's idempotency key is the call's key plus the step and the item: leaseline-icp-track-1-<step>-<item>.

Change it

AskCompiles to
Write to the operations lead at each new hit within a day.Prospect.reach
Also watch for property managers hiring an assistant property manager.ICP.track
Only tell me about funding rounds over $1M.ICP.track
TypeScript
import { $, workflow } from 'startup-builder'

export default workflow({
  name: 'icp-track',
  verb: 'ICP.track',
  input: { icp: 'string', changes: "('funding' | 'hiring' | 'technology')[]", roles: 'string[]' },
  trigger: { schedule: 'mon 06:00' },
  maxCost: 2,
  execute: async (ctx, { icp, changes = ['funding', 'hiring', 'technology'], roles = ['leasing coordinator'], watch = 'audiences/audience_accounts' }) => {
    const hits = []
    if (changes.includes('funding')) hits.push(...(await ctx.step('funding', () => $.Organization.find({ icp, where: { event: { kind: 'funded', within: '7d' } }, maxCost: 1 }))).organizations)
    if (changes.includes('hiring')) hits.push(...(await ctx.step('hiring', () => $.Organization.find({ icp, where: { hiringFor: roles, within: '7d' }, maxCost: 0.3 }))).organizations)
    if (changes.includes('technology')) hits.push(...(await ctx.step('technology', () => $.Organization.enrich({ audience: watch, fields: ['events'], limit: 50, maxCost: 0.6 }))).changed)
    return ctx.step('append', () => $.Audience.create({ name: 'Buying triggers', members: matchIcp(hits, icp), merge: true }))   // emits each Event
  },
})

Extend it with extends: 'ICP.track' and base(), or compose your own from these steps.

Works with

Plays that order it: lead reactivation, Moment outreach, Objection watch.

It serves Find your first customers, and runs in Hands-on. It deepens Outbound.

For agents

For agents: the guide, its approvals, retries and lookups
FactValue
GuideICP.track
Guide approvallimits
GoalTell me which property managers in my ICP started hiring a leasing coordinator this week, spend up to $2, and show me the plan first. It may change counts, the order of steps, soft filters and the route a read takes, and it stops early when the goal is met. It never relaxes your words, raises its own budget, answers its own approval, calls a Play or acts outside your standing approval.
Triggerevery('mon 06:00', ($) => $.ICP.track({ icp: 'icps/icp_4', changes: ['funding', 'hiring', 'technology'] }))
RetryThree times with backoff, then the next route; the same idempotency key never charges, sends or posts twice
Idempotency keyleaseline-icp-track-1
LookupsA find: input asks unless exactly one record fits
Step
1. Read the week’s funding rounds
2. Read the week’s job posts for your roles
3. Read what changed at the watched accounts
4. Keep the hits that match your sentence
5. Add them to the account Audience with why now

The amounts live once, on the hub (approvals).

Who does each step, and how it is checked
StepFunctionDoerCheckerAssuranceInputs
1. Read the week’s funding roundscodeCodeCode checks each result against its declared typemeasured$0.icp
2. Read the week’s job posts for your rolescodeCodeCode checks each result against its declared typemeasured$0.icp, $0.roles
3. Read what changed at the watched accountscodeCodeCode checks each result against its declared typemeasured$0.watch
4. Keep the hits that match your sentencecodeCodeCode checks each result against its declared typemeasured$1, $2, $3, $0.icp
5. Add them to the account Audience with why nowcodeCodeCode reads the result back from where it landedmeasured$4.hits

The doer is never the checker, and the weakest assurance on the path is the whole call’s.

Under the hood

Under the hood: the Systems, Nouns and Events it touches
KindWhat it touches
SystemsAds
NounsOrganization, Collection, Audience
EventsCollection.queried, Audience.created

Reference

Inputs, outputs, its Event and its errors
NameTypeDefaultMeaning
icpICPRequiredYour saved customer sentence.
changes('funding' | 'hiring' | 'technology')[]['funding', 'hiring', 'technology']The buying triggers to watch.
rolesstring[]['leasing coordinator']The job titles whose posting means the pain is growing: the role your product saves.
watchAudienceyour account AudienceThe accounts read for technology changes each week, 50 at a time, oldest-read first.
everystring'7d'How often the feed reads.
maxCostnumber2.00The most this call spends each time it runs, in USD. It stops before a step would cross it and returns what it has, with a resume link.

Emits ICP.tracked. Refuses with max-cost before it spends, and with the Data calls and Accounts groups (refusals).

Contents