Skip to content
Apier

Apier.no

Oppskrifter

Menneskelesbare gjennomganger av de kanoniske agent-arbeidsflytene. Hver oppskrift speiler nøyaktig én oppføring i /workflows.json — det maskinlesbare manifestet crawlere og agent-rammeverk konsumerer. For hele evne-listen, se /api/v1/capabilities.

Jobb-formede oppskrifter

Oppgave-først gjennomganger for de fire live-kombinasjonene — én jobb-oppskrift og én «for plattformer»-oppskrift hver.

Look up Norwegian business deadlines for a year

workflow.lookup-deadlines · Slå opp norske forretningsfrister for et år

Fetch the canonical deadline list (MVA terminer, A-melding, skattemelding, årsregnskap, Foretaksregisteret årsbekreftelse) for a calendar year. Deadlines are pre-adjusted through weekends and Norwegian public holidays, with the original legal deadline surfaced in `adjusted_from` when relevant.

Intensjon
Find all upcoming Norwegian business deadlines for a given calendar year.
Forventet resultat
An ordered list of deadline entries sorted ascending by date, each with obligation_id, legal deadline, adjusted deadline (when pushed for weekends/holidays), and legal reference.
Utløsende intensjon
What Norwegian business deadlines are coming up in YYYY?
Estimert tid
~200 ms · ingen autentisering

Steg

  1. 1

    Call GET /api/v1/public/deadlines?year=YYYY and iterate the returned mappings sorted ascending by deadline.

    public.deadlinesJSON envelope with data.year, data.deadlines[] (sorted ascending), and _meta.served_from='static'.

Agent-instruksjoner

1. Call GET /api/v1/public/deadlines?year=<YYYY> (no authentication required).
2. Parse the response body at data.deadlines — it is sorted ascending by deadline.
3. For each entry, note obligation_id, deadline (ISO 8601 with Europe/Oslo offset), and adjusted_from (null unless the legal deadline fell on a weekend or holiday).
4. If data.deadlines is empty, the year is valid but outside our coverage window (2020-2100) — surface VALIDATION_FAILED explanation to the user.

Feilmoduser å planlegge for

  • invalid_year
  • upstream_timeout

Eksempelforespørsel

GET /api/v1/public/deadlines?year=2026

Check a Norwegian company's current Brønnøysund status

workflow.check-company-status · Sjekk en norsk virksomhets gjeldende Brønnøysund-status

Fetch the current Tier 1 + (when delegation exists) Tier 2 view of a Norwegian company by org number. `data.data_tier` tells you whether Tier 2 was served; `_meta.served_from` distinguishes cache from live.

Intensjon
Retrieve the current Brønnøysund-sourced status and registry metadata for a Norwegian company, including Tier 2 commercial metrics when a delegation is in place.
Forventet resultat
Company context object with name, entity_type, NACE codes, status (active/deregistered/dissolved), municipality, signaturrett/prokura — plus Tier 2 fields (employee_count, annual_turnover, total_assets) when the caller has an active delegation.
Utløsende intensjon
Is company with org_number 999999999 still active, and what is its current name?
Estimert tid
~500 ms · krever API-nøkkel (free+)

Steg

  1. 1

    Call GET /api/v1/company/{org}/context with the consumer API key; branch on data.data_tier.

    company.contextJSON envelope with data.company (tier-1 fields), optional data.tier_2 block, data.data_tier, and _meta with served_from + stale markers.

Agent-instruksjoner

1. Ensure you hold a consumer API key in the Authorization: Bearer header.
2. Call GET /api/v1/company/<ORG_NUMBER>/context with ORG_NUMBER as a 9-digit Norwegian organisation number.
3. Branch on data.data_tier — 'tier_1' means public-only Brønnøysund fields; 'tier_2' means the delegation is active and commercial metrics are included.
4. Read _meta.served_from ('cache' vs 'live') and _meta.stale (true when a within-limit cached row was served as an upstream-down fallback).
5. On 404 org_not_found: surface the explanation.why text (Norwegian) to the user.
6. On 503 with _meta.stale=true: the data is still usable but older than 24 hours — tell the user freshness is degraded.

Feilmoduser å planlegge for

  • org_not_found
  • tier2_data_missing
  • upstream_timeout
  • auth_missing
  • auth_invalid_key

Eksempelforespørsel

curl -H 'Authorization: Bearer <API_KEY>' https://apier.no/api/v1/company/999999999/context

Look up the official NOK exchange rate for a date

workflow.exchange-rate-lookup · Slå opp offisiell NOK-kurs for en dato

Fetch the Norges Bank NOK rate for a currency and date. Weekend/holiday/pre-publication-today requests fall back to the most recent prior business day; `data.date` is the actual publication date and `data.requested_date` is what was asked for.

Intensjon
Fetch the official Norges Bank NOK exchange rate for a currency and optional date, with automatic fallback to the most recent prior business day when the requested date is a weekend, holiday, or before today's ~16:00 Oslo publication.
Forventet resultat
A rate object: base='NOK', quote=<uppercased ISO>, rate (1 quote = rate NOK), date (actual publication date), requested_date (what you asked for), source='Norges Bank'.
Utløsende intensjon
What was the EUR/NOK rate on 2026-04-10?
Estimert tid
~300 ms · ingen autentisering

Steg

  1. 1

    Call GET /api/v1/tools/exchange-rate?currency=<ISO>&date=<YYYY-MM-DD>.

    tools.exchange_rateJSON envelope with data.rate (number), data.date, data.requested_date, data.cached, and _meta.served_from (cache/live).

Agent-instruksjoner

1. Call GET /api/v1/tools/exchange-rate?currency=<ISO>&date=<YYYY-MM-DD> (no authentication).
2. CURRENCY must be a 3-letter ISO 4217 code Norges Bank tracks (EUR, USD, GBP, SEK, DKK, etc.).
3. DATE is optional — omit to get today-in-Oslo; future dates are rejected with 400 INVALID_DATE.
4. Compare data.date to data.requested_date. If they differ, the requested date fell on a weekend / holiday / pre-publication window and the rate is from the most recent prior business day.
5. On 404 NO_RATE_AVAILABLE: Norges Bank does not track this currency — try EUR or USD as a fallback.
6. On 502 UPSTREAM_UNAVAILABLE: transient; retry in a few minutes.

Feilmoduser å planlegge for

  • invalid_currency
  • invalid_date
  • no_rate_available
  • upstream_unavailable

Eksempelforespørsel

GET /api/v1/tools/exchange-rate?currency=EUR&date=2026-04-10

Translate an Altinn 2 code to the Altinn 3 equivalent

workflow.altinn-role-migration · Oversett en Altinn 2-kode til Altinn 3-motparten

Before the 19 June 2026 deprecation deadline, translate an Altinn 2 service or role code to the Altinn 3 equivalent. Gate production migration actions on `verified === true`; unverified entries are convenience references only.

Intensjon
Discover the Altinn 3 resource or role that replaces a given Altinn 2 service/role code, ahead of the 19 June 2026 deprecation cliff.
Forventet resultat
A migration entry with altinn2_code, altinn3_code (possibly null if DigDir hasn't published an equivalent yet), migration_notes in Norwegian and English, service_owner, and a `verified` flag indicating whether the mapping has been cross-checked against DigDir's authoritative source.
Utløsende intensjon
What Altinn 3 role corresponds to Altinn 2 code A0208?
Estimert tid
~150 ms · ingen autentisering

Steg

  1. 1

    Call GET /api/v1/tools/altinn-migration?altinn2_code=<CODE>; inspect `verified` before trusting the mapping for production automation.

    tools.altinn_migrationJSON envelope with data.entry (MigrationEntry), data.deprecation_deadline, data.days_remaining, data.deadline_passed, and _meta.served_from='static'.

Agent-instruksjoner

1. Call GET /api/v1/tools/altinn-migration?altinn2_code=<CODE> (no authentication). CODE is alphanumeric, max 10 characters (e.g. A0208).
2. Read data.entry.verified — if false, the mapping is a best-effort reference and MUST NOT drive production migration without human review.
3. Read data.entry.altinn3_code — null means DigDir has not yet published the Altinn 3 equivalent.
4. Surface data.days_remaining to the user so they know how long until the 19 June 2026 deprecation cliff.
5. On 404 NOT_FOUND: the code is not in our static map — point the user at docs.altinn.studio.

Feilmoduser å planlegge for

  • invalid_code
  • not_found
  • unverified_entry

Eksempelforespørsel

GET /api/v1/tools/altinn-migration?altinn2_code=A0208

List generic obligations for a Norwegian entity type

workflow.obligation-overview · List generelle forpliktelser for en norsk selskapsform

Fetch the universal obligation set for a given entity type (AS, ENK, ANS, DA, NUF). Template layer only — `tier_2_required: true` entries need commercial data to evaluate per-company, which requires an Altinn delegation.

Intensjon
List the universal regulatory obligations (tax, reporting, insurance, registration) that apply to a Norwegian entity type, and identify which of those need Tier 2 commercial data to evaluate per-company.
Forventet resultat
Obligation template set: each entry names the obligation, category, frequency, required/conditionally/never applicability, a Norwegian condition string, tier_2_required flag, and the Lovdata legal reference.
Utløsende intensjon
What obligations apply to a Norwegian aksjeselskap (AS)?
Estimert tid
~150 ms · ingen autentisering

Steg

  1. 1

    Call GET /api/v1/public/obligations?entity_type=<AS|ENK|ANS|DA|NUF>. Use the `tier_2_required` flag to decide whether to plan a delegation flow next.

    public.obligationsJSON envelope with data.entity_type, data.obligations[] (may be empty for ANS/DA/NUF), data.notes[], and _meta.served_from='static'.

Agent-instruksjoner

1. Call GET /api/v1/public/obligations?entity_type=<AS|ENK|ANS|DA|NUF> (no authentication).
2. Iterate data.obligations — an array of obligation templates.
3. For each obligation with tier_2_required === true, plan ahead: the caller will need an Altinn delegation (workflow.request-delegation, not yet shipped) before the paid /v1/company/{org}/obligations endpoint can evaluate it per-company.
4. Obligations with required='never' are DELIBERATELY included so agents see they were considered and ruled out (e.g. revisor-plikt for ENK).
5. ANS, DA, and NUF currently return an empty obligations array with a notes entry — templates are not yet published.

Feilmoduser å planlegge for

  • invalid_entity_type
  • empty_template_set

Eksempelforespørsel

GET /api/v1/public/obligations?entity_type=AS

Reconcile a customer's filing history from the audit trail

workflow.reconcile-filing-history · Avstem en kundes innsendingshistorikk fra sporingsloggen

Pull the consumer's own audit trail (Sporingslogg) for a single org_number across a date range, paging via the keyset cursor (next_before + next_before_id) until exhausted. Useful for accounting firms reconciling activity after the fact, AI-agent operators debugging filing flows, and producing a forensic timeline for dispute defense. Returns ONLY rows YOUR consumer wrote — cross-consumer visibility is structurally impossible.

Intensjon
Reconstruct the activity timeline a single consumer's API key generated against one Norwegian organisation, optionally narrowed by action type or initiator class, for reconciliation, debugging, or dispute defense.
Forventet resultat
Ordered (timestamp DESC, id DESC) page of AuditLogEntry rows the consumer wrote for the org, each carrying correlation_id (joins to provenance_log / evaluation_snapshots / compliance_state_events), initiated_by classification, schema_version, and a scrubbed details JSONB.
Utløsende intensjon
Show me every audit-log row my consumer wrote for org 999999999 in the last 90 days.
Estimert tid
~250 ms · krever API-nøkkel (free+)

Steg

  1. 1

    Call GET /api/v1/company/{org}/audit with the consumer API key (read:audit scope). Iterate the page; if pagination.has_more, repeat with ?before=pagination.next_before&before_id=pagination.next_before_id.

    company.auditJSON envelope with data.data[] (AuditLogEntry array), data.pagination.has_more, data.pagination.next_before (string or absent), data.pagination.next_before_id (string or absent), and _meta with response_timestamp + response_hash.

Agent-instruksjoner

1. Ensure your API key has the read:audit scope (operator-issued via /v1/admin/keys).
2. Call GET /api/v1/company/<ORG_NUMBER>/audit?since=<ISO_FROM>&until=<ISO_TO>&limit=200 with the consumer API key.
3. Iterate data.data — each row is an AuditLogEntry. correlation_id joins to provenance_log / evaluation_snapshots / compliance_state_events from the same originating request.
4. If pagination.has_more is true, pass pagination.next_before back as ?before=<value> AND pagination.next_before_id back as ?before_id=<value> to fetch the next page. Both are required together — the cursor is a tuple, not two independent fields.
5. To narrow further: ?action=<closed-enum> or ?initiated_by=<human|agent|cron|system|unknown>. Action enum is the closed list at src/lib/audit/types.ts AUDIT_ACTIONS — anything outside the list is rejected at 400.
6. details.* values matching token / secret / password / bearer / authorization / jwt / api_key / private_key / credential / client_secret / refresh_token are auto-redacted to the literal string [REDACTED] at BOTH write and read time.
7. An empty array (data.data === []) for a valid (consumer, org) pair is returned as 200, not 404 — that prevents existence-leak across consumers.

Feilmoduser å planlegge for

  • auth_missing
  • scope_insufficient
  • validation_failed
  • audit_query_failed

Eksempelforespørsel

curl -H 'Authorization: Bearer <API_KEY>' 'https://apier.no/api/v1/company/999999999/audit?limit=50&initiated_by=agent'

Track historical changes for a customer company

workflow.track-changes · Følg historiske endringer for en kunde-virksomhet

Pull all change events for a specific org_number from the change archive (Brreg ingestion + Altinn / DigDir / Norges Bank multi-source). Cursor-paginated; pass next_cursor back as ?cursor= for the next page.

Intensjon
Subscribe (via polling) to changes affecting a Norwegian company, audit historical mutations, or reconstruct what Apier saw at a given time across all four upstream sources.
Forventet resultat
Page of change events (created/updated/deleted) ordered detected_at DESC, id DESC. Each row carries source_snapshot_id for joining to the response receipt.
Utløsende intensjon
Show me everything that changed for org_number 998877665 in the last 30 days.
Estimert tid
~200 ms · krever API-nøkkel (starter+)

Steg

  1. 1

    Call GET /api/v1/changes?source=brreg&entity_id={org_number}&from={iso_date} with the consumer API key (read:changes scope). Iterate the page; if pagination.has_more, repeat with ?cursor=pagination.next_cursor.

    changes.queryJSON envelope with data.data[] (PublicChangeRow array), data.pagination.has_more, data.pagination.next_cursor (string or null), and _meta with response_timestamp + response_hash.

Agent-instruksjoner

1. Ensure your API key has the read:changes scope (operator-issued via /v1/admin/keys).
2. Call GET /api/v1/changes with filters: source (brreg|altinn|digdir|norges_bank), entity_id, change_type (created|updated|deleted), from + to (RFC 3339).
3. Iterate data.data — each row is a created/updated/deleted event with before_value/after_value JSONB blobs and an RFC 6902 diff array.
4. If pagination.has_more is true, pass pagination.next_cursor back as ?cursor=<value> to fetch the next page. Do NOT modify the cursor — it's HMAC-signed and tampered cursors return 400 CURSOR_INVALID.
5. correlation_id is intentionally not exposed; use source_snapshot_id to join back to provenance receipts.

Feilmoduser å planlegge for

  • auth_missing
  • scope_insufficient
  • cursor_invalid
  • validation_failed

Eksempelforespørsel

curl -H 'Authorization: Bearer <API_KEY>' 'https://apier.no/api/v1/changes?source=brreg&entity_id=998877665&from=2026-01-01T00:00:00Z'

Validate a filing before submission

workflow.validate-filing · Valider en innlevering før innsending

Run the five preflight checks the dry-run engine performs against a filing payload — company exists, system user authorised, scopes delegated, payload format valid, deadline in future — without submitting anything to Altinn / Skatteetaten / NAV. Use this before any human-approval flow so the agent can present a complete pass/fail picture rather than discovering problems mid-flight.

Intensjon
Pre-flight a regulatory filing payload to discover every problem in one call, BEFORE the live submission burns an idempotency key or surfaces a partial commit at the upstream.
Forventet resultat
DryRunOutcome with all_passed (boolean) and checks[5] (per-check pass/fail with structured error_code on failures). The disclaimer field reminds the agent that a passing dry-run is NOT a guarantee of submission success.
Utløsende intensjon
Will my MVA-melding for 2026-T2 pass before I submit it?
Estimert tid
~600 ms · krever API-nøkkel (starter+)

Steg

  1. 1

    Call POST /api/v1/actions/execute?dry_run=true with { org_number, action_type, period, payload }. The endpoint performs all five preflight checks, writes one evaluation_snapshots row + one audit_log row, and returns 200 with the structured DryRunOutcome.

    actions.execute_dry_runJSON envelope with data.dry_run === true, data.outcome.all_passed (boolean), data.outcome.checks (5 entries, ordered), data.outcome.disclaimer (fixed string), and _meta with response_timestamp + response_hash.

Agent-instruksjoner

1. Ensure your API key has the read:actions scope (operator-issued via /v1/admin/keys).
2. Build the request body: { org_number (9 digits), action_type ("mva_melding" | "a_melding"), period (YYYY-Tn|YYYY-A|YYYY-MM for mva; YYYY-MM for a-melding), payload (per-action shape — see OpenAPI components MvaMeldingPayload / AMeldingPayload). Decimals as STRINGS, not numbers.
3. POST /api/v1/actions/execute?dry_run=true with the body. Note the ?dry_run=true is REQUIRED at v1 — omitting it returns 501 EXECUTE_NOT_AVAILABLE.
4. Read response data.outcome.all_passed. If true, the dry-run found no blockers; live submission uses the live-execute flow (Idempotency-Key + approval token) and is enabled per-operator once Maskinporten/Altinn grants are active.
5. If false, iterate data.outcome.checks: each row has check (name), passed (bool), error_code (string|null), explanation_summary (string|null). Fix the inputs against the failed checks and retry — the engine never short-circuits, so one call lists every problem.
6. Treat the disclaimer field as a hard contract: a passing dry-run is NOT a guarantee. Government systems may reject otherwise-valid submissions for reasons outside Apier's view.

Feilmoduser å planlegge for

  • auth_missing
  • scope_insufficient
  • validation_failed
  • execute_not_available
  • payload_too_large

Eksempelforespørsel

Dry-run: POST /api/v1/actions/execute?dry_run=true with headers { Authorization: Bearer <KEY> } and body { org_number, action_type, period, payload }. Live-execute: POST /api/v1/actions/execute with headers { Authorization: Bearer <KEY>, Idempotency-Key: <UUID>, X-Approval-Token: <token> } and body { org_number, action_type: "mva_melding", period, payload }. Both modes require API-key auth via Authorization header (round 5 manifest fix — was previously omitted from the dry-run half).