Set up a signal for a client
Create a new signal setup for one of your clients.
Creates a new signal setup for the named client. Name the signal template with signal_template_id (from List a client's signal templates) and give its parameters, validated against the setup.fields of that signal template.
You can set up the same signal several times for one persona, for example once per set of keywords. Each call creates its own, independent setup.
There is no idempotency key: sending the same request twice creates two signal setups. Before you retry, check the state with GET /v3/partner/workspaces/{partner_workspace_id}/signal-setups.
Route
Path parameters
| Parameter | Type | Description |
|---|---|---|
| partner_workspace_id | string | Your own ID for the client workspace, as you chose it at creation. URL-encode it in the path. |
Body parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
| signal_template_id | integer | Yes | The ID of the signal template to set up, from GET /v3/partner/workspaces/{partner_workspace_id}/signal-templates. An ID that is not an available signal template is refused with 422. |
| name | string | No | Display name for the new setup, 1 to 100 characters. Defaults to the name of the signal template. |
| parameters | object | Yes | The parameters of the setup, as the setup.fields of the signal template describe them. A parameter you leave out is filled with its default. Carries list_id for a signal that watches a list. |
| schedule | string or null | No | "weekly" to run the setup right away, then every week. null, or leaving it out, means no schedule: the setup runs only when you launch a signal run. See Schedule. |
| persona_id | integer | See Persona required | The persona this setup belongs to, from List personas. |
Parameters
parameters is required. It is validated against the setup.fields of the signal template, and each signal template has its own page listing its parameters, their allowed values and their Default: see Signal Templates.
- A parameter you leave out is filled with its default when the setup is created. The default is stored, and every read of the setup returns it:
parametersin the response are the parameters as applied, not only the ones you sent. - A parameter that is missing, of the wrong type or not an allowed value is refused with
422, anderrorsnames it with its full path, for exampleparameters.scopes. An emptyscopes([]) is refused the same way: send at least one. - The persona's job titles are never copied into a setup:
use_persona_job_titlesreads them at each run. See The persona's job titles.
Schedule
schedule is a top-level property, next to parameters:
"weekly"runs the setup a first time right away, then every week. Whenscopesincludesdiscovery, the first run spends credits immediately.null, or leavingscheduleout, means no schedule: the setup runs only when you launch a signal run.
schedule is never one of the parameters: sending it inside parameters is refused with 422, and errors names parameters.schedule. Any other value than "weekly" or null is refused with 422, and errors names schedule.
Signals that watch a list
Some signals watch a list the client has built: competitors, partners, influencers or champions. Those signals ask for it: their setup.fields declares a list_id property and lists it as required, except "Engaged with my content on LinkedIn", where list_id defaults to the All my employees list. The property carries an x-list-type saying which kind of list it accepts, for example competitor.
Send the ID of one of that client's own lists of that type, from GET /v3/partner/workspaces/{partner_workspace_id}/lists. Nothing is created for you: a signal that watches a list is never set up without one.
{
"signal_template_id": 7,
"parameters": { "list_id": 12, "scopes": ["discovery"] }
}A list_id that is missing, unknown, not the client's, or not of the type the signal watches is refused with 422, and errors names parameters.list_id: "must be the id of a competitor list of this workspace. See GET /v3/lists.", naming the list type the signal watches (here competitor). For "Engaged with my content on LinkedIn", list_id is an employee list, defaults to the All my employees list when left out, and null is refused ("cannot be removed or set to null: send the new value instead, or leave it out to keep the current one").
A list attached only to personas other than the setup's persona cannot be used: the request is refused with 409, and the error message names the list and the personas it is attached to.
A setup can be moved to another list later: see Update a client's signal setup.
Persona required
Most signals look for people matching a persona, so they need one: a signal setup belongs to one persona, and the persona must have at least one job title and at least one location (job_titles and locations). See Personas.
Which persona the setup belongs to is given by persona_id, an ID from List personas:
- The client's workspace has one persona:
persona_idis optional. Leave it out and that persona is used. - The client's workspace has several personas:
persona_idis required. Without it the request is refused with422, anderrorsnamespersona_id. - The client's workspace has no persona: the request is refused with
422and the titlePersona incomplete, with adetailand noerrors. Create one withPOST /v3/partner/workspaces/{partner_workspace_id}/personasfirst. - The persona is incomplete: the persona has no job title, or no location. The request is refused with
422and the titlePersona incomplete, anderrorsnamespersona_id. Add what is missing, then send the request again. persona_idis unknown, archived, or not one of the client's personas: the request is refused with422, anderrorsnamespersona_id.
The signal templates "Champion joined a new company or promoted", "Mentioned keywords in their job offers" and "Hiring for roles my product serves" are the exception: they can be set up without a persona. Leave persona_id out and the setup is tied to no persona, and persona_id is null in the response. You can still send one: the setup then belongs to that persona. "Hiring for roles my product serves" reads the persona's job titles unless you send use_persona_job_titles: false: with one persona, such a setup is tied to it when you leave persona_id out, so a persona added later never changes its job titles; with several personas, persona_id is required, and without it the request is refused with 422 and errors names persona_id.
An incomplete persona is answered like this:
{
"type": "about:blank",
"title": "Persona incomplete",
"status": 422,
"code": "persona_incomplete",
"detail": "This persona is missing locations. Add it before setting up this signal.",
"instance": "/api/v3/partner/workspaces/ws_123/signal-setups",
"errors": {
"persona_id": ["persona is missing locations"]
}
}A setup keeps its persona for its whole life: it cannot be changed, except that a setup created without a persona can be given one once. See Update a client's signal setup. You can set up the same signal several times for one persona, for example once per set of keywords.
Example request
curl -X POST "https://api.getsillage.com/api/v3/partner/workspaces/ws_123/signal-setups" \
-H "Authorization: Bearer $SILLAGE_MASTER_KEY" \
-H "Content-Type: application/json" \
-d '{
"signal_template_id": 2,
"name": "Acme brand mentions",
"parameters": {
"scopes": [
"discovery"
]
},
"schedule": "weekly"
}'Success response
Status: 201 Created
{
"data": {
"id": 42,
"signal_template": {
"id": 2,
"key": "mentioned-my-brand",
"name": "Mentioned my brand",
"description": "Detect when prospects mention your brand on LinkedIn.",
"row_summary": "Posts naming your product anywhere on LinkedIn.",
"category": "my_network",
"status": "live",
"subjects": ["person"],
"scopes": ["discovery", "account_monitoring"],
"tags": [],
"pricing": {
"account_monitoring": {
"signal_bucket": "essential",
"credits": 50,
"unit": "per_key_account_per_month"
},
"discovery": {
"credits": 20,
"unit": "signal_found"
}
},
"archived_at": null
},
"name": "Acme brand mentions",
"status": "enabled",
"parameters": {
"scopes": ["discovery"],
"keywords": ["acme.com"]
},
"schedule": "weekly",
"persona_id": 7,
"created_at": "2026-09-18T12:00:00.000Z",
"last_detected_at": null
}
}Response fields
| Field | Type | Description |
|---|---|---|
| data.id | integer | ID of the signal setup. |
| data.signal_template | object | The signal template this setup is for, as List a client's signal templates returns it, without its setup block. It carries the template's id, key, name, category, status, subjects, scopes, tags, pricing and the other fields listed there. |
| data.name | string | Display name for this setup. |
| data.status | string | enabled when the setup is active, disabled when it is paused. An active setup runs every week when it has a schedule, and otherwise only when you launch a signal run. |
| data.parameters | object | The parameters the setup runs with, as applied: the ones you sent, plus the default of every parameter you left out. They are validated against the setup.fields of the signal template. The schedule is not one of them: it has its own schedule field. |
| data.schedule | string or null | "weekly" when the setup runs every week, null when it has no schedule. |
| data.persona_id | integer or null | The persona this setup belongs to. null when it is tied to no persona (see Persona required). It never changes. |
| data.last_detected_at | string or null | When this setup last found a signal you can list, null while it has found none. |
| data.created_at | string | When this setup was created. |
The example sends only scopes: the response shows keywords too, filled with its default.
Errors
| Status | Meaning |
|---|---|
| 401 | The master key is missing or invalid. |
| 404 | No workspace found for this partner_workspace_id. |
| 409 | The signal template is archived (template_unavailable), or list_id is a list attached only to personas other than the setup's persona (list_persona_conflict; the message names the list and those personas). |
| 422 | The body or parameters is not valid: a parameter is missing or not allowed (named as parameters.<field>), schedule is not "weekly" or null, a property the route does not accept is sent, signal_template_id is not the ID of an available signal template, list_id is not usable, or the persona is missing, incomplete or not given (see Persona required). Also returned when partner_workspace_id is invalid. |
| 429 | Rate limit exceeded. |
| 500 | An unexpected server error occurred. |
Error responses use RFC 9457 problem documents with Content-Type: application/problem+json. type is always about:blank; code tells one problem from another, detail says what went wrong this time, and errors names the field at fault. A 422 names the offending property under errors:
{
"type": "about:blank",
"title": "Unprocessable Entity",
"status": 422,
"code": "invalid_body",
"detail": "Invalid setup parameters",
"instance": "/api/v3/partner/workspaces/ws_123/signal-setups",
"errors": {
"parameters.scopes": ["is required"]
}
}