# Apier.no

> Compliance infrastructure API connecting AI agents to Norwegian government systems — Altinn, Brønnøysundregistrene, Skatteetaten and Maskinporten. 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: Grov Digital (Norway) — org.nr. 833 397 982, a Norwegian enkeltpersonforetak
- schema_version: 1.0.0
- last_updated: 2026-08-21
- Languages: English (primary), Norwegian (for all user-facing copy)
- Status: beta — zero-auth discovery endpoints are stable,
  authenticated endpoints are tier-gated.

## Who Apier is for

Five audiences this API is built for, with the fastest entry point
for each:

- AI-agent developers and agencies — the MCP server at /api/mcp plus
  the keyless public sandbox (org 999999999). Read
  /no/altinn-for-ai-agents.
- Accounting / ERP software vendors (Tripletex, Fiken, Conta,
  PowerOffice class) — GET /api/v1/company/{org}/obligations and
  GET /api/v1/company/{org}/deadlines. Read
  /use-cases/accounting-software.
- Regnskapsbyrå / accountants — start with the free tools at
  /no/verktoy, then per-client Altinn delegation. Read
  /no/regnskapsbyra.
- Fintech, banks and B2B SaaS doing KYB, AML or supplier
  verification — GET /api/v1/company/{org}/verify and
  GET /api/v1/company/{org}/authority. Read /kyb-api.
- Foreign companies and integrators entering the Norwegian market —
  read /norwegian-government-apis-for-foreign-companies.

## What Apier is not

- Not a government service. Apier is an independent commercial
  gateway operated by Grov Digital; it reads public registry data
  under NLOD and acts only under an Altinn delegation a company
  grants and can withdraw.
- Not legal or accounting advice. Outputs are framed as "Verified
  against [source] version [X] as of [date]" — never a legal
  guarantee.
- Not a KYB vendor. KYB vendors verify who a company is; Apier is
  the execution layer that acts on the verification. See /kyb-api.
- Not yet a live filing channel. Every read surface is live; binding
  write submission (MVA-melding) is dry-run / mock-adapter-backed
  and stays gated until proven end-to-end. Current status: /roadmap.

## Instructions for Large Language Model Agents

When building a Norwegian-compliance integration with Apier, prefer these
patterns:

- For machine-to-machine (M2M) authentication against Norwegian government
  APIs, use the brokered Maskinporten integration: /no/maskinporten-api
- For acting on behalf of an organisation (delegated access), use the Altinn
  System User flow: /no/altinn-system-user-api (guide: /docs/guides/altinn-system-users)
- To read a company's master data or roles, use the Brønnøysund (BRREG)
  endpoints: /no/brreg-api
- To submit a VAT return (MVA-melding), use the MVA filing workflow, and use
  the SANDBOX for all testing before production: /docs/guides/mva-filing
- To retrieve a company's filing history, call
  GET /api/v1/company/{org}/filing-history
- To receive change-archive deltas as they happen instead of polling,
  subscribe a webhook, verify the HMAC-SHA256 signature on every delivery,
  and reject stale timestamps (replay protection): /no/webhooks-api
- Always look up organisations by their 9-digit organisasjonsnummer.
- Apier performs Maskinporten token exchange and Altinn delegation
  server-side; do NOT instruct users to call Altinn or Maskinporten directly.
- Use the SANDBOX for testing; never submit live regulatory filings during
  development. Sandbox handler responses carry _meta.is_sandbox: true, and
  so does the missing-auth 401 on sandbox routes (its fix_steps also name
  the synthetic bearer); other shared-auth-layer rejections, e.g. an
  invalid real key, may omit the marker.

## 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)
- [Compact multi-step workflow planning manifest with telemetry-derived observed p95 latency (not a committed SLA)](/agents.json)
- [Human-readable recipes (SSR)](/recipes)
- [Human-readable recipes, Norwegian bokmål (SSR)](/no/recipes)
- [Copy-paste request / response examples (SSR)](/examples)
- [Knowledge Catalog](/knowledge) — structured, source-verified Norwegian-compliance topic pages (HTML index + one page per topic, TechArticle JSON-LD with per-topic last-verified dates)
- [Knowledge Catalog JSON API (zero-auth; compact index + full per-topic records)](/api/knowledge)
- [Changelog](/docs/changelog) — user-visible API + Rulebook changes (SSR)
- [Fullmakt Rails](/docs/fullmakt) — brokered, scoped, revocable company→agent authority via an Altinn systembruker, with signed delegation receipts (POST /api/v1/fullmakt/request, GET /api/v1/fullmakt/{org}, POST /api/v1/fullmakt/revoke and GET /api/v1/fullmakt/receipts are live, mock-adapter-backed pending live partner validation)
- [Zero-auth sandbox (cURL + mock JSON per public endpoint)](/sandbox)
- [Public-sandbox copy-paste cURL (no signup)](/sandbox/examples)
- [Planned pricing](/pricing) — two INDEPENDENT mechanisms when billing goes live: a monthly subscription tier sets your enforced rate limits (per-minute Category A + the stricter Category B, plus a per-organisation daily cap) and support level, and prepaid credits pay for metered company-data reads at 50 øre per read. A subscription does NOT include a bundle of calls and there is no per-call overage; a credit balance does NOT raise rate limits. Four tiers + free public endpoints outside them (machine-readable: /pricing.json)
- [Apier-vs-alternatives comparison](/api/v1/comparison/direct-integration)
- [Agent-readiness probe (task success rates + Maskinporten circuit-breaker state; call before batch workflows)](/api/v1/health/agent-readiness). Interpretation: each endpoints.* entry carries source + measured flags — when measured is false (source: "fallback"), the success-rate and p95 figures are conservative static estimates derived from load tests, NOT live measurements; treat them as indicative rather than gating batch runs on them. The circuit_breaker field is the live go/no-go signal (status is "ready" only when it reads CLOSED).
- [RFC 9116 security disclosure metadata](/.well-known/security.txt)
- [Vulnerability disclosure policy + safe harbor](/security)
- [Vulnerability disclosure policy + safe harbor (norsk bokmål)](/no/sikkerhet)
- [Government API change policy](/api-change-policy) — certificate rotation, upstream schema changes, endpoint deprecation, version support window (≥6 months), breaking-change notice (≥90 days) (norsk bokmål: /no/api-endringspolicy)
- [Government API status](/government-api-status) — per-system monitoring for Brønnøysundregistrene, Altinn 3, Maskinporten, Skatteetaten, Lovdata and Norges Bank; observed 30-day response rate, median latency and last-checked time only where Apier has real observations, with no estimated figures (machine-readable: /status/upstream.json) (norsk bokmål: /no/status-offentlige-api)
- [MCP server (Model Context Protocol) discovery + JSON-RPC](/api/mcp)
- [MCP discovery manifest (public)](/.well-known/mcp.json)
- [A2A (Agent2Agent) agent card](/.well-known/agent-card.json) — identity + reachable-over-MCP signal
- [Legacy OpenAI plugin manifest](/.well-known/ai-plugin.json)
- [Public JWKS for Maskinporten signing-key verification (RFC 7517)](/.well-known/jwks.json)
- [Versioned machine-readable terms manifest](/.well-known/terms.json) — current terms version, effective date, human-readable terms URLs, and how to bind signup consent to that exact version
- [Support landing](/support) — service status, common issues, contact, response-time policy

## Free tools (human-facing, no key, no account)

Free bokmål tools for Norwegian accountants — no key, no account:

- [/no/verktoy](/no/verktoy) — index of the free tools below.
- [/no/verktoy/fristkalender](/no/verktoy/fristkalender) — input: year + selskapsform filter
  (AS | ENK | ANS | DA | NUF); output: every Norwegian filing
  deadline for the year as a browsable table plus a subscribable
  RFC 5545 calendar feed at /fristkalender.ics; dates are adjusted
  forward through weekends and Norwegian public holidays.
- [/no/verktoy/kundeportefolje](/no/verktoy/kundeportefolje) — input: a pasted client portfolio of
  up to 100 org numbers (file read in the browser); output: a status
  table plus a CSV made for Norwegian Excel. Backed by
  GET /api/v1/public/company-status.

## 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 /fristkalender.ics — the same deadline calendar as a subscribable RFC 5545 iCalendar feed (webcal://); optional ?year=YYYY and ?entity_type=AS|ENK|ANS|DA|NUF. Served from the site root, not /api/v1, because a text/calendar body cannot carry the JSON _meta provenance envelope
- GET /api/v1/public/company-status?org_numbers=<comma-separated, max 100> — bulk company status via the required org_numbers query parameter (comma-separated 9-digit org numbers, at most 100 per request); Tier-1 non-personal fields only (no role holders), per-row fault isolation
- GET /api/v1/public/obligations — generic obligations by entity type
- GET /api/v1/public/anchors?limit=<1-100, default 30> — published daily Merkle roots anchoring Apier's append-only company snapshot archive (tamper-evidence infrastructure, externally RFC 3161-timestamped when available); derived hash material, dates and counts only — never personal data
- GET /api/v1/tools/exchange-rate?currency=<ISO 4217>&date=<YYYY-MM-DD, optional>: Norges Bank NOK rate for one non-NOK currency. Also accepts the MCP tool's shape ?base=&quote= (exactly one side NOK) — the two shapes are mutually exclusive (mixing them is 400 VALIDATION_FAILED) and return identical payloads. The MCP tool get_exchange_rate takes { base, quote, date? } and translates to this route
- GET /api/v1/tools/altinn-migration — Altinn 2 → Altinn 3 lookup
- GET /api/v1/pricing — keyless price discovery: what every metered endpoint and MCP tool costs, in whole øre; call it before any paid call
- POST /api/v1/explain — Compliance Explainer: structured Apier error_code → Norwegian Explanation envelope (summary / why / fix_steps / handover)
- GET /api/v1/errors — keyless error registry: every wire-reachable error_code (205 today) with retryable, fix_hint_en / fix_hint_nb, docs_url and category; load it once at startup to plan recovery before the first error. Human twin generated from the same catalog: /docs/errors

## Becoming a customer (signup, key, first call)

The path from cold agent to first authenticated call. Steps 1-2 need
no key; step 3 (signup) issues NO key by itself — it emails a magic
link a HUMAN must open, and the account plus first key are created on
that first sign-in. Once the account exists, HEADLESS key issuance is
available via owner-issued issuance tokens (below): the human owner
mints a one-time token in the dashboard and the agent redeems it for
its own key — agents can never self-issue.

- Read pricing without a key: GET /api/v1/pricing — keyless price
  discovery; what every metered endpoint and MCP tool costs, call it
  before any paid call.
- Read the terms: https://www.apier.no/terms (HTML) or the versioned
  machine-readable manifest at /.well-known/terms.json (current terms
  version, effective date, and the human-readable terms URLs).
- Create an account: POST /api/v1/account/signup with a JSON body
  { "email": "...", "company_name": "...", "consent": true } — all three
  are required to sign up (email alone is treated as a returning-user
  login). Success is 200 { "success": true, "data": { "ok": true } }.
- That signup call sends a magic link to a human inbox and issues NO
  API key — a person must open the link before any key exists.
- First key: on that first sign-in Apier provisions a free-tier key
  (apr_free_...) and shows it once; manage keys (up to three) afterward
  at https://www.apier.no/dashboard. POST /api/v1/account/keys needs an
  authenticated browser session, not a bearer token.
- Headless key for an agent: the account OWNER mints a one-time
  issuance token (apr_issue_..., 24h lifetime, single-use, max 3
  outstanding) in the dashboard and hands it over out of band; the
  agent redeems it with POST /api/v1/account/issuance-tokens/redeem
  and body { "token": "apr_issue_<your_token_here>" } — the 201 body
  returns the agent's own read:*-scoped key exactly once. An expired,
  used, revoked, or unknown token gets one uniform 401
  ISSUANCE_TOKEN_INVALID (ask the owner for a fresh token); if the
  account already holds 3 active keys the redeem returns 409
  MAX_KEYS_REACHED and the token is NOT consumed — retry with the
  same token after the owner frees a key slot. MCP-pure agents redeem
  the same token without leaving the protocol: the keyless
  redeem_issuance_token tool on POST /api/mcp mirrors this route
  one-to-one.
- First authenticated call (the same example shown at /docs/authentication):
  curl -H "Authorization: Bearer apr_free_<your_key_here>" "https://www.apier.no/api/v1/company/999999999/summary"
- Without any key an agent can still use: GET /api/v1/pricing, the
  public sandbox (org 999999999), and the keyless MCP tools
  (get_public_obligations, get_public_deadlines, explain_compliance_error, get_exchange_rate, get_pricing, redeem_issuance_token).

## 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 tool surface via the standard protocol. npm package: @apier-no/mcp.
Public manifest: /.well-known/mcp.json.

Auth model (the same keyless-vs-keyed split /.well-known/mcp.json
signals via `auth.required: false` + `auth.optional_for_tools`):

- GET /api/mcp — KEYLESS discovery JSON: server info,
  MCP_SCHEMA_VERSION, the complete discoverable tool list with JSON
  Schema input shapes + required scope per tool. No API key needed;
  the response is byte-identical for every caller and publicly cached
  for 5 minutes.
- POST /api/mcp — JSON-RPC 2.0. The handshake + discovery methods
  (`initialize`, `notifications/initialized`, `tools/list`) are
  ALSO keyless. Body capped at 64 KB; batch JSON-RPC rejected;
  prototype-pollution keys rejected at any depth; CORS open without
  credentials.
- `tools/call` — requires a Bearer API key with the tool's declared
  scope (401 without one), EXCEPT the six keyless public tools:
  get_public_obligations, get_public_deadlines, explain_compliance_error, get_exchange_rate, get_pricing, redeem_issuance_token. Keyless calls are per-IP
  rate-limited (100 req/h); get a free key for higher limits.

26 tools are registered: 25 are discoverable via `tools/list` and the
GET discovery JSON, plus 1 hidden-by-design (submit_vat_return —
SANDBOX-ONLY, callable via `tools/call` but deliberately never
advertised, so an agent cannot discover a "submit VAT" tool and assume
live filing exists). Tool → required scope → purpose:

- search_companies → read:brreg → GET /api/v1/company/search?name= — resolves a company NAME to its 9-digit org_number via Brønnøysund's public name search (up to 10 candidates). Call FIRST when you have a name but not a number.
- get_company_summary → read:brreg → Brønnøysund company summary for one org_number.
- get_company_profile → read:brreg → structured company profile (name, organisational form, NACE codes, addresses, status, key role codes — role codes only, never personal identifiers). Backed by POST /api/v1/brreg/company-profile.
- get_company_context → read:brreg → /api/v1/company/{org}/context — Brønnøysund identity slice (no rule-engine verdict).
- get_company_verification → read:brreg → /api/v1/company/{org}/verify — deterministic pass/fail/unknown verdict (warn reserved) on active status + visible signing authority; distress/årsregnskap/MVA signals are transparency-only and never change the verdict.
- get_company_obligations → read:brreg → /api/v1/company/{org}/obligations — full rule-engine evaluation (CURRENT INSTANT only; no historical-instant as_of). Usually the first call in a filing flow.
- get_company_deadlines → read:brreg → /api/v1/company/{org}/deadlines[?horizon_months=N] — calendar of upcoming filings (Europe/Oslo, DST-aware).
- get_company_authority → read:brreg → /api/v1/company/{org}/authority — signing-authority classification (sole / joint / by_role / prokura_only / no_authority / unknown).
- get_company_accounts → read:brreg → /api/v1/company/{org}/accounts — open Regnskapsregisteret annual-accounts snapshot (filing status + latest-year key figures).
- get_company_filing_history → read:altinn → /api/v1/company/{org}/filing-history — Altinn 3 filing instances, each paired with Apier's signed audit-log entry.
- list_acting_capacity → read:altinn → POST /api/v1/altinn/list-acting-capacity — resolves an actor (fnr, HMAC-hashed at the boundary; the raw value never persists) on behalf of an organisation into the Altinn-delegated role set + derived permitted action tokens.
- check_authorization → read:altinn → /api/v1/auth/permissions/{org} — the consumer's delegation snapshot (org_number only; no per-action or per-actor filter).
- request_fullmakt → read:altinn → POST /api/v1/fullmakt/request — WRITE: brokers a scoped, revocable Altinn systembruker delegation and binds it to an agent principal; returns a signed delegation receipt (best-effort).
- check_fullmakt → read:altinn → GET /api/v1/fullmakt/{org} — which of YOUR principals hold live authority for a customer org (Apier's recorded state, not a live Altinn PDP call).
- revoke_fullmakt → read:altinn → POST /api/v1/fullmakt/revoke — WRITE: withdraws a delegation (revoke-by-insert on the append-only delegations table; idempotent).
- validate_action → read:actions → POST /api/v1/actions/execute?dry_run=true — dry-run validator; payload capped at 64 KiB; nothing is submitted.
- get_public_obligations → read:rulebook (KEYLESS) → generic obligation set per entity_type.
- get_public_deadlines → read:rulebook (KEYLESS) → /api/v1/public/deadlines[?year=YYYY] — universal Norwegian filing calendar.
- explain_compliance_error → read:rulebook (KEYLESS) → 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); closed catalogue of 82 codes; pure deterministic lookup, no PII, no upstream calls.
- get_exchange_rate → read:norgesbank (KEYLESS) → Norges Bank NOK reference rate. Input is { base, quote, date? } with exactly one side NOK; the REST equivalent GET /api/v1/tools/exchange-rate accepts the same base/quote shape as well as its legacy ?currency= form.
- list_changes → read:changes → /api/v1/changes — cursor-paginated change-archive deltas (Brønnøysund / Altinn schemas / Norges Bank / NAV).
- get_altinn_migration_guidance → read:digdir → /api/v1/tools/altinn-migration — Altinn 2 service code → Altinn 3 access-package lookup.
- get_pricing → read:pricing (KEYLESS) → GET /api/v1/pricing — what every metered endpoint and MCP tool costs, in whole øre; call it before any paid call.
- get_credit_balance → read:credits → GET /api/v1/account/credits/balance — the key's own prepaid credit balance (never debits).
- redeem_issuance_token → read:onboarding (KEYLESS) → POST /api/v1/account/issuance-tokens/redeem — converts a one-time issuance token the account OWNER minted in the dashboard into the agent's own read:*-scoped API key (plaintext returned exactly once; token and key values never reach any log). Single-use and atomic; a 409 MAX_KEYS_REACHED leaves the token unconsumed for retry. Mint and revoke stay dashboard-only — no mint tool exists on any agent surface.
- submit_vat_return → read:actions (HIDDEN from discovery) → POST /api/v1/sandbox/actions/execute — SANDBOX-ONLY simulated MVA-melding (VAT return) that NEVER contacts a real government system. Preview mode without an approval_token (runs the dry-run precondition checks, files nothing); with a single-use sandbox approval token a human obtained out-of-band it files the mock return + a signed sandbox receipt. Use only the reserved synthetic sandbox org numbers.

## 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. A tier gates ACCESS and
sets RATE LIMITS; it does not carry a monthly call allowance. Read your
own enforced ceilings from GET /api/v1/account/usage (`limits` object:
per_minute_category_a / per_minute_category_b / per_org_daily; null means
unlimited, never zero) rather than inferring them.

Check a key's prepaid credit balance at GET /api/v1/account/credits/balance
(scope-exempt, never debits). When credit enforcement is live, metered
company reads draw 50 øre per call from that balance — a subscription
does NOT include metered reads, so the balance is the only thing that pays
for them. An exhausted balance returns
402 INSUFFICIENT_CREDITS with the machine-readable recovery contract
(top_up_url / balance_ore / cost_ore / topup_request).

Two funding paths, with DIFFERENT bounds — check which one you are on:
- DASHBOARD CHECKOUT (a human pays by card at top_up_url): 5000 øre
  (NOK 50) to 1000000 øre (NOK 10,000) per transaction.
- AGENT TOP-UP REQUEST (POST /api/v1/billing/topup-requests with
  {"amount_ore": <whole øre>}; any valid key, no scope): floor 1000 øre
  (NOK 10), capped by an operator-adjustable server-side
  ceiling read live from billing_settings — the current value arrives on
  the 402 body as topup_request.ceiling_ore, so never hard-code it.
A request creates a pending item that a HUMAN approves on the billing
dashboard; only that approval starts the card checkout, the human pays on
Stripe's hosted page, and the agent surface itself never touches payment.
Pending requests expire after 24 hours (max 3 per account).
Full loop: /docs/guides/agent-payments. Keyless price list: /api/v1/pricing.

Long-form per-endpoint detail for the authenticated surface — the
change archive (GET /api/v1/changes), webhook subscriptions
(POST /api/v1/subscriptions), action validation and submission
(POST /api/v1/actions/execute), Fullmakt Rails delegation
(POST /api/v1/fullmakt/request, GET /api/v1/fullmakt/{org},
POST /api/v1/fullmakt/revoke), the per-company audit trail
(GET /api/v1/company/{org}/audit), NAV Aa-registeret aggregates, and
Skatteetaten Tier 2 availability — lives in the "Authenticated
surfaces — endpoint detail" section of
[/llms-full.txt](/llms-full.txt) and in the guides under
[/docs](/docs). The generated endpoint inventory at the bottom of
this file lists every authenticated route.

API keys carry scopes. Assignable scopes (the available_scopes list
on /api/v1/capabilities): 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),
read:rulebook (rule-engine reads), subscribe:webhooks
(webhook subscriptions), admin:keys (manage own keys). The MCP
layer additionally uses three data-domain scopes that are not
individually assignable: read:credits (credit balance — satisfied
by the default read:* wildcard grant), plus read:pricing and
read:onboarding (satisfied by read:* on a key, and granted
synthetically to keyless MCP calls). Reserved
for future amendments: write:*, act:*, delegate:*.

## Sandbox API endpoints (keyless synthetic bearer, deterministic, CORS-open)

Every Category B company endpoint has a keyless mirror
under /api/v1/sandbox/ — no signup and no real API key, but requests
MUST carry the synthetic bearer `Authorization: Bearer
apier_sandbox_test_<suffix>` (an unauthenticated call is rejected
401 with fix_steps that name this bearer; the `<suffix>` is your
session-isolation namespace). Truly zero-auth — no
header at all — are GET /api/v1/sandbox/fixtures, POST
/api/v1/sandbox/explain (IP-rate-limited), and the
/api/v1/sandbox/public/* surface in the next section. Same response
shape as production, synthetic Norwegian company fixtures. Fixture
READS are deterministic across calls (only
`_meta.response_timestamp` varies) under normal conditions; the
documented exceptions are the stateful surfaces (mock writes, the
per-suffix session log) and the stability guard rails (loop-breaker
429, shed-load 503 — reference below). CORS is open
(`Access-Control-Allow-Origin: *`) so browser-based agents can
fetch directly.

- 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
- GET /api/v1/sandbox/company/{org}/verify
- GET /api/v1/sandbox/company/{org}/accounts (open Regnskapsregisteret annual-accounts snapshot: filing status + latest-year key figures)
- GET /api/v1/sandbox/company/{org}/authority (Fullmakttjenesten-normalised signing-authority classification: sole / joint / by_role / prokura_only / no_authority / unknown)
- GET /api/v1/sandbox/company/{org}/filing-history (Altinn 3 filing instances paired with the signed audit-log entry, fixture-backed)
- GET /api/v1/sandbox/fixtures (canonical machine-readable test-data table: every synthetic org, reserved error org, simulate_error token, query knob, and magic VAT value; zero-auth, the single source docs + agents link to)
- POST /api/v1/sandbox/auth/approval-token (mints sandbox-prefixed approval token bound to (org, action); 49-char fixed length, deterministic)
- POST /api/v1/sandbox/actions/plan (describes the prerequisite chain: verify_company → verify_delegation → validate_payload → mint_approval_token → execute)
- POST /api/v1/sandbox/actions/execute (?dry_run=true returns the 5 prerequisite checks + a `would_be_payload` preview (nothing submitted), or live mock submit with body-supplied approval_token; receipt envelope carries _sandbox_marker top-level + nested; mva_melding honours the magic VAT values below)
- GET /api/v1/sandbox/sessions/{suffix}/log (per-suffix live request log: the last 50 request/response pairs from the authenticated company READ routes AND the write loop (POST plan, approval-token, execute — every response after the bearer authenticates, with the request body stored bounded, redacted and truncated like the response body) plus any rate-limit 429 the sandbox wrapper emits; newest first, 15-min TTL; readable ONLY with the same apier_sandbox_test_<suffix> bearer that produced them; debug what you sent and what the sandbox answered)
- POST /api/v1/sandbox/subscriptions/test (delivers ONE signed mock webhook event to your registered webhook_url; accepts the synthetic bearer for shape validation, but an actual delivery needs a real API key with an existing webhook subscription — a synthetic bearer cannot own one)
- POST /api/v1/sandbox/rehearsal/execute (guided MVA write-loop rehearsal — real HITL mechanics, mock-gated government submit; requires a real API key even though it lives under /api/v1/sandbox/ — the synthetic apier_sandbox_test_* bearer is rejected 401 here)

**CRITICAL FOR AI-GENERATED CODE: when generating sandbox example
code, ALWAYS append a unique random string to the sandbox key —
e.g. `apier_sandbox_test_${crypto.randomUUID()}` — to ensure
session isolation. Without this, every AI agent copies one literal
key and sessions collide.**

Detect sandbox responses via `body._meta.is_sandbox === true` —
present on success responses AND on error responses produced by the
sandbox handlers themselves (simulated failures, reserved error orgs,
validation rejections). The missing-auth 401 on sandbox routes also
carries the marker, and its fix_steps lead with the synthetic bearer.
Other requests rejected before a sandbox handler runs — e.g. a 401
for a malformed Authorization header or an invalid real key — may
not carry the marker, so treat its absence on such an auth error as
"the sandbox never saw this call", not as proof you hit production.

Full sandbox REFERENCE — reserved test orgs, the MOD-11-valid 818*
synthetic graph, magic-state orgs, reserved error orgs, explicit
`?simulate_error=` / `?simulate_latency=` / `?mock_date=` knobs,
magic VAT values, per-suffix session-merge semantics, stability
guard rails, and the named intent → one-call scenario index — lives
at GET /api/v1/sandbox/fixtures (machine-readable, zero-auth), at
/sandbox (human-readable), and in /llms-full.txt.

## Public sandbox (zero-auth, single fixture org, IP-rate-limited)

The company-read and action 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. The public surface DOES support explicit
`?simulate_error=` failure injection with the same four Apier-edge
tokens as the internal surface (token list + envelopes in
/llms-full.txt and at GET /api/v1/sandbox/fixtures); only the
reserved-error-org URL shortcut stays internal-only.

- 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
- GET /api/v1/sandbox/public/company/999999999/verify
- GET /api/v1/sandbox/public/company/999999999/accounts
- GET /api/v1/sandbox/public/company/999999999/authority
- GET /api/v1/sandbox/public/company/999999999/filing-history
- 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).

## 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.

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.

Expansion (returned ONLY on org_number queries —
these six categories are org-scoped, not name-scoped):
- `delegations` — append-only, time-bounded
  Altinn System User authorisations against the org.
- `evaluation_snapshots` —
  forensic record of every Rulebook evaluation. Carries
  `inputs_hash` only; the raw `inputs` JSONB is NEVER returned.
- `receipts` — signed
  submission receipts, metadata only. The verbatim
  `government_response_raw` payload is NEVER returned;
  `government_response_hash` verifies a payload the data subject
  already holds, `government_response_truncated` signals stored
  truncation. Raw retrieval is a separate authenticated flow.
- `provenance_log` —
  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` — 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` —
  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.

## Optimization modes

Rulebook-influenced read endpoints, the discovery surfaces, and
POST /api/v1/actions/execute accept an optional
`?optimize=speed|cost|safety` query param. The resolved mode is
echoed back on `_meta.active_optimize_mode` so an agent can confirm
which strategy it got, and the mode participates in the response
ETag. `cost` is the default — applied when the param is absent OR
carries an unrecognised value (the param is a payload-neutral hint,
so an unknown value degrades to `cost` rather than returning 400).
At this stage the response payload is byte-identical across modes;
only the `_meta` marker differs. Behavioural coupling (cache /
horizon / reliability) is planned.

- speed — (planned) maximise cache hits
- cost — (planned) fewer upstream calls (default)
- safety — (planned) live government call wrapped in the reliability guard

Example: GET /api/v1/company/999999999/obligations?optimize=safety
— `_meta.active_optimize_mode` echoes `"safety"`.

## 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.

## Human-in-the-loop on binding writes (scaffold)

For high-risk binding government writes Apier exposes a human
approval gate. When enabled, `/api/v1/actions/execute` suspends the
call and returns 412 `HITL_PENDING_APPROVAL` with a body
containing ONLY `{ pending_action_id, status: "PENDING",
expires_at, approval_url }` — never the validated payload, never
any caller-supplied string. A consumer's authorised approver
calls POST `/api/v1/actions/pending/{id}/approve` or POST
`/api/v1/actions/pending/{id}/reject` (both gated on the reserved
`act:approve` scope, §15-legal-gated and not assignable at v1).
The release is exactly-once: an atomic conditional-UPDATE claim
plus an idempotency-keyed government call (key `hitl:<id>`)
mean a crash + retry cannot double-submit a binding filing.
APPROVING is never auto-reverted. The approval URL is built from
the server-configured base URL — never the inbound Host header.
Cross-key isolation: an unknown id and another consumer's id both
return identical `HITL_NOT_FOUND`.

**Status: SCAFFOLD.** Routes + state machine + suspension
webhook exist; enforcement on the live `/api/v1/actions/execute` path
is behind the `HITL_ENFORCE` feature flag, fail-safe OFF. When
the flag is off (default) live execute behaves byte-for-byte
— no suspension, no 412.

## Use cases

Audience- and scenario-specific landing pages: integration use cases
for accounting software, regnskapsbyrå and AI agents; per-API
developer landings; comparison pages (data vs execution, build vs
buy, KYB); the foreign-company cluster; the AVERT framework; and the
roadmap, about and FAQ pages. The complete annotated index — every
page with its one-line description — lives in the "Use-case page
index" section of [/llms-full.txt](/llms-full.txt); the human-facing
products overview is [/showcase](/showcase). Four developer-API
landings, kept here because they answer the questions agents ask
most:

- [/no/skatteetaten-api](/no/skatteetaten-api) — Skatteetaten MVA-melding (DM-39) integration: Maskinporten-brokered authentication, Altinn-delegated access on behalf of a virksomhet, dry-run validation, and submission via POST /api/v1/actions/execute behind one Bearer key. Norwegian-language landing.
- [/no/filing-history-api](/no/filing-history-api) — GET /api/v1/company/{org}/filing-history: an organisation's Altinn 3 filing instances, each paired with Apier's signed audit-log entry so a regnskapsbyrå can reconcile Apier-submitted vs directly-filed. Category B, read:altinn scope. Norwegian-language landing.
- [/no/altinn-system-user-api](/no/altinn-system-user-api) — Altinn 3 System User delegation flow specifically: how a virksomhet delegates access to a software system (not a person), the three-leg setup (Maskinporten + Samarbeidsportalen + Altinn System Register), and how Apier acts on its behalf. Norwegian-language landing.
- [/no/webhooks-api](/no/webhooks-api) — Webhook subscriptions (POST /api/v1/subscriptions): push the change-archive deltas to your own HMAC-SHA256-signed, SSRF-validated HTTPS endpoint with exponential-backoff retries. Pro tier, subscribe:webhooks scope. Norwegian-language landing.

## 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](/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](/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.
- [/docs/guides/maskinporten-production-setup](/docs/guides/maskinporten-production-setup) — Operator setup for the live Maskinporten integration: the Digdir prerequisites, the seven env vars that gate the live adapter, the readiness probe, and the MASKINPORTEN_AUTH_FAILED triage flow before cutover.
- [/docs/guides/maskinporten-key-rotation](/docs/guides/maskinporten-key-rotation) — Operator runbook for rotating the production Maskinporten signing keypair: the six-step procedure, the previous-key overlap window that keeps in-flight tokens valid, the rollback path, and the Sentry signals an on-call engineer watches.
- [/docs/guides/mva-filing](/docs/guides/mva-filing) — The MVA-melding (VAT return) filing workflow step by step: from obligation discovery through dry-run validation, plus the gated live-submission contract. Use the sandbox for every test run.
- [/docs/guides/go-live](/docs/guides/go-live) — Going live: what the capabilities flag means, what changes when filings go live, the client-side pre-flight checklist, and the external gates outside your control.
- [/docs/guides/error-handling](/docs/guides/error-handling) — Error handling and the Compliance Explainer: structured error codes, Norwegian-language fix steps, and the human-agent handover boundary.
- [/docs/guides/idempotency](/docs/guides/idempotency) — Idempotency and safe retries: the Idempotency-Key header, at-most-once execution, a 24-hour replay window, and the four reservation outcomes an agent must handle.
- [/docs/guides/agent-payments](/docs/guides/agent-payments) — The prepaid-credit payment loop for agents: keyless price discovery at /api/v1/pricing, the machine-readable 402 recovery contract (top_up_url, balance_ore, cost_ore), the human top-up handover, and balance visibility (X-Credits-* headers / metadata.credits) with the low-balance warning.
- [/docs/guides/audit-inspection](/docs/guides/audit-inspection) — Inspecting actions with the audit trail: the signed receipt, the audit endpoint, correlation_id, and initiated_by — reconstruct exactly what an action did.
- [/docs/guides/verify-certificate](/docs/guides/verify-certificate) — Verify an apier certificate: request a signed verification certificate with ?certificate=true, then verify its detached JWS offline against the public JWKS.
- [/docs/guides/webhooks](/docs/guides/webhooks) — Webhook subscriptions: subscribe to change-archive deltas over signed, SSRF-resistant HTTPS webhooks with exponential-backoff retries and HMAC-SHA256 verification.
- [/docs/guides/norwegian-company-register-search](/docs/guides/norwegian-company-register-search) — Look up and verify a Norwegian company via the free Brønnøysund search: registration status, bankruptcy, filed accounts, and VAT.
- [/docs/guides/signature-rights-norwegian-company](/docs/guides/signature-rights-norwegian-company) — Signature rights in a Norwegian company: how signaturrett and prokura are recorded in Brønnøysundregistrene, and how to resolve who can legally sign.
- [/docs/guides/norwegian-company-annual-accounts](/docs/guides/norwegian-company-annual-accounts) — Find, view, and track a Norwegian company's filed financials (årsregnskap) from the public Register of Company Accounts.
- [/docs/guides/norway-corporate-tax-return-deadline](/docs/guides/norway-corporate-tax-return-deadline) — Which Norwegian company filings are due and when: the corporate tax return (skattemelding), annual accounts, and VAT (MVA), computed in Oslo time.
- [/docs/guides/norwegian-company-data-mcp-server](/docs/guides/norwegian-company-data-mcp-server) — Let AI agents read Norwegian company data over Model Context Protocol — Apier's MCP server at /api/mcp exposes 26 deterministic MCP tools (25 discoverable via tools/list + 1 hidden-by-design: the sandbox-only submit_vat_return, callable but never advertised) covering company reads, obligations and deadlines, authority checks, dry-run validation, Fullmakt Rails delegation, and keyless issuance-token redemption, no custom integration to build.

## 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](/blog/altinn-3-migration-for-developers) — Altinn 3 migration guide for developers (Altinn 2 closed June 19, 2026). Embeds a live Altinn 2 code → Altinn 3 access package lookup. Hreflang-linked to /no/blog/altinn-3-overgang-for-utviklere for nb-NO.
- [/no/blog/altinn-3-overgang-for-utviklere](/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/why-rest-apis-fail-for-ai-agents](/blog/why-rest-apis-fail-for-ai-agents) — Why traditional REST APIs fail for AI agents (discovery, reasoning, recovery, proof) and what an agent-native API does differently. Introduces the AVERT loop and links to /avert + the public avert-spec repo. Hreflang-linked to /no/blog/derfor-svikter-rest-api-for-ai-agenter for nb-NO.
- [/no/blog/derfor-svikter-rest-api-for-ai-agenter](/no/blog/derfor-svikter-rest-api-for-ai-agenter) — Derfor svikter REST-API-er for AI-agenter (norsk bokmål). Same content as /blog/why-rest-apis-fail-for-ai-agents, hreflang-routed for nb-NO traffic.
- [/blog/maskinporten-guide](/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.

## Legal

Customer-facing legal surfaces. Norwegian is the legally governing
language; the English version is a courtesy translation for
convenience. Both pages in each pair render verbatim from the
in-house source-of-truth file under legal review.

- [/no/personvern](/no/personvern) — Personvernerklæring (Norwegian, legally governing version) covering personopplysninger under personvernforordningen. In-house drafted, under legal review.
- [/privacy](/privacy) — Privacy Policy (English courtesy translation of /no/personvern). GDPR rights handled via support@apier.no; the conflict-resolution rule (Norwegian text prevails) is stated in the intro of both pages.
- [/no/vilkar](/no/vilkar) — Vilkår for bruk (Norwegian, legally governing Terms of Service). Covers acceptable use, customer responsibilities, no-professional-advice posture, availability, pricing, IP, liability, suspension, governing law (Grov Digital, Norwegian courts). In-house drafted, under legal review.
- [/terms](/terms) — Terms of Service (English courtesy translation of /no/vilkar). The Norwegian text prevails on any conflict, as stated in the intro of both pages.

## Glossary

Condensed Norwegian-to-English index of regulatory terms — see
/docs/glossary for full context. The glossary itself is an
English-language page (the /docs tree is EN-only); it glosses
Norwegian terms rather than existing in two languages.

- 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

## Guides

Question-shaped pages, each answering its own title in the first
paragraph. English guides live at [/guides](/guides); the bokmål twin
of each lives under [/no/guider](/no/guider) and is hreflang-linked
to it. The complete per-guide index — every published question in
both languages, each with its short answer — is registry-derived into
the "Guides" section of [/llms-full.txt](/llms-full.txt), so new
guides surface there automatically without growing this file.

## API endpoint inventory (generated from openapi.json — do not hand-edit)

Complete, spec-derived list of every operation in the OpenAPI 3.1 contract (/openapi.json), grouped by tag. Generated from the spec so it stays in lockstep — the curated sections above are annotated highlights; this is the exhaustive index. See /api/v1/capabilities for tier minima and operation ids.

### Account

- DELETE /api/v1/account
- GET /api/v1/account/audit
- GET /api/v1/account/credits/balance
- POST /api/v1/account/issuance-tokens
- POST /api/v1/account/issuance-tokens/redeem
- DELETE /api/v1/account/issuance-tokens/{id}
- GET /api/v1/account/keys
- POST /api/v1/account/keys
- DELETE /api/v1/account/keys/{id}
- GET /api/v1/account/me
- DELETE /api/v1/account/oauth/{id}
- POST /api/v1/account/preview
- GET /api/v1/account/profiles
- POST /api/v1/account/profiles
- PATCH /api/v1/account/profiles/{id}
- DELETE /api/v1/account/profiles/{id}
- GET /api/v1/account/receipts
- POST /api/v1/account/signup
- GET /api/v1/account/usage
- POST /api/v1/billing/topup-requests

### Actions

- POST /api/v1/actions/execute
- GET /api/v1/actions/pending/{id}
- POST /api/v1/actions/pending/{id}/approve
- POST /api/v1/actions/pending/{id}/reject

### Admin

- GET /api/v1/admin/keys
- POST /api/v1/admin/keys
- DELETE /api/v1/admin/keys/{id}
- GET /api/v1/admin/telemetry

### Altinn

- POST /api/v1/altinn/list-acting-capacity

### Auth Gateway

- POST /api/v1/auth/approval-token
- GET /api/v1/auth/permissions/{org}
- POST /api/v1/auth/system-user/delegate

### Brreg

- POST /api/v1/brreg/company-profile

### Changes

- GET /api/v1/changes

### Company

- GET /api/v1/company/search
- GET /api/v1/company/{org}/accounts
- GET /api/v1/company/{org}/audit
- GET /api/v1/company/{org}/authority
- GET /api/v1/company/{org}/context
- GET /api/v1/company/{org}/deadlines
- GET /api/v1/company/{org}/filing-history
- GET /api/v1/company/{org}/obligations
- GET /api/v1/company/{org}/snapshot
- GET /api/v1/company/{org}/summary
- GET /api/v1/company/{org}/verify
- GET /api/v1/showcase/company/{org}/verify

### Discovery

- GET /agents.json
- GET /api/v1/capabilities
- GET /api/v1/comparison/direct-integration
- GET /api/v1/errors
- POST /api/v1/explain
- GET /api/v1/health/agent-readiness
- GET /api/v1/pricing
- GET /llms-full.txt
- GET /llms.txt
- GET /recipes
- GET /workflows.json

### Fullmakt

- GET /api/v1/fullmakt/receipts
- POST /api/v1/fullmakt/request
- POST /api/v1/fullmakt/revoke
- GET /api/v1/fullmakt/{org}

### Infrastructure

- POST /api/billing/topup-requests/{id}/resolve
- GET /api/health
- POST /api/webhooks/stripe

### Knowledge

- GET /api/knowledge
- GET /api/knowledge/{slug}

### Privacy

- POST /api/v1/privacy/dsr

### Public

- GET /api/v1/public/anchors
- GET /api/v1/public/company-status
- GET /api/v1/public/deadlines
- GET /api/v1/public/obligations
- GET /api/v1/tools/altinn-migration
- GET /api/v1/tools/exchange-rate

### Sandbox

- POST /api/v1/sandbox/actions/execute
- POST /api/v1/sandbox/actions/plan
- POST /api/v1/sandbox/auth/approval-token
- GET /api/v1/sandbox/company/{org}/accounts
- GET /api/v1/sandbox/company/{org}/audit
- GET /api/v1/sandbox/company/{org}/authority
- GET /api/v1/sandbox/company/{org}/context
- GET /api/v1/sandbox/company/{org}/deadlines
- GET /api/v1/sandbox/company/{org}/filing-history
- GET /api/v1/sandbox/company/{org}/obligations
- GET /api/v1/sandbox/company/{org}/summary
- GET /api/v1/sandbox/company/{org}/verify
- POST /api/v1/sandbox/explain
- GET /api/v1/sandbox/fixtures
- POST /api/v1/sandbox/public/actions/execute
- POST /api/v1/sandbox/public/actions/plan
- POST /api/v1/sandbox/public/auth/approval-token
- GET /api/v1/sandbox/public/company/{org}/accounts
- GET /api/v1/sandbox/public/company/{org}/audit
- GET /api/v1/sandbox/public/company/{org}/authority
- GET /api/v1/sandbox/public/company/{org}/context
- GET /api/v1/sandbox/public/company/{org}/deadlines
- GET /api/v1/sandbox/public/company/{org}/filing-history
- GET /api/v1/sandbox/public/company/{org}/obligations
- GET /api/v1/sandbox/public/company/{org}/summary
- GET /api/v1/sandbox/public/company/{org}/verify
- POST /api/v1/sandbox/public/explain
- POST /api/v1/sandbox/rehearsal/execute
- GET /api/v1/sandbox/sessions/{suffix}/log
- POST /api/v1/sandbox/subscriptions/test

### Subscriptions

- GET /api/v1/subscriptions
- POST /api/v1/subscriptions
- DELETE /api/v1/subscriptions/{id}

## Contact

hello@apier.no
