openapi: 3.0.3
info:
  title: Nordic Crypto data API
  version: "1"
  description: "Public read-only JSON for Nordic Crypto (https://nordiccrypto.no/). No authentication. News, newsletters, events, sources, academia, the who's who, profiles, images, the rules map, the changelog, the article archive and Nordic exchange prices (market data, not investment advice). Kaupr is a news source only, never a sponsor. The sign-off is The Nordic Crypto team. GitHub Pages sends Access-Control-Allow-Origin: * so browsers can fetch these files. English text is the default; published translations are inside each object under *_i18n. Site languages: /api/v1/languages.json. IP-country language guess: /api/v1/geo-language.json (the nc_lang cookie wins). Discovery: https://nordiccrypto.no/api/v1/index.json. Human docs: https://nordiccrypto.no/api/."
  license:
    name: MIT
    url: "https://github.com/jQrgen/nordic-crypto/blob/main/LICENSE"
  contact:
    name: Nordic Crypto
    url: "https://nordiccrypto.no/about/"
servers:
  - url: "https://nordiccrypto.no"
    description: Public site
paths:
  "/api/v1/index.json":
    get:
      operationId: index
      summary: "Discovery document: every endpoint, with example URLs."
      responses:
        "200":
          description: "Discovery document: every endpoint, with example URLs."
          content:
            "application/json":
              schema:
                "$ref": "#/components/schemas/Discovery"
  "/api/v1/news.json":
    get:
      operationId: api_v1_news
      summary: "Published news and our own stories, newest first."
      responses:
        "200":
          description: "Published news and our own stories, newest first."
          content:
            "application/json":
              schema:
                "$ref": "#/components/schemas/NewsList"
  "/api/v1/news/{id}.json":
    get:
      operationId: api_v1_news_item
      summary: One item from /api/v1/news.json
      responses:
        "200":
          description: One item from /api/v1/news.json
          content:
            "application/json":
              schema:
                "$ref": "#/components/schemas/Document"
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
  "/api/v1/news/by-country/{country}.json":
    get:
      operationId: news_by_country
      summary: "Published news for one country code: NO, SE, DK, FI, IS, NORDIC or EU."
      responses:
        "200":
          description: "Published news for one country code: NO, SE, DK, FI, IS, NORDIC or EU."
          content:
            "application/json":
              schema:
                "$ref": "#/components/schemas/NewsList"
      parameters:
        - name: country
          in: path
          required: true
          schema:
            type: string
            enum:
              - "NO"
              - SE
              - DK
              - FI
              - IS
              - NORDIC
              - EU
  "/api/v1/news/topics.json":
    get:
      operationId: api_v1_news_topics
      summary: "Topic ids present in the published news, with counts."
      responses:
        "200":
          description: "Topic ids present in the published news, with counts."
          content:
            "application/json":
              schema:
                "$ref": "#/components/schemas/TopicIndex"
  "/api/v1/news/by-topic/{topic}.json":
    get:
      operationId: api_v1_news_topics_item
      summary: One item from /api/v1/news/topics.json
      responses:
        "200":
          description: One item from /api/v1/news/topics.json
          content:
            "application/json":
              schema:
                "$ref": "#/components/schemas/Document"
      parameters:
        - name: topic
          in: path
          required: true
          schema:
            type: string
  "/api/v1/newsletters.json":
    get:
      operationId: api_v1_newsletters
      summary: "Published newsletter issues, newest first. The list omits the HTML body; the issue URL includes text and html."
      responses:
        "200":
          description: "Published newsletter issues, newest first. The list omits the HTML body; the issue URL includes text and html."
          content:
            "application/json":
              schema:
                "$ref": "#/components/schemas/NewsletterList"
  "/api/v1/newsletters/{id}.json":
    get:
      operationId: api_v1_newsletters_item
      summary: One item from /api/v1/newsletters.json
      responses:
        "200":
          description: One item from /api/v1/newsletters.json
          content:
            "application/json":
              schema:
                "$ref": "#/components/schemas/Document"
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
  "/api/v1/events.json":
    get:
      operationId: api_v1_events
      summary: "Public events, soonest start first, including past events."
      responses:
        "200":
          description: "Public events, soonest start first, including past events."
          content:
            "application/json":
              schema:
                "$ref": "#/components/schemas/EventList"
  "/api/v1/events/{id}.json":
    get:
      operationId: api_v1_events_item
      summary: One item from /api/v1/events.json
      responses:
        "200":
          description: One item from /api/v1/events.json
          content:
            "application/json":
              schema:
                "$ref": "#/components/schemas/Document"
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
  "/api/v1/events/upcoming.json":
    get:
      operationId: api_v1_events_upcoming
      summary: "Events that have not ended, soonest first. Judged in the event's own offset."
      responses:
        "200":
          description: "Events that have not ended, soonest first. Judged in the event's own offset."
          content:
            "application/json":
              schema:
                "$ref": "#/components/schemas/EventList"
  "/api/v1/events/past.json":
    get:
      operationId: api_v1_events_past
      summary: "Finished public events, newest first. Finished events stay in the archive."
      responses:
        "200":
          description: "Finished public events, newest first. Finished events stay in the archive."
          content:
            "application/json":
              schema:
                "$ref": "#/components/schemas/EventList"
  "/api/v1/events/by-country/{country}.json":
    get:
      operationId: events_by_country
      summary: Public events for one country code.
      responses:
        "200":
          description: Public events for one country code.
          content:
            "application/json":
              schema:
                "$ref": "#/components/schemas/EventList"
      parameters:
        - name: country
          in: path
          required: true
          schema:
            type: string
            enum:
              - "NO"
              - SE
              - DK
              - FI
              - IS
              - NORDIC
              - EU
  "/api/v1/sources.json":
    get:
      operationId: api_v1_sources
      summary: "News outlets, the public search terms, and event sources. Kaupr is marked as a news source only. logo is the outlet image for that source id when one is on file."
      responses:
        "200":
          description: "News outlets, the public search terms, and event sources. Kaupr is marked as a news source only. logo is the outlet image for that source id when one is on file."
          content:
            "application/json":
              schema:
                "$ref": "#/components/schemas/SourceCatalogue"
  "/api/v1/academia.json":
    get:
      operationId: api_v1_academia
      summary: "Editor-approved courses, student groups, publications and research."
      responses:
        "200":
          description: "Editor-approved courses, student groups, publications and research."
          content:
            "application/json":
              schema:
                "$ref": "#/components/schemas/Academia"
  "/api/v1/academia/courses.json":
    get:
      operationId: api_v1_academia_courses
      summary: "Academia section: courses."
      responses:
        "200":
          description: "Academia section: courses."
          content:
            "application/json":
              schema:
                "$ref": "#/components/schemas/AcademiaSection"
  "/api/v1/academia/groups.json":
    get:
      operationId: api_v1_academia_groups
      summary: "Academia section: groups."
      responses:
        "200":
          description: "Academia section: groups."
          content:
            "application/json":
              schema:
                "$ref": "#/components/schemas/AcademiaSection"
  "/api/v1/academia/publications.json":
    get:
      operationId: api_v1_academia_publications
      summary: "Academia section: publications."
      responses:
        "200":
          description: "Academia section: publications."
          content:
            "application/json":
              schema:
                "$ref": "#/components/schemas/AcademiaSection"
  "/api/v1/academia/research.json":
    get:
      operationId: api_v1_academia_research
      summary: "Academia section: research."
      responses:
        "200":
          description: "Academia section: research."
          content:
            "application/json":
              schema:
                "$ref": "#/components/schemas/AcademiaSection"
  "/api/v1/academia/{id}.json":
    get:
      operationId: academia_item
      summary: One academia row. The id is in academia.json.
      responses:
        "200":
          description: One academia row. The id is in academia.json.
          content:
            "application/json":
              schema:
                "$ref": "#/components/schemas/AcademiaItem"
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
  "/api/v1/orgchart.json":
    get:
      operationId: api_v1_orgchart
      summary: "Published who's who: organisations, people, relations, regulation notes and caveats."
      responses:
        "200":
          description: "Published who's who: organisations, people, relations, regulation notes and caveats."
          content:
            "application/json":
              schema:
                "$ref": "#/components/schemas/OrgChart"
  "/api/v1/orgchart/{id}.json":
    get:
      operationId: api_v1_orgchart_item
      summary: One item from /api/v1/orgchart.json
      responses:
        "200":
          description: One item from /api/v1/orgchart.json
          content:
            "application/json":
              schema:
                "$ref": "#/components/schemas/Document"
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
  "/api/v1/orgchart/relations.json":
    get:
      operationId: api_v1_orgchart_relations
      summary: "Relations between published who's who entries."
      responses:
        "200":
          description: "Relations between published who's who entries."
          content:
            "application/json":
              schema:
                "$ref": "#/components/schemas/RelationList"
  "/api/v1/orgchart/regulation.json":
    get:
      operationId: api_v1_orgchart_regulation
      summary: "Short regulation status for each Nordic country, as on the who's who page."
      responses:
        "200":
          description: "Short regulation status for each Nordic country, as on the who's who page."
          content:
            "application/json":
              schema:
                "$ref": "#/components/schemas/RegulationList"
  "/api/v1/orgchart/relations/{id}.json":
    get:
      operationId: orgchart_relation
      summary: "One relation from the who's who."
      responses:
        "200":
          description: "One relation from the who's who."
          content:
            "application/json":
              schema:
                "$ref": "#/components/schemas/Relation"
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
  "/api/v1/profiles.json":
    get:
      operationId: api_v1_profiles
      summary: "Public profile links (Wikipedia, X, Wikidata and similar) for people and organisations."
      responses:
        "200":
          description: "Public profile links (Wikipedia, X, Wikidata and similar) for people and organisations."
          content:
            "application/json":
              schema:
                "$ref": "#/components/schemas/ProfileList"
  "/api/v1/profiles/{id}.json":
    get:
      operationId: api_v1_profiles_item
      summary: One item from /api/v1/profiles.json
      responses:
        "200":
          description: One item from /api/v1/profiles.json
          content:
            "application/json":
              schema:
                "$ref": "#/components/schemas/Document"
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
  "/api/v1/images.json":
    get:
      operationId: api_v1_images
      summary: "Logos and photos used on the public who's who, with licence and credit."
      responses:
        "200":
          description: "Logos and photos used on the public who's who, with licence and credit."
          content:
            "application/json":
              schema:
                "$ref": "#/components/schemas/ImageList"
  "/api/v1/changelog.json":
    get:
      operationId: api_v1_changelog
      summary: "Site changelog (product changes, not the news), newest first."
      responses:
        "200":
          description: "Site changelog (product changes, not the news), newest first."
          content:
            "application/json":
              schema:
                "$ref": "#/components/schemas/ChangelogList"
  "/api/v1/changelog/{id}.json":
    get:
      operationId: api_v1_changelog_item
      summary: One item from /api/v1/changelog.json
      responses:
        "200":
          description: One item from /api/v1/changelog.json
          content:
            "application/json":
              schema:
                "$ref": "#/components/schemas/Document"
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
  "/api/v1/rules.json":
    get:
      operationId: api_v1_rules
      summary: "How EU crypto rules become law in the five countries. Simplified, not legal advice. Omitted while the page is still a placeholder."
      responses:
        "200":
          description: "How EU crypto rules become law in the five countries. Simplified, not legal advice. Omitted while the page is still a placeholder."
          content:
            "application/json":
              schema:
                "$ref": "#/components/schemas/Rules"
  "/api/v1/archive/articles.json":
    get:
      operationId: api_v1_archive_articles
      summary: Append-only archive of stories that have been on the public site. removed is  true when a story later left the site; the row stays.
      responses:
        "200":
          description: Append-only archive of stories that have been on the public site. removed is  true when a story later left the site; the row stays.
          content:
            "application/json":
              schema:
                "$ref": "#/components/schemas/ArticleArchive"
  "/api/v1/archive/articles/{id}.json":
    get:
      operationId: api_v1_archive_articles_item
      summary: One item from /api/v1/archive/articles.json
      responses:
        "200":
          description: One item from /api/v1/archive/articles.json
          content:
            "application/json":
              schema:
                "$ref": "#/components/schemas/Document"
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
  "/api/v1/markets.json":
    get:
      operationId: markets
      summary: "Nordic exchange prices. Market data, not investment advice. Each ticker names the exchange, fetched_at, the source URL and volume when the exchange published it. NOK, SEK, DKK and EUR only. aggregated is one row per pair."
      responses:
        "200":
          description: "Nordic exchange prices. Market data, not investment advice. Each ticker names the exchange, fetched_at, the source URL and volume when the exchange published it. NOK, SEK, DKK and EUR only. aggregated is one row per pair."
          content:
            "application/json":
              schema:
                "$ref": "#/components/schemas/MarketCatalogue"
  "/api/v1/markets/aggregated.json":
    get:
      operationId: markets_aggregated
      summary: "One price per base-quote pair. BTC-NOK is separate from BTC-EUR. last is the mean of published last prices. mid is the mean of bid/ask midpoints and is not blended into last. Volume is summed only within the same field and the same pair. logo_url is a CC0 icon when cryptocurrency-icons includes the asset, otherwise null."
      responses:
        "200":
          description: "One price per base-quote pair. BTC-NOK is separate from BTC-EUR. last is the mean of published last prices. mid is the mean of bid/ask midpoints and is not blended into last. Volume is summed only within the same field and the same pair. logo_url is a CC0 icon when cryptocurrency-icons includes the asset, otherwise null."
          content:
            "application/json":
              schema:
                "$ref": "#/components/schemas/MarketAggregated"
  "/api/v1/markets/{exchange}.json":
    get:
      operationId: markets_exchange
      summary: "Prices from one included exchange: firi (Norway), nbx (Norway) or coinmotion (Finland)."
      responses:
        "200":
          description: "Prices from one included exchange: firi (Norway), nbx (Norway) or coinmotion (Finland)."
          content:
            "application/json":
              schema:
                "$ref": "#/components/schemas/MarketExchange"
      parameters:
        - name: exchange
          in: path
          required: true
          schema:
            type: string
  "/api/v1/markets/by-asset/{symbol}.json":
    get:
      operationId: markets_asset
      summary: "Prices for one asset (the base symbol, such as BTC) on every included Nordic exchange, plus aggregated pairs for each quote currency and logo_url when an icon is available."
      responses:
        "200":
          description: "Prices for one asset (the base symbol, such as BTC) on every included Nordic exchange, plus aggregated pairs for each quote currency and logo_url when an icon is available."
          content:
            "application/json":
              schema:
                "$ref": "#/components/schemas/MarketAsset"
      parameters:
        - name: symbol
          in: path
          required: true
          schema:
            type: string
  "/api/v1/languages.json":
    get:
      operationId: api_v1_languages
      summary: "Site UI languages: code, native name, English name, rtl, html lang and home URL."
      responses:
        "200":
          description: "Site UI languages: code, native name, English name, rtl, html lang and home URL."
          content:
            "application/json":
              schema:
                "$ref": "#/components/schemas/LanguageList"
  "/api/v1/geo-language.json":
    get:
      operationId: api_v1_geo_language
      summary: Country to default site language. An IP guess only; the nc_lang cookie from the language switcher wins.
      responses:
        "200":
          description: Country to default site language. An IP guess only; the nc_lang cookie from the language switcher wins.
          content:
            "application/json":
              schema:
                "$ref": "#/components/schemas/GeoLanguage"
  "/api/v1/meta.json":
    get:
      operationId: api_v1_meta
      summary: "Site name, languages, countries, page list, CORS, editorial notes and brand social accounts (social.telegram, social.x)."
      responses:
        "200":
          description: "Site name, languages, countries, page list, CORS, editorial notes and brand social accounts (social.telegram, social.x)."
          content:
            "application/json":
              schema:
                "$ref": "#/components/schemas/SiteMeta"
components:
  schemas:
    Document:
      type: object
      additionalProperties: true
    Discovery:
      type: object
      properties:
        api_version:
          type: string
        name:
          type: string
        generated_at:
          type: string
        preview:
          type: boolean
        endpoints:
          type: array
        counts:
          type: object
        cors:
          type: object
      description: Discovery
    NewsOutlet:
      type: object
      required:
        - url
        - primary
      properties:
        outlet:
          type: string
          description: Source id from sources.json.
        outlet_name:
          type: string
        url:
          type: string
        title:
          type: string
          description: "That outlet's headline."
        published:
          type: string
          description: ISO 8601 date-time with offset.
        lang:
          type: string
          description: "Language name, same vocabulary as language on the story."
        language_code:
          type: string
          nullable: true
        country:
          type: string
        source_type:
          type: string
          enum:
            - national
            - regional
            - official
            - international
          description: "national, regional (regional and local), official (justice and official), or international."
        paywall:
          type: boolean
        primary:
          type: boolean
        logo:
          type: object
          nullable: true
        source_note:
          type: string
          nullable: true
          description: "Set when the outlet is Kaupr: a news source only, never a sponsor."
    NewsCoverage:
      type: object
      required:
        - count
        - by_country
        - by_source_type
      properties:
        count:
          type: integer
        by_country:
          type: array
          items:
            type: object
            properties:
              country:
                type: string
              count:
                type: integer
              share:
                type: number
        by_source_type:
          type: array
          description: "Always national, regional, official and international, in that order. count 0 is included."
          items:
            type: object
            properties:
              type:
                type: string
              count:
                type: integer
              share:
                type: number
    NewsItem:
      type: object
      required:
        - id
        - title
        - published
        - api_url
      properties:
        id:
          type: string
        url:
          type: string
          description: Story the reader follows. Absolute.
        html_url:
          type: string
          nullable: true
          description: Our story page. For our own articles this is the article. For other outlets this is the coverage page; url is the primary outlet.
        api_url:
          type: string
        title:
          type: string
        title_en:
          type: string
          nullable: true
        source:
          type: string
          description: Source id from sources.json.
        source_name:
          type: string
        source_logo:
          type: object
          nullable: true
          description: Outlet logo for this source id. Null when no checked image is on file; show the name only. file_url is the image. The id → file map is assets/img/logos/logos.json.
          properties:
            kind:
              type: string
            file_url:
              type: string
            source_url:
              type: string
            license:
              type: string
              nullable: true
            credit:
              type: string
              nullable: true
        source_note:
          type: string
          nullable: true
        country:
          type: string
        language:
          type: string
        language_code:
          type: string
          nullable: true
        published:
          type: string
          description: ISO 8601 date-time with offset.
        topics:
          type: array
          items:
            type: string
        summary:
          type: string
          nullable: true
          description: Our English summary.
        summary_i18n:
          type: object
          additionalProperties:
            type: string
          description: "Keys are site language codes: nn, nb, sv, da, fi, is. English lives in the sibling field."
        paywall:
          type: boolean
        links:
          type: array
          items:
            type: object
        own_story:
          type: boolean
        primary_source:
          "$ref": "#/components/schemas/NewsOutlet"
        also_covered_by:
          type: array
          items:
            "$ref": "#/components/schemas/NewsOutlet"
          description: Other outlets on the same event. Empty when only the primary covered it.
        sources:
          type: array
          items:
            "$ref": "#/components/schemas/NewsOutlet"
          description: "Primary first, then also_covered_by."
        coverage:
          "$ref": "#/components/schemas/NewsCoverage"
    NewsList:
      type: object
      properties:
        api_version:
          type: string
        name:
          type: string
        generated_at:
          type: string
        preview:
          type: boolean
        count:
          type: integer
        items:
          type: array
          items:
            type: object
            required:
              - id
              - title
              - published
              - api_url
            properties:
              id:
                type: string
              url:
                type: string
                description: Story the reader follows. Absolute.
              html_url:
                type: string
                nullable: true
                description: Our story page. For our own articles this is the article. For other outlets this is the coverage page; url is the primary outlet.
              api_url:
                type: string
              title:
                type: string
              title_en:
                type: string
                nullable: true
              source:
                type: string
                description: Source id from sources.json.
              source_name:
                type: string
              source_logo:
                type: object
                nullable: true
                description: Outlet logo for this source id. Null when no checked image is on file; show the name only. file_url is the image. The id → file map is assets/img/logos/logos.json.
                properties:
                  kind:
                    type: string
                  file_url:
                    type: string
                  source_url:
                    type: string
                  license:
                    type: string
                    nullable: true
                  credit:
                    type: string
                    nullable: true
              source_note:
                type: string
                nullable: true
              country:
                type: string
              language:
                type: string
              language_code:
                type: string
                nullable: true
              published:
                type: string
                description: ISO 8601 date-time with offset.
              topics:
                type: array
                items:
                  type: string
              summary:
                type: string
                nullable: true
                description: Our English summary.
              summary_i18n:
                type: object
                additionalProperties:
                  type: string
                description: "Keys are site language codes: nn, nb, sv, da, fi, is. English lives in the sibling field."
              paywall:
                type: boolean
              links:
                type: array
                items:
                  type: object
              own_story:
                type: boolean
              primary_source:
                "$ref": "#/components/schemas/NewsOutlet"
              also_covered_by:
                type: array
                items:
                  "$ref": "#/components/schemas/NewsOutlet"
                description: Other outlets on the same event. Empty when only the primary covered it.
              sources:
                type: array
                items:
                  "$ref": "#/components/schemas/NewsOutlet"
                description: "Primary first, then also_covered_by."
              coverage:
                "$ref": "#/components/schemas/NewsCoverage"
        updated:
          type: string
          nullable: true
      description: NewsList
    TopicIndex:
      type: object
      properties:
        api_version:
          type: string
        name:
          type: string
        generated_at:
          type: string
        preview:
          type: boolean
        topics:
          type: array
      description: TopicIndex
    Event:
      type: object
      required:
        - id
        - title
        - start
      properties:
        id:
          type: string
        title:
          type: string
        title_original:
          type: string
          nullable: true
        start:
          type: string
          description: ISO 8601 date-time with offset.
        end:
          type: string
          nullable: true
        place:
          type: string
          nullable: true
        city:
          type: string
          nullable: true
        country:
          type: string
        online:
          type: boolean
        organiser:
          type: string
        url:
          type: string
        source:
          type: string
        paid:
          nullable: true
        sponsored:
          nullable: true
          description: "false, true, or the sponsor's name. Never Kaupr."
        note:
          type: string
          nullable: true
        note_i18n:
          type: object
          additionalProperties:
            type: string
          description: "Keys are site language codes: nn, nb, sv, da, fi, is. English lives in the sibling field."
        past:
          type: boolean
        html_url:
          type: string
        api_url:
          type: string
    EventList:
      type: object
      properties:
        api_version:
          type: string
        name:
          type: string
        generated_at:
          type: string
        preview:
          type: boolean
        count:
          type: integer
        events:
          type: array
          items:
            type: object
            required:
              - id
              - title
              - start
            properties:
              id:
                type: string
              title:
                type: string
              title_original:
                type: string
                nullable: true
              start:
                type: string
                description: ISO 8601 date-time with offset.
              end:
                type: string
                nullable: true
              place:
                type: string
                nullable: true
              city:
                type: string
                nullable: true
              country:
                type: string
              online:
                type: boolean
              organiser:
                type: string
              url:
                type: string
              source:
                type: string
              paid:
                nullable: true
              sponsored:
                nullable: true
                description: "false, true, or the sponsor's name. Never Kaupr."
              note:
                type: string
                nullable: true
              note_i18n:
                type: object
                additionalProperties:
                  type: string
                description: "Keys are site language codes: nn, nb, sv, da, fi, is. English lives in the sibling field."
              past:
                type: boolean
              html_url:
                type: string
              api_url:
                type: string
      description: EventList
    NewsletterIssue:
      type: object
      required:
        - id
        - date
        - title
      properties:
        id:
          type: string
        number:
          type: integer
        date:
          type: string
          description: ISO date YYYY-MM-DD.
        period:
          type: object
          properties:
            start:
              type: string
            end:
              type: string
        title:
          type: string
        subtitle:
          type: string
        title_i18n:
          type: object
          additionalProperties:
            type: string
          description: "Keys are site language codes: nn, nb, sv, da, fi, is. English lives in the sibling field."
        subtitle_i18n:
          type: object
          additionalProperties:
            type: string
          description: "Keys are site language codes: nn, nb, sv, da, fi, is. English lives in the sibling field."
        sign_off:
          type: string
        text:
          type: string
          description: "Plain text of the English issue. Present on the issue URL, not the list."
        html:
          type: string
        text_i18n:
          type: object
        html_i18n:
          type: object
        video:
          type: object
          nullable: true
        api_url:
          type: string
        html_url:
          type: string
    NewsletterList:
      type: object
      properties:
        api_version:
          type: string
        name:
          type: string
        generated_at:
          type: string
        preview:
          type: boolean
        count:
          type: integer
        issues:
          type: array
          items:
            type: object
            required:
              - id
              - date
              - title
            properties:
              id:
                type: string
              number:
                type: integer
              date:
                type: string
                description: ISO date YYYY-MM-DD.
              period:
                type: object
                properties:
                  start:
                    type: string
                  end:
                    type: string
              title:
                type: string
              subtitle:
                type: string
              title_i18n:
                type: object
                additionalProperties:
                  type: string
                description: "Keys are site language codes: nn, nb, sv, da, fi, is. English lives in the sibling field."
              subtitle_i18n:
                type: object
                additionalProperties:
                  type: string
                description: "Keys are site language codes: nn, nb, sv, da, fi, is. English lives in the sibling field."
              sign_off:
                type: string
              text:
                type: string
                description: "Plain text of the English issue. Present on the issue URL, not the list."
              html:
                type: string
              text_i18n:
                type: object
              html_i18n:
                type: object
              video:
                type: object
                nullable: true
              api_url:
                type: string
              html_url:
                type: string
      description: NewsletterList
    SourceCatalogue:
      type: object
      properties:
        api_version:
          type: string
        name:
          type: string
        generated_at:
          type: string
        preview:
          type: boolean
        sources:
          type: array
        search:
          type: array
        event_sources:
          type: array
      description: SourceCatalogue
    Academia:
      type: object
      properties:
        api_version:
          type: string
        name:
          type: string
        generated_at:
          type: string
        preview:
          type: boolean
        courses:
          type: array
        groups:
          type: array
        publications:
          type: array
        research:
          type: array
      description: Academia
    AcademiaSection:
      type: object
      properties:
        api_version:
          type: string
        name:
          type: string
        generated_at:
          type: string
        preview:
          type: boolean
        section:
          type: string
        items:
          type: array
      description: AcademiaSection
    AcademiaItem:
      type: object
      properties:
        api_version:
          type: string
        name:
          type: string
        generated_at:
          type: string
        preview:
          type: boolean
        item:
          type: object
      description: AcademiaItem
    OrgChart:
      type: object
      properties:
        api_version:
          type: string
        name:
          type: string
        generated_at:
          type: string
        preview:
          type: boolean
        entities:
          type: array
        relations:
          type: array
        regulation:
          type: array
      description: OrgChart
    Relation:
      type: object
    RelationList:
      type: object
      properties:
        api_version:
          type: string
        name:
          type: string
        generated_at:
          type: string
        preview:
          type: boolean
        relations:
          type: array
      description: RelationList
    RegulationList:
      type: object
      properties:
        api_version:
          type: string
        name:
          type: string
        generated_at:
          type: string
        preview:
          type: boolean
        regulation:
          type: array
      description: RegulationList
    ProfileList:
      type: object
      properties:
        api_version:
          type: string
        name:
          type: string
        generated_at:
          type: string
        preview:
          type: boolean
        profiles:
          type: array
      description: ProfileList
    ImageList:
      type: object
      properties:
        api_version:
          type: string
        name:
          type: string
        generated_at:
          type: string
        preview:
          type: boolean
        images:
          type: array
      description: ImageList
    ChangelogList:
      type: object
      properties:
        api_version:
          type: string
        name:
          type: string
        generated_at:
          type: string
        preview:
          type: boolean
        entries:
          type: array
      description: ChangelogList
    Rules:
      type: object
      properties:
        api_version:
          type: string
        name:
          type: string
        generated_at:
          type: string
        preview:
          type: boolean
        available:
          type: boolean
        checked:
          type: string
      description: Rules
    ArticleArchive:
      type: object
      properties:
        api_version:
          type: string
        name:
          type: string
        generated_at:
          type: string
        preview:
          type: boolean
        articles:
          type: array
      description: ArticleArchive
    SiteMeta:
      type: object
      properties:
        api_version:
          type: string
        name:
          type: string
        generated_at:
          type: string
        preview:
          type: boolean
        languages:
          type: array
        countries:
          type: array
        cors:
          type: object
        ios:
          type: object
          description: Public TestFlight invite. Not an App Store listing.
        social:
          type: object
          description: "Nordic Crypto brand accounts. telegram is https://t.me/nordiccryptochat. x is https://x.com/xcryptonordic. label and name are English. name_i18n has nn, nb, sv, da, fi and is. Other languages use name."
          properties:
            note:
              type: string
            telegram:
              type: object
              properties:
                label:
                  type: string
                  example: Telegram
                name:
                  type: string
                  example: Nordic Crypto on Telegram
                name_i18n:
                  type: object
                url:
                  type: string
                  example: "https://t.me/nordiccryptochat"
            x:
              type: object
              properties:
                label:
                  type: string
                  example: X
                name:
                  type: string
                  example: Follow Nordic Crypto on X
                name_i18n:
                  type: object
                url:
                  type: string
                  example: "https://x.com/xcryptonordic"
                handle:
                  type: string
                  example: "@xcryptonordic"
        urls:
          type: object
          description: "github, substack, telegram and x, plus the API bases."
      description: SiteMeta
    LanguageList:
      type: object
      properties:
        api_version:
          type: string
        name:
          type: string
        generated_at:
          type: string
        preview:
          type: boolean
        count:
          type: integer
        languages:
          type: array
          items:
            type: object
      description: LanguageList
    GeoLanguage:
      type: object
      properties:
        api_version:
          type: string
        name:
          type: string
        generated_at:
          type: string
        preview:
          type: boolean
        note:
          type: string
        default:
          type: string
        by_country:
          type: object
          additionalProperties:
            type: string
        order:
          type: array
          items:
            type: string
      description: GeoLanguage
    MarketTicker:
      type: object
      required:
        - symbol
        - base
        - quote
        - exchange
        - fetched_at
        - source_url
      properties:
        id:
          type: string
        symbol:
          type: string
          description: "BASE-QUOTE, for example BTC-NOK."
          example: BTC-NOK
        exchange_symbol:
          type: string
          description: The pair id used by the exchange.
        base:
          type: string
        quote:
          type: string
          enum:
            - NOK
            - SEK
            - DKK
            - EUR
        last:
          type: string
          nullable: true
          description: "Last price as published, decimal string. Null when the exchange does not publish a last trade."
        bid:
          type: string
          nullable: true
          description: "Best bid as published, decimal string."
        ask:
          type: string
          nullable: true
          description: "Best ask as published, decimal string."
        exchange:
          type: object
          required:
            - id
            - name
            - country
          properties:
            id:
              type: string
            name:
              type: string
            country:
              type: string
        fetched_at:
          type: string
          description: "When Nordic Crypto fetched this row, ISO 8601 UTC."
        source_url:
          type: string
          description: Exchange URL the figure was read from.
        volume_base:
          type: string
          nullable: true
          description: "Base-asset volume as published. Null when the exchange omits it. Firi's volume is stored here; that payload does not name a 24-hour window. Not treated as zero when missing."
        volume_quote:
          type: string
          nullable: true
          description: "Quote-currency volume as published, window not named. Null when omitted."
        volume_base_24h:
          type: string
          nullable: true
          description: Base-asset volume over the last 24 hours. Set only when the exchange names that window (NBX). Not added to volume_base.
        volume_quote_24h:
          type: string
          nullable: true
          description: "Quote-currency volume over the last 24 hours (NBX). The unit is this pair's quote (NOK, SEK, DKK or EUR)."
        high:
          type: string
          nullable: true
        low:
          type: string
          nullable: true
        change_pct:
          type: string
          nullable: true
        exchange_time:
          type: string
          nullable: true
          description: "Timestamp from the exchange payload, when it sends one."
    MarketLogo:
      type: object
      nullable: true
      description: Present when cryptocurrency-icons (CC0-1.0) includes this asset. Null fields on the parent when it does not. Nordic Crypto does not draw substitutes.
      properties:
        format:
          type: string
          example: svg
        source:
          type: string
        source_url:
          type: string
        version:
          type: string
        license:
          type: string
          example: CC0-1.0
        license_name:
          type: string
        license_url:
          type: string
        authors:
          type: string
        attribution:
          type: string
    MarketVolume:
      type: object
      description: Sums of like volume fields inside one pair. Fields are not mixed. A null sum means nobody published that field.
      properties:
        volume_base:
          type: string
          nullable: true
          description: "Sum of volume_base. Unit: base asset. Window not named."
        volume_base_exchanges:
          type: integer
        volume_quote:
          type: string
          nullable: true
          description: "Sum of volume_quote. Unit: quote currency. Window not named."
        volume_quote_exchanges:
          type: integer
        volume_base_24h:
          type: string
          nullable: true
          description: "Sum of volume_base_24h. Unit: base asset over the last 24 hours."
        volume_base_24h_exchanges:
          type: integer
        volume_quote_24h:
          type: string
          nullable: true
          description: "Sum of volume_quote_24h. Unit: quote currency over the last 24 hours."
        volume_quote_24h_exchanges:
          type: integer
        units:
          type: object
    MarketAggregate:
      type: object
      required:
        - symbol
        - base
        - quote
        - currency
        - exchange_count
        - updated_at
        - method
        - price
        - last
        - mid
        - min
        - max
        - contributors
        - volume
      properties:
        symbol:
          type: string
          example: BTC-NOK
          description: BASE-QUOTE. One bucket per quote currency.
        base:
          type: string
        name:
          type: string
          nullable: true
        quote:
          type: string
          enum:
            - NOK
            - SEK
            - DKK
            - EUR
        currency:
          type: string
          description: "Same as quote. NOK is never combined with EUR, SEK or DKK."
        updated_at:
          type: string
          nullable: true
          description: "Newest fetched_at among the contributors, ISO 8601 UTC."
        oldest_fetched_at:
          type: string
          nullable: true
        exchange_count:
          type: integer
          description: How many exchanges quoted this pair.
        method:
          type: string
          nullable: true
          enum:
            - mean_last
            - mean_bid_ask_mid
          description: "mean_last when any last exists, otherwise mean_bid_ask_mid. Null when no price can be formed."
        method_note:
          type: string
        price:
          type: string
          nullable: true
          description: "Equals last, or mid when no last exists."
        min:
          type: string
          nullable: true
          description: Lowest value in the same series as price.
        max:
          type: string
          nullable: true
          description: Highest value in the same series as price.
        last:
          type: string
          nullable: true
          description: Arithmetic mean of published last prices. Null if none.
        last_count:
          type: integer
        last_min:
          type: string
          nullable: true
        last_max:
          type: string
          nullable: true
        mid:
          type: string
          nullable: true
          description: Arithmetic mean of (bid+ask)/2 where both were published. Not blended into last.
        mid_count:
          type: integer
        mid_min:
          type: string
          nullable: true
        mid_max:
          type: string
          nullable: true
        vwap:
          type: string
          nullable: true
          description: "Always null. Volume windows are not comparable, so there is no VWAP."
        volume_used_for_price:
          type: boolean
        volume:
          "$ref": "#/components/schemas/MarketVolume"
        contributors:
          type: array
          items:
            type: object
        logo_url:
          type: string
          nullable: true
          description: "Absolute GitHub Pages URL of the SVG, or null."
        logo_url_custom_domain:
          type: string
          nullable: true
        logo_path:
          type: string
          nullable: true
          description: "Site-relative path, for example api/v1/markets/logos/btc.svg."
        logo:
          "$ref": "#/components/schemas/MarketLogo"
    MarketCatalogue:
      type: object
      properties:
        api_version:
          type: string
        name:
          type: string
        generated_at:
          type: string
        preview:
          type: boolean
        disclaimer:
          type: string
        count:
          type: integer
        aggregated_count:
          type: integer
        aggregation:
          type: object
          description: "How last, mid, volume and logos are derived."
        exchanges:
          type: array
        skipped:
          type: array
          description: Venues checked and left out because they have no public ticker.
        tickers:
          type: array
          items:
            "$ref": "#/components/schemas/MarketTicker"
        aggregated:
          type: array
          items:
            "$ref": "#/components/schemas/MarketAggregate"
        urls:
          type: object
        refresh:
          type: object
      description: MarketCatalogue
    MarketExchange:
      type: object
      properties:
        api_version:
          type: string
        name:
          type: string
        generated_at:
          type: string
        preview:
          type: boolean
        exchange:
          type: object
        count:
          type: integer
        tickers:
          type: array
          items:
            "$ref": "#/components/schemas/MarketTicker"
      description: MarketExchange
    MarketAsset:
      type: object
      properties:
        api_version:
          type: string
        name:
          type: string
          nullable: true
        generated_at:
          type: string
        preview:
          type: boolean
        symbol:
          type: string
        count:
          type: integer
        tickers:
          type: array
          items:
            "$ref": "#/components/schemas/MarketTicker"
        aggregated:
          type: array
          items:
            "$ref": "#/components/schemas/MarketAggregate"
          description: One object per quote currency for this asset.
        aggregation:
          type: object
        logo_url:
          type: string
          nullable: true
        logo_url_custom_domain:
          type: string
          nullable: true
        logo_path:
          type: string
          nullable: true
        logo:
          "$ref": "#/components/schemas/MarketLogo"
      description: MarketAsset
    MarketAggregated:
      type: object
      properties:
        api_version:
          type: string
        name:
          type: string
        generated_at:
          type: string
        preview:
          type: boolean
        kind:
          type: string
          example: markets-aggregated
        count:
          type: integer
        aggregation:
          type: object
        pairs:
          type: array
          items:
            "$ref": "#/components/schemas/MarketAggregate"
        urls:
          type: object
      description: MarketAggregated
