Skip to main content

For external developers building on Atlas

This section is for anyone consuming Atlas's public PostgREST API to build their own thing — frontends, CLIs, agent integrations, mobile apps, scripts. If you're contributing to Atlas itself (writing dbt models, adding ingest sources), see /contributors/ instead.

Status: stub. Real content (getting-started walkthrough, embedded API reference, versioning policy, examples) is being designed in INVESTIGATE-developer-docs-surface.md. For now, the pointers below are the canonical entry points.

59 upstream sources from 10 publishers, served as 97 read-only relations.

publishersourcesbroadly
Folkehelseinstituttet21public health, and the Ungdata youth surveys
Statistisk sentralbyrå20population, income, families, housing, education, crime
Brønnøysundregistrene5the company and voluntary-organisation registers
Utdanningsdirektoratet4—
Arbeids- og velferdsdirektoratet3—
Barne-, ungdoms- og familiedirektoratet2child poverty
Husbanken1—
Integrerings- og mangfoldsdirektoratet1—
Lotteri- og stiftelsestilsynet1—
Norges Røde Kors1local chapters and their activities

By EU data theme: SOCI 30 (society) · HEAL 12 (health) · EDUC 9 (education) · GOVE 7 (government) · JUST 1 (justice).

Licences: NLOD for 55 of 59 — Norwegian public data, free to reuse with attribution. The exceptions are nav-aap (CC BY 4.0) and nav-helt-ledige (CC BY 4.0) and nav-uforetrygd (CC BY 4.0) and redcross-branches (permissive) — Red Cross's own data rather than the state's.

What you can query​

relationwhat it holds
activity_catalogOne row per organisation and activity, with its Atlas service category.
atlas_inventoryWhat Atlas publishes: one row per endpoint with its row count, freshness and origin.
brreg_enhetEvery organisation registered in Norway, mirrored from Brønnøysundregistrene's Enhetsregisteret.
bufdir_indicator_aliasMaps Bufdir indicator ids across releases, so a renumbered indicator still resolves.
chapter_kommune_coveragePer-kommune rollup of which chapters cover it.
coverage_gap_barnefattigdomChild poverty per kommune for the latest year of SSB 08764, as a share and as counts.
dim_activityAtlas's canonical activity dimension, each row mapped to a service category.
dim_chapterAtlas's canonical local-chapter dimension.
dim_fylkeThe county dimension: one row per fylke code, current and historical.
dim_kommuneThe canonical municipality registry from SSB Klass 131, with fylke name joined.
dim_postnummerNorwegian postal codes resolved to a primary kommune, 5 122 rows.
distrikt_summaryOne row per district chapter, with its child chapters and kommune coverage.
fact_chapter_activitiesOne row per chapter and activity, joined to Atlas's dimensions.
indicator_latest_valuesThe latest value of every indicator for every active kommune, in long format.
indicator_missing_kommunerOne row per indicator and kommune that the indicator does not cover.
indicator_summaryOne row per indicator and source: latest year, kommune coverage and value range.
indicators__bufdir_barnefattigdomPer-source indicator data for bufdir-barnefattigdom, at the publisher's own grain.
indicators__bufdir_barnevernPer-source indicator data for bufdir-barnevern, at the publisher's own grain.
indicators__fhi_alkoholPer-source indicator data for fhi-alkohol (Folkehelseinstituttet), at the publisher's own grain.
indicators__fhi_befolkningPer-source indicator data for fhi-befolkning (Folkehelseinstituttet), at the publisher's own grain.
indicators__fhi_befolkningsvekstPer-source indicator data for fhi-befolkningsvekst (Folkehelseinstituttet), at the publisher's own grain.
indicators__fhi_bor_alenePer-source indicator data for fhi-bor-alene (Folkehelseinstituttet), at the publisher's own grain.
indicators__fhi_depresjonPer-source indicator data for fhi-depresjon (Folkehelseinstituttet), at the publisher's own grain.
indicators__fhi_fortrolig_vennPer-source indicator data for fhi-fortrolig-venn (Folkehelseinstituttet), at the publisher's own grain.
indicators__fhi_hasjPer-source indicator data for fhi-hasj (Folkehelseinstituttet), at the publisher's own grain.
indicators__fhi_innvandrerePer-source indicator data for fhi-innvandrere (Folkehelseinstituttet), at the publisher's own grain.
indicators__fhi_innvkatPer-source indicator data for fhi-innvkat (Folkehelseinstituttet), at the publisher's own grain.
indicators__fhi_kpr_1aarPer-source indicator data for fhi-kpr-1aar (Folkehelseinstituttet), at the publisher's own grain.
indicators__fhi_livskvalitetPer-source indicator data for fhi-livskvalitet (Folkehelseinstituttet), at the publisher's own grain.
indicators__fhi_mediebruk_somePer-source indicator data for fhi-mediebruk-some (Folkehelseinstituttet), at the publisher's own grain.
indicators__fhi_mediebruk_spillPer-source indicator data for fhi-mediebruk-spill (Folkehelseinstituttet), at the publisher's own grain.
indicators__fhi_mediebruk_underholdPer-source indicator data for fhi-mediebruk-underhold (Folkehelseinstituttet), at the publisher's own grain.
indicators__fhi_mobbingPer-source indicator data for fhi-mobbing (Folkehelseinstituttet), at the publisher's own grain.
indicators__fhi_neetPer-source indicator data for fhi-neet (Folkehelseinstituttet), at the publisher's own grain.
indicators__fhi_prognosePer-source indicator data for fhi-prognose (Folkehelseinstituttet), at the publisher's own grain.
indicators__fhi_selvmordPer-source indicator data for fhi-selvmord (Folkehelseinstituttet), at the publisher's own grain.
indicators__fhi_smertestillendePer-source indicator data for fhi-smertestillende (Folkehelseinstituttet), at the publisher's own grain.
indicators__fhi_trangboddPer-source indicator data for fhi-trangbodd (Folkehelseinstituttet), at the publisher's own grain.
indicators__fhi_vgs_gjennomforingPer-source indicator data for fhi-vgs-gjennomforing (Folkehelseinstituttet), at the publisher's own grain.
indicators__husbanken_bostottePer-source indicator data for husbanken-bostotte (Husbanken), at the publisher's own grain.
indicators__imdi_bosettingPer-source indicator data for imdi-bosetting (Integrerings- og mangfoldsdirektoratet), at the publisher's own grain.
indicators__lottstift_momskompensasjonPer-source indicator data for lottstift-momskompensasjon (Lotteri- og stiftelsestilsynet), at the publisher's own grain.
indicators__nav_aapPer-source indicator data for nav-aap (Arbeids- og velferdsdirektoratet), at the publisher's own grain.
indicators__nav_helt_ledigePer-source indicator data for nav-helt-ledige (Arbeids- og velferdsdirektoratet), at the publisher's own grain.
indicators__nav_uforetrygdPer-source indicator data for nav-uforetrygd (Arbeids- og velferdsdirektoratet), at the publisher's own grain.
indicators__ssb_06083Per-source indicator data for ssb-06083 (Statistisk sentralbyrå), at the publisher's own grain.
indicators__ssb_06913Per-source indicator data for ssb-06913 (Statistisk sentralbyrå), at the publisher's own grain.
indicators__ssb_06944Per-source indicator data for ssb-06944 (Statistisk sentralbyrå), at the publisher's own grain.
indicators__ssb_06947Per-source indicator data for ssb-06947 (Statistisk sentralbyrå), at the publisher's own grain.
indicators__ssb_07459Per-source indicator data for ssb-07459 (Statistisk sentralbyrå), at the publisher's own grain.
indicators__ssb_08484Per-source indicator data for ssb-08484, at the publisher's own grain.
indicators__ssb_08487Per-source indicator data for ssb-08487, at the publisher's own grain.
indicators__ssb_08764Per-source indicator data for ssb-08764 (Statistisk sentralbyrå), at the publisher's own grain.
indicators__ssb_09405Per-source indicator data for ssb-09405, at the publisher's own grain.
indicators__ssb_09406Per-source indicator data for ssb-09406, at the publisher's own grain.
indicators__ssb_09429Per-source indicator data for ssb-09429 (Statistisk sentralbyrå), at the publisher's own grain.
indicators__ssb_10501Per-source indicator data for ssb-10501 (SSB), at the publisher's own grain.
indicators__ssb_10826Per-source indicator data for ssb-10826 (Statistisk sentralbyrå), at the publisher's own grain.
indicators__ssb_12063Per-source indicator data for ssb-12063 (Statistisk sentralbyrå), at the publisher's own grain.
indicators__ssb_12131Per-source indicator data for ssb-12131 (Statistisk sentralbyrå), at the publisher's own grain.
indicators__ssb_12132Per-source indicator data for ssb-12132 (Statistisk sentralbyrå), at the publisher's own grain.
indicators__ssb_12292Per-source indicator data for ssb-12292 (Statistisk sentralbyrå), at the publisher's own grain.
indicators__ssb_12451Per-source indicator data for ssb-12451 (Statistisk sentralbyrå), at the publisher's own grain.
indicators__ssb_12891Per-source indicator data for ssb-12891 (SSB), at the publisher's own grain.
indicators__ssb_12944Per-source indicator data for ssb-12944 (Statistisk sentralbyrå), at the publisher's own grain.
indicators__ssb_13995Per-source indicator data for ssb-13995 (Statistisk sentralbyrå), at the publisher's own grain.
indicators__udir_elevundersokelsen_mobbingPer-source indicator data for udir-elevundersokelsen-mobbing (Utdanningsdirektoratet), at the publisher's own grain.
indicators__udir_fravarPer-source indicator data for udir-fravar (Utdanningsdirektoratet), at the publisher's own grain.
indicators__udir_gsiPer-source indicator data for udir-gsi (Utdanningsdirektoratet), at the publisher's own grain.
indicators__udir_nasjonale_proverPer-source indicator data for udir-nasjonale-prover (Utdanningsdirektoratet), at the publisher's own grain.
ingest_healthOne row per source: its most recent completed ingest run, and whether that run succeeded.
kommune_befolkning_alderPopulation by kommune, year and age band — the denominator layer for rates.
kommune_local_chaptersOne row per local chapter resolved to a kommune, with its NGO and category.
kommune_ngo_summaryActive voluntary organisations per kommune and ICNPO category.
kommune_ngo_totalsOne row per kommune: how many active voluntary organisations are registered there.
meta_dimensionsOne row per source and coded dimension, explaining what that column's codes mean.
meta_endpointsOne row per queryable endpoint, with filterable tags.
meta_sourcesOne row per ingested source: publisher, licence, coverage, freshness and what it feeds.
ngo_chapter_registry_matchThe 9 federated NGOs' chapters, found by name pattern in Brønnøysundregistrene's register.
ngo_chapter_subunitsThe local units of the 2 unitary NGOs (Frelsesarmeen, Kirkens Bymisjon), found as Brreg underenheter.
ngo_indexOne row per voluntary organisation Atlas tracks, with its identity, branding and focus.
ngo_overviewOne row per NGO with its six headline counts, precomputed for the per-NGO page.
ref_activity_familyThe 10 families Atlas's service-category vocabulary groups into.
ref_atlas_service_categoryAtlas's own cross-NGO service vocabulary, 38 categories, built from real search demand.
ref_brreg_icnpoDecoder for the ICNPO category codes in kommune_ngo_summary: 14 groups and 32 subgroups.
ref_fhi_innvkatDecoder for FHI table 360's INNVKAT dimension, which holds only '0'.
ref_fhi_utdannDecoder for FHI's education-level codes; in vgs_gjennomforing this is the parents' education.
ref_region_kindDecoder for region_kind: what a region code denotes, and whether it is a real kommune.
ref_ssb_family_typeDecoder for SSB's family-type codes.
ref_ssb_household_typeDecoder for SSB's household-type codes, which are zero-padded text.
ref_ssb_nivaaDecoder for SSB's NUS2000 education levels.
ref_un_sdgThe 17 UN Sustainable Development Goals, with Norwegian and English labels.
source_freshnessOne row per raw source declaring a loaded_at_field: whether it is inside its own declared cadence.
supply__redcross_branch_activitiesOne row per Røde Kors branch and activity, from a static 2026-04-21 export.
supply__redcross_branchesOne row per Norges Røde Kors branch, from a static 2026-04-21 export.
supply__redcross_chapter_kommune_coverageWhich kommuner each Røde Kors chapter covers, inferred from its local branches.
unattributed_totalsThe part of a published quantity that belongs to no municipality.

Every relation, with its columns and their descriptions:

curl -s $ATLAS/meta_endpoints # what is queryable
curl -s $ATLAS/meta_sources # every upstream, with freshness
curl -s $ATLAS/indicator_summary # every published series
warning
downstream_model_count says a source has a model, not that you can reach it

A source can have downstream_model_count > 0 and still produce nothing you can query — the model exists and feeds no published relation. fhi-innvandrere is in that state today: one model, 32 720 rows ingested, absent from indicator_summary and from every api_v1 relation.

The measure that answers "can I use it" is whether the source appears in indicator_summary, or whether some api_v1 relation carries it. Subtracting those from meta_sources gives what Atlas holds and does not yet serve.

⚠️ Those three are the live answer. The numbers above are regenerated on release; coverage, row counts and freshness change between releases and are only true in the catalogue.

Open by default​

Atlas's posture: anything not explicitly gated is queryable. The public PostgREST API exposes three schemas, all anonymous-read:

SchemaWhat's in itWhen you'd query it
api_v1Curated wrapper views — the production-stable contract surfaceWhen you want guaranteed-stable column shapes for a published product
martsEvery dbt-built mart (dim, fact, indicator, supply, ref)When you want the working dataset that hasn't been frozen into an api_v1 view yet
rawVerbatim ingest landings — every row Atlas pulled from upstreamWhen you want full provenance or are debugging a transformation

Private schemas (private_marts, private_raw) carry personal data and stay outside the schema list — atlas_web_anon has no grants on them; PostgREST returns 404 even with explicit Accept-Profile: private_marts.

Reaching non-default schemas​

PostgREST routes header-less requests to the first schema in --schemas, which Atlas configures as api_v1. To reach marts.* or raw.*, send Accept-Profile: <schema> per request:

# Default (api_v1) — header omitted
curl -s "$ATLAS/distrikt_summary?limit=2"

# marts schema — explicit Accept-Profile
curl -s -H 'Accept-Profile: marts' "$ATLAS/dim_kommune?limit=2"

# raw schema — same pattern
curl -s -H 'Accept-Profile: raw' "$ATLAS/ssb_08764?limit=2&region_code=eq.0301"

Naive curl /dim_kommune (without the header) returns 404 because PostgREST resolves it as api_v1.dim_kommune which doesn't exist. That's correct routing, not a misconfiguration.

Catalog as a queryable endpoint​

The catalog itself is exposed as a queryable endpoint — no separate scraping or hand-rolled discovery needed:

# Every endpoint Atlas serves, with provider/topic/geo/cadence/eu_theme/layer tags
curl -s "$ATLAS/meta_endpoints" | jq '.[0]'

# Every upstream Atlas ingests, with freshness signals
curl -s "$ATLAS/meta_sources?provider=eq.ssb" | jq '.[0]'

# Per-source × per-upstream-dimension editorial pass-through
curl -s "$ATLAS/meta_dimensions?source_id=eq.ssb-08764"

These are the same endpoints the customer frontend at https://atlas.helpers.no/data reads — your app gets the same introspection surface for free.

Tag-filter URL pattern (for the human catalog)​

The customer app at atlas.helpers.no/data is fully URL-driven. External developers can deep-link to filtered views:

URLWhat it shows
/dataEvery endpoint, no filter
/data?tag=topic:incomeEvery income-related endpoint
/data?tag=topic:income&tag=geo:kommuneAND across namespaces — income AND kommune-level
/data?tag=topic:income&tag=topic:educationOR within a namespace — income OR education
/data?tag=provider:ssb&tag=cadence:annualSSB tables published annually
/data?tag=layer:api_v1Only the curated public-API surface
/data?q=osloFree-text search across endpoint names + tags

Same logic at the catalog-data layer — the URL params translate to filter passes against meta_endpoints.tags. Useful if you want to embed a "show me Atlas data about my topic" link in your own product.

Where to start today​

1. Read the API spec directly​

PostgREST self-describes. The full schema (every endpoint, every column type, every description) is at the API root:

curl https://api-atlas.helpers.no/ # Swagger 2.0 spec — human and machine readable
curl http://api-atlas.localhost/ # local dev (UIS rancher-desktop)

Pretty-print it with jq:

curl -s http://api-atlas.localhost/ | jq '.paths | keys[]' # list every endpoint
curl -s http://api-atlas.localhost/ | jq '.definitions.indicator_summary' # one view's columns + descriptions

Per-endpoint row counts without fetching the data:

curl -sI -H "Prefer: count=exact" http://api-atlas.localhost/indicator_summary?limit=0 | grep -i content-range
# → Content-Range: */163
danger
Use count=exact, not count=estimated

count=estimated is accurate on most endpoints and badly wrong on a few, and you cannot tell which from the API. Every api_v1 relation is a view, so "is it a view?" does not distinguish them.

Two relations are wildly over. kommune_ngo_summary and kommune_ngo_totals are views that GROUP BY, so the planner has to guess how many groups the query will produce. Measured 2026-09-20:

endpointexactestimated
kommune_ngo_summary5,43569,46212.8×
kommune_ngo_totals3576,94619.5×

Every other endpoint reads from a pre-built table, so its rows were counted when it was built and the estimate is accurate — including heavily aggregated ones like indicator_summary, because that aggregating happened before the planner saw it.

Separately, estimated = 1 does not mean one row. It is the planner's floor, so an empty relation reports 1. Three endpoints currently hold zero rows and all three report estimated = 1 — so "is there any data here?" asked cheaply answers yes when the answer is no.

The largest published relation here is ~72,000 rows and an exact count is cheap, so the estimate saves nothing worth being wrong about.

warning
The spec advertises post, patch and delete. They do not work, and this will not change.

15 of 17 relations list write methods in the OpenAPI document. Every one of them is refused by the database — the anonymous role is granted SELECT and nothing else, so a write returns 401 / 42501 permission denied.

The API is read-only. The grant is one statement, in atlas-data/dbt/api_v1_generated.sql, and it says GRANT SELECT.

Why the document says otherwise. PostgREST advertises write methods for any view Postgres considers auto-updatable, independently of who may actually write it. The only two relations that do not advertise writes — kommune_ngo_summary and kommune_ngo_totals — are the only two that GROUP BY, which is what makes a view non-auto-updatable. It is the same structural line that decides whether count=estimated is accurate.

This is a property of PostgREST v14.10, not a misconfiguration, and it is not going to be fixed here. Treat the method list as a claim about the document, not about the database. If you generate a client from the spec, delete the write methods.

No row cap — and how to tell if that ever changes​

PostgREST can be configured with db-max-rows, which silently truncates a response to N rows. Atlas does not set it. Measured against the live API:

GET /brreg_enhet?limit=100000 -> 206, 100,000 rows of 1,174,770
GET /brreg_enhet?limit=200000 -> 206, 200,000 rows

⚠️ That is a measurement of behaviour, not a reading of configuration. PostgREST exposes no endpoint that reports its effective settings, so "unset" and "set above 200,000" are indistinguishable from outside. Nobody can hand you the value — including us.

So do not trust it, detect it. Send Prefer: count=exact and compare the total in Content-Range against the rows you actually received:

curl -sD- -H "Prefer: count=exact" "$ATLAS/brreg_enhet?limit=200000" -o body.json \
| grep -i content-range
# Content-Range: 0-199999/1174770 <- you got 200,000 of 1,174,770

Content-Range is exposed cross-origin (access-control-expose-headers), so this works from a browser app as well as from curl. A cap can only ever be discovered by exceeding it and noticing the discrepancy — that check is the right pattern, not a workaround, and it keeps working whatever the cap is.

If Atlas ever does set db-max-rows, it will be treated as a contract change and announced, even though nothing in the schema moves.

Request-size ceiling​

Long or=() filters run into a 48 KiB URL limit, binary-searched against the live API:

48.91 KiB → 200
49.89 KiB → 400 Bad Request (3 runs each side, no flapping)
~78 KiB+ → connection refused before any HTTP response

Consistent with a 49,152-byte buffer. For scale: a 44-series or=() filter is about 1,000 characters, so there is roughly 48× headroom. Past the ceiling, split the request or filter server-side with in.().

⚠️ Not attributable from outside whether the limit is the CDN's, a proxy's or PostgREST's, so treat 48 KiB as observed behaviour rather than a guaranteed contract.

2. Fork the customer app as a starting template​

atlas-frontend/ is Atlas's public-facing Next.js app, deployed at atlas.helpers.no. It's also positioned as a forkable reference implementation — clone the folder, change NEXT_PUBLIC_API_URL, and you have a working starting point for your own UI on Atlas's API. Its README has the fork-me walkthrough.

The customer app demonstrates the patterns this docs surface will eventually formalise: typed fetch helpers (src/lib/api.ts — note the acceptProfile option for non-default schemas), OpenAPI codegen for types (src/lib/api-types.ts), a tag-filtered catalog page driven by meta_endpoints (app/data/page.tsx), per-endpoint table viewer with multi-schema dispatch (app/data/[schema]/[table]/page.tsx), and the no-DB-driver / no-postgres.js discipline.

What's coming​

Per INVESTIGATE-developer-docs-surface.md, the planned full content for this section:

  • Getting started — first curl walkthrough with real responses.
  • API reference — embedded Swagger UI live-pointed at api-atlas.helpers.no/.
  • Concepts — canonical conventions (kommune_nr, fylke_nr, orgnr) framed for API consumers.
  • Forking the customer app — full guide; the atlas-frontend/README.md becomes a teaser pointing here.
  • Versioning — the api_v1 ↔ api_v2 deprecation policy.
  • Changelog — version-bump and breaking-change record.
  • Agent integration — wiring the API into LLM agents / MCP servers.

The follow-on PLAN-006 ships these. Until it does, this index page + the customer app's README + the live spec are the entry points.

See also​