REST API
Update a subscription
Change any part of a subscription (every key optional; a given key replaces the stored one whole) and/or set status active | paused.
POST
/v1/subscriptions/:subscription_idParameters
subscription_idstringrequirednamestringoptionalendpoint_idstringoptionalreplaces the webhook sink(s): shorthand for sinks
sinksany[]optionalreplaces every sink (up to 4 items)
clientstringoptionaltriggeranyoptionalscopeanyoptionalpredicateobjectoptionalactionsany[]optional(up to 6 items)
payloadobjectoptionaldedupeobjectoptionallimitsobjectoptionaldeliveryobjectoptionalbackfill_daysintegeroptionalgiven again =
since is moved back by this many days from now; ignored for a monitor scope (which starts at its oldest monitor’s creation) (min 0, max 30)status"active" | "paused"optionalpause / resume; resuming an
invalid subscription re-validates itWhat your agent reads
The tool description exactly as an MCP client receives it in tools/list — it doubles as the full behaviour of the endpoint.
Change any part of a subscription (every key optional; a given key replaces the stored one whole) and/or set status active | paused. Re-validated like create_subscription; bumps `version` (a match records the version it used). No record cost. `trigger`: {kind:'events', event_types:[…], where:{attr: value | [values] | {eq|in|contains|not_contains|gte|lte|exists}}} (types and attrs from describe_events); `contains`/`not_contains` take a string or a list (any of); WATERFALL = where.any: [{…tier 1…}, {…tier 2…}] — a person matches when ANY tier matches, e.g. {any:[{function:['marketing'], seniority:['director','vp','cxo']}, {seniority:['cxo','owner']}, {title:{contains:['gtm engineer','revops']}}]}. Or {kind:'search_diff', search:{kind:'jobs'|'companies'|'people', request:{…the search body…}}, every:'24h', on:['entered','left']} — re-runs the search and emits search.entered / search.left (the first run only seeds). `scope`: {kind:'list', list_ids} | {kind:'domains', domains (≤5000)} | {kind:'monitor', monitor_ids} | {kind:'people_list', list_ids} | {kind:'all'}. `predicate`: the search DSL, verbatim — for job.* events search_jobs' query/title/status/filters/company_filters; for company.* and list.* events company_filters/company_exclude_filters/must_terms/exclude_terms/site_text; validated by a dry run through the same query builders (any ICP size: the predicate is evaluated per event, never materialised). `payload`: {preset: minimal|job_default|company_default|person_default|full, fields:[paths], format: nested|flat, max_people, excerpt_chars}. `actions`: find_people, find_email, verify_email, company, job — run before delivery, charged at their usual rates. `dedupe` (one match per company per window, reposts suppressed; per_person_window for person events), `limits.max_matches_per_day`, `limits.max_records_per_day` (a record budget — preview_subscription's estimated_records_per_day sizes it), `delivery` (single | batch | digest; wait_max for enrichment), `backfill_days` (events already recorded, ≤ plan; ignored for a monitor scope, which starts at its oldest monitor's creation). `sinks`: deliver to a webhook endpoint and/or a people list — [{kind:'webhook', endpoint_id}] and/or [{kind:'people_list', list_id}] (endpoint_id alone = one webhook sink; a people list alone needs no endpoint: create_people_list, then read it with list_people_list_items). MONITORS (LinkedIn post engagers): event_types engager.found / engager.engaged_again / post.published with scope {kind:'monitor', monitor_ids} (or 'all'); the persona is trigger.where on the engager attributes (seniority, function, title, company_country, company_headcount, headline contains …, kind reaction|comment, count_window) — several acceptable roles go in where.any tiers (see above); title/seniority/function come from a STRUCTURED position, headline is the raw text; no predicate. PRICE: collecting and resolving are our cost; you pay per person DELIVERED or LISTED — a commenter 40 records, a reactor 80 (once per person per monitor, whichever path shows them first), a watched profile's daily look 40, an e-mail found +2 (find_email). person.* events (champion tracking) are coming.
Errors follow one format.