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 extracted from a source article and tied to a single company.

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. To read the announcement an event came from, fetch source_article_id from the articles endpoint. It is null when that article is no longer live. 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.

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. Both compare against the UTC scheduled_at, which puts the day-precision trap back in play. A dividend dated 1 October in Stockholm is stored at 2026-09-30T22:00:00Z, so a window opening at 2026-10-01T00:00:00Z misses it. Pad each bound by a day and trim on local_time. scheduled_after is inclusive, scheduled_before exclusive.
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 September 3, 2026