Skip to main content
Nordic financial event data sits in five languages, on seven exchange calendars, and on every issuer’s own investor relations page. This endpoint pulls all of it into one calendar: reporting dates, dividend timetables, shareholder meetings, and deal deadlines, each one tied to a single company. Most dates come from news articles and company announcements, and an issuer’s own investor relations calendar fills in report dates that no article has stated yet.

Before you start

Generate an API key in API key settings 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 for scopes and rate limits.

Step 1: Get the upcoming calendar

GET /calendar_events returns scheduled events soonest first, starting from today.
Response
Each row carries its issuer inline as company, with the name and the primary ticker. Many titles carry no company name at all, so read the issuer from company rather than parsing title. ticker is null for an issuer with no active listing. The feed floors at today by the issuer’s local date, so an event stays listed for the whole of its own day. Results are cursor-paginated, described in Pagination. There is no q parameter here. Titles are templated, so searching them only rediscovers what the fields already hold: six issuers in one week share the exact title “Extraordinary General Meeting 2026”. Filtering is the search, and Step 2 lists the filters. source names who published the event’s current date, so you can cite it next to the date you show. The event above was dated by an EFN news article. See Who published the date for the other kinds of source. List rows are complete records: GET /calendar_events/{id} returns the same fields for one event, so you never need a second call.
plan_limited: true means your plan restricted the calendar to a short upcoming window. Filters narrow within that window rather than searching the full calendar, so a company or index filter can come back empty even when the events exist. See the pricing page for current limits.

Which date to trust

Each event carries the same instant twice. scheduled_at is UTC, and local_time is that instant in the issuer’s timezone. Read your calendar date off local_time.
A date_precision: day event is stored at local midnight, so its UTC scheduled_at falls on the previous day wherever the issuer’s zone is ahead of UTC. The response above shows it: local 2026-09-24 is UTC 2026-09-23T22:00:00Z. Group by scheduled_at and a Swedish earnings calendar comes out a day early.
Slice the date off local_time and group on that. The first ten characters are already the issuer’s local date, so no timezone conversion is involved:
Python
Precision follows the event type. Dividends, listings, and delistings are almost always day; meetings, earnings calls, and investor events are usually exact; earnings reports go either way. Every event carries one or the other, so you never have to render a partial date. An event the issuer dated only to a month or a quarter is left out of the calendar rather than placed on a guessed day, which is one reason a report you expect to see may not be listed yet. The offset comes from the event’s own timezone, not from the market the issuer trades on. The calendar covers Nordic-listed issuers domiciled anywhere, so Icelandic and North American zones turn up too.

Who published the date

Most dates come from a news article or company announcement. For issuers whose investor relations calendar NFN reads, that calendar can also supply earnings report, trading update, and AGM dates that no article has stated yet. source names who published the current date, and what its other fields hold depends on type: source is null when an NFN editor set the date. For an article source, name and article_id are null when the article is no longer available. Where the issuer’s calendar has supplied a date, a news report giving a different one does not overwrite it. source_article_id is a separate field: the article the event was extracted from, which you can fetch from the articles endpoint. It is null when that article is no longer live, and for an event found only on a company website. If a website later supplies the date for an event first reported in an article, source_article_id keeps the article and source names the website. Use source to attribute the date, and source_article_id to read the coverage behind the event.

Step 2: Narrow to what you track

event_type selects the kinds of event you care about and takes a comma-separated list. Pick companies with ticker or company, each taking up to 25 comma-separated values, or pick a group with index, market, exchange, country, domicile, sector, or watchlist. Send ticker and company together and they intersect, like any other pair of filters. The two groups fail differently. Every value in ticker, company, and sector has to resolve, so one typo fails the request with a 400. index, exchange, market, country, and domicile never error: an unrecognized code drops out or returns an empty list, so a mistyped index looks like a quiet week.
cURL
scheduled_after and scheduled_before bound the window, and either one lifts the upcoming-only floor so past events come back too. Use them for a fixed reporting season rather than a rolling feed. Send a bare YYYY-MM-DD and each bound is that calendar date in the issuer’s own timezone, inclusive at both ends. That is the same local date you group by from local_time, so an October window returns October in every issuer’s calendar. Send a full datetime instead and the bound is an exact UTC instant: scheduled_after at or after it, scheduled_before strictly before it. A datetime bound compares against the UTC scheduled_at, which puts the day-precision trap back in play. Use one when you want a time of day, or an end that excludes the date you name.
cURL

Step 3: Follow a single company

Plans with a capped calendar cannot use this route. It returns 403 whatever you pass. The flat feed is the fallback, subject to the same cap: filters narrow within the capped window, so a company with no event inside it comes back empty.
GET /companies/{identifier}/calendar_events fixes the company in the path and resolves identifiers the same way the company news routes do: a ticker, an exchange-suffixed ticker, a former ticker, or a company ID.
cURL
It accepts event_type, status, scheduled_after, scheduled_before, updated_after, fields, and the pagination parameters. The company and group filters are absent, since the path already fixes the company.

Dividends

A dividend event carries a nested dividend object with ex_date, record_date, payment_date, declaration_date, and kind. Its scheduled_at is the first of those the issuer stated, in the order ex-date, then record-date, then payment-date. dividend is null on every other event type.
Response
Do not build an ex-dividend calendar by reading ex_date. It is null on most dividend events, including the one above. The event date is whichever lifecycle date the issuer published, and the dividend object tells you which one that was. Check the field before you label the date.
The dividend dates are strings copied from the issuer’s announcement, not validated dates. Values such as 2026-09-31 do occur, so parse them defensively. kind separates the recurring ordinary dividend from a one-off special one. An issuer proposing both on the same date produces two events sharing a date and a company, so key your dividend records on the event id rather than on the pair. There is no structured amount field. Many titles carry the amount as free text in whatever form the issuer wrote it, so treat it as a label rather than a value to parse.

When a date moves or an event is cancelled

scheduled_at_changed_at records when an event was last rescheduled and is null for a date that has never moved. Compare it against your stored copy to catch reschedules. status runs scheduled, then published, then cancelled if the issuer withdraws the event. published arrives on a daily sweep once scheduled_at is more than two days past, so an event flips two to three days after its date rather than the morning after. List responses return scheduled and published and exclude cancelled, so a cancellation looks like an event that quietly disappeared. Ask for them directly, and pair status with a past window. Two things make that pairing necessary: status on its own does not lift the upcoming-only floor, and issuers usually withdraw an event at or after its own date, which puts most cancellations behind you.
cURL
Keeping a mirror in sync needs a second pass for the same reason. Real-time updates covers the updated_after walk and the separate cancellation poll it requires. On a capped plan updated_after returns 403 rather than a partial walk, since a window that moves with the clock cannot produce a coherent change feed.

Next steps

Company news

Pair a reporting date with the coverage that follows it.

Real-time updates

Walk updated_after to catch reschedules and cancellations.

CLI

Run nfn calendar list --ticker VOLV-B without writing code.

MCP server

Ask an AI assistant what reports are due this week.
Last modified on October 7, 2026