This REST walkthrough searches people, creates or reuses a dedicated List, adds up to five matches, then collects that List’s events into a local checkpoint file. It does not send outreach or modify an ATS.
Before you run
- Use Node.js 22+ and a server-side API key for an organization with active access.
- Keep the key and the generated state file out of git.
- Run only one copy of this script at a time. It writes a List in your organization.
Zero events is a valid result. Adding someone to a List does not fabricate a profile change.
Runnable script
Why this is safe to rerun
- The script resolves a List before creating it, so a timed-out create is inspected rather than blindly replayed.
- It skips people already on the List because a repeated add can overwrite stage and notes.
- It uses one fixed
since while paging; an event cursor is only for older pages in that pass.
- It overlaps each polling window by five minutes and deduplicates on
event.id. Store deduplication and checkpoints in a database for production.
- It saves the checkpoint only after the whole event pass succeeds. Replace the local sink with an idempotent ATS write or transactional outbox.
Production checklist
- Do not reuse the final cursor for the next scheduled poll. Start a new pass with the last successful checkpoint minus a small overlap.
- Treat
person.linkedin_url as the ATS/CRM join key and event.id as the activity deduplication key.
- Honor
Retry-After on 429; retry bounded GETs on 429/5xx, but reconcile uncertain POST/PATCH requests before retrying.
- Event visibility is evaluated at request time and there is no published retention SLA. Add periodic reconciliation if completeness matters.
- For exact repeat searches, save and replay the echoed
query on people search. Target discovery uses a different schema and is not an exact replay of the graph search. See Search query compatibility.
Next: Event polling contract, add members safely, and ATS/CRM architecture.