Nordic Crypto data API
A public JSON feed of the site, for apps and for other tools. No account and no API key. It is regenerated whenever the site is built.
Version 1. 42 news items, 1 newsletter issues, 12 events in this build. Generated 2026-10-06T01:06:46+00:00.
Start here
- Discovery — every endpoint and example URL.
- OpenAPI (also YAML).
- llms.txt — plain-language instructions.
- API catalog (RFC 9727 linkset; .json copy).
Fetch news and a newsletter
curl -fsS https://jqrgen.github.io/nordic-crypto/api/v1/news.json curl -fsS https://jqrgen.github.io/nordic-crypto/api/v1/newsletters.json curl -fsS https://jqrgen.github.io/nordic-crypto/api/v1/newsletters/001.json
The same paths on the custom domain, at the site root: https://cryptonordic.no/api/v1/news.json. Swap https://jqrgen.github.io/nordic-crypto/ for https://cryptonordic.no/.
Market prices
Nordic exchange prices are market data, not investment advice. /api/v1/markets.json lists each pair with symbol, base, quote, last, bid and ask when the exchange publishes them, the exchange id, name and country, fetched_at, the source URL, and volume when the exchange published it. volume_base is the base asset with no named window (Firi). volume_base_24h and volume_quote_24h are the last 24 hours (NBX). A missing volume is null, not zero. Quotes are NOK, SEK, DKK and EUR. One exchange is /api/v1/markets/{exchange}.json (firi, nbx, coinmotion). One asset is /api/v1/markets/by-asset/{symbol}.json. Venues without a public ticker are listed under skipped and are not given a made-up price.
/api/v1/markets/aggregated.json is one row per pair. BTC-NOK is not averaged with BTC-EUR. last is the arithmetic mean of published last prices. mid is the mean of (bid+ask)/2 and is not mixed into last. price equals last when any last exists, otherwise mid. min and max use that same series. There is no VWAP. Volume is summed only inside the same field and the same pair. logo_url is an SVG from cryptocurrency-icons (CC0 1.0) when that set includes the asset, served at /api/v1/markets/logos/{symbol}.svg, and null otherwise. The per-asset file repeats aggregated and the logo.
The build fetches the exchanges. .github/workflows/markets-refresh.yml rewrites the JSON on gh-pages about once an hour, including the aggregated file and the icons. The markets page reloads this file, and refreshes Firi and Coinmotion in the browser because those APIs send Access-Control-Allow-Origin: *. NBX does not, so those rows follow the file. The same document on the gh-pages branch: raw.githubusercontent.com/jQrgen/nordic-crypto/gh-pages/api/v1/markets.json.
curl -fsS https://jqrgen.github.io/nordic-crypto/api/v1/markets.json curl -fsS https://jqrgen.github.io/nordic-crypto/api/v1/markets/aggregated.json
Several outlets, one story
A story keeps one primary outlet. Other outlets that covered the same event are in also_covered_by. sources lists the primary first, then the others. Each outlet has outlet, outlet_name, url, title (that outlet's headline), published, lang, country, source_type and logo. source_type is national, regional (regional and local), official (justice and official: police, prosecutors, courts, regulators) or international. coverage.count is the number of outlets. coverage.by_country and coverage.by_source_type are the counts and shares for the bars. Every source type is present, including a count of zero. html_url is our page for that story. url is the primary outlet. Kaupr stays a news source only.
Languages
English is the default field (summary, title, text). Translations that we have published sit in summary_i18n, title_i18n, subtitle_i18n, note_i18n, text_i18n and about_i18n, keyed by nn, nb, sv, da, fi and is. Other site languages use the English field until a translation is published. Headlines from other outlets stay in the original language. Dates are ISO 8601.
/api/v1/languages.json lists every site language with code, native_name, english_name, rtl, html_lang and home. /api/v1/geo-language.json is the country-to-language guess used on a first visit. The IP country comes from the tipworker GET /api/geo (Cloudflare request.cf.country). Nothing is stored. The nc_lang cookie, set by the language switcher, always wins.
CORS
GitHub Pages sends Access-Control-Allow-Origin: * on these files, so a page on another site can fetch() them. GitHub Pages does not apply a custom headers file. Use the .json file name; opening a directory does not return the JSON.
Editorial
The sign-off is The Nordic Crypto team. Kaupr (kaupr.io) is a news source only and is never a sponsor. Nothing here is investment advice.
Brand accounts
/api/v1/meta.json includes social for the iOS app. social.telegram is the Nordic Crypto chat at https://t.me/nordiccryptochat. social.x is the brand account at https://x.com/xcryptonordic (@xcryptonordic), also listed as urls.x. urls.telegram repeats the chat URL. label is the short name (Telegram, X). name is the English link text. name_i18n has nn, nb, sv, da, fi and is. Other site languages use name.
Endpoints
| Method | Path | Returns |
|---|---|---|
| GET | /api/v1/index.json | Discovery document: every endpoint, with example URLs. |
| GET | /api/v1/news.json | Published news and our own stories, newest first. |
| GET | /api/v1/news/by-country/{country}.json | Published news for one country code: NO, SE, DK, FI, IS, NORDIC or EU. |
| GET | /api/v1/news/topics.json | Topic ids present in the published news, with counts. |
| GET | /api/v1/newsletters.json | Published newsletter issues, newest first. The list omits the HTML body; the issue URL includes text and html. |
| GET | /api/v1/events.json | Public events, soonest start first, including past events. |
| GET | /api/v1/events/upcoming.json | Events that have not ended, soonest first. Judged in the event's own offset. |
| GET | /api/v1/events/past.json | Finished public events, newest first. Finished events stay in the archive. |
| GET | /api/v1/events/by-country/{country}.json | Public events for one country code. |
| GET | /api/v1/sources.json | 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. |
| GET | /api/v1/academia.json | Editor-approved courses, student groups, publications and research. |
| GET | /api/v1/academia/courses.json | Academia section: courses. |
| GET | /api/v1/academia/groups.json | Academia section: groups. |
| GET | /api/v1/academia/publications.json | Academia section: publications. |
| GET | /api/v1/academia/research.json | Academia section: research. |
| GET | /api/v1/academia/{id}.json | One academia row. The id is in academia.json. |
| GET | /api/v1/orgchart.json | Published who's who: organisations, people, relations, regulation notes and caveats. |
| GET | /api/v1/orgchart/relations.json | Relations between published who's who entries. |
| GET | /api/v1/orgchart/regulation.json | Short regulation status for each Nordic country, as on the who's who page. |
| GET | /api/v1/orgchart/relations/{id}.json | One relation from the who's who. |
| GET | /api/v1/profiles.json | Public profile links (Wikipedia, X, Wikidata and similar) for people and organisations. |
| GET | /api/v1/images.json | Logos and photos used on the public who's who, with licence and credit. |
| GET | /api/v1/changelog.json | Site changelog (product changes, not the news), newest first. |
| GET | /api/v1/rules.json | How EU crypto rules become law in the five countries. Simplified, not legal advice. Omitted while the page is still a placeholder. |
| GET | /api/v1/archive/articles.json | 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. |
| GET | /api/v1/markets.json | 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. |
| GET | /api/v1/markets/aggregated.json | 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. |
| GET | /api/v1/markets/{exchange}.json | Prices from one included exchange: firi (Norway), nbx (Norway) or coinmotion (Finland). |
| GET | /api/v1/markets/by-asset/{symbol}.json | 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. |
| GET | /api/v1/languages.json | Site UI languages: code, native name, English name, rtl, html lang and home URL. |
| GET | /api/v1/geo-language.json | Country to default site language. An IP guess only; the nc_lang cookie from the language switcher wins. |
| GET | /api/v1/meta.json | Site name, languages, countries, page list, CORS, editorial notes and brand social accounts (social.telegram, social.x). |
Not included
Drafts, the editor queue, rejected stories, reader tips, newsletter subscriber addresses, the analytics token, and private personal data are not in this feed. An unknown id is a normal site 404, not a JSON error.