---
title: "List Events"
method: GET
path: "/api/v1/events"
tags: ["Events"]
---

# List Events

`GET /api/v1/events`

## Request

- Base URL: `https://nordicfinancialnews.com`
- URL: `https://nordicfinancialnews.com/api/v1/events`
- Auth: HTTP bearer

Returns a paginated list of Events. An event groups the articles reporting a single real-world development (an earnings report, an M&A announcement, a dividend, an executive change, and so on). Sorted by when the event was first reported, most recent first.

An event is only returned if at least one of its live member articles survives your plan's age and source restrictions. This is the same visibility rule the event feed on the website uses. If none survive, the event does not appear at all. `GET /api/v1/events/:id` distinguishes that case from an event your plan can see but whose full coverage it cannot (see below).

## Merges and removals
Events sometimes merge (two events turn out to describe the same development) or are removed (no live articles remain, or the event was found to be incorrect). Both are terminal. The event never reappears in a normal list, and `GET /api/v1/events/:id` on one returns a **minimal tombstone**: `id`, `status`, `merged_into` (the surviving event's `id`, when merged), and `updated_at` only. A tombstone carries no title, summary, counts or id arrays.

Poll with `updated_after` to learn about merges and removals. Tombstones for events that changed since your watermark are included in that sync walk (uncapped, on every plan), which is otherwise the only way to learn that an event you previously fetched is gone. They are never returned by the default list.

A tombstone still respects your event-grain filters: `company`, `ticker`, `exchange`, `index`, `sector`, `market_segment`, `listed`, `event_type`, `event_category`, `significance`, `watchlist`, `first_reported_after`/`before`, and `last_article_after`/`before`. A merged event that involved the company you filtered by still surfaces its tombstone.

Those filters are checked against the tombstone's companies as they are now. With `listed`, a tombstone whose only listed company was delisted or stopped appearing in the API's company data before the merge or removal no longer matches, so it is not returned. Poll without `listed` for full-fidelity tombstone coverage.

On `exchange`, `market`, `domicile`, `index`, `sector`, `market_segment` and `listed`, a merged or removed commentary event's tombstone is returned when any matching company is on it, in any role, so a filtered sync can include a tombstone for an event it never returned. A filtered sync returns events that match the filters now: an event that stops matching (for example, when its articles are no longer about a matching company) is not returned by it. Poll without those filters to see every change.

A tombstone does not respect `country`, `category`, `sources`, `source_type` or `content_type`, which are article-grain filters. It has no live articles left to filter by, so poll without them for full-fidelity tombstone coverage.

A merged event's `last_article_at` freezes at merge time, so `last_article_after`/`before` filter a tombstone against that frozen value rather than against when the merge happened. `window` cannot be used for sync polling at all (see below).

## Polling for updates
Use `updated_after` with the timestamp of your last completed sync to fetch only events that have changed since. Results are then ordered by `updated_at` ascending and cursor-paginated: follow `pagination.next_cursor`, resending the same `updated_after`, until it is null. Advance your stored timestamp only once every page is drained.

A merge takes the earlier of the two `first_reported_at` values, so it only ever moves the surviving event earlier in the default sort. Under the default (non-sync) ordering a cursor walk can therefore re-emit a row you have already seen, but it can never skip one. Treat the walk as at-least-once and dedupe by `id`.

`company_ids`/`story_ids` membership can drift out from under `updated_after` without bumping `updated_at`: a company merge, a company leaving or rejoining the API's company data, or a story being withdrawn from an event you already hold. A change to a story itself is tracked, and bumps the parent event. Treat the ids in those arrays as current as of your last poll rather than as ground truth.

Some low-value wire items are deleted outright rather than marked `removed`. Like every other resource on this API, deletions of that kind are not signaled by `updated_after`, so treat a local mirror as append-and-update rather than an exact replica.

## Pagination
List responses include `pagination.next_cursor` when more pages are available. Pass it back as the `cursor` parameter on the next request. Cursors are opaque. Do not parse them.

## Caching
Responses carry an `ETag` and `Cache-Control: private, max-age=0, must-revalidate`; send the ETag back as `If-None-Match` to receive a `304 Not Modified`. There is no `Last-Modified` on this endpoint, so `If-Modified-Since` alone never revalidates: an event's visible company and story membership and its live article count all change without moving its `updated_at`, and only the `ETag` reflects them. A changed `ETag` therefore does not necessarily mean a record was updated. It also moves when a plan limit alters the visible set.

Requests carrying `q` or `updated_after` are not cached and return `Cache-Control: no-cache, no-store`.

## Query parameters

- `limit` integer
- `cursor` string
- `fields` string
- `updated_after` string
- `q` string
- `mode` 'semantic'
- `event_type` string
- `event_category` string
- `significance` string
- `ticker` string
- `company` string
- `country` string
- `category` string
- `sources` string
- `source_type` string
- `content_type` string
- `exchange` string
- `market` string
- `domicile` string
- `index` string
- `sector` string
- `market_segment` string
- `listed` string
- `watchlist` string
- `first_reported_after` string
- `first_reported_before` string
- `last_article_after` string
- `last_article_before` string
- `window` string
- `sort` string
- `related_to` string
- `include_peripheral` boolean

## Headers

- `If-None-Match` string

## Response `200`

Events retrieved successfully

- object
  - `events` EventSummary[], required
    - `id` string, required: Unique event identifier
    - `title` string: Event title (omitted on a tombstone)
    - `status` 'active' | 'closed' | 'merged' | 'removed', required: Lifecycle status. `active`/`closed` are live (closed = coverage window lapsed but the event stays visible and can reopen). `merged` = absorbed into another event (see `merged_into`); `removed` = withdrawn from the feed (no live articles remain, or it was found to be incorrect). `merged`/`removed` never appear in the default list and carry only the tombstone fields.
    - `significance` 'notable' | 'routine' | 'commentary': Editorial importance (omitted on a tombstone). `notable` = front-page-worthy; `routine` = factual ledger record; `commentary` = single-article opinion/analysis.
    - `event_type` object, nullable: The kind of event (omitted on a tombstone)
      - `slug` string
      - `label` string
      - `category` string
    - `article_count` integer: Number of live articles reporting this event (omitted on a tombstone). This is the total count. Your plan's age and source restrictions do not reduce it; use GET on the event to see which of them your plan can fetch.
    - `first_reported_at` string, date-time, nullable: When this event was first reported (ISO 8601, omitted on a tombstone): the earliest known publication time among this event's member articles. Falls back to `last_article_at` for ordering when null. This is editorial time, not the time the record reached this API.
    - `last_article_at` string, date-time, nullable: Publication time of the newest article reporting this event (ISO 8601, omitted on a tombstone).
    - `updated_at` string, date-time, required: When this record last changed (ISO 8601). This is the clock incremental sync runs on. Pass your last completed sync time as `updated_after`, drain every page via `pagination.next_cursor`, and only then advance your stored timestamp.
    - `company_ids` string[]: IDs of companies associated with this event, verified and visible only (omitted on a tombstone). Restricted to companies with an active-involvement role (subject, acquirer, target, investor, issuer, partner) unless `include_peripheral=true`.
    - `story_ids` string[]: IDs of published stories generated from this event, if any (omitted on a tombstone)
    - `merged_into` string, nullable: ID of the surviving event this one was merged into. Present only when `status` is `merged`; null for every other status, including `removed` and on some older merged events.
    - `related_to` string, nullable: Commentary-only metadata: the `id` of the factual event this commentary event comments on or reacts to, when the piece is about a specific factual event. Always null for non-commentary events, and often null for commentary events too (the piece may not be about a specific event). Filter with `related_to=<id>` to find commentary reacting to a given event.
  - `pagination` object, required
    - `count` integer
    - `next_cursor` string, nullable: Opaque cursor to fetch the next page. `null` when there are no more results.
  - `plan_limited` boolean: Present and `true` when your plan capped the result to its top-N most recent events. Absent when your plan applies no cap. With `mode=semantic`, present and `true` when your plan's source or age restrictions are in force instead.
  - `truncated` boolean: Only with `mode=semantic`. Present and `true` when the article-match horizon was exhausted, so further matching events exist that this response cannot reach.

## Other responses

- `304`: Not Modified
- `400`: Invalid parameter
- `401`: Missing or invalid API key

---

[API](https://skmtc.dev/nordicfinancialnews/apis/nordic-financial-news-api.md) - [All operations](https://skmtc.dev/nordicfinancialnews/apis/nordic-financial-news-api/llms.txt) - [OpenAPI document](https://skmtc.dev/nordicfinancialnews/apis/nordic-financial-news-api/revisions/aa48db8c82fc?raw)
