TL;DR. Third-party intent signals are now in the Warmly MCP and REST API. One new tool: list_third_party_signals. Finds prospects showing recent buying-intent signals (financial events, hiring trends, leadership changes, news, G2 reviews, SEC filings, LinkedIn posts, and more), or enriches a known company with its recent signal history. Already installed the Warmly MCP? /mcp in Claude Code shows the new tool. Credit-charged per row with monthly dedupe, see How Credits Work below.
The Shift
Last week we shipped Warmly's MCP and REST API for website visitor data. The identified humans on your site, exposed for any agent to pull.
That's the visitors you know about. The other half of pipeline is the world before someone hits your site. Who just changed jobs into the buyer seat. Who's hiring SDRs right now. Who filed an 8-K. Who's leaving Glassdoor reviews about budget cuts. That data has historically lived inside a separate intent platform, with a separate seat license per rep, with a UI no one logs into.
It doesn't need to live there. So we shipped it into the same MCP. Same OAuth. Same REST endpoint. Same credit pool.
The Tool
list_third_party_signals is one tool with two modes.
Mode 1: by_signal (the default). "Which companies are showing this signal right now?" Pass a signalCategory or signalType and get back a flat list of companies (with contacts when available) that fired on that signal recently. Use this for prospect discovery, list-building, or surfacing "who's hot right now."
Mode 2: by_company. "What signals fired on acme.com recently?" Pass a companyDomain and get back every recent signal on that account, collapsed into a single row. Use this for enriching a known account list pulled from somewhere else.
Inputs
mode — by_signal (default) or by_company.
signalCategory, signalType, signalSubtype — selectors. See Selector Grammar. At least one of category or type is required in by_signal mode.
companyDomain — required in by_company mode. Optional arrays signalTypes[], signalCategories[], signalSubtypes[] (max 20 each) narrow within the company.
detectedSince — ISO datetime. Defaults to 30 days ago. Narrow to "this week" or widen to "this quarter" with one timestamp.
take — 1 to 500. Default 25.
preview — true returns the total count plus a free 5-row sample. Zero credit charge. Use this before committing to an expensive query.
includePhone — reveal contact phone numbers. Carries a per-phone surcharge. See credits section. Phone reveal is in active rollout, see Phone Status.
Output
Every result is a row per (company, contact) pair, with all signals on that pair collapsed into an events array. So if Acme fires three signals in your window (a hiring spike, a CMO change, and an 8-K filing), you get one row for Acme with three events on it, not three rows.
Each row contains:
- company — domain, name, LinkedIn URL, industry, size band, country, public ticker (where applicable), last-updated timestamp.
- contact (when the signal is contact-level, like a job change or LinkedIn post engagement) — email, LinkedIn URL, first name, last name, title, phone (when
includePhone and rollout-enabled).
- events[] — one entry per signal. Each event has
signalId, signalType, signalCategory, signalSubtype, detectedAt, a relevance score, confidence, sentiment, and a sanitized details payload (headline, URL, role delta, etc., depending on signal type).
The envelope also returns total (full match count), isTruncated, an optional narrowQueryHint (when the query is too broad), creditsConsumed, creditsRemaining, and quotaResetAt.
Selector Grammar
Three levels of granularity, broad to narrow. Pick the level that matches how specific your query is.
signalCategory (broad)
Use when you want to cast a wide net. 31 categories cover the universe of third-party signals we track. The top categories by row volume:
- financial — SEC filings, earnings, debt events, capex.
- strategic — partnerships, acquisitions, expansion announcements.
- sentiment — Glassdoor, G2, brand reputation events.
- market — market-data movements, analyst notes.
- risk — distress signals, restructuring, layoffs.
- product — product launches, expansions, removals, pricing changes.
- leadership — executive changes, promotions, contact updates.
- technology — tech-stack adoption, github investments, AI/ML moves.
- workforce — hiring trends, hiring velocity, team expansion, restructuring.
- buying-intent — the highest-conviction bucket: content engagement, marketing-channel shifts, vendor-evaluation signals.
Plus: operations, esg, revenue, pain-point, competitive, efficiency, growth, distress, earnings, momentum, valuation, stagnation, quality, capital, budget, priority, pain, guidance, organizational, partnership, analyst.
signalType (medium)
A narrower event within a category. 25 types. The most useful:
- workmilestone — work anniversaries, promotions, job changes.
- hiring-trends — companies posting roles above baseline in a function.
- hiring-velocity — the delta version: companies accelerating hiring vs. their own baseline. Different from
hiring-trends because velocity matters more than volume.
- linkedin-post-company / linkedin-post-contact — LinkedIn activity at the company or contact level.
- linkedin-comment — comments on tracked posts (yours, a competitor's, an industry post).
- glassdoor-review — reviews matching tracked sentiment patterns (compensation, leadership, culture, growth).
- g2-product-review — reviews on G2.
- news — press / media mentions.
- website-traffic — traffic surge or decline events.
- ten_q_filing, ten_k_filing, eight_k_filing, six_k_filing, twenty_f_filing — SEC filings by type. Public companies only.
- earnings_transcript — companies that just held an earnings call with relevant transcript content.
- departmental-growth-trends — growth in a tracked department over time.
- github-initiative — significant repo activity at engineering-led companies.
- patent-filing — new patent filings.
- reddit-mentions, youtube-video-company, youtube-video-contact, social_media, financial, website.
signalSubtype (fine)
For when category + type still returns too many rows. Subtypes are an open enum: about 395 distinct values in production. The top 20 by volume:
workAnniversary, linkedinPost, websiteUpdate, productUpdate, expansionGeneral, technicalUpdate, eventAnnouncement, partnershipAnnouncement, youtubeVideo, productLaunch, marketingContent, marketingShift, featureUpdate, linkedinPostComment, marketingChannel, pricingChange, serviceUpdate, hiringVelocity, twitter_post, recognitionAward.
Other useful subtypes: jobChange, fundingNews, executiveChange, customerWin, acquisition, hiringSalesRoles, hiringMarketingRoles, hiringEngineeringRoles, trafficSurge, trafficDecline, restructuring, hires, promotion, brandReputation.
Most subtypes are camelCase. A handful use snake_case (twitter_post, partners_with, attends_event). The full 395 are accepted; if you pass an exotic one and get an empty result, the response includes a narrowQueryHint telling you what to try.
How Credits Work
This is the part to read carefully. Third-party signals are the one Warmly tool that draws down credits per row, not per call. Reads of warm visitors and warm accounts (the data you already pay for via website visitor identification) stay free.
What charges:
- 1 credit per unique company returned
- 1 credit per unique contact returned
- +20 credits per unique phone surfaced when
includePhone: true (see Phone Status below)
What doesn't charge:
list_warm_visitors, list_warm_accounts, get_credits_remaining — all free, same as before
preview: true on list_third_party_signals — returns total count plus a 5-row sample at zero credit cost. Use this before any large query.
- Re-pulling a company or contact you already paid for in the same EST billing month — dedupe is per row, not per call.
How the monthly dedupe works. The billing period is the calendar month in EST. Once you've been charged for Acme this month, every subsequent row returning Acme is free for the rest of the month, regardless of which signal type or category surfaced it. Same for contacts.
Worked example. You pull "companies with hiring velocity in workforce category, past 30 days" and get 10 rows back. That's 10 company credits. The next day, you pull "people who commented on LinkedIn posts in the same window" and 4 of those contacts work at Acme (which you already paid for): you pay 4 credits for the new contacts, and zero credits for Acme. Run the same query again the next morning and pay nothing.
The dedupe matters more than people expect. It means you can run an agent loop daily across overlapping signal types without burning credits on stable accounts. The credit ceiling is the universe of unique companies and contacts you've unlocked this month, not the number of API calls.
Over-charge gate. If a call would charge more credits than you have left in your monthly pool, the whole call is rejected with a structured error (rather than partially charging some rows). Drop the take size and retry, or upgrade.
Rate limit. 60 calls per minute on free, 120 per minute on paid. Returns HTTP 429 / rate_limit error category with a back-off message when exceeded. About 60 seconds and retry.
Quota exhaustion. When the monthly credit pool hits zero, list_third_party_signals returns a rate_limit error category with quotaResetAt in the user-facing message. Reads on already-paid rows keep working. Upgrade self-serve via HubSpot payment links or wait for the reset.
Phone Status
The includePhone parameter is wired end-to-end, but the upstream phone source (ENG-6943) is still landing. Until that ships, every contact.phoneNumber returns null. You can set includePhone: true today without being charged the surcharge, because no phones resolve. When the source lands, the surcharge starts firing.
If your org needs phone-reveal early access, email support@warmly.ai.
Six Playbooks to Try Today
Paste these into Claude Code, Claude Desktop, or any agent connected to your Warmly MCP.
1. The buyer just landed
Job changes are the highest-conviction third-party signal in B2B. A net-new role at a target account is a six-month-ahead buying signal.
Prompt: "Use list_third_party_signals with signalSubtype: 'jobChange', past 60 days, then narrow to titles containing VP, Director, or Head of in marketing or sales functions at 100 to 1000 employee companies. Show me 25. Draft a 2-line congrats note for each."
2. Steal a competitor's engagement
Anyone actively engaging with a competitor's LinkedIn content is in-market for the category, even if they haven't found you yet.
Prompt: "Pull signalType: 'linkedin-comment' for the past 14 days. Filter to Director-and-above in marketing. Show me the top 50 sorted by relevance. Which of those are already in our HubSpot?"
3. Hiring intent equals pipeline intent
A company that just decided it needs more SDRs is a company that just decided it needs more pipeline. Get in front of them before the new hires ramp.
Prompt: "Pull signalCategory: 'workforce' with signalSubtype: 'hiringSalesRoles' in the past 30 days. Show 25 companies. For each, surface the head of sales from LinkedIn enrichment and draft a 3-line cold email."
4. Account enrichment in one call
Have a target account list? Run by_company mode to get the full recent signal history per domain.
Prompt: "For each domain in this list, call list_third_party_signals with mode: 'by_company' and the past 90 days. Return only accounts with at least 3 signals fired. Rank by signal density. That's my call list for next week."
5. Sentiment-driven outbound
Glassdoor signals are an underused source. A pattern of compensation complaints at a competitor is a hiring-spike opportunity for your customer's recruiting tool. A pattern of leadership turnover is a buying window for your management consultancy.
Prompt: "Pull signalType: 'glassdoor-review', signalSubtype: 'glassdoorCompensationDissatisfaction', past 90 days. Show 25. For each, draft outreach to the head of people."
6. Daily signal watch with preview
Use preview: true to monitor signal volume without spending credits.
Prompt: "Every morning, call list_third_party_signals with preview: true for each of these signal categories: financial, leadership, workforce, buying-intent. Show me the row count per category. If any category is above 20 rows, pull the full set and DM me the top 5."
How to Get Started
If you already installed the Warmly MCP last week, list_third_party_signals is already in your tool list. Run /mcp in Claude Code to see it. Same OAuth, same credit pool.
If you haven't installed yet, one line in your terminal: claude mcp add --transport http warmly https://opps-api.getwarmly.com/api/mcp. Or follow the full install guide for Claude Desktop, Cursor, Zed, or REST.
REST. The same tool is callable from REST. POST /api/agent-tools/execute with Authorization: Bearer $WARMLY_API_KEY and a body like:
{ "toolName": "list_third_party_signals", "organizationId": "<your-org-id>", "input": { "mode": "by_signal", "signalCategory": "workforce", "signalSubtype": "hiringSalesRoles", "take": 25 } }
API keys are issued per organization from the Warmly admin UI. See the REST API section of last week's launch for the full endpoint reference.
Pricing
Same credit pool, same tiers as the rest of the API. Third-party signals draw from the credit pool you're already on. New customers get 250 free credits per month to try it.
Tier
Price
Credits/mo
$/credit
Annual
Free
$0
250
—
$0
Starter
$99/mo
500
$0.198
$1,188
Growth Popular
$199/mo
1,000
$0.199
$2,388
Pro
$499/mo
2,500
$0.200
$5,988
Enterprise
2,500+
—
Custom
Heavy users (multi-thousand-row daily pulls across signal types) will want Enterprise. Quarterly and annual commits get a better unit rate and we'll work out a usage estimate based on your signal mix. Talk to sales.
Troubleshooting
rate_limit error, "Monthly credit pool exhausted" — You've spent the monthly pool. The error body has quotaResetAt. Reads on already-paid rows keep working. Upgrade or wait.
rate_limit error, "Too many list_third_party_signals calls" — Per-minute rate limit. Back off about 60 seconds and retry with a smaller batch.
rate_limit error, "This call would charge X but only Y remain" — The over-charge gate. Drop your take size to fit inside your remaining pool, or upgrade.
- mode="by_signal" requires at least one of signalType or signalCategory — Pass a selector.
signalCategory: 'workforce' is a safe broad default.
- Empty results when you expected fires — Widen
detectedSince. Most signals are sparse on a 1-day window.
- contact fields are null — First name, last name, title, phone are all wired to ENG-6943 which is in flight.
email and linkedinUrl resolve today.
- Duplicate rows across calls — Expected. Same row across two calls in the same EST billing month is one credit, not two. Dedupe is built in.
What's Coming Next
- Phone number reveal end-to-end (ENG-6943).
- First-name, last-name, and title resolution on contacts (same ticket).
- Filter signals by visited-page on already-known visitors. "Show me the hiring-velocity firers among accounts who hit the pricing page this week."
- Async write tools: take a signal row and push the contact directly to a HubSpot sequence, an Outreach mailbox, or a LinkedIn ads audience without leaving the MCP context.
- Webhooks on signal firing so your agent doesn't have to poll for new signals on watchlists.
This is the surface I want Warmly to be in 2026. Not a dashboard you log into. A data layer your agents talk to, with the third-party signals collapsed in. Tell me what's broken or what's missing. alan@warmly.ai.