Who to contact today
A morning brief that ranks the accounts where something just happened, so your reps know where to start.
Your reps have more accounts than they can work in a day. This playbook reads the signals from the last 24 hours, ranks the accounts by what moved, and gives you a short list with the reason and the person to reach. Run it before standup and the team opens the day with a plan instead of a flat list.
What you need
A workspace with a few agents running, so there are signals to rank: a keyword agent, a job-update agent, a competitor agent. The skills or the MCP set these up in a few minutes. A competitor or other watchlist agent also needs a watchlist of companies to watch, see Competitor radar for that setup.
The result
However you run it, you end up with the same brief:
1. Acme (3 signals today)
Reach: Jane Doe, VP Product at Acme
Why now: buying intent, sales efficiency
2. Widgets (2 signals today)
Reach: John Smith, Head of Sales at Widgets
Why now: competitor engagement
3. Globex (1 signal today)
Reach: see account mapping
Why now: hiring, series aTwo ways to run it
With the MCP connected, or the sillage-api skill installed, give your assistant the brief in plain language. It reads your signals, ranks the accounts, and writes the list.
Look at every signal my agents picked up in the last 24 hours. Group them by
account and rank the accounts by how much moved, counting a decision maker
joining as more important than a keyword mention. For the top five, tell me who
to contact (the person named in the signal, or the most senior contact from the
account mapping that fits my persona) and a one-line reason to reach out today.
Give me a short ranked brief, freshest accounts first, that I can read before
standup.To narrow it, add a line like "only my EMEA accounts" or "only accounts owned by Sarah". Run it every morning, or save it as a routine.
Three reads and a sort. Use this when you want the brief on a schedule or inside your own tool.
Read the last day of signals
Pull recent detections, filtered to the last 24 hours. Results come back newest first. Each detection carries the company it fired on, the agent that produced it, and a data payload.
const key = { Authorization: `Bearer ${process.env.SILLAGE_API_KEY}` }
const base = 'https://api.getsillage.com/api/v2'
const since = new Date(Date.now() - 24 * 60 * 60 * 1000).toISOString()
const { data: signals } = await fetch(
`${base}/workspace/signals?limit=100&detection_start_date=${encodeURIComponent(since)}`,
{ headers: key },
).then((r) => r.json())
// Signals use cursor pagination. For more than 100, follow meta.next_cursor while meta.has_more.Rank the accounts
Detections reference their agent by agent_id, so read your agents once and map each id to its type. Then group signals by company and score each account. A new decision maker joining should outweigh another keyword mention, so give job_update more weight.
const { data: agents } = await fetch(`${base}/agents?page_size=25`, { headers: key }).then((r) => r.json())
const typeOf = new Map(agents.map((a) => [a.id, a.type]))
// tune these to match what your team acts on first
const weight = { job_update: 3, competitor: 2, customer: 2, keyword_detection: 1 }
const scoreOf = (s) => weight[typeOf.get(s.agent_id)] ?? 1
const byCompany = new Map()
for (const s of signals) {
if (!s.company_id) continue
const acc = byCompany.get(s.company_id) ?? { companyId: s.company_id, signals: [] }
acc.signals.push(s)
byCompany.set(s.company_id, acc)
}
const ranked = [...byCompany.values()]
.map((acc) => ({ ...acc, score: acc.signals.reduce((n, s) => n + scoreOf(s), 0) }))
.sort((a, b) => b.score - a.score)
.slice(0, 5)Name the account, pick the person, print
company_id is a number, so resolve the name with the Companies endpoint. For the contact, use the author carried on a signal. When no signal names a person, fall back to the account mapping.
for (const [i, acc] of ranked.entries()) {
const company = await fetch(`${base}/companies/${acc.companyId}`, { headers: key }).then((r) => r.json())
const author = acc.signals.map((s) => s.data?.author).find((a) => a?.full_name)
console.log(
`${i + 1}. ${company.name} (${acc.signals.length} signals today)\n` +
` Reach: ${author ? `${author.full_name}, ${author.headline}` : 'see account mapping'}\n` +
` Why now: ${acc.signals[0].data?.keywords_found?.join(', ') ?? acc.signals[0].signal_type}\n`,
)
}Field names above are the real response shape, but a detection's data varies by
signal_type. See the Signals reference for every
variant.
Make it yours
- Change the weights so the ranking matches what your team acts on first.
- Send the brief somewhere instead of the console: an email before standup, or a Slack message.
- Filter to one segment or one rep's accounts before you rank, so each person gets their own list.
- Keep the last run's timestamp and pass it as
detection_start_date, so the brief never repeats itself.
Next steps
- Draft outreach from a signal writes the first message once you know who to reach.
- Signal reference explains what each signal type means and who to contact for it.
- Signals API lists every field on a detection.