> ## 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.

# List Calendar Events

> Returns a paginated list of scheduled Nordic financial calendar events — earnings reports (Q1 / H1 / FY etc.), earnings calls, trading updates, AGMs/EGMs, capital markets days, conference presentations, dividends, and M&A milestones (announcements, offer deadlines, completions).

Each event is tied to a single company and is sorted by `scheduled_at` ascending (soonest first). `scheduled_at` is always in UTC; for local-time display use the `local_time` field (`scheduled_at` rendered in the issuer's `timezone`, ISO 8601 with offset). Prefer `local_time` for the calendar date — a day-precision event is stored at local midnight, so its UTC `scheduled_at` falls on the previous day for ahead-of-UTC (Nordic) zones. `title` and `description` are always English regardless of the source-article language.

## Dividends
Each dividend row carries a nested `dividend` object with `ex_date`, `record_date`, `payment_date`, `declaration_date`, and `kind`. `scheduled_at` follows the priority **ex-date > record-date > payment-date** — whichever is explicitly stated, in that order. `dividend` is `null` for non-dividend events.

## Default window
By default only upcoming events are returned, from today onward by the issuer's local date (so events scheduled for today stay listed throughout the day). Pass `scheduled_after` or `scheduled_before` to query a specific window — this also surfaces past events, which carry `status: published` (events flip from `scheduled` to `published` ~2 days after their date). An `updated_after` sync walk also lifts this floor, since sync must cover past events too.

## Status
List endpoints return `scheduled` + `published` events and **exclude `cancelled`** by default. Pass the `status` parameter to filter (`status=cancelled` to retrieve cancellations, or `scheduled`/`published` to narrow). Discarded events are never returned. Note: a `scheduled → cancelled` transition is *not* surfaced by default `updated_after` polling — to track cancellations, poll with `status=cancelled` or subscribe to cancellation alerts.

## Filtering
Compose `ticker`, `country`, `exchange`, `index`, `sector`, and `event_type` to narrow the result set. All filters are intersected.

## 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. The walk covers the full served dataset, including past events — a first sync from an old watermark returns history, not just upcoming events. Updates to past events that occurred before your currently stored watermark are not replayed; reset the watermark (or start a fresh sync) to backfill them.

## 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.



## OpenAPI

````yaml https://nordicfinancialnews.com/openapi/v1/openapi.yaml get /api/v1/calendar_events
openapi: 3.0.1
info:
  title: Nordic Financial News API
  version: v1.0
  description: >
    REST API for Nordic financial news. Each article is summarized in English
    (headline, short summary, and key points) with the original-language article
    linked via `article_url`. The full article body stays at the source.


    ## Authentication

    All endpoints require Bearer token authentication using an API key.

    Include the API key in the Authorization header:

    ```

    Authorization: Bearer YOUR_API_KEY

    ```


    ## Rate Limiting

    The API enforces per-hour rate limits based on your plan:

    - **Free**: 100 requests/hour

    - **Pro**: 5,000 requests/hour


    Rate limit information is included in response headers:

    - `X-RateLimit-Limit`: Maximum requests per hour

    - `X-RateLimit-Remaining`: Requests remaining

    - `X-RateLimit-Reset`: Seconds until limit resets

    - `X-RateLimit-Policy`: Human-readable rate limit policy (e.g. `5000 per
    hour; token bucket`)


    The `/health` endpoint is exempt from rate limiting and does not return rate
    limit headers.


    ## Monthly Usage Limits

    Free and Plus keys have a fixed monthly allowance that resets at the start
    of each

    calendar month:

    - **Free**: 100 requests/month

    - **Plus**: 100 requests/month


    Responses on these plans include:

    - `X-Monthly-Limit`: Maximum requests for the current month

    - `X-Monthly-Remaining`: Requests remaining this month

    - `X-Monthly-Reset`: ISO 8601 timestamp when the allowance resets


    When the allowance is exceeded, the API returns `429 Too Many Requests` with
    a `Retry-After` header.


    Pro has no hard limit. It includes 25,000 requests per billing cycle, with
    usage-based

    pricing beyond that, so requests are never blocked. Responses on Pro
    include:

    - `X-Monthly-Usage`: Requests used in the current billing cycle

    - `X-Monthly-Reset`: ISO 8601 timestamp when the current billing cycle ends


    A Pro billing cycle follows your subscription's billing period, which begins
    on the

    date you subscribed and is not necessarily a calendar month. Usage is
    counted by day,

    so the first day of a billing cycle is counted in full.


    ## Caching

    The API supports HTTP caching with ETags. Include the `If-None-Match`

    header with the ETag from a previous response to receive a 304 Not Modified

    response if the data hasn't changed.


    ## Pagination

    List endpoints support cursor-based pagination. Use the `cursor` parameter

    with the value from `pagination.next_cursor` in the response to fetch the
    next page.

    Paginated responses also include a `Link` header with `rel="next"` pointing
    to the next page URL.


    ## Incremental Sync

    To keep a local copy current, poll `updated_after` — not `published_after`.


    1. Request `?updated_after=<your last completed sync>`.

    2. Results are ordered by `updated_at` ascending and cursor-paginated.

    3. Follow `pagination.next_cursor`, resending the same `updated_after`,
    until it is `null`.

    4. Only then store the time the sync started, minus a small overlap, as your
    new
       watermark. A minute is plenty.

    Step 3 matters: a response is capped at `limit` (default 25, max 100), so a
    changed set

    larger than one page arrives across several. Advancing your watermark before
    draining

    every page skips the remainder.


    The overlap in step 4 matters for the same reason: a record's `updated_at`
    is set when

    the write happens, but it only becomes visible when that write commits a
    moment later.

    Without an overlap a record can be stamped just before your watermark and
    land just

    after it, and you would never ask for it again. Re-reading a minute of
    changes is

    cheap and idempotent.


    `published_at` is editorial time — when the news happened, not when the
    record reached

    this API — so a record can appear with a `published_at` older than one you
    already hold.

    Records are re-sent when they change, so reconcile by `id`.


    Removals are not signalled: an article withdrawn from the feed simply stops
    being

    returned. Incremental sync tells you what changed, not what disappeared, so
    treat a

    local mirror as append-and-update rather than an exact replica.


    ## Error Handling

    Errors follow the RFC 9457 Problem Details format with appropriate HTTP
    status codes.
  contact:
    name: API Support
    email: hello@nordicfinancialnews.com
servers:
  - url: https://nordicfinancialnews.com
    description: Production server
security: []
paths:
  /api/v1/calendar_events:
    get:
      tags:
        - Calendar Events
      summary: List Calendar Events
      description: >-
        Returns a paginated list of scheduled Nordic financial calendar events —
        earnings reports (Q1 / H1 / FY etc.), earnings calls, trading updates,
        AGMs/EGMs, capital markets days, conference presentations, dividends,
        and M&A milestones (announcements, offer deadlines, completions).


        Each event is tied to a single company and is sorted by `scheduled_at`
        ascending (soonest first). `scheduled_at` is always in UTC; for
        local-time display use the `local_time` field (`scheduled_at` rendered
        in the issuer's `timezone`, ISO 8601 with offset). Prefer `local_time`
        for the calendar date — a day-precision event is stored at local
        midnight, so its UTC `scheduled_at` falls on the previous day for
        ahead-of-UTC (Nordic) zones. `title` and `description` are always
        English regardless of the source-article language.


        ## Dividends

        Each dividend row carries a nested `dividend` object with `ex_date`,
        `record_date`, `payment_date`, `declaration_date`, and `kind`.
        `scheduled_at` follows the priority **ex-date > record-date >
        payment-date** — whichever is explicitly stated, in that order.
        `dividend` is `null` for non-dividend events.


        ## Default window

        By default only upcoming events are returned, from today onward by the
        issuer's local date (so events scheduled for today stay listed
        throughout the day). Pass `scheduled_after` or `scheduled_before` to
        query a specific window — this also surfaces past events, which carry
        `status: published` (events flip from `scheduled` to `published` ~2 days
        after their date). An `updated_after` sync walk also lifts this floor,
        since sync must cover past events too.


        ## Status

        List endpoints return `scheduled` + `published` events and **exclude
        `cancelled`** by default. Pass the `status` parameter to filter
        (`status=cancelled` to retrieve cancellations, or
        `scheduled`/`published` to narrow). Discarded events are never returned.
        Note: a `scheduled → cancelled` transition is *not* surfaced by default
        `updated_after` polling — to track cancellations, poll with
        `status=cancelled` or subscribe to cancellation alerts.


        ## Filtering

        Compose `ticker`, `country`, `exchange`, `index`, `sector`, and
        `event_type` to narrow the result set. All filters are intersected.


        ## 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.
        The walk covers the full served dataset, including past events — a first
        sync from an old watermark returns history, not just upcoming events.
        Updates to past events that occurred before your currently stored
        watermark are not replayed; reset the watermark (or start a fresh sync)
        to backfill them.


        ## 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.
      parameters:
        - name: limit
          in: query
          required: false
          description: Number of events to return per page (default 25, max 100).
          example: 25
          schema:
            type: integer
        - name: cursor
          in: query
          required: false
          description: >-
            Opaque pagination cursor returned as `pagination.next_cursor` from a
            previous response. When continuing an `updated_after` sync, resend
            the same `updated_after` value alongside it.
          schema:
            type: string
        - name: fields
          in: query
          required: false
          description: >-
            Comma-separated list of fields to include in the response. Reduces
            payload size. `id` is always included. Available fields: `title`,
            `description`, `event_type`, `status`, `date_precision`,
            `fiscal_period`, `scheduled_at`, `timezone`, `local_time`,
            `scheduled_at_changed_at`, `source_article_id`, `company_id`,
            `country`, `dividend`, `updated_at`.
          example: title,event_type,scheduled_at,company_id,dividend
          schema:
            type: string
        - name: updated_after
          in: query
          required: false
          description: >-
            ISO 8601 datetime. Returns only events updated after this timestamp.
            Use for incremental sync: store the timestamp of your last completed
            sync and pass it on the next request. Results are ordered by
            `updated_at` ascending and cursor-paginated — drain
            `pagination.next_cursor` before advancing your stored timestamp.
            Passing this parameter also disables the default upcoming-only
            floor, so past events with newer updates are included.
          example: '2026-03-01T00:00:00Z'
          schema:
            type: string
        - name: ticker
          in: query
          required: false
          description: >-
            Filter by company stock ticker (e.g. `VOLV-B`). Also accepts
            exchange-suffixed form (e.g. `VOLV-B.ST`).
          example: VOLV-B
          schema:
            type: string
        - name: company
          in: query
          required: false
          description: >-
            Filter to a single company by its `id` (as returned by the companies
            endpoints). Complements `ticker`; use this to reach companies
            without a stock listing.
          example: cmpny1234567
          schema:
            type: string
        - name: country
          in: query
          required: false
          description: >-
            Filter by country using ISO 3166-1 alpha-2 code (e.g. `SE`, `DK`,
            `NO`, `FI`, `IS`). Comma-separated for multiple (e.g. `SE,NO`).
            Case-insensitive.
          example: SE
          schema:
            type: string
        - name: exchange
          in: query
          required: false
          description: >-
            Filter by exchange using ISO 10383 Market Identifier Code (e.g.
            `XSTO` for Nasdaq Stockholm, `XCSE` for Nasdaq Copenhagen, `XHEL`
            for Nasdaq Helsinki, `XOSL` for Oslo Børs). Case-insensitive.
          example: XSTO
          schema:
            type: string
        - name: index
          in: query
          required: false
          description: >-
            Filter by stock index id or symbol (e.g. `OMXS30`, `OMXC25`,
            `OMXH25`, `OBX`). Returns events only for companies in that index.
            Case-insensitive for symbols.
          example: OMXS30
          schema:
            type: string
        - name: sector
          in: query
          required: false
          description: >-
            Filter by company sector. Must exactly match one of the standard
            sector names: `Communication Services`, `Consumer Discretionary`,
            `Consumer Staples`, `Energy`, `Financials`, `Health Care`,
            `Industrials`, `Information Technology`, `Materials`, `Real Estate`,
            `Utilities`.
          example: Industrials
          schema:
            type: string
        - name: event_type
          in: query
          required: false
          description: >-
            Filter by event type. Accepts a single value or a comma-separated
            list for multiple types.
          example: earnings_report,earnings_call
          schema:
            type: string
            enum:
              - earnings_report
              - earnings_call
              - agm
              - egm
              - dividend
              - capital_markets_day
              - trading_update
              - conference_presentation
              - ma_announcement
              - ma_offer_deadline
              - ma_completion
              - listing
              - delisting
        - name: status
          in: query
          required: false
          description: >-
            Filter by lifecycle status. Omitted: returns `scheduled` + past
            `published` events and excludes `cancelled`. Pass `cancelled` to
            retrieve cancellations, or `scheduled`/`published` to narrow.
          example: cancelled
          schema:
            type: string
            enum:
              - scheduled
              - published
              - cancelled
        - name: scheduled_after
          in: query
          required: false
          description: >-
            ISO 8601 datetime. Only events at or after this time. Passing this
            parameter disables the default upcoming-only floor, allowing past
            events to be returned.
          example: '2026-01-01T00:00:00Z'
          schema:
            type: string
        - name: scheduled_before
          in: query
          required: false
          description: >-
            ISO 8601 datetime. Only events before this time. Passing this
            parameter disables the default upcoming-only floor, allowing past
            events to be returned.
          example: '2026-12-31T23:59:59Z'
          schema:
            type: string
        - name: watchlist
          in: query
          required: false
          description: >-
            Restricts to events for companies in a single watchlist, identified
            by its `id` (from the List Watchlists endpoint). An unknown id
            returns no events. Requires `read:watchlist` scope.
          example: wl_8fk2a1b3c4d5
          schema:
            type: string
      responses:
        '200':
          description: Calendar events retrieved successfully
          content:
            application/json:
              examples:
                upcoming_events_with_dividend:
                  value:
                    calendar_events:
                      - id: cale_q3volvo1
                        title: Volvo AB Q3 2026 interim report
                        description: >-
                          Publication of the interim report for Q3 2026 and
                          earnings call at 10:00 CET.
                        event_type: earnings_report
                        status: scheduled
                        date_precision: exact
                        fiscal_period: q3_2026
                        scheduled_at: '2026-10-22T05:00:00.000Z'
                        timezone: Europe/Stockholm
                        local_time: '2026-10-22T07:00:00.000+02:00'
                        scheduled_at_changed_at: null
                        source_article_id: art_xyz45678
                        company_id: w55fcw3pbg3p
                        country: SE
                        dividend: null
                        updated_at: '2026-03-01T09:00:00.000Z'
                      - id: cale_dividlim1
                        title: Lime Technologies dividend 2026
                        description: Cash dividend resolved at AGM on 2026-04-23.
                        event_type: dividend
                        status: scheduled
                        date_precision: day
                        fiscal_period: null
                        scheduled_at: '2026-04-24T22:00:00.000Z'
                        timezone: Europe/Stockholm
                        local_time: '2026-04-25T00:00:00.000+02:00'
                        scheduled_at_changed_at: null
                        source_article_id: art_limediv12
                        company_id: limeabxxx234
                        country: SE
                        dividend:
                          ex_date: '2026-04-25'
                          record_date: '2026-04-28'
                          payment_date: '2026-05-06'
                          declaration_date: '2026-04-23'
                          kind: ordinary
                        updated_at: '2026-04-23T08:30:00.000Z'
                    pagination:
                      count: 2
                      next_cursor: IlVtcHByZXRPQVZTWnJrVS4uLiI=
              schema:
                type: object
                required:
                  - calendar_events
                  - pagination
                properties:
                  calendar_events:
                    type: array
                    items:
                      $ref: '#/components/schemas/CalendarEventSummary'
                  pagination:
                    type: object
                    properties:
                      count:
                        type: integer
                        example: 2
                      next_cursor:
                        type: string
                        nullable: true
                        description: >-
                          Opaque cursor to fetch the next page. `null` when
                          there are no more results.
                        example: IlVtcHByZXRPQVZTWnJrVS4uLiI=
                  plan_limited:
                    type: boolean
                    description: >-
                      Present and `true` when your plan restricted the result to
                      its upcoming-events window, so the result may be
                      incomplete. Filters narrow within that window rather than
                      searching the full calendar, so on a limited plan an
                      issuer filter often returns an empty list. Absent when
                      your plan applies no restriction.
                    example: true
        '400':
          description: Invalid parameter
          content:
            application/json:
              examples:
                invalid_event_type:
                  value:
                    type: >-
                      https://docs.nordicfinancialnews.com/problems/invalid-parameter
                    title: Invalid parameter
                    status: 400
                    detail: >-
                      Unknown event_type(s): not_a_type. Valid values:
                      earnings_report, earnings_call, agm, egm, dividend,
                      capital_markets_day, trading_update,
                      conference_presentation, ma_announcement,
                      ma_offer_deadline, ma_completion, listing, delisting
                    instance: urn:request:a1b2c3
                    parameter: event_type
              schema:
                $ref: '#/components/schemas/problem_details'
        '401':
          description: Missing or invalid API key
          content:
            application/json:
              examples:
                unauthorized:
                  value:
                    type: https://docs.nordicfinancialnews.com/problems/auth-invalid
                    title: Authentication required
                    status: 401
                    detail: Missing or invalid API key
                    instance: urn:request:a1b2c3
              schema:
                $ref: '#/components/schemas/problem_details'
      security:
        - bearer_auth: []
components:
  schemas:
    CalendarEventSummary:
      type: object
      required:
        - id
        - title
        - event_type
        - status
        - scheduled_at
        - company_id
      properties:
        id:
          type: string
          description: Unique calendar event identifier
          example: cale_q3volvo1
        title:
          type: string
          description: Event title as reported by the issuer or exchange
          example: Q3 2026 Interim Report
        description:
          type: string
          nullable: true
          description: Optional long-form description
          example: >-
            Publication of the interim report for Q3 2026 and earnings call at
            10:00 CET.
        event_type:
          type: string
          description: The kind of calendar event
          enum:
            - earnings_report
            - earnings_call
            - agm
            - egm
            - dividend
            - capital_markets_day
            - trading_update
            - conference_presentation
            - ma_announcement
            - ma_offer_deadline
            - ma_completion
            - listing
            - delisting
          example: earnings_report
        status:
          type: string
          description: >-
            Event lifecycle status. `scheduled` is upcoming; `published` means
            the event has occurred (events flip ~2 days after their date);
            `cancelled` means the issuer withdrew it. List endpoints return
            `scheduled` + `published` and exclude `cancelled` by default — pass
            the `status` query parameter to filter (e.g. `status=cancelled`).
          enum:
            - scheduled
            - published
            - cancelled
          example: scheduled
        date_precision:
          type: string
          description: >-
            Granularity of `scheduled_at`. `exact` = timestamp known; `day` =
            date only; `month` = only the month is known. Consumers that need a
            date should still use `scheduled_at` (set to a representative point
            inside the window).
          enum:
            - exact
            - day
            - month
          example: day
        fiscal_period:
          type: string
          nullable: true
          description: >-
            Fiscal period slug (required for report-type events, e.g. `q3_2026`,
            `fy_2025`)
          example: q3_2026
        scheduled_at:
          type: string
          format: date-time
          description: >-
            Scheduled date/time in UTC (ISO 8601). For the local calendar date
            use `local_time` instead — a day-precision event is stored at local
            midnight, so its UTC instant falls on the previous day for
            ahead-of-UTC (Nordic) zones.
          example: '2026-10-22T05:00:00.000Z'
        timezone:
          type: string
          description: >-
            The issuer's IANA timezone, used to interpret `scheduled_at`.
            Resolved from the source article, falling back to the company's
            country zone.
          example: Europe/Stockholm
        local_time:
          type: string
          format: date-time
          description: >-
            `scheduled_at` rendered in the issuer's `timezone` (ISO 8601 with
            offset). Use this for the correct local date/time — its date is
            right even for day-precision events.
          example: '2026-10-22T07:00:00.000+02:00'
        scheduled_at_changed_at:
          type: string
          format: date-time
          nullable: true
          description: >-
            When `scheduled_at` last changed. Useful for change-feed consumers
            tracking date moves.
          example: '2026-03-15T10:00:00.000Z'
        source_article_id:
          type: string
          nullable: true
          description: >-
            ID of the article the event was extracted from. `null` when the
            source article is not retrievable (not live, or removed).
            Best-effort: on the free plan it may reference an article your plan
            can't fetch (premium source or outside the age window).
          example: art_xyz45678
        company_id:
          type: string
          description: ID of the company this event relates to
          example: w55fcw3pbg3p
        country:
          type: string
          nullable: true
          description: Country ISO 3166-1 alpha-2 code
          example: SE
        dividend:
          type: object
          nullable: true
          description: >-
            Dividend lifecycle dates. `null` for non-dividend events.
            `scheduled_at` follows the priority ex-date > record-date >
            payment-date — whichever is explicitly stated.
          properties:
            ex_date:
              type: string
              nullable: true
              description: >-
                Ex-dividend date (YYYY-MM-DD). The market-event anchor — share
                price drops on this day.
              example: '2026-04-25'
            record_date:
              type: string
              nullable: true
              description: >-
                Record date (YYYY-MM-DD). Holders of record on this date receive
                the dividend.
              example: '2026-04-28'
            payment_date:
              type: string
              nullable: true
              description: >-
                Payment date (YYYY-MM-DD). When the cash is distributed to
                shareholders.
              example: '2026-05-06'
            declaration_date:
              type: string
              nullable: true
              description: >-
                Declaration / announcement date (YYYY-MM-DD). Metadata only —
                never used as the calendar anchor.
              example: '2026-03-20'
            kind:
              type: string
              enum:
                - ordinary
                - special
              description: >-
                Tranche type. `ordinary` for the recurring/regular dividend;
                `special` for an extra/bonus/one-off dividend. When an issuer
                proposes both for the same date, they are returned as two
                separate events.
              example: ordinary
        updated_at:
          type: string
          format: date-time
          description: >-
            When the event was last updated (ISO 8601) — use with
            `updated_after` for polling
          example: '2026-03-01T09:00:00.000Z'
    problem_details:
      type: object
      required:
        - type
        - title
        - status
        - detail
        - instance
      properties:
        type:
          type: string
          description: URI that identifies the problem type
        title:
          type: string
          description: Short human-readable summary
        status:
          type: integer
          description: HTTP status code
        detail:
          type: string
          description: Human-readable explanation
        instance:
          type: string
          description: URI that identifies the specific occurrence
  securitySchemes:
    bearer_auth:
      type: http
      scheme: bearer
      bearerFormat: API Key
      description: API Key authentication using Bearer token

````