- A tracked person starts a new job or changes their title or headline — a strong “in motion” signal.
- A tracked person earns a certification or receives an award.
- A tracked person relocates, adds a degree, or lists a new skill.
Every request requires the
x-api-version: 2025-11-01 header and a Bearer
token. Replace YOUR_API_KEY in each example with your API key. This
endpoint is open to all API customers — no per-endpoint grant is needed.Pricing — you pay only for notifications. The first run of every
watch is a free baseline that records each person’s starting
values internally (for diffing only — it isn’t delivered) and never fires. After
that you’re charged 5 credits per notification — 5 credits for
each watched person that changed on a run. A run that surfaces nothing costs
nothing, and the price is the same whether you check hourly or monthly. If your
balance is too low, the run is suspended rather than partially delivered. See
Pricing for the canonical rates.
How a person entity watcher runs
1
Create the watch
POST your entities (people to watch), a track (what to watch for), a
config (schedule + caps), and one or more notifications channels. The response
returns the full watch object, including its id.2
Baseline run (free)
The first run records an internal snapshot of the fields you’re tracking for
each person — just enough to diff against next time. With no prior snapshot to
compare, the baseline never fires and is never charged, and isn’t itself
delivered — it only establishes “before”. To read a person’s current profile on
demand, use the Enrich APIs.
3
Recurring runs
On your schedule (
every_hours), the watcher re-checks each person, diffs them
against their last snapshot, and delivers a notification for every person whose
track condition just became true. You’re charged 5 credits per notification.An Entity Watcher only fires on a transition — the moment a value crosses
from its previous state to a new one. It never fires on the baseline, and won’t
re-notify about a change it already reported. To read a list’s current state on
demand instead of watching for change, use the
Person Enrich API.
What you can track
Thetrack describes the change that triggers a notification — a tree of condition
leaves, optionally combined with and / or groups.
A leaf has the shape:
Crustdata writes “greater-than-or-equal” as
=> and “less-than-or-equal” as
=< — not >= / <=. Those reversed forms return unknown operator.value is required for the comparison operators and omitted for changed and added.
Combine leaves with a group node — { "op": "and" | "or", "conditions": [ … ] } — to
watch several signals at once. An or group fires if any child fires; an and
group fires only when all conditions hold and at least one just became true.
Common person signals
Examples only — a person profile has 200+ addressable fields, and you can track any of them (any scalar withchanged, any array with added).
field paths address the same profile structure the Enrich API returns, so browse
the full set of trackable fields in the
Person Enrich reference. changed requires a
scalar path and added an array path — mixing them returns a 400 (for
example, "changed" on the array experience.employment_details.current is
rejected; watch basic_profile.current_title instead).Recipes: combine signals
Group leaves withor to fire on any of several signals, or and to require them together. These track blocks are all live-verified.
track field of a create request. Groups nest, so you can mix and/or — e.g. “a title change and a new certification.”
track and fields are different
Two independent knobs, and the distinction matters:
Set them independently. Track one field but deliver many (watch for a title change,
yet receive the full employment history and education), or track many and deliver few.
track decides whether you get a notification; fields decides what’s inside it.
Requesting all fields
fields does not affect pricing — an entity watch is a flat 5 credits per
notification regardless of how many field groups you deliver (see
Pricing). There’s no cost reason to keep the payload thin;
request whatever your workflow needs.
There’s no wildcard — to receive the complete record, list every field group your
API key is entitled to. fields is a top-level key (a sibling of track), fixed at
create time.
Person — all fields
Some groups require a field-level entitlement on your key (e.g.
certifications).
Requesting a group you aren’t entitled to returns a field-permission error, so list
only the groups your key can access. The group names match the Enrich API — see the
Person Enrich fields reference.Choosing the entities
entities maps an identifier type to a list of values. A single watch holds up
to 10,000 people.
Schedule and limits
Theconfig block controls timing and result caps:
Delivery channels
Add one or more channels tonotifications and every change fans out to all of them.
At least one notification channel is required today. Every delivery is also
recorded, so beyond the live push you can re-read a watch’s past runs from the
run-history endpoint.
Quick start
Watch one person and get a webhook whenever they start a new job. This request and response are real.Edit the watched list any time
Unlike a saved search, an Entity Watcher’s list is mutable — add or remove people as your pipeline or contact list changes, without recreating the watch.PATCH the
watch with a new entities object:
PATCH status (active / paused), config, and notifications. A
watch’s track and fields are fixed once created; to change what you watch for,
create a new watch.
Manage your watches
Full request/response for each, verified live.
List your watches — GET /watch/person
List your watches — GET /watch/person
status, page with limit and offset.Get one watch — GET /watch/person/{id}
Get one watch — GET /watch/person/{id}
last_run_at is null until the baseline run completes, then carries the most recent run’s timestamp.Pause or resume — PATCH status
Pause or resume — PATCH status
{ "status": "active" } to resume.Delete a watch — DELETE /watch/person/{id}
Delete a watch — DELETE /watch/person/{id}
Request
204 No Content. Deletion is terminal — the watch cannot be resumed.What a notification looks like
Every fired person carries two things: thechanges array (exactly what moved,
independent of fields) and a record (the person’s current data projected to
the fields you requested — the same shape the Enrich API returns, so with default
fields it’s just basic_profile + social_handles). The person’s identity travels
inside the record as crustdata_person_id.
Two ways to receive these, each with a different envelope:
Pushed to your webhook
When a watch fires, wePOST this body to each channel. The example below is from a
watch created with fields: ["basic_profile", "experience"]:
Webhook POST body
results is a flat list — one object per fired person, each
with its own changes and record. A changed scalar reports as
{ "field": …, "type": "changed", "from": …, "to": … }; an added array as
{ "field": …, "type": "added", "new_elements": [ … ] }.
Pulled from run history
To re-read a past run — or audit exactly what was delivered — the run-history endpoint returns the same content under a different envelope.GET /watcher/watches/{id}/runs/{run_id}/summary
Rate limits
Watch-management requests are rate-limited to 10 requests per minute per API key. This bounds bursty create/update loops; steady use is unaffected.Person Discovery Watcher
Need to find new matching people instead of watching a known list? Use the
Person Discovery Watcher.
Person field reference
Browse the full set of trackable
field paths for people.
