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

> Returns a paginated list of live articles ordered by publication date (newest first). Each article includes an English headline, a short summary, and key points, with `article_url` linking to the full original-language article at the source. Supports filtering by country, category, source, company ticker, and content type. Use `GET /api/v1/sources` to discover source IDs for the `sources` filter. Use `updated_after` for incremental syncing, or `q` for full-text search ranked by relevance. Use `ids` for batch lookup of specific articles. Responses include cursor-based pagination and support field projection to minimize payload size.



## OpenAPI

````yaml https://nordicfinancialnews.com/openapi/v1/openapi.yaml get /api/v1/articles
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/articles:
    get:
      tags:
        - Articles
      summary: List Articles
      description: >-
        Returns a paginated list of live articles ordered by publication date
        (newest first). Each article includes an English headline, a short
        summary, and key points, with `article_url` linking to the full
        original-language article at the source. Supports filtering by country,
        category, source, company ticker, and content type. Use `GET
        /api/v1/sources` to discover source IDs for the `sources` filter. Use
        `updated_after` for incremental syncing, or `q` for full-text search
        ranked by relevance. Use `ids` for batch lookup of specific articles.
        Responses include cursor-based pagination and support field projection
        to minimize payload size.
      parameters:
        - name: limit
          in: query
          required: false
          description: Number of articles 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. Mutually exclusive with `q`.
          schema:
            type: string
        - name: fields
          in: query
          required: false
          description: >-
            Comma-separated list of fields to include in the response. Reduces
            payload size. Available fields: `id`, `title`, `article_url`,
            `published_at`, `content_type`, `source`, `company_ids`, `country`,
            `category`.
          example: id,title,published_at
          schema:
            type: string
        - name: updated_after
          in: query
          required: false
          description: >-
            ISO 8601 datetime. Returns only articles updated after this
            timestamp. Use this for incremental sync: store the timestamp of
            your last completed sync, then request only newer results on each
            poll. Results are ordered by `updated_at` ascending and are
            cursor-paginated — follow `pagination.next_cursor`, resending the
            same `updated_after` value, until it is null. Only advance your
            stored timestamp once you have drained every page (see the Real-Time
            Updates guide at https://docs.nordicfinancialnews.com).
          example: '2024-01-01T00:00:00Z'
          schema:
            type: string
        - name: q
          in: query
          required: false
          description: >-
            Full-text search query (2-200 characters). Results are ranked by
            relevance instead of publication date. Mutually exclusive with
            `cursor`. Disables caching.
          example: Volvo earnings
          schema:
            type: string
        - name: country
          in: query
          required: false
          description: >-
            Filter by country using ISO 3166-1 alpha-2 code (e.g. `SE`, `NO`,
            `DK`). Comma-separated for multiple (e.g. `SE,NO`).
            Case-insensitive.
          example: SE
          schema:
            type: string
        - name: sources
          in: query
          required: false
          description: >-
            Comma-separated list of source IDs (max 25). Use `GET
            /api/v1/sources` to discover source IDs. Also accepts array form
            (`sources[]=id1&sources[]=id2`). Disabled sources resolve to empty
            results.
          example: abc123def456,ghi789jkl012
          schema:
            type: string
        - name: ticker
          in: query
          required: false
          description: >-
            Filter by company stock ticker symbol (e.g. `VOLV-B`). Accepts full
            tickers with exchange suffix (e.g. `VOLV-B.ST`). Returns articles
            mentioning the company. Former tickers resolve too — a company that
            renamed or moved venues is still reachable by an old ticker; the
            returned company `former_tickers` lists any such historical tickers.
          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: 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). Returns articles about
            companies actively listed there. 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 articles about companies in that index.
            Case-insensitive for symbols.
          example: OMXS30
          schema:
            type: string
        - name: sector
          in: query
          required: false
          description: >-
            Filter by company sector. Case-sensitive; must exactly match one of:
            `Communication Services`, `Consumer Discretionary`, `Consumer
            Staples`, `Energy`, `Financials`, `Health Care`, `Industrials`,
            `Information Technology`, `Materials`, `Real Estate`, `Utilities`.
          example: Industrials
          schema:
            type: string
        - name: content_type
          in: query
          required: false
          description: Filter by article content type.
          example: news
          schema:
            type: string
            enum:
              - news
              - analysis
              - press_release
              - market_commentary
              - market_news
              - trading_halt
              - trading_event
              - other
        - name: published_after
          in: query
          required: false
          description: >-
            ISO 8601 datetime. Returns articles published on or after this
            timestamp.
          example: '2024-06-01T00:00:00Z'
          schema:
            type: string
        - name: published_before
          in: query
          required: false
          description: ISO 8601 datetime. Returns articles published before this timestamp.
          example: '2024-12-31T23:59:59Z'
          schema:
            type: string
        - name: listed
          in: query
          required: false
          description: >-
            When `true`, only return articles mentioning at least one publicly
            listed company.
          example: 'true'
          schema:
            type: string
        - name: watchlist
          in: query
          required: false
          description: >-
            Restricts to articles mentioning companies in a single watchlist,
            identified by its `id` (from the List Watchlists endpoint). An
            unknown id returns no articles. Requires `read:watchlist` scope.
          example: wl_8fk2a1b3c4d5
          schema:
            type: string
        - name: ids
          in: query
          required: false
          description: >-
            Comma-separated list of article IDs for batch lookup (max 100).
            Cannot be combined with `cursor` or `updated_after`.
          example: art_abc123,art_def456
          schema:
            type: string
      responses:
        '200':
          description: Articles retrieved successfully
          content:
            application/json:
              schema:
                type: object
                properties:
                  articles:
                    type: array
                    items:
                      $ref: '#/components/schemas/ArticleSummary'
                  pagination:
                    type: object
                    properties:
                      count:
                        type: integer
                        example: 25
                      next_cursor:
                        type: string
                        nullable: true
                required:
                  - articles
        '401':
          description: unauthorized
          content:
            application/json:
              examples:
                unauthorized:
                  value:
                    type: https://docs.nordicfinancialnews.com/problems/auth-invalid
                    title: Unauthorized
                    status: 401
                    detail: Missing or invalid API key
                    instance: urn:request:abc123
              schema:
                $ref: '#/components/schemas/problem_details'
      security:
        - bearer_auth: []
components:
  schemas:
    ArticleSummary:
      type: object
      required:
        - id
        - title
        - published_at
        - updated_at
        - article_url
        - content_type
        - category
        - source
        - company_ids
        - country
      properties:
        id:
          type: string
          description: Unique article identifier
          example: art_abc123def
        title:
          type: string
          description: Article title in English
          example: Volvo Reports Record Q3 Earnings
        article_url:
          type: string
          description: Link to the original article
          example: https://di.se/articles/volvo-q3-2026
        content_type:
          type: string
          description: Type of article content
          example: news
          enum:
            - news
            - analysis
            - press_release
            - market_commentary
            - market_news
            - trading_halt
            - trading_event
            - other
        published_at:
          type: string
          format: date-time
          description: >-
            When the article was published by its source (ISO 8601). This is
            editorial time, not the time the article reached this API — use it
            to filter by when news happened, never to track what is new to you.
          example: '2026-03-15T09:30:00.000Z'
        updated_at:
          type: string
          format: date-time
          description: >-
            When this record last changed (ISO 8601). This is the clock
            incremental sync runs on — it only ever moves forward, unlike
            published_at. To sync: pass your last completed sync time as
            `updated_after`, drain every page via `pagination.next_cursor`, and
            only then advance your stored timestamp.
          example: '2026-03-15T09:35:00.000Z'
        category:
          type: object
          description: Article category
          properties:
            id:
              type: string
              example: cat_earnings1
            name:
              type: string
              example: Earnings & Financial Results
        source:
          type: object
          description: The news source that published this article
          properties:
            id:
              type: string
              description: Unique source identifier
              example: abc123def456
            name:
              type: string
              example: Dagens Industri
            domain:
              type: string
              example: di.se
        company_ids:
          type: array
          items:
            type: string
          description: IDs of companies mentioned in the article
          example:
            - uejazctgchj4
        country:
          type: string
          nullable: true
          description: Country code (ISO 3166-1 alpha-2)
          example: SE
    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

````