# Managing Signals

Coming soon – create, list, pause, resume and delete signals with the /signals endpoints, one signal per thing to watch on a LinkedIn account.

> 🚧 **Coming soon.** Signals are not available yet. This page describes how they will work at launch – the `/signals` endpoints, `signal.*` events and the SDK, CLI and MCP signal commands do not work today.

Signals belong to a LinkedIn account. Every request below carries the same two [authorization headers](/docs/making-requests#authorization) as the rest of the API, and the `identification-token` decides which account the signal watches.

| Task | Request |
|---|---|
| Create a signal | `POST /signals` |
| List signals | `GET /signals` |
| Get one signal | `GET /signals/{signalId}` |
| Pause or resume | `POST /signals/{signalId}/pause`, `POST /signals/{signalId}/resume` |
| Delete | `DELETE /signals/{signalId}` |

To read what signals detected, see [Receiving events](/docs/signal-events).

## Creating a signal

```text
POST https://api.linkedapi.io/signals
```

The body names the signal `type` and its target. The target fields depend on the type and are described on each type's page.

```json
{
  "type": "personPosts",
  "personUrl": "https://www.linkedin.com/in/person1",
  "label": "lead-1042"
}
```

- `type` (required) – one of `network`, `personPosts`, `companyPosts`, `postSearch`, `postEngagement`, `profileViewers`.
- Target fields – see [Signal types](#signal-types) below.
- `label` (optional) – your own identifier, up to 64 characters, such as a CRM record ID. It is returned with the signal and with every event it produces, so you can route events without keeping a map of signal IDs.

If your request is correct, you receive the signal:

```json
{
  "success": true,
  "result": {
    "id": "5b0d3c1e-8f2a-4c1b-9e7d-2a6f4c8b1d90",
    "type": "personPosts",
    "personUrl": "https://www.linkedin.com/in/person1",
    "label": "lead-1042",
    "status": "active",
    "createdAt": "2026-10-12T10:00:00Z",
    "baselineAt": null,
    "lastCheckedAt": null,
    "nextCheckAt": "2026-10-12T10:20:00Z"
  }
}
```

- `id` – signal identifier.
- `type` and the target fields – as you created it.
- `label` – your label, or `null`.
- `status` – `active`, `paused` or `stopped`. See [Signal status](#signal-status).
- `createdAt` – when the signal was created.
- `baselineAt` – when the [silent baseline](/docs/signals-overview#how-a-signal-works) was recorded. `null` until the first check; events can appear only after it.
- `lastCheckedAt` – the latest completed check, or `null`.
- `nextCheckAt` – the planned time of the next check, or `null` when the signal is not active. It is a plan: your workflows and working hours can move it.

Creating a signal that already exists on this account – the same `type` and target – returns that signal with `200` instead of creating a second one. A paused signal stays paused; resume it explicitly.

### Signal types

| `type` | Target fields | Page |
|---|---|---|
| `network` | none | [Connections and invitations](/docs/signal-network) |
| `personPosts` | `personUrl` | [Posts by person or company](/docs/signal-posts) |
| `companyPosts` | `companyUrl` | [Posts by person or company](/docs/signal-posts) |
| `postSearch` | `term` or `customSearchUrl`, optional `filter` | [Posts by keyword](/docs/signal-keyword-posts) |
| `postEngagement` | `postUrl`, or `myPosts: true` | [Comments and reactions](/docs/signal-post-engagement) |
| `profileViewers` | none | [Profile viewers](/docs/signal-profile-viewers) |

## Listing signals

```text
GET https://api.linkedapi.io/signals?type=personPosts&status=active
```

Both query parameters are optional:

- `type` – return only signals of this type.
- `status` – return only signals with this status.

```json
{
  "success": true,
  "result": {
    "signals": [
      {
        "id": "5b0d3c1e-8f2a-4c1b-9e7d-2a6f4c8b1d90",
        "type": "personPosts",
        "personUrl": "https://www.linkedin.com/in/person1",
        "label": "lead-1042",
        "status": "active",
        "createdAt": "2026-10-12T10:00:00Z",
        "baselineAt": "2026-10-12T10:21:00Z",
        "lastCheckedAt": "2026-10-12T16:40:00Z",
        "nextCheckAt": "2026-10-13T09:15:00Z"
      }
    ]
  }
}
```

`GET /signals/{signalId}` returns one signal in the same shape.

## Pausing and resuming

```text
POST https://api.linkedapi.io/signals/{signalId}/pause
POST https://api.linkedapi.io/signals/{signalId}/resume
```

A paused signal is not checked and spends nothing. Its events stay available. Pausing an already paused signal, or resuming an active one, changes nothing and succeeds.

On resume, the first check reports what appeared while the signal was paused, as far as LinkedIn still shows it – for example, posts the person published in the meantime. It is not a new baseline.

## Deleting a signal

```text
DELETE https://api.linkedapi.io/signals/{signalId}
```

Checks stop immediately. Events the signal already produced stay available through [polling](/docs/signal-events#polling) until their 90 days run out.

## Signal status

- `active` – checked on schedule.
- `paused` – you paused it.
- `stopped` – Linked API stopped checking because the target can no longer be watched. `stoppedReason` says why:
  - `targetNotFound` – the profile, company page or post no longer exists or is not visible to the account.
  - `watchPeriodEnded` – a `postEngagement` signal on a single post reached 30 days after the post was published.

A stopped signal cannot be resumed. To watch the target again once it is available, delete the stopped signal and create a new one – while the stopped signal exists, creating the same signal returns it.

> 💡 If the account itself is not active – it needs reconnection or is frozen – signals keep the status `active` but are not checked. Checks resume on their own when the account is back.

## Errors

### invalidRequestPayload

The body is missing a required field, names an unknown `type`, or carries target fields that do not belong to the type. `message` names the field.

```json
{
  "success": false,
  "error": {
    "type": "invalidRequestPayload",
    "message": "'personUrl' is required for signals of type 'personPosts'."
  }
}
```

### signalLimitReached

The account already has 50 active signals. Delete or pause one first.

```json
{
  "success": false,
  "error": {
    "type": "signalLimitReached",
    "message": "This LinkedIn account already has the maximum number of active signals (50)."
  }
}
```

### signalNotFound

No signal with this ID exists on the account.

```json
{
  "success": false,
  "error": {
    "type": "signalNotFound",
    "message": "Signal not found."
  }
}
```

### signalStopped

You tried to resume a signal with the status `stopped`.

```json
{
  "success": false,
  "error": {
    "type": "signalStopped",
    "message": "This signal was stopped and cannot be resumed: targetNotFound."
  }
}
```
