Monitors

GET
/v1/monitors

Lists monitors of ALL kinds by default (decision 3); narrow with plain ?kind=watch|discovery or ?target=list|market filters (decision 25). Newest first.

Authorization

ApiKeyAuth
AuthorizationBearer <token>

API key authentication using Bearer token. Format: sk_live_ followed by a secure random string.

In: header

Query Parameters

kind?string

Value in

  • "watch"
  • "discovery"
target?string

Value in

  • "list"
  • "market"
limit?integer
Range1 <= value <= 100
Default20
offset?integer
Range0 <= value
Default0

Response Body

application/json

application/json

curl -X GET "https://example.com/v1/monitors"
{  "results": [    {      "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",      "object": "monitor",      "kind": "watch",      "name": "string",      "status": "active",      "checks": [        {          "kind": "enrichment",          "templateId": "196100ac-4eec-4fb6-a7f7-86c8b584771d",          "type": "job_posted",          "prompt": "string",          "filters": {}        }      ],      "target": {        "type": "list",        "listId": "9fc6ad7d-902a-4834-b161-a4911b883d44",        "entity": "company"      },      "schedule": {        "frequency": "daily",        "cronExpression": "string",        "timezone": "string"      },      "webhook": {        "url": "http://example.com",        "intervalSignalLimit": 1,        "interval": "daily"      },      "lastRunAt": "2019-08-24T14:15:22Z",      "nextRunAt": "2019-08-24T14:15:22Z",      "createdAt": "2019-08-24T14:15:22Z",      "updatedAt": "2019-08-24T14:15:22Z"    }  ],  "total": 0,  "limit": 0,  "offset": 0,  "count": 0}
POST
/v1/monitors

Creates a standing watch that emits signals over time (decision 25). The create body carries checks: [{kind, …}] — exactly ONE check at launch; the array is the forward contract for multi-check monitors later.

  • {kind: "enrichment", templateId} + target: {type: "list", listId, entity} (+ optional schedule) — a watch monitor: re-runs the template's question against every entity on the list and emits a result_changed signal when an answer changes.

  • {kind: "signal", type, prompt?, filters?} (+ optional webhook) — a discovery monitor: watches the market for occurrences of the given type (job_posted, social_posted, funding_raised, investment_made, ipo_announced, ipo_stage_changed, ipo_rumoured, repo_engaged). Omit webhook to keep the results in Saber: the signals are still detected, stored and charged, and are read from GET /v1/monitors/{monitorId}/signals.

    repo_engaged watches the GitHub repositories and organizations you name and emits one occurrence per person who opens an issue or a pull request there, resolved to the company they work for. It requires an active GitHub connector on your organization: without one, the create is rejected with 422 rather than accepted as a monitor that can never run.

    The occurrence payload names the person as author.login, author.name and author.profileUrl (their GitHub profile). It also carries author.linkedinUrl when the author was identified through your own Sales Navigator connector. The value is the person's public LinkedIn profile (https://www.linkedin.com/in/...). We search for the author by name at the employer the signal names; when no source names the employer, we search by name and confirm the match from the GitHub profile. The key is absent whenever no single person could be named: for example, when you have no Sales Navigator connector, when we hold no LinkedIn page for that employer, when the GitHub profile has no first and last name, when more than one person of that name works there, when LinkedIn holds no public profile for that person, or when no search for this author has answered yet (for example, the search failed or was deferred to a later cycle). An answer found earlier is reused for later signals from the same author. Naming the wrong individual is worse than naming none.

Upsert on the (template, list) pair — not a no-op. An enrichment check for a template + list that already has a monitor does NOT create a duplicate; it replaces that monitor's configuration with this request's values. Because the create body fills defaults, fields you omit are cleared, not preserved: omitting schedule nulls the existing frequency/cron and resets the timezone to UTC (so the monitor stops firing while its status stays active), and omitting name clears it. The response is 201 with the pre-existing monitor's id/createdAt. To change one field on an existing monitor, use PATCH /v1/monitors/{monitorId} (partial update) rather than a re-POST. (A future revision may 409 this collision instead — tracked in SEL-3916.)

Credits

Monitor configuration, lifecycle, and reads are free. Each signal a monitor EMITS is charged under the monitor-signals feature (see /pricing for the current rate; per-organization overrides apply) — a watch run that detects no change emits nothing and costs nothing. The legacy subscription routes keep working (and keep their pricing) until their announced sunset.

Pricing follows the surface that CREATED the underlying subscription: when this endpoint's upsert returns a pre-existing subscription originally created on a legacy route, that monitor keeps its legacy per-run pricing (including charging for no-change watch runs). Delete it and re-create it here to move it to per-emission pricing.

Authorization

ApiKeyAuth
AuthorizationBearer <token>

API key authentication using Bearer token. Format: sk_live_ followed by a secure random string.

In: header

Request Body

application/json

TypeScript Definitions

Use the request body type in TypeScript.

name?string
Lengthlength <= 200
checks*array<>
Items1 <= items <= 1
target?
schedule?
webhook?

Discovery monitors — delivery webhook.

Response Body

application/json

application/json

curl -X POST "https://example.com/v1/monitors" \  -H "Content-Type: application/json" \  -d '{    "name": "Funding watch",    "checks": [      {        "kind": "signal",        "type": "funding_raised",        "prompt": "Series A+ rounds in European fintech"      }    ],    "webhook": {      "url": "https://myapp.com/webhooks/signals"    }  }'
{  "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",  "object": "monitor",  "kind": "watch",  "name": "string",  "status": "active",  "checks": [    {      "kind": "enrichment",      "templateId": "196100ac-4eec-4fb6-a7f7-86c8b584771d",      "type": "job_posted",      "prompt": "string",      "filters": {}    }  ],  "target": {    "type": "list",    "listId": "9fc6ad7d-902a-4834-b161-a4911b883d44",    "entity": "company"  },  "schedule": {    "frequency": "daily",    "cronExpression": "string",    "timezone": "string"  },  "webhook": {    "url": "http://example.com",    "intervalSignalLimit": 1,    "interval": "daily"  },  "lastRunAt": "2019-08-24T14:15:22Z",  "nextRunAt": "2019-08-24T14:15:22Z",  "createdAt": "2019-08-24T14:15:22Z",  "updatedAt": "2019-08-24T14:15:22Z"}
GET
/v1/monitors/{monitorId}

Free.

Authorization

ApiKeyAuth
AuthorizationBearer <token>

API key authentication using Bearer token. Format: sk_live_ followed by a secure random string.

In: header

Path Parameters

monitorId*string
Formatuuid

Response Body

application/json

application/json

curl -X GET "https://example.com/v1/monitors/497f6eca-6276-4993-bfeb-53cbbbba6f08"
{  "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",  "object": "monitor",  "kind": "watch",  "name": "string",  "status": "active",  "checks": [    {      "kind": "enrichment",      "templateId": "196100ac-4eec-4fb6-a7f7-86c8b584771d",      "type": "job_posted",      "prompt": "string",      "filters": {}    }  ],  "target": {    "type": "list",    "listId": "9fc6ad7d-902a-4834-b161-a4911b883d44",    "entity": "company"  },  "schedule": {    "frequency": "daily",    "cronExpression": "string",    "timezone": "string"  },  "webhook": {    "url": "http://example.com",    "intervalSignalLimit": 1,    "interval": "daily"  },  "lastRunAt": "2019-08-24T14:15:22Z",  "nextRunAt": "2019-08-24T14:15:22Z",  "createdAt": "2019-08-24T14:15:22Z",  "updatedAt": "2019-08-24T14:15:22Z"}
PATCH
/v1/monitors/{monitorId}

Watch monitors update name, schedule, or target.listId; discovery monitors update name, the check's prompt/filters, or webhook. A monitor's kind and signal type are immutable — create a new monitor instead. Free.

Authorization

ApiKeyAuth
AuthorizationBearer <token>

API key authentication using Bearer token. Format: sk_live_ followed by a secure random string.

In: header

Path Parameters

monitorId*string
Formatuuid

Request Body

application/json

TypeScript Definitions

Use the request body type in TypeScript.

name?string
Lengthlength <= 200
checks?array<>

Discovery monitors — update the check's prompt/filters (type is immutable).

Items1 <= items <= 1
target?
schedule?
webhook?

Response Body

application/json

application/json

application/json

curl -X PATCH "https://example.com/v1/monitors/497f6eca-6276-4993-bfeb-53cbbbba6f08" \  -H "Content-Type: application/json" \  -d '{}'
{  "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",  "object": "monitor",  "kind": "watch",  "name": "string",  "status": "active",  "checks": [    {      "kind": "enrichment",      "templateId": "196100ac-4eec-4fb6-a7f7-86c8b584771d",      "type": "job_posted",      "prompt": "string",      "filters": {}    }  ],  "target": {    "type": "list",    "listId": "9fc6ad7d-902a-4834-b161-a4911b883d44",    "entity": "company"  },  "schedule": {    "frequency": "daily",    "cronExpression": "string",    "timezone": "string"  },  "webhook": {    "url": "http://example.com",    "intervalSignalLimit": 1,    "interval": "daily"  },  "lastRunAt": "2019-08-24T14:15:22Z",  "nextRunAt": "2019-08-24T14:15:22Z",  "createdAt": "2019-08-24T14:15:22Z",  "updatedAt": "2019-08-24T14:15:22Z"}
DELETE
/v1/monitors/{monitorId}

Deletes a monitor of either kind (previously the watch family had no delete). An active watch monitor's schedule is stopped first. Free.

Authorization

ApiKeyAuth
AuthorizationBearer <token>

API key authentication using Bearer token. Format: sk_live_ followed by a secure random string.

In: header

Path Parameters

monitorId*string
Formatuuid

Response Body

application/json

curl -X DELETE "https://example.com/v1/monitors/497f6eca-6276-4993-bfeb-53cbbbba6f08"
Empty
POST
/v1/monitors/{monitorId}/pause

One pause/resume vocabulary across both kinds (decision 2). Free.

Authorization

ApiKeyAuth
AuthorizationBearer <token>

API key authentication using Bearer token. Format: sk_live_ followed by a secure random string.

In: header

Path Parameters

monitorId*string
Formatuuid

Response Body

application/json

application/json

curl -X POST "https://example.com/v1/monitors/497f6eca-6276-4993-bfeb-53cbbbba6f08/pause"
{  "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",  "object": "monitor",  "kind": "watch",  "name": "string",  "status": "active",  "checks": [    {      "kind": "enrichment",      "templateId": "196100ac-4eec-4fb6-a7f7-86c8b584771d",      "type": "job_posted",      "prompt": "string",      "filters": {}    }  ],  "target": {    "type": "list",    "listId": "9fc6ad7d-902a-4834-b161-a4911b883d44",    "entity": "company"  },  "schedule": {    "frequency": "daily",    "cronExpression": "string",    "timezone": "string"  },  "webhook": {    "url": "http://example.com",    "intervalSignalLimit": 1,    "interval": "daily"  },  "lastRunAt": "2019-08-24T14:15:22Z",  "nextRunAt": "2019-08-24T14:15:22Z",  "createdAt": "2019-08-24T14:15:22Z",  "updatedAt": "2019-08-24T14:15:22Z"}
POST
/v1/monitors/{monitorId}/resume

Free.

Authorization

ApiKeyAuth
AuthorizationBearer <token>

API key authentication using Bearer token. Format: sk_live_ followed by a secure random string.

In: header

Path Parameters

monitorId*string
Formatuuid

Response Body

application/json

application/json

curl -X POST "https://example.com/v1/monitors/497f6eca-6276-4993-bfeb-53cbbbba6f08/resume"
{  "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",  "object": "monitor",  "kind": "watch",  "name": "string",  "status": "active",  "checks": [    {      "kind": "enrichment",      "templateId": "196100ac-4eec-4fb6-a7f7-86c8b584771d",      "type": "job_posted",      "prompt": "string",      "filters": {}    }  ],  "target": {    "type": "list",    "listId": "9fc6ad7d-902a-4834-b161-a4911b883d44",    "entity": "company"  },  "schedule": {    "frequency": "daily",    "cronExpression": "string",    "timezone": "string"  },  "webhook": {    "url": "http://example.com",    "intervalSignalLimit": 1,    "interval": "daily"  },  "lastRunAt": "2019-08-24T14:15:22Z",  "nextRunAt": "2019-08-24T14:15:22Z",  "createdAt": "2019-08-24T14:15:22Z",  "updatedAt": "2019-08-24T14:15:22Z"}
POST
/v1/monitors/{monitorId}/trigger

Runs the monitor immediately.

The trigger call itself is free. The run it starts bills per emitted signal under the monitor-signals feature (see /pricing for the current rate; per-organization overrides apply):

  • a watch run charges only for entities whose answer is new or changed — unchanged entities and cached answers emit nothing and cost nothing;
  • a discovery run charges per stored signal.

A trigger against a large list can therefore debit many credits. A run can also stop part-way with 402 if the balance is exhausted mid-fan-out, leaving the entities already processed billed and the rest not run.

Authorization

ApiKeyAuth
AuthorizationBearer <token>

API key authentication using Bearer token. Format: sk_live_ followed by a secure random string.

In: header

Path Parameters

monitorId*string
Formatuuid

Response Body

application/json

application/json

application/json

curl -X POST "https://example.com/v1/monitors/497f6eca-6276-4993-bfeb-53cbbbba6f08/trigger"
{  "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",  "object": "monitor",  "kind": "watch",  "name": "string",  "status": "active",  "checks": [    {      "kind": "enrichment",      "templateId": "196100ac-4eec-4fb6-a7f7-86c8b584771d",      "type": "job_posted",      "prompt": "string",      "filters": {}    }  ],  "target": {    "type": "list",    "listId": "9fc6ad7d-902a-4834-b161-a4911b883d44",    "entity": "company"  },  "schedule": {    "frequency": "daily",    "cronExpression": "string",    "timezone": "string"  },  "webhook": {    "url": "http://example.com",    "intervalSignalLimit": 1,    "interval": "daily"  },  "lastRunAt": "2019-08-24T14:15:22Z",  "nextRunAt": "2019-08-24T14:15:22Z",  "createdAt": "2019-08-24T14:15:22Z",  "updatedAt": "2019-08-24T14:15:22Z"}
GET
/v1/monitors/{monitorId}/signals

The occurrences this monitor emitted, newest first, on the signal envelope (type, occurredAt, observedAt, entity, payload). Watch monitors emit result_changed when an answer changes — silent no-change runs are runs, not signals, and are not returned here. Enumerating every individual run (no-change and failed runs included) is not available on the MCP surface; this route returns emitted signals only. Reads are free.

Authorization

ApiKeyAuth
AuthorizationBearer <token>

API key authentication using Bearer token. Format: sk_live_ followed by a secure random string.

In: header

Path Parameters

monitorId*string
Formatuuid

Query Parameters

limit?integer
Range1 <= value <= 100
Default20
offset?integer
Range0 <= value
Default0

Response Body

application/json

application/json

curl -X GET "https://example.com/v1/monitors/497f6eca-6276-4993-bfeb-53cbbbba6f08/signals"
{  "results": [    {      "id": "string",      "object": "signal",      "monitorId": "075fef10-8522-4c43-ac39-f1796133943e",      "type": "string",      "occurredAt": "2019-08-24T14:15:22Z",      "observedAt": "2019-08-24T14:15:22Z",      "entity": {},      "payload": {}    }  ],  "total": 0,  "limit": 0,  "offset": 0,  "count": 0}
GET
/v1/monitors/{monitorId}/actions

Watch monitors only at launch. Free.

Authorization

ApiKeyAuth
AuthorizationBearer <token>

API key authentication using Bearer token. Format: sk_live_ followed by a secure random string.

In: header

Path Parameters

monitorId*string
Formatuuid

Response Body

application/json

application/json

curl -X GET "https://example.com/v1/monitors/497f6eca-6276-4993-bfeb-53cbbbba6f08/actions"
{  "items": [    {      "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",      "subscriptionId": "d079718b-ff63-45dd-947b-4950c023750f",      "type": "webhook",      "webhook": {        "destination": "http://example.com"      },      "enabled": true,      "createdAt": "2019-08-24T14:15:22Z",      "updatedAt": "2019-08-24T14:15:22Z"    }  ],  "total": 0,  "limit": 0,  "offset": 0,  "hasMore": true}
POST
/v1/monitors/{monitorId}/actions

Actions fire when the monitor emits signals. Watch monitors only at launch — discovery monitors deliver via their webhook and return 422 here. Free.

Authorization

ApiKeyAuth
AuthorizationBearer <token>

API key authentication using Bearer token. Format: sk_live_ followed by a secure random string.

In: header

Path Parameters

monitorId*string
Formatuuid

Request Body

application/json

TypeScript Definitions

Use the request body type in TypeScript.

Create a new action on a subscription. The type field determines which configuration object is required.

type*"webhook"

The action type discriminator

Value in

  • "webhook"
webhook?

Configuration for a webhook action.

Response Body

application/json

application/json

curl -X POST "https://example.com/v1/monitors/497f6eca-6276-4993-bfeb-53cbbbba6f08/actions" \  -H "Content-Type: application/json" \  -d '{    "type": "webhook"  }'
{  "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",  "subscriptionId": "d079718b-ff63-45dd-947b-4950c023750f",  "type": "webhook",  "webhook": {    "destination": "http://example.com"  },  "enabled": true,  "createdAt": "2019-08-24T14:15:22Z",  "updatedAt": "2019-08-24T14:15:22Z"}
GET
/v1/monitors/{monitorId}/actions/{actionId}

Free.

Authorization

ApiKeyAuth
AuthorizationBearer <token>

API key authentication using Bearer token. Format: sk_live_ followed by a secure random string.

In: header

Path Parameters

monitorId*string
Formatuuid
actionId*string
Formatuuid

Response Body

application/json

application/json

curl -X GET "https://example.com/v1/monitors/497f6eca-6276-4993-bfeb-53cbbbba6f08/actions/497f6eca-6276-4993-bfeb-53cbbbba6f08"
{  "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",  "subscriptionId": "d079718b-ff63-45dd-947b-4950c023750f",  "type": "webhook",  "webhook": {    "destination": "http://example.com"  },  "enabled": true,  "createdAt": "2019-08-24T14:15:22Z",  "updatedAt": "2019-08-24T14:15:22Z"}
PATCH
/v1/monitors/{monitorId}/actions/{actionId}

Free.

Authorization

ApiKeyAuth
AuthorizationBearer <token>

API key authentication using Bearer token. Format: sk_live_ followed by a secure random string.

In: header

Path Parameters

monitorId*string
Formatuuid
actionId*string
Formatuuid

Request Body

application/json

TypeScript Definitions

Use the request body type in TypeScript.

Update the configuration of an existing action. The action type is immutable; only the type-specific configuration can be changed.

webhook?

Configuration for a webhook action.

Response Body

application/json

application/json

curl -X PATCH "https://example.com/v1/monitors/497f6eca-6276-4993-bfeb-53cbbbba6f08/actions/497f6eca-6276-4993-bfeb-53cbbbba6f08" \  -H "Content-Type: application/json" \  -d '{}'
{  "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",  "subscriptionId": "d079718b-ff63-45dd-947b-4950c023750f",  "type": "webhook",  "webhook": {    "destination": "http://example.com"  },  "enabled": true,  "createdAt": "2019-08-24T14:15:22Z",  "updatedAt": "2019-08-24T14:15:22Z"}
DELETE
/v1/monitors/{monitorId}/actions/{actionId}

Free.

Authorization

ApiKeyAuth
AuthorizationBearer <token>

API key authentication using Bearer token. Format: sk_live_ followed by a secure random string.

In: header

Path Parameters

monitorId*string
Formatuuid
actionId*string
Formatuuid

Response Body

application/json

curl -X DELETE "https://example.com/v1/monitors/497f6eca-6276-4993-bfeb-53cbbbba6f08/actions/497f6eca-6276-4993-bfeb-53cbbbba6f08"
Empty
POST
/v1/monitors/{monitorId}/actions/{actionId}/pause

Free.

Authorization

ApiKeyAuth
AuthorizationBearer <token>

API key authentication using Bearer token. Format: sk_live_ followed by a secure random string.

In: header

Path Parameters

monitorId*string
Formatuuid
actionId*string
Formatuuid

Response Body

application/json

application/json

curl -X POST "https://example.com/v1/monitors/497f6eca-6276-4993-bfeb-53cbbbba6f08/actions/497f6eca-6276-4993-bfeb-53cbbbba6f08/pause"
{  "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",  "subscriptionId": "d079718b-ff63-45dd-947b-4950c023750f",  "type": "webhook",  "webhook": {    "destination": "http://example.com"  },  "enabled": true,  "createdAt": "2019-08-24T14:15:22Z",  "updatedAt": "2019-08-24T14:15:22Z"}
POST
/v1/monitors/{monitorId}/actions/{actionId}/resume

The unified verb for the legacy unpause (decision 2). Free.

Authorization

ApiKeyAuth
AuthorizationBearer <token>

API key authentication using Bearer token. Format: sk_live_ followed by a secure random string.

In: header

Path Parameters

monitorId*string
Formatuuid
actionId*string
Formatuuid

Response Body

application/json

application/json

curl -X POST "https://example.com/v1/monitors/497f6eca-6276-4993-bfeb-53cbbbba6f08/actions/497f6eca-6276-4993-bfeb-53cbbbba6f08/resume"
{  "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",  "subscriptionId": "d079718b-ff63-45dd-947b-4950c023750f",  "type": "webhook",  "webhook": {    "destination": "http://example.com"  },  "enabled": true,  "createdAt": "2019-08-24T14:15:22Z",  "updatedAt": "2019-08-24T14:15:22Z"}

On this page