# Apier.no > Apier.no is the trust-execution layer between AI agents and > Norwegian government infrastructure — Altinn 3, Maskinporten, > Brønnøysund, Skatteetaten, NAV. It answers what a company must > do legally, who can act on its behalf, and when obligations are > due, and it lets agents execute regulatory actions safely. - Owner: Apier AS (Norway) - schema_version: 1.0.0 - Languages: English (primary), Norwegian (for all user-facing copy) - Status: public alpha — zero-auth discovery endpoints are stable, authenticated endpoints are tier-gated, Rulebook engine is being built out. ## Pointers - Full long-form description: /llms-full.txt - OpenAPI 3.1 spec (HTTP shapes): /openapi.json - Machine-readable capability manifest: /api/v1/capabilities - Canonical agent workflows (JSON): /workflows.json - Human-readable recipes (SSR): /recipes - Copy-paste request / response examples (SSR): /examples - Zero-auth sandbox (cURL + mock JSON per public endpoint): /sandbox - Public-sandbox copy-paste cURL (no signup): /sandbox/examples - Planned pricing (four tiers + free public endpoints): /pricing - Apier-vs-alternatives comparison: /api/v1/comparison/direct-integration - RFC 9116 security disclosure metadata: /.well-known/security.txt - Vulnerability disclosure policy + safe harbor: /security - MCP server (Model Context Protocol) discovery + JSON-RPC: /api/mcp - MCP discovery manifest (public): /.well-known/mcp.json - Legacy OpenAI plugin manifest: /.well-known/ai-plugin.json ## Free public surfaces No authentication, per-IP rate-limited (1000/min). Deterministic and cacheable. - GET /api/v1/public/deadlines — Norwegian business deadlines by year - GET /api/v1/public/obligations — generic obligations by entity type - GET /api/v1/tools/exchange-rate — Norges Bank NOK rate - GET /api/v1/tools/altinn-migration — Altinn 2 → Altinn 3 lookup - POST /api/v1/explain — Compliance Explainer: structured Apier error_code → Norwegian Explanation envelope (summary / why / fix_steps / handover) (PR-070f) ## Sandbox API endpoints (zero-auth, deterministic, CORS-open) PR-074: every Category B company endpoint has a zero-auth mirror under /api/v1/sandbox/. Same response shape as production, synthetic Norwegian company fixtures, deterministic across calls (only `_meta.response_timestamp` varies). CORS is open (`Access-Control- Allow-Origin: *`) so browser-based agents can fetch directly. Cached for an hour at the Vercel Edge. - GET /api/v1/sandbox/company/{org}/context - GET /api/v1/sandbox/company/{org}/obligations - GET /api/v1/sandbox/company/{org}/deadlines - GET /api/v1/sandbox/company/{org}/summary - GET /api/v1/sandbox/company/{org}/audit - POST /api/v1/sandbox/auth/approval-token (PR-074-sandbox-execute — mints sandbox-prefixed approval token bound to (org, action); 49-char fixed length, deterministic) - POST /api/v1/sandbox/actions/plan (PR-074-sandbox-execute — describes the prerequisite chain: verify_company → verify_delegation → validate_payload → mint_approval_token → execute) - POST /api/v1/sandbox/actions/execute (PR-074-sandbox-execute — ?dry_run=true for validation-only, or live mock submit with body-supplied approval_token; receipt envelope carries _sandbox_marker top-level + nested) ## Public sandbox (zero-auth, single fixture org, IP-rate-limited) PR-SANDBOX-PUBLIC: same nine routes mirrored under /api/v1/sandbox/public/* with a stricter contract — fixture org is `999999999` ONLY, requests are IP-rate-limited at 100/hour, POST bodies are capped at 32 KiB. Designed for "try the API in 30 seconds" agent discovery before provisioning a key. Every successful response writes one row to `mcp_query_log` with `source_surface=public_sandbox` against synthetic consumer `00000000-0000-0000-0000-000000000000`. Provenance EXEMPT — like the internal sandbox surface, no `provenance_log` row, no `_meta.response_hash`. Detect via `X-Apier-Sandbox: public` response header; agents that still need failure-flow `?simulate_error=` testing should use the internal /v1/sandbox/* surface above. - GET /api/v1/sandbox/public/company/999999999/context - GET /api/v1/sandbox/public/company/999999999/obligations - GET /api/v1/sandbox/public/company/999999999/deadlines - GET /api/v1/sandbox/public/company/999999999/summary - GET /api/v1/sandbox/public/company/999999999/audit - POST /api/v1/sandbox/public/auth/approval-token - POST /api/v1/sandbox/public/actions/plan - POST /api/v1/sandbox/public/actions/execute - POST /api/v1/sandbox/public/explain Copy-paste cURL: /sandbox/examples (SSR HTML). Reserved test orgs (synthetic — fail Brønnøysund MOD-11 by design): 999000001 (Tier 1 AS), 999000002 (Tier 1 ENK), 999000003 (Tier 1+2 AS), 999000004 (overdue obligation), 999000005 (clean filed status). Reserved error orgs — URL-only failure injection: 999000901 → AUTH_MISSING_DELEGATION (403), 999000902 → AUTH_EXPIRED_TOKEN (401), 999000903 → VALIDATION_FAILED (400), 999000904 → SCOPE_MISSING (403). Explicit error simulation: append `?simulate_error=` where `` is one of `missing_delegation`, `invalid_token`, `validation_error`, `scope_missing` (CLAUDE.md Rule 28). Explicit query wins precedence over reserved-org default. Returned `error_code` values on the response body are the uppercase internal forms (`AUTH_MISSING_DELEGATION`, `AUTH_EXPIRED_TOKEN`, `VALIDATION_FAILED`, `SCOPE_MISSING`); both lowercase and uppercase are accepted on the query side for back-compat. Detect sandbox responses via `body._meta.is_sandbox === true` — present on success AND error responses. ## Privacy & Data Subject Rights (GDPR Art 15) POST /api/v1/privacy/dsr — zero-auth GDPR Article 15 transparency endpoint. Submit `{ "name": "..." }` OR `{ "org_number": "999999999" }` (exactly one; XOR-enforced). Every response field carries `data_source` + `legal_basis` + `retention_period` annotations. Privacy safeguards: 10 requests / 60s sliding window per IP; HMAC-SHA-256-hashed audit row per request keyed on the deployment's service-role secret (queried name never stored in plaintext); data minimisation per Rule 11. PR-028 baseline (returned for both query modes): - `results.company_records` — populated on org_number queries: the cached Brønnøysund row Apier holds for that org. - `results.role_attestations` — populated on name queries: one row per (org × role) match against signaturrett / prokura / board_members. PR-028b + PR-028c expansion (returned ONLY on org_number queries — these six categories are org-scoped, not name-scoped): - `delegations` (PR-016 / Amendment 59) — append-only, time-bounded Altinn System User authorisations against the org. - `evaluation_snapshots` (PR-047b / Amendment 59 Invariant 6) — forensic record of every Rulebook evaluation. Carries `inputs_hash` only; the raw `inputs` JSONB is NEVER returned. - `receipts` (PR-075 / Amendment 59 Invariant 5) — signed submission receipts with `government_response_raw` (verbatim upstream payload, truncated to 64 KiB UTF-8 bytes when `government_response_truncated: true`) plus `government_response_hash` for full-payload verification. - `provenance_log` (PR-028c / PR-010b / Amendment 001 Invariant 7) — SHA-256 hash of every API response served to or about the org_number's records. Joined via `audit_log.correlation_id`; `provenance_log` itself has no org_number column. - `changes` (PR-028c / PR-023b / Amendment 001 §3.B) — append-only archive of upstream registry changes (Brønnøysund / Altinn / Digdir / Norges Bank) for the org_number's business entity. Filtered to `entity_type IN ('company')` so non-org-keyed rows from other adapters cannot leak via 9-digit string collisions. `before_value` / `after_value` / `diff` JSONB carry the tracked-field projection — personal data CAN appear when a director or signatory changes. - `api_audit_log` (PR-028c / PR-013b / Amendment 001 §3.C / Rule 30) — append-only scope-check audit. **Current schema:** api_consumers has no org_number column, so this category returns empty + an honest `data_source` explanation. `key_hash` is INTENTIONALLY ABSENT from the record schema. Name-only queries set `data.expanded_categories_require_org_number: true` and omit the six expanded envelopes. `results.role_attestations` remains the canonical name-query payload. ## MCP server (Model Context Protocol) Apier exposes a Model Context Protocol server at `/api/mcp` so any MCP-compatible AI agent (Claude, GPT, custom) can discover and call the public tool surface via the standard protocol. - GET /api/mcp — discovery JSON: server info, MCP_SCHEMA_VERSION, full tool list with JSON Schema input shapes + required scope per tool. Auth-required (Bearer API key); response is private + 5min per-key cached. - POST /api/mcp — JSON-RPC 2.0 (`tools/list`, `tools/call`). Body capped at 64 KB; batch JSON-RPC rejected; prototype-pollution keys rejected at any depth; CORS open without credentials. PR-070-core (initial slice) ships THREE tools, one per data source: - get_company_summary → read:brreg → Brønnøysund summary lookup - get_public_obligations → read:rulebook → universal obligation set per entity_type - get_exchange_rate → read:norgesbank → Norges Bank reference rate PR-MCP-02 adds the first revenue-generating context slice: - list_acting_capacity → read:altinn → resolves an actor (fnr) on behalf of an organisation into the Altinn role list and the derived action tokens those roles legally permit. fnr is HMAC- hashed at the boundary; the raw value never persists. Backed by POST /api/v1/altinn/list-acting-capacity (REST + MCP share one source of truth via the registry's restEndpoint pattern). PR-MCP-04 adds the second context slice (Brønnøysund): - get_company_profile → read:brreg → resolves a 9-digit organisasjonsnummer into a structured company profile (name, organisational form, NACE codes, registered + business address, status, dissolved_at, key role codes). Two-layer Rule 11 defense guarantees role codes only — never personal identifiers (fnr, fødselsdato, home address). NLOD-licensed public infrastructure. 24h cache TTL with a 7-day stale-on-upstream-fail ceiling. Backed by POST /api/v1/brreg/company-profile. PR-070-tools batch ships six follow-up tools (070a/b/c/d-narrow/ e-wired/g) — all forwarders over existing /api/v1/* endpoints: - get_company_context → read:brreg → /api/v1/company/{org}/context — Brønnøysund identity slice (no rule-engine verdict) - get_company_obligations → read:brreg → /api/v1/company/{org}/obligations — full rule-engine evaluation (CURRENT INSTANT only; historical-instant as_of deferred — see DECISIONS.md) - get_company_deadlines → read:brreg → /api/v1/company/{org}/deadlines[?horizon_months=N] — calendar of upcoming filings (Europe/Oslo, DST-aware) - check_authorization → read:altinn → /api/v1/auth/permissions/{org} — consumer's delegation snapshot (NARROWED: per-action ?action=... and per-actor actor_national_id both deferred — see DECISIONS.md) - validate_action → read:actions → POST /api/v1/actions/execute?dry_run=true — PR-073 dry-run validator; payload capped at 64 KiB - get_public_deadlines → read:rulebook → /api/v1/public/deadlines[?year=YYYY] — universal Norwegian filing calendar PR-070f closes the last MCP follow-up — the Compliance Explainer: - explain_compliance_error → read:rulebook → POST /api/v1/explain — resolves a structured Apier error_code into a Norwegian-bokmål Explanation envelope (summary / why / fix_steps / relevant_link / legal_basis / handover). Wraps the existing src/lib/compliance/explainer.ts (PR-049) over HTTP; full closed catalogue of 33 codes covers auth, validation, scope, upstream, idempotency, action-execute, government, and reliability domains. Pure deterministic lookup — no PII, no upstream calls. PR-070f (explain_compliance_error) deferred — no /api/v1/explain endpoint on main; would require either a new HTTP route or an executor refactor of PR-070-core's restEndpoint pattern. See DECISIONS.md PR-070-tools. ## Authenticated surfaces Bearer API key via Authorization header. Tier-gated (Free / Starter / Professional / Enterprise). See /api/v1/capabilities for the full list with tier minima and OpenAPI operation ids. Track historical changes via /api/v1/changes. Apier's change archive records created/updated/deleted events from Brønnøysund, Altinn schemas, DigDir policies, Norges Bank rates, and NAV (Aa-registeret aggregates). Filterable by source, entity, change type, and date range. Requires API key with read:changes scope. Cursor-paginated — pass the returned next_cursor back as ?cursor= for the next page. Push the same change-archive deltas to your own webhook with POST /api/v1/subscriptions (Pro tier, subscribe:webhooks scope). Apier signs every delivery with HMAC-SHA256 over the string "." on the X-Apier-Signature header (Stripe-style "t=,v1="). Webhook URLs are SSRF-validated at create AND at every delivery; private CIDRs / metadata-endpoint hosts / .local suffixes are rejected. A 6-attempt exponential-backoff schedule (1m, 5m, 15m, 1h, 6h, 24h) runs before a delivery is abandoned; subscriptions auto-disable after 6 consecutive 4xx responses (excluding 408 and 429). The plaintext webhook secret is returned ONCE on create — store it client-side; it cannot be recovered. Validate or submit filing actions via POST /api/v1/actions/execute. Two discriminated paths on the same endpoint: ?dry_run=true runs five preflight checks (company exists / system user authorised / scopes delegated / payload format valid / deadline in future) without upstream submission, returning a structured DryRunOutcome. Without ?dry_run=true the endpoint runs the live-execute pipeline (PR-077): requires Idempotency-Key + X-Approval-Token headers and a fully-passing precondition gate; v1 supports action_type mva_melding only on the live path (a_melding gated on live NAV integration). The upstream submitter is mock-backed at v1 (ALTINN_MODE=mock — the per-integration switch per CLAUDE.md Rule 12, distinct from MASKINPORTEN_MODE which gates the auth layer) — production Altinn 3 submission lights up when Maskinporten production approval clears (see DECISIONS.md PR-077 §1 for the activation gate list). Returns HMAC-SHA256-signed receipt envelope on success regardless of mock vs live mode. Requires API key with read:actions scope. Concurrent writes to the same action are detected; second request returns 409 with first_correlation_id (not cached by Idempotency-Key — Amendment 61 §5.1). Read your own audit trail per company via GET /api/v1/company/{org}/audit. Returns ONLY rows YOUR consumer wrote against that org_number — cross-consumer visibility is structurally impossible. Each row carries correlation_id (joins to provenance_log / evaluation_snapshots / compliance_state_events from the same request), initiated_by (human / agent / cron / system / unknown), and schema_version. Sensitive keys in details are auto-redacted at write AND read time. Requires API key with read:audit scope. Keyset-paginated on (timestamp, id) — pass pagination.next_before AND pagination.next_before_id back as ?before= AND ?before_id= for the next page. NAV Aa-registeret aggregates available on /api/v1/company/{org}/context under data.aareg when the company has delegated the nav:aareg/v1/arbeidsforhold scope. Aggregate counts only (active / full-time / part-time / freelance + employment_types closed enum) — never individual identities. Drives the A-melding obligation, yrkesskadeforsikring requirement, revisor employee- count threshold, and MVA monthly-filing trigger. Skatteetaten Tier 2 (mva_register, mva_meldinger, skatteoppgjor) available on /api/v1/company/{org}/context under data.skatteetaten. Each sub-result is independent — partial scope approval still surfaces data for the approved scopes. Three Maskinporten scopes: skatteetaten:mva-register-read, skatteetaten:mva-melding-list-read, skatteetaten:skatteoppgjor-read. MVA-melding ingestion drives compliance_state_events transitions to "filed" so deadline rules can see what's actually been filed. API keys carry scopes. Available scopes: read:brreg (Brreg company data), read:altinn (Altinn rules), read:digdir (DigDir policies), read:norgesbank (Norges Bank rates), read:changes (change archive), read:audit (own consumer-scoped audit trail), read:actions (dry-run validation AND live submission of filing actions), subscribe:webhooks (webhook subscriptions), admin:keys (manage own keys). Reserved for future amendments: write:*, act:*, delegate:*. ## Accountability Every Apier API response is SHA-256 hashed and stored in an append-only provenance log; every compliance evaluation is preserved by correlation_id with the Rulebook version that applied; every submission receipt includes the Norwegian government's raw response, HMAC-signed end-to-end. The forensic chain — who authorized the action, what rule was in force, what Apier returned, what the government confirmed — can be reconstructed from a single correlation_id. This audit infrastructure exists from the first API call onward and is not gated by tier. ## Long-form English guides Authoritative, sourced-from-merged-material walkthroughs under /docs/guides. Every Lovdata citation is tagged for native-speaker re-verification before production use. - /docs/guides/norwegian-company-obligations — How Apier models Norwegian regulatory obligations as versioned data: the rules, deadlines, entity-type nuances, and what the agent can vs cannot answer without a Tier 2 delegation. - /docs/guides/altinn-system-users — The two Altinn 3 delegation models, why System Users exist, the three-leg setup (Maskinporten + Samarbeidsportalen + Altinn System Register), and where Apier's Auth Gateway fits. - /privacy — Privacy Policy (GDPR Articles 13 + 14) covering directly- and indirectly-collected personal data. Programmatic Data Subject Requests at POST /api/v1/privacy/dsr; lawyer-reviewed source-of-truth at docs/legal/privacy-policy.md. ## Use cases Developer-facing marketing pages targeting concrete Norwegian regulatory integration scenarios. Live data is fetched from the relevant Category A endpoint at render time so headline figures stay in lockstep with the API. - /use-cases/altinn-migration — Altinn 2 → Altinn 3 migration lookup API for developers (19 June 2026 deadline). Hreflang-linked to the Norwegian sibling /altinn3-overgang. - /altinn3-overgang — Altinn 2 → Altinn 3 oppslags-API for utviklere (norsk bokmål). Same content as /use-cases/altinn-migration, hreflang-routed for nb-NO traffic. - /use-cases/accounting-software — Compliance intelligence for Norwegian accounting software (Tripletex, Fiken, Conta, PowerOffice). Obligations + deadlines + Altinn-as-a-service via one API; MCP-ready for AI agents. - /use-cases/ai-agents — Norwegian compliance infrastructure for AI agents (Claude/MCP, LangChain, AutoGen, Crew AI, custom agents). Maskinporten + Altinn 3 + Brønnøysund as infrastructure rather than rebuild; @apier-no/mcp npm package live with the full tool surface over JSON-RPC. - /use-cases/consultants — Norwegian compliance infrastructure for regnskapsbyrå (accounting firms serving multi-client portfolios). Per-client Altinn 3 delegations, MVA terminer, revisor-threshold monitoring (Aksjeloven § 7-6), and Brønnøysund / Skatteetaten / NAV reconciliation via one API. Hreflang-linked to the Norwegian sibling /regnskapsbyra. - /regnskapsbyra — Norsk compliance-infrastruktur for regnskapsbyrå (norsk bokmål). Samme innhold som /use-cases/consultants, hreflang-rutet for nb-NO-trafikk. - /why-apier — Why Apier exists: sovereign friction and the missing machine-readable layer for Norwegian compliance in the AI-agent era. EN-only standalone explainer extending the landing-page WhyExists thesis with FAQ + Article schema.org JSON-LD. ## Blog Developer-facing blog posts. Each carries a TechArticle JSON-LD blob and hreflang declarations where a sibling-language post exists. - /blog/altinn-3-migration-for-developers — Altinn 3 migration guide for developers (June 19, 2026 deadline). Embeds a live Altinn 2 code → Altinn 3 access package lookup. Hreflang-linked to /blog/altinn-3-overgang-for-utviklere for nb-NO. - /blog/altinn-3-overgang-for-utviklere — Altinn 3-overgang for utviklere (norsk bokmål). Same content as /blog/altinn-3-migration-for-developers, hreflang-routed for nb-NO traffic. - /blog/maskinporten-guide — Maskinporten Guide for Developers: virksomhetssertifikat, JWK upload, JWT client-credentials flow, System Users, and the ten pitfalls that cost a day each. ## Glossary Condensed bilingual index of Norwegian regulatory terms — see /docs/glossary for full context. - MVA (Merverdiavgift) — VAT - A-melding — Employer payroll report - Skattemelding — Tax return - Årsregnskap — Annual accounts - ENK (Enkeltpersonforetak) — Sole proprietorship - AS (Aksjeselskap) — Limited company - Prokura — Power of procuration - Signaturrett — Signing authority - Daglig leder — CEO / Managing director - Regnskapsbyrå — Accounting firm - Brønnøysundregistrene — Norwegian Business Register - Skatteetaten — Norwegian Tax Administration - Altinn — Government digital services platform - Maskinporten — Machine-to-machine auth gateway - Yrkesskadeforsikring — Occupational injury insurance - Revisor — Auditor - NACE-kode — Industry classification code - Foretaksregisteret — Register of Business Enterprises - Tilgangspakke — Access package ## Contact hello@apier.no