Ísland, Evrópa og heimurinn

Integrations → Public API

Public API contract

Run saved public-data selections from your own tools, or download shared reference dimensions. No account, API key or credentials are required. The API queries the built-in public providers; source terms and attribution still apply.

Download OpenAPI 3.1.1 contract · Recipe API descriptor · Sources and terms

The stable contract URL is /api/v1/openapi.json, using JSON Schema 2020-12. Recipe requests use datahub.analysis version 2; successful execution responses use version 1. These version numbers describe different documents.

Complete examples

  • Download simple live recipe: World Bank Iceland midyear population for 2022 and 2023. Expected: one series with two annual points, including null if a source value is missing.
  • Download multi-source recipe: the same population series plus Central Bank CPI twelve-month change for November and December 2023. Expected: two series and four separate rows. Annual population and monthly inflation retain their own periods and units; no averaging, joining or causal comparison is implied.
  • Download offline snapshot: a pinned, illustrative two-point example. Expected values are 100000 and null, with flags p and missing. Values, flags and retrieval timestamp are authored fixtures, not official statistics. Execution makes zero provider requests.

Download and run the live recipe with curl in a Bash/POSIX shell. For the multi-source example, substitute multi-source.json in both commands.

curl --fail-with-body -o simple-live.json \
  https://datahub.kristinn.eu/api/v1/examples/simple-live.json
curl --fail-with-body -X POST \
  -H 'Content-Type: application/json' \
  --data-binary @simple-live.json \
  https://datahub.kristinn.eu/api/v1/recipes/run

In Windows PowerShell, run these two single-line commands:

curl.exe --fail-with-body -o simple-live.json https://datahub.kristinn.eu/api/v1/examples/simple-live.json
curl.exe --fail-with-body -H 'Content-Type: application/json' --data-binary '@simple-live.json' https://datahub.kristinn.eu/api/v1/recipes/run

Run the offline example through the same handler, then compare with the complete expected snapshot response:

curl --fail-with-body -o offline-snapshot.json \
  https://datahub.kristinn.eu/api/v1/examples/offline-snapshot.json
curl --fail-with-body -H 'Content-Type: application/json' \
  --data-binary @offline-snapshot.json \
  https://datahub.kristinn.eu/api/v1/recipes/run

The offline commands above use Bash/POSIX continuation syntax. In PowerShell, use the two single-line commands above with offline-snapshot.json in place of simple-live.json.

All examples are complete JSON documents and are schema-validated in CI. Live examples also run through the actual route handlers and source adapters with deterministic transport fixtures. Those fixtures establish interface behavior; they do not certify today’s provider availability or values.

Read the result

rows contains the selected layout. With join: separate, each row has series, period and a number-or-null value. Inner and outer joins return period and a values array in the same order as series. Outer joins retain missing periods as null; inner joins require the period in every series. Neither fills missing values.

series has id, label, unit, layerKey and points. Points retain original dimension labels and codes, source quality status, originalPeriod, normalized calendar key/frequency/start/end and geography matching outcome. For example, 2024K1 normalizes to 2024-Q1; annual 2024 remains distinct from January 2024. Country aggregates, ambiguous and unmatched identities stay explicit. Numeric country and currency codes are text to preserve leading zeroes.

Null means missing, not zero. Units are provider-reported and may be an indicator code when no descriptive unit is supplied. Preserve flags, dimensions and codes: they can contain methodological context, agreement quotations, source documents or extraction confidence. Do not discard them when interpreting observations.

manifest.sources preserves the selected queries, source URLs, retrieval timestamps, source updates when supplied, notes, governance and transformations. registryVersion identifies the reviewed indicator rules. Retrieval time is not publication time; an observation period is not a source update date. The complete request URL/method/body remains in a snapshot’s result.request or layer provenance.request; keep the input snapshot alongside the response.

Rebasing uses a shared nonzero base period and retains sourceValue/sourceUnit. Reviewed annual averages expose derivation source periods, quality flags, completeness and expected count. Unsupported transformations fail validation. Rates, counts and unknown measures are never silently treated as index levels.

Inputs and semantic validation

Every workspace has a name, question, creation/save timestamps, layers, display settings and nullable comparison. Unknown fields are rejected. Each layer has a unique key, title and query with provider, dataset ID, language (en or is) and dimension-code selections. Custom provider dimension names are supported; use dataset metadata to obtain valid codes.

The JSON Schema checks structure and documented bounds. The handler additionally checks valid timestamps/calendar bases, ordered requested years, unique layer keys, comparison references, equality of nested result and layer queries, and selection products. Queries selected for execution require safe dataset IDs of at most 600 characters, 1–20 dimension names of at most 100 characters, unique nonempty value codes of at most 100 characters, and at most 12,000 selected cells. Provider-specific required dimensions, ranges and metadata values are validated. World Bank spans include intermediate years in its upstream budget. Arion requires provider access and is not connected for execution.

comparison.keys optionally selects active layers and overrides base/overlay. All selected snapshot layers must contain result.observations; unselected layers may omit results. Live recipes cannot embed results. Chart, map and overlay are display preferences; base and join affect results. Retain the full schema when generating documents.

Routes and query parameters

All supported query parameters appear below. Repeated or unknown query parameters on reference GETs and connection GETs fail validation. Recipe run reads its JSON body; its query string is unused. Country POST reads its body and ignores query parameters.

/api/v1/recipes/run

Discover recipe versions, contract links, limits and transformations

POST accepts the workspace JSON above. GET describes versions, limits and contract links; OPTIONS supports browser preflight.

/api/v1/recipes/table

Refresh live recipe as a long-form CSV

UTF-8 with BOM. Columns: series, seriesId, period, value, unit, country, countryCode, frequency, originalPeriod, status, source, retrieved, dimensions, codes, derivationMethod, derivationVersion, derivationSourcePeriods, derivationQualityFlags, derivationComplete, derivationExpected. Null numeric values are empty cells; codes/dimensions and derivation arrays are JSON text. Joined missing observations have status 'no observation'. Source-controlled spreadsheet formula prefixes are escaped. No observations returns 400.

recipe (required)
Exactly one unpadded base64url UTF-8 datahub.analysis v2 live recipe. No snapshots or other parameters. The UI emits at most 5,800 input bytes; decoder accepts at most 7,800 encoded characters.

/api/v1/recipes/model

Refresh live recipe as Power BI HTML model tables

Static HTML with Data and Date tables; Country and Currency only when resolved. Data adds periodKey, currencyCode and baseCurrencyCode to the CSV columns. Join Data.periodKey→Date.periodKey, countryCode→Country.iso2, currencyCode→Currency.code. Preserve text keys. Date represents observed period grain, not a daily DAX table. Currency is resolved from units, never guessed from country. No observations returns 400. CSP default-src 'none'; frame-ancestors 'none'; base-uri 'none'.

recipe (required)
Exactly one unpadded base64url UTF-8 datahub.analysis v2 live recipe. No snapshots or other parameters. The UI emits at most 5,800 input bytes; decoder accepts at most 7,800 encoded characters.

/api/dimensions/countries

Country list or identity resolution

All parameters occur at most once, ≤200 characters. lookup cannot combine with q/region and requires JSON. Preserve ISO/numeric keys as text. Aggregate and ambiguous inputs do not become countries.

lookup (optional)
Resolve one name or code
joinOn (optional)
Resolution field; default auto Allowed values: auto, iso2, iso3, numeric, name.
q (optional)
Substring filter on names, aliases and codes
region (optional)
Exact case-insensitive region, regionCode or continent
format (optional)
List output format; default json. Lookups require json. CSV preserves text codes; keep its linked manifest. Allowed values: json, csv, manifest.

POST accepts {"values":["IS","008",8,"World"],"joinOn":"auto"}. Maximum 64,000 body bytes, 1,000 values; strings up to 200 characters or integer numeric codes 0–999. Optional joinOn is auto, iso2, iso3, numeric or name (null also means auto). Response has a reference and ordered results, each with input, status, country or null, and candidate codes.

/api/dimensions/currencies

Currency list or identity resolution

All parameters occur at most once, ≤200 characters. lookup requires JSON and cannot combine with q. ISO 4217 current codes only; no exchange rates or historical validity. numeric is text, minorUnit may be null.

lookup (optional)
Exact code, numeric code or currency name
q (optional)
Substring filter on code, numeric code, name or entities
format (optional)
List output format; default json. Lookups require json. CSV preserves text codes; keep its linked manifest. Allowed values: json, csv, manifest.

/api/dimensions/dates

Generate Gregorian UTC periods or normalize a source period

All parameters occur once, ≤100 characters. For generation supply start and end in 1900–2100, ordered and inclusive; ≤12,000 periods. Complete periods intersecting the range are returned. lookup excludes start/end/frequency and requires JSON; calendar normalization accepts years 0001–9999.

start (optional)
Inclusive range start YYYY-MM-DD
end (optional)
Inclusive range end YYYY-MM-DD
frequency (optional)
Default daily Allowed values: daily, monthly, quarterly, annual.
lookup (optional)
Source annual, monthly, quarterly or daily period (e.g. 2024M01 or 2024K1)
format (optional)
List output format; default json. Lookups require json. CSV preserves text codes; keep its linked manifest. Allowed values: json, csv, manifest.

/api/dimensions/crosswalks

Bounded historical relationship pilot

No parameters returns the index. Otherwise kind is required. Municipality: list with kind alone, or code/sourceDate/targetDate together, JSON only; excludes country/date/role. Country-currency: list with optional role, or country/date together, JSON only; excludes code/sourceDate/targetDate. Coverage is Skagafjörður merger and Croatia currency changeover, 2022-01-01 inclusive to 2026-09-14 exclusive. No automatic allocation, weights or exchange rates. All parameters occur once, ≤200 characters.

kind (optional)
Relationship family Allowed values: municipality, country-currency.
code (optional)
Original municipality code as text
sourceDate (optional)
Original date YYYY-MM-DD
targetDate (optional)
Target date YYYY-MM-DD
country (optional)
Country name or code
date (optional)
Membership date YYYY-MM-DD
role (optional)
Default account Allowed values: account, cash.
format (optional)
List output format; default json. Lookups require json. CSV preserves text codes; keep its linked manifest. Allowed values: json, csv, manifest.

Reference GETs return a versioned reference plus a count and list, or a lookup result. Dates return period for normalization. Crosswalks expose relationships and explicit unmatched/out-of-coverage/allocation outcomes. format=manifest returns the reference terms, query parameters, row count and CSV URL. A manifest describes the current export, not an immutable copy; retain it with the CSV and re-download both after reference changes.

Connection links encode a compact live recipe as unpadded base64url UTF-8 JSON. The UI generates at most 5,800 input bytes; the decoder accepts up to 7,800 encoded characters. They cannot contain snapshots. Use the Workbench’s integration actions to create them. CSV uses long-form rows and empty cells for nulls. The model endpoint returns HTML Data and Date tables, plus Country/Currency where resolved. Preserve text keys; the period dimension is not a continuous daily DAX date table.

Limits, caching and browser access

Recipe run accepts 2,097,152 bytes (2 MiB), at most eight layers and 12,000 observations per layer. Export limits are 96,000 rows and 20,971,520 bytes (20 MiB). Narrow filters if a limit is exceeded. Any selected source failure fails the whole live recipe. Sources execute sequentially; shared provider cache and traffic limits apply. Upstream request timeout is 25 seconds; no API uptime or commercial quota commitment is offered.

Public CORS uses Access-Control-Allow-Origin: * without credentials. Run preflight allows GET/POST/OPTIONS and Content-Type, cached for 86,400 seconds. Table/model preflight allows GET/OPTIONS. Dimension preflight allows GET/HEAD/OPTIONS and Content-Type (countries also POST), cached for 600 seconds; unsupported requested methods or headers return 403. Dimensions support HEAD with GET status/headers and no body; unsupported methods return 405 and Allow.

Recipes use Cache-Control: no-store. Successful country/currency/crosswalk references use max-age=3600; dates use 86400. Country POST and reference errors use no-store. Run exposes X-Request-ID, Retry-After and X-Datahub-Recipe-Version. Table exposes Retry-After and Content-Disposition; model exposes Retry-After. Dimensions expose X-Reference-Version, X-Country-Reference-Version, Content-Disposition, Retry-After and Link. CSV reference downloads link to their manifest. Crosswalk responses also carry X-Crosswalk-Reference-Version; browser clients can use the exposed X-Reference-Version.

Errors and retry behavior

Recipe errors contain error, code, requestId and optional numeric retryAfter. Country/date/currency errors contain error only. Crosswalk query errors add code: INVALID_QUERY; errors from the shared method/preflight wrapper still contain only error. Always check the HTTP status before interpreting a success payload.

  • 400: invalid JSON, input, query or unsupported transformation.
  • 403: upstream access denied; or unsupported dimension preflight.
  • 404: source dataset not found.
  • 405: unsupported reference method.
  • 413: request or result too large.
  • 422: unsupported provider or upstream query rejection.
  • 429: provider busy or throttled.
  • 500: unexpected reference failure.
  • 502: upstream unavailable or invalid response.
  • 504: upstream timeout.

Respect Retry-After seconds whenever present. Do not immediately retry 429 or build tight polling loops. Prefer manual or release-driven refresh. A live refresh uses current provider cache entries; it does not bypass caches.

Revisions, snapshots and compatibility

Live recipes preserve selections and transformations but source revisions can change historical values. A snapshot pins the supplied observations and provenance, makes no source request and can be saved for reproducibility. It does not independently authenticate those observations or freeze future analysis rules; retain the original response and registry version when exact output reproduction matters. The bundled snapshot is explicitly illustrative.

Source availability does not imply an unrestricted redistribution licence. Keep attribution, exceptions and reviewed/unresolved/access-required status from the source manifest. Check the dataset’s own notices before reuse.

Incompatible recipe changes use a new URL version. Before retiring v1, a dated notice and migration instructions must appear here and in the recipe descriptor. Existing snapshots retain their document version. Additive response metadata and source/reference updates may appear; consumers should preserve unknown response metadata, while requests must follow the accepted schema. There is no announced retirement date for v1.