Developer Resources

Norsk Luftvern — Data & API

Norsk Luftvern publishes all article metadata as a machine-readable JSON index, updated on every content deploy. No authentication. No rate limits. 224 articles (129 EN · 95 NO) as of 2026-05-23.

Endpoints

MethodURLContent-TypeAuth
GET /api/articles.json application/json None

The file is pre-built at deploy time. It reflects the state of all published articles at the moment the site last rebuilt. Typical rebuild lag after a new article is published is under five minutes.

Response schema

The response is a JSON object with two top-level keys: meta and articles.

meta

FieldTypeDescription
titlestringHuman-readable feed name
urlstringCanonical URL of this feed
generatedstring (ISO 8601)Build timestamp (UTC)
countintegerTotal number of published articles
countByLangobjectArticle count keyed by language code, e.g. {"en": 129, "no": 95}

articles[ ]

FieldTypeNullableDescription
slugstringnoURL-safe identifier, unique across all articles
urlstringnoAbsolute canonical URL of the article page
titlestringnoFull article title
datestring (YYYY-MM-DD)noOriginal publication date
excerptstringnoOne-to-three sentence summary
categorystringnoPrimary category slug (e.g. analyse, missilforsvar)
lang"no" | "en"noArticle language
authorstringnoByline
tagsstring[]noLowercase hyphenated topic tags; empty array if none
seriesstringyesSeries slug if the article belongs to a series, otherwise null
crossSeriesstring[]noAdditional series slugs for articles that appear in more than one series
featuredbooleannotrue for editorially featured articles (at most one per language)
readingTimeintegernoEstimated reading time in minutes
heroImagestringyesAbsolute URL to the article's hero image, or null

Example response (truncated)

{
  "meta": {
    "title": "Norsk Luftvern — Article Index",
    "url": "https://norskluftvern.no/api/articles.json",
    "generated": "2026-05-20T14:51:00.855Z",
    "count": 224,
    "countByLang": { "en": 129, "no": 95 }
  },
  "articles": [
    {
      "slug": "intercepting-hypersonic-glide-vehicles-physics-sensors-and-the-programs-closing-the-gap",
      "url": "https://norskluftvern.no/articles/intercepting-hypersonic-glide-vehicles-...",
      "title": "Intercepting Hypersonic Glide Vehicles: Physics, Sensors, and the Programs Closing the Gap",
      "date": "2026-05-16",
      "excerpt": "Hypersonic glide vehicles don't just fly fast — they exploit a specific altitude band...",
      "category": "analyse",
      "lang": "en",
      "author": "Norsk luftvern",
      "tags": ["hypersonic", "missile-defense", "sensors", "thaad", "arrow-4", "sm-6"],
      "series": null,
      "crossSeries": [],
      "featured": false,
      "readingTime": 10,
      "heroImage": "https://norskluftvern.no/images/IMG_9678.jpeg"
    },
    ...
  ]
}

Code examples

curl

curl -s https://norskluftvern.no/api/articles.json | jq '.meta'

JavaScript — fetch all English articles, newest 10

const res  = await fetch('https://norskluftvern.no/api/articles.json');
const data = await res.json();

const latest = data.articles
  .filter(a => a.lang === 'en')
  .slice(0, 10);

console.log(latest.map(a => a.title));

JavaScript — filter by tag

const res  = await fetch('https://norskluftvern.no/api/articles.json');
const data = await res.json();

const patriotArticles = data.articles
  .filter(a => a.tags.includes('patriot'));

Python — build a category index

import requests
from collections import defaultdict

data = requests.get('https://norskluftvern.no/api/articles.json').json()

by_category = defaultdict(list)
for article in data['articles']:
    by_category[article['category']].append(article)

for cat, articles in sorted(by_category.items()):
    print(f"{cat}: {len(articles)} articles")

Python — export all English articles to CSV

import csv, requests

data = requests.get('https://norskluftvern.no/api/articles.json').json()
en  = [a for a in data['articles'] if a['lang'] == 'en']

with open('norsk-luftvern-en.csv', 'w', newline='') as f:
    writer = csv.DictWriter(f, fieldnames=['slug','title','date','category','tags','url'])
    writer.writeheader()
    for a in en:
        writer.writerow({**a, 'tags': ','.join(a['tags'])})

Adjacent resources

RSS /rss.xml

Full RSS 2.0 feed of all published articles, sorted newest-first. The push alternative to polling the JSON index — suitable for feed readers and news aggregators that support Atom/RSS subscriptions.

Includes: title, pubDate, description (excerpt), link, categories (category + tags), author.

JSON-LD per article page

Every article page includes an embedded <script type="application/ld+json"> block with Schema.org Article markup. Useful for scrapers that need per-article structured data — headline, author, dates, image, reading time, keywords — without consuming the full index.

Fields: @type Article, headline, description, datePublished, dateModified, inLanguage, url, timeRequired, author, publisher (with logo), image, keywords.

Sitemap index generated at build time. Covers all article pages, category pages, series pages, tag pages, and pagination routes. Use this to discover all URLs on the site for crawling or archival.

HTML <link rel="alternate">

Every page on the site includes two <link rel="alternate"> tags in <head>: one for the RSS feed (type="application/rss+xml") and one for this JSON index (type="application/json"). Feed readers and tools that sniff for alternate representations will discover both automatically.

Usage guidelines

Attribution

When displaying or republishing content derived from this feed, please link back to the original article URL (available as the url field on each record) and credit Norsk Luftvern as the source.

Caching

The JSON file is regenerated on every content deploy. We recommend caching it for one hour on the client side. The meta.generated timestamp lets you detect whether a cached copy is stale.

Stability

All field names listed in the schema above are stable and will not be renamed or removed without a changelog entry. New optional fields may be added without notice — write your parser defensively. The articles array is always sorted newest-first.

No authentication or rate limits

The endpoint is a plain static file served from the same CDN as the rest of the site. There is no API key, no OAuth, and no enforced rate limit. Please apply reasonable polling intervals — polling more often than once per hour provides no benefit given the deploy cadence.

Changelog

2026-05-20
Initial release/api/articles.json launched with full article index. Fields: slug, url, title, date, excerpt, category, lang, author, tags, series, crossSeries, featured, readingTime, heroImage. Schema.org Article JSON-LD added to all article pages. <link rel="alternate" type="application/json"> added to all page heads.