Signals, checks, Triggers
A Signal produces checks. A check whose criteria match produces a Trigger.
You create Signals and consume Triggers. Credits are spent on checks.
What it costs
Signals draw from the same prepaid credit balance as the rest of the API. There is no subscription and no billing cycle. Each check deducts the cost of its underlying scrape when it runs:
Spend scales with the schedule. A profile Signal on a
7d interval costs 1 credit a week. A 500-profile list checked daily costs 500 credits a day. A daily net-new people search at max_results: 50 costs 2 credits a day (2 pages × 1 credit).
Every check that completes is billable, whether or not it triggers. There is no separate fee for Triggers.
For
profile_list, this applies per member: a partial check bills only the profiles that scraped successfully and carries failed members’ previous snapshots forward. If every profile fails, the check is free.
To watch and cap spend:
estimated_monthly_credits, returned when you create a Signal, is its projected spend at the current schedule.credits_used_this_monthon every Signal attributes spend to each rule.monitoring.monthly_check_budgeton your account caps total check spend. When the cap is reached, Signals pause.
Platform attribution
Passexternal_id and optional metadata when you create Signals on behalf of a tenant or end user. We echo those fields on Triggers, webhook payloads, and GET /v1/usage/signals rollups so you can attribute spend without maintaining a parallel ID map. Trigger history and check logs are retained for 90 days (all plans today).
2 types of Signals
Both use the same object. They answer different questions:When to use which
Net-new is a search-backed target with
criteria.mode: new_entity, not a separate product. See recipe 6 in the Signals cookbook.
The Signal object
Target types
Entity targets bill one scrape per successful target per check. Search-backed targets re-run the query each check. Post-engager targets scrape the inbound engagement list and diff people (by profile URN/URL) with
new_entity. Set max_results (default 25, max 100); search billing matches the underlying search, engager billing matches /v1/posts/engagement/*. Pass either structured filters or a sales_nav_url on people and company search targets. For post_reactions, optional filters.reaction_type mirrors the reactions endpoint.
Schedule
15m. The interval determines how often checks run, and therefore what the Signal costs (see What it costs). The optional anchor aligns the cadence, for example a 1d Signal that always checks at 9am local time. Checks get slight jitter to keep delivery smooth; next_check_at on every Signal tells you exactly when the next one runs.
Criteria modes
field_change with thresholds
text_match on posts
refire: on_change_only). Set refire: always for repeat alerts on every matching check.
Net-new (Sales Nav saved search)
Sales Navigator lets you save a search and get notified when new people or companies enter the result set. Up2Data does the same withpeople_search or company_search plus new_entity:
title, location_id, industry_id, and company_size are accepted and normalized to their plural forms. LinkedIn location, industry, company, and school facets require IDs; a name such as "location": "United States" is rejected with a precise validation error rather than silently broadening the search.
Or paste the Sales Nav URL you already use:
include_removals: false). The Trigger’s diff.added[] carries the new stubs; pipe URLs into batch enrich if you want full profiles.
Filtering
A change only fires a Trigger if it means something. Three rules govern entity diffs:- Strings compare normalized. Case, whitespace and punctuation drift from re-scrapes don’t fire; real token changes (“VP Eng @ Acme” → “CTO @ Beta”) do.
- Volatile fields are excluded from
fields: ["*"]—followers_count,connections_count, post engagement counts, photo/media URLs. Watch them by naming them explicitly, ideally with a threshold. - Numeric fields take thresholds.
{ "name": "headcount", "min_change_pct": 2 }means 2,841 → 2,843 stays silent; 2,841 → 2,950 fires. Without a threshold, any delta fires.
new_entity), identity is by URN (else URL). Only additions fire by default. People dropping out of a search window stay silent unless you set include_removals: true.
Diffable fields are the same fields the enrichment API returns; each endpoint’s field glossary is the reference.
Signals at scale
Most production setups watch hundreds or thousands of entities:- Tags on every Signal: filter
GET /v1/signals?tag=andGET /v1/triggers?tag= - Bulk create: one template × up to 1,000 targets → N Signals in one call
- Bulk pause/resume by tag:
POST /v1/signals/pausewith{ "tag": "q3-pipeline" }— see Pause - Account-level notify defaults (
PATCH /v1/account): setdefault_webhook_urlonce instead of on every Signal
Triggers
Every Trigger’s diff and snapshot are stored durably for 90 days (all plans today) and delivered to the Signal’s webhook. Entity change (field moved):notify to use the account default:
check_number; order by it and dedupe by trigger_id. Signing, retries and auto-pause rules live in Webhooks. Missed a delivery? Everything is queryable via GET /v1/triggers.
When to use this
Use Signals when you care about changes over time: job moves, headcount jumps, new people entering a search, posts that match a phrase. Use the enrichment API when you need data once. Credits are the same either way; Signals replaces the scheduling, snapshot storage, diffing, and delivery you would otherwise build and run yourself.Signals cookbook
Copy-paste recipes: job-change alerts, net-new ICP searches, fleet monitoring, cost estimation.