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

# Events Interface (merged stream)

> One message per event revision — the conclusion. A stable event_id, monotonic revisions, the full label state, what changed, accumulated facts, and our per-ticker impact reading.

The Events interface (`stream: "merged"`) is FocusAlpha's conclusion layer. Everything that turns out to be about the same thing — the wire write-ups, the 8-K, our reading of the guidance, the analyst reactions — hangs onto one stable `event_id`, and you receive one message per **revision** of that event, not one per article.

Measured on a real replay, an event averages **about two pushes**: the first arrival, then one more when a materially new label lands. Nine arrivals about one earnings print become three messages, not nine.

## Payload

Real output — the second push of an earnings event, where the guidance label arrived:

```json theme={null}
{
  "event_id": "CSCO:results:20260812",
  "revision": 2,
  "reason": "new_label",
  "closed": false,
  "symbols": ["CSCO"],
  "company_id": "US_17275R102",
  "subject": null,
  "origin": {
    "at": "2026-08-12T20:05:00+00:00",
    "basis": "published",
    "precision": "minute",
    "what": "CISCO REPORTS FOURTH QUARTER AND FISCAL YEAR 2026 EARNINGS",
    "ref": null
  },
  "delta": {
    "added": [["guidance", "guidance_raise"]],
    "dissent": {},
    "since_revision": 1,
    "since": "2026-08-12T20:05:00+00:00"
  },
  "state": {
    "labels": [
      ["earnings", "earnings_result"],
      ["guidance", "guidance_raise"]
    ],
    "facts": { "revenue": "$17.3 billion", "eps_gaap": "$0.97" },
    "evidence": ["news:90101", "filing_8k:0000858877-26-000106", "news:90102"]
  },
  "trigger": {
    "id": "news:90102",
    "kind": "news",
    "title": "Cisco forecasts upbeat annual revenue",
    "why": "Cisco guided FY27 revenue above consensus on AI infrastructure demand.",
    "link": "https://www.reuters.com/technology/cisco-forecast",
    "impacts": [{ "ticker": "CSCO", "direction": "bullish", "score": 80 }]
  },
  "at": "2026-08-12T20:12:50+00:00",
  "channel": "wire",
  "publisher": "reuters.com",
  "title": "Cisco forecasts upbeat annual revenue"
}
```

## Fields

| field                                    | meaning                                                                                                                                                                                                                                                                            |
| ---------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `event_id`                               | Stable across every revision. Format `TICKER:family:YYYYMMDD` (date of the event's first item).                                                                                                                                                                                    |
| `revision`                               | 1, 2, 3… per event. Never reused, never renumbered.                                                                                                                                                                                                                                |
| `reason`                                 | `first` or `new_label`.                                                                                                                                                                                                                                                            |
| `closed`                                 | A terminal label arrived (a deal closed or terminated). No further revisions will follow.                                                                                                                                                                                          |
| `symbols` / `company_id`                 | Who this is about — your distribution list. A list, because one event can involve several names (both sides of a deal). A ticker only enters after both the entity layer found it in the text and the impact model scored it as relevant, so name-collision junk is kept out.      |
| `subject`                                | The entity when there is no ticker — an unlisted target, a government.                                                                                                                                                                                                             |
| `origin`                                 | The event's own start, repeated identically in every revision — receiving revision 3 out of the blue, you can still tell which event it updates. `origin.basis` names the clock: `published`, `filing_accepted`, or `stated`. Never compare timestamps across two different bases. |
| `delta.added`                            | What is new **in this revision** — the "what changed" line to highlight.                                                                                                                                                                                                           |
| `delta.since_revision`                   | The previous revision number. Holding r1 and receiving r3, you see `since_revision: 2` and know to backfill exactly one.                                                                                                                                                           |
| `delta.dissent`                          | A second value seen on an axis where one is already set. Almost never a reversal — surfaced so it is queryable, never pushed as its own event.                                                                                                                                     |
| `state.labels`                           | The full label set as of now, as `[family, subtype]` pairs — see [Event labels](/websocket/event-labels). `subtype: null` is a positive statement: family known, direction not yet readable.                                                                                       |
| `state.facts`                            | Numbers accumulated from whichever arrivals carried a body (revenue, EPS…).                                                                                                                                                                                                        |
| `state.evidence`                         | Every raw item seen on this event so far, by `id` — pull any of them in full from the [Raw news interface](/websocket/news-stream). You never have to guess which items belong to an event by time window.                                                                         |
| `trigger`                                | The arrival that caused **this** revision, with its content — title, one-line `why`, link, and per-ticker `impacts`.                                                                                                                                                               |
| `at` / `title` / `channel` / `publisher` | The triggering arrival's timestamp, headline and provenance.                                                                                                                                                                                                                       |

<Warning>
  `trigger.why` and `trigger.impacts` are **this system's reading** of the material, not the outlet's words and not a price forecast. Attribute them to FocusAlpha, never to the publisher. The payload deliberately carries no article text — title, labels, `why` and the link are the content; the article is one click away.
</Warning>

## When a revision fires

* **Revision 1 fires on the first arrival and carries facts only, no direction.** Most first arrivals have no readable direction yet, and shipping the first outlet's verdict would mean shipping a verdict the source never gave. The exception is anticipatory labels (`earnings_preview`, `merger_acquisition_rumour`): "this has not happened yet" *is* the fact, and it is kept.
* **A new label fires a revision.** A repeat of a known label does not, however many outlets carry it.
* **A second value on the same axis does not fire** — it lands in `delta.dissent`.
* After roughly a day an event stops moving; each family has its own quiet window, after which an arrival opens a *new* event rather than revising this one.
