> ## Documentation Index
> Fetch the complete documentation index at: https://docs.openpulse.cloud/llms.txt
> Use this file to discover all available pages before exploring further.

# Events

> The six events a webhook endpoint can subscribe to, with what each one fires on and an example payload.

Six events, covering signals, runs, pipeline moves and content. Each example below is the same example Openpulse serves in its OpenAPI document, so a payload shown here is exactly what a `POST` to your endpoint contains — never a paraphrase of it.

## `signal.created`

A new signal was kept. One delivery per signal, the first time it is seen.

```json theme={null}
{
  "listener": { "id": "lst_example", "name": "Example Listener", "mode": "rivals" },
  "signal": {
    "id": "sig_example",
    "url": "https://www.trustpilot.com/reviews/example",
    "title": "Finally moving off RivalCo after the last outage",
    "excerpt": "Third time this quarter their scheduling went down mid-clinic. We are actively looking at alternatives now.",
    "source": "trustpilot",
    "author": "example_user",
    "classification": "switching",
    "relevanceScore": 88,
    "rationale": "Names the rival, states an active problem, and says explicitly they are evaluating alternatives.",
    "suggestedAngle": "Lead with reliability during clinic hours and offer a migration that keeps their existing bookings.",
    "matchedKeywords": ["scheduling", "outage", "alternatives"],
    "themes": ["reliability", "downtime"],
    "rating": 1,
    "subjectName": "RivalCo",
    "postedAt": "2026-01-01T00:00:00.000Z",
    "firstSeenAt": "2026-01-01T00:00:00.000Z"
  }
}
```

## `signal.urgent`

A signal cleared your urgency bar. These also fire `signal.created` — subscribe to this one alone if you only want the interruptions. Carries the whole signal body plus the `urgency` block: the threshold that was crossed, the level, and the score that crossed it.

```json theme={null}
{
  "listener": { "id": "lst_example", "name": "Example Listener", "mode": "rivals" },
  "signal": { "...": "the same shape as signal.created" },
  "urgency": { "level": "immediate", "threshold": 85, "score": 88 }
}
```

## `run.completed`

A listener finished a pass, with what it searched and kept.

```json theme={null}
{
  "listener": { "id": "lst_example", "name": "Example Listener", "mode": "rivals" },
  "run": {
    "id": "run_example",
    "status": "completed",
    "startedAt": "2026-01-01T00:00:00.000Z",
    "completedAt": "2026-01-01T00:00:00.000Z",
    "searchedCount": 214,
    "matchedCount": 7
  }
}
```

## `run.failed`

A listener run could not finish. The one worth alerting on.

```json theme={null}
{
  "listener": { "id": "lst_example", "name": "Example Listener", "mode": "rivals" },
  "run": {
    "id": "run_example",
    "status": "failed",
    "startedAt": "2026-01-01T00:00:00.000Z",
    "completedAt": "2026-01-01T00:00:00.000Z",
    "error": "SerpApi responded with 429: rate limit exceeded"
  }
}
```

## `pipeline.stage_changed`

Somebody moved a deal to another stage. The event a CRM wants — carries where it moved from, where it moved to, and who moved it.

```json theme={null}
{
  "entry": {
    "id": "pipe_example",
    "signalId": "sig_example",
    "accountKey": "d:rivalco.com",
    "stage": "meeting",
    "from": "contacted",
    "ownerUserId": "user_example",
    "changedAt": "2026-01-01T00:00:00.000Z",
    "actorId": "user_example"
  },
  "signal": {
    "id": "sig_example",
    "title": "Finally moving off RivalCo after the last outage",
    "url": "https://www.trustpilot.com/reviews/example",
    "subjectName": "RivalCo"
  }
}
```

## `content.piece.ready`

A generated content draft finished. One delivery per piece, so four channels on the same idea arrive as four events.

```json theme={null}
{
  "piece": {
    "id": "piece_example",
    "ideaId": "idea_example",
    "channel": "blog",
    "warnings": [{ "rule": "meta-length", "severity": "advisory" }],
    "generatedAt": "2026-01-01T00:00:00.000Z"
  },
  "idea": {
    "id": "idea_example",
    "title": "Why tiered support queues lose your best customers",
    "theme": "hold times",
    "signalCount": 41,
    "authorCount": 12
  }
}
```

## Every event's response contract

Any `2XX` response marks the delivery accepted. Anything else — including a timeout — is retried with backoff. See [Webhooks](/webhooks/overview) for signing, verification and delivery history.


## Related topics

- [Webhooks](/webhooks/overview.md)
