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

# How to get company news

> Fetch news articles and stories for a specific Nordic company by ticker or company ID, then filter them by content type, source, and date.

Nordic business news is scattered across dozens of local-language sources, and speaking one Nordic language doesn't cover the other four. This API collapses that into one request: pass a ticker and get that company's news in English, translated within minutes of publication.

## Before you start

Generate an API key in [API key settings](https://nordicfinancialnews.com/settings/api_keys) under **Settings > API Keys**, and keep it in an `API_KEY` environment variable. Every request below sends it as `Authorization: Bearer $API_KEY` against `https://nordicfinancialnews.com/api/v1`. See [Authentication](/guides/authentication) for scopes and rate limits.

## Step 1: Find the company

Every company route takes a company ID or a ticker as its path identifier. Plain symbols, exchange-suffixed forms, and former tickers all resolve. Matching is case-insensitive.

```bash cURL theme={"dark"}
curl -H "Authorization: Bearer $API_KEY" \
  "https://nordicfinancialnews.com/api/v1/companies/VOLV-B"
```

If you only have a name, search with `q`. Results rank exact ticker matches first, then exact name matches, then listed companies ahead of unlisted ones.

```bash cURL theme={"dark"}
curl -H "Authorization: Bearer $API_KEY" \
  "https://nordicfinancialnews.com/api/v1/companies?q=Nordea"
```

<Warning>
  A few symbols are shared by more than one company. The API returns the one holding a listing on a Nordic exchange, then the one with an active listing, then the most recently listed. Pass the company `id` when the lookup has to be unambiguous.
</Warning>

When you already hold identifiers, resolve them as a batch rather than one at a time. `company` takes up to 25 company `id` values and `ticker` up to 25 tickers, so a page of articles costs one request per 25 distinct companies rather than one per company.

```bash cURL theme={"dark"}
curl -H "Authorization: Bearer $API_KEY" \
  "https://nordicfinancialnews.com/api/v1/companies?ticker=VOLV-B,ERIC-B,NOVO-B"
```

Rows come back in name order rather than the order you asked for, so key each one by its own `id`. Every value has to resolve, or the request fails with a `400` naming the ones that did not. Here a shared symbol resolves to every issuer using it instead of tie-breaking to one, so a batch can return more rows than it sent: follow `next_cursor` rather than assuming a single page.

Cross-listings and multiple share classes are common in the Nordics, so check `also_listed_on` on [company detail](/api-reference/companies/get-company-details) to see a company's other venues.

## Step 2: Get the company's articles

An **article** is a single news item from a single source. It carries an English `title`, a `summary`, `key_points`, the publishing `source`, a `content_type`, and `article_url` pointing at the full original-language article.

<CodeGroup>
  ```bash cURL theme={"dark"}
  curl -H "Authorization: Bearer $API_KEY" \
    "https://nordicfinancialnews.com/api/v1/companies/VOLV-B/articles?limit=10"
  ```

  ```python Python theme={"dark"}
  import os
  import requests

  BASE = "https://nordicfinancialnews.com/api/v1"
  HEADERS = {"Authorization": f"Bearer {os.environ['API_KEY']}"}

  resp = requests.get(
      f"{BASE}/companies/VOLV-B/articles",
      headers=HEADERS,
      params={"limit": 10},
  )
  for article in resp.json()["articles"]:
      print(article["published_at"], article["title"])
  ```

  ```javascript JavaScript theme={"dark"}
  const BASE = "https://nordicfinancialnews.com/api/v1";
  const HEADERS = { Authorization: `Bearer ${process.env.API_KEY}` };

  const resp = await fetch(
    `${BASE}/companies/VOLV-B/articles?limit=10`,
    { headers: HEADERS }
  );
  const { articles } = await resp.json();
  articles.forEach((a) => console.log(a.published_at, a.title));
  ```
</CodeGroup>

```json Response theme={"dark"}
{
  "articles": [
    {
      "id": "art_abc123def",
      "title": "Volvo reports record profit",
      "article_url": "https://di.se/articles/volvo-q3-2026",
      "content_type": "news",
      "published_at": "2026-03-15T09:30:00.000Z",
      "updated_at": "2026-03-15T09:35:00.000Z",
      "source": { "name": "Dagens Industri", "domain": "di.se", "source_type": "news_publication" },
      "country": "SE"
    }
  ],
  "pagination": { "count": 10, "next_cursor": "eyJpZCI6..." }
}
```

Articles come back newest first and are cursor-paginated. See [Pagination](/guides/pagination) for the cursor walk, and [Real-time updates](/guides/real-time-updates) to keep a local copy in sync with `updated_after`.

Add `primary_only=true` to drop articles where the company is a passing mention in a sector round-up rather than the subject.

<Warning>
  `title`, `summary`, and `key_points` are machine-translated and AI-paraphrased from the source article. They are not verbatim quotations and they are not human-verified. Link to `article_url` when a reader needs the original wording.
</Warning>

<Note>
  `plan_limited: true` in a response means your plan capped it. A company request returns that company's newest articles rather than a slice of the platform feed, so the filters below narrow within the company's own set. Your plan's source list and recency window still apply first. See the [pricing page](https://nordicfinancialnews.com/pricing) for current limits.
</Note>

## Step 3: Get the company's stories

A **story** is an AI-synthesized narrative that groups several articles covering one developing event into a single account. Where the articles route returns every report on an acquisition separately, this one returns the single story they all belong to.

<CodeGroup>
  ```bash cURL theme={"dark"}
  curl -H "Authorization: Bearer $API_KEY" \
    "https://nordicfinancialnews.com/api/v1/companies/VOLV-B/stories?limit=5"
  ```

  ```python Python theme={"dark"}
  resp = requests.get(
      f"{BASE}/companies/VOLV-B/stories",
      headers=HEADERS,
      params={"limit": 5},
  )
  for story in resp.json()["stories"]:
      print(story["title"], f"({story['article_count']} articles)")
  ```

  ```javascript JavaScript theme={"dark"}
  const resp = await fetch(
    `${BASE}/companies/VOLV-B/stories?limit=5`,
    { headers: HEADERS }
  );
  const { stories } = await resp.json();
  stories.forEach((s) => console.log(s.title, `(${s.article_count} articles)`));
  ```
</CodeGroup>

Each story carries `article_count` and `article_ids`, ordered most relevant first, so you can walk from a story to its sources. Fetch [`GET /stories/{id}`](/api-reference/stories/get-story-details) for the full narrative, which arrives as Markdown in the `content` field.

## Articles or stories?

| You want                               | Use      |
| -------------------------------------- | -------- |
| Every mention, as it is published      | Articles |
| A briefing on what happened            | Stories  |
| To filter by content type or source    | Articles |
| A single account of a developing event | Stories  |

Build a company page with stories at the top for the narrative and the article feed beneath it for the detail.

## Step 4: Filter the feed

Both routes take the same filters as the flat `/articles` and `/stories` feeds, applied to the company in the path: `q`, `sort`, `updated_after`, `country`, `sources`, `published_after`, and `published_before`. Add `fields` to trim the payload and `category` to filter by subject, using an ID from [`GET /categories`](/api-reference/categories/list-categories). Articles also take `content_type`, `source_type`, and `primary_only`.

`content_type` says what kind of item an article is:

| `content_type`      | What it covers                     |
| ------------------- | ---------------------------------- |
| `news`              | Standard reporting                 |
| `analysis`          | Interpretive and analytical pieces |
| `press_release`     | Company-issued announcements       |
| `market_commentary` | Opinion and market color           |
| `market_news`       | Broad market movement reporting    |
| `trading_halt`      | Trading suspensions                |
| `trading_event`     | Other trading-related notices      |
| `other`             | Everything else                    |

`source_type` says what kind of publisher it came from: `news_publication`, `wire_service`, `press_release`, `government`, `trade_publication`, `blog`, `stock_exchange`, or `research`. [Coverage](/coverage) lists which publishers fall into each group.

Only the company's press releases:

```bash cURL theme={"dark"}
curl -H "Authorization: Bearer $API_KEY" \
  "https://nordicfinancialnews.com/api/v1/companies/VOLV-B/articles?content_type=press_release"
```

Only its own exchange disclosures, filed this quarter. `source_type=stock_exchange` narrows to exchange newsfeeds, the lowest-latency tier, and leaves out the news coverage that follows:

```bash cURL theme={"dark"}
curl -H "Authorization: Bearer $API_KEY" \
  "https://nordicfinancialnews.com/api/v1/companies/VOLV-B/articles?source_type=stock_exchange&published_after=2026-07-01T00:00:00Z"
```

A keyword search inside the company's coverage. The default `sort=relevance` returns one ranked page with no cursor, which suits a search box. `sort=latest` makes `q` an ordinary filter under the newest-first order and restores cursor pagination, which suits a feed:

```bash cURL theme={"dark"}
curl -H "Authorization: Bearer $API_KEY" \
  "https://nordicfinancialnews.com/api/v1/companies/VOLV-B/articles?q=electric%20truck&sort=latest"
```

<Warning>
  These routes reject nine parameters that would describe a different company or listing: `ticker`, `company`, `watchlist`, `listed`, `exchange`, `market`, `domicile`, `index`, and `sector`. Sending one returns `400`. The path already fixes the company. To cover several companies, see below.
</Warning>

## News for several companies

The company routes cover one company each. To follow several at once, switch to the flat [`GET /articles`](/api-reference/articles/list-articles) and [`GET /stories`](/api-reference/stories/list-stories) feeds. On those, `ticker` and `company` each take a comma-separated list of up to 25 values and match any of them. Send both and they intersect, like any other pair of filters.

```bash cURL theme={"dark"}
curl -H "Authorization: Bearer $API_KEY" \
  "https://nordicfinancialnews.com/api/v1/articles?ticker=VOLV-B,ERIC-B"
```

To select companies by group rather than by name, the same feeds take `watchlist`, `index` (`OMXS30`), `sector`, `exchange`, `market`, and `domicile`, alongside every filter from step 4. Use `market` for companies listed on a country's exchanges and `domicile` for those legally registered there.

```bash cURL theme={"dark"}
curl -H "Authorization: Bearer $API_KEY" \
  "https://nordicfinancialnews.com/api/v1/articles?index=OMXS30&content_type=press_release"
```

<Warning>
  Every value in a `ticker` or `company` list has to resolve to a company the API publishes. One typo fails the whole request with a `400` and `Unknown ticker(s): VOLVB`, rather than quietly dropping that company from the feed. `index` and `exchange` go the other way. An unrecognized code there never errors: it drops out of the filter, or returns an empty page when nothing in it matches.
</Warning>

## Next steps

<Columns cols={2}>
  <Card title="Real-time updates" icon="rotate" color="#01B2FF" href="/guides/real-time-updates" horizontal>
    Poll with `updated_after` to keep a local mirror in sync.
  </Card>

  <Card title="Caching" icon="bolt" color="#01B2FF" href="/guides/caching" horizontal>
    Send `If-None-Match` and skip the payload when nothing changed.
  </Card>

  <Card title="CLI" icon="terminal" color="#01B2FF" href="/cli/commands" horizontal>
    Run `nfn companies articles VOLV-B` without writing code.
  </Card>

  <Card title="MCP server" icon="robot" color="#01B2FF" href="/model-context-protocol/tools" horizontal>
    Give an AI assistant the same company filters.
  </Card>
</Columns>
