Skip to content
Apier

Knowledge Catalog

MVA (VAT) filing workflow

MVA (merverdiavgift, Norwegian VAT) filing through Apier runs in four steps: discover the company's MVA obligation, dry-run the submission to validate the payload without submitting, mint a single-use human-approved token, and submit. Obligation discovery and dry-run validation are available today; live submission is gated pending Maskinporten production validation and Altinn scope approval.

Jurisdiction: Norway · Verified against Skatteetaten as of 2026-05-25

Periods are terminer, not quarters

The MVA period identifier uses Norwegian MVA terminer in the form YYYY-Tn with n from 1 to 6 (e.g. 2026-T1) — six two-month terms per year, not calendar quarters.

Step 1 — discover the obligation

GET /api/v1/company/{org}/obligations returns the company's obligations; the MVA obligation's obligation_id identifies the MVA filing rule, alongside its evaluation_result and deadline. An evaluation_result of insufficient_data means the company has not delegated Altinn access to Apier — turnover-dependent MVA rules cannot be evaluated until it does.

Step 2 — dry-run the submission

Always dry-run first: POST /api/v1/actions/execute?dry_run=true with action_type mva_melding validates the payload against the action's preflight checks without submitting anything. A successful dry-run returns HTTP 200 with an outcome object; outcome.all_passed reports whether every preflight check passed. A 200 with all_passed false is still the success path — individual check verdicts are content, not transport errors.

Step 3 — approval token

Live submission requires a single-use, human-approved token minted via POST /api/v1/auth/approval-token with the org_number and the action_id being approved (e.g. mva_melding:<org>:<period>). The token is single-use and short-lived; an expired token is rejected with APPROVAL_TOKEN_EXPIRED.

Step 4 — submit (gated)

The live path requires both an Idempotency-Key header (so a network retry cannot double-submit) and an X-Approval-Token header (the human-in-the-loop gate). A successful response carries a signed receipt with the upstream altinn_receipt_id and a _meta.rulebook_version so the active rule version at submission time is auditable. Live submission is not yet enabled — the contract is published ahead of the gate lifting.

Use cases

  • Discover whether and when a company must file MVA for a given termin
  • Validate an MVA payload against preflight checks without submitting (dry-run)
  • Prepare a human-in-the-loop approval flow for an eventual live submission

Requirements

  • An API key with the read:actions scope
  • The organisation number of the company to file for
  • For the live path: a delegated Altinn system user carrying the skatteetaten:mva_melding/write scope (the canonical delegated scope validated for the mva_melding action; the tier baseline skatteetaten:mva is not sufficient)
  • For the live path: an Idempotency-Key header and a fresh approval token per submission

Authentication

Method: api_key · Scopes: read:actions

Dry-run validation is served under read:actions with layered non-scope gates on the live path (approval token + idempotency key). Write scopes (act:*) are reserved and not assignable at v1.

Common errors

  • APPROVAL_TOKEN_REQUIRED

    A live submission was attempted without a human-approved token.

    Fix: Mint a token via POST /api/v1/auth/approval-token and pass it in the X-Approval-Token header promptly.

  • APPROVAL_TOKEN_EXPIRED

    The approval token's short lifetime elapsed before submission.

    Fix: Mint a fresh token and submit promptly — tokens are single-use and short-lived by design.

  • IDEMPOTENCY_KEY_REQUIRED

    A write was attempted without an Idempotency-Key header.

    Fix: Generate a unique key per logical submission and send it on every retry of that submission.

  • DEADLINE_PASSED

    The obligation deadline for the period is in the past.

    Fix: Escalate to a human — late filing has consequences the agent must not decide on alone.

Related topics

Related APIs

Capability ids — resolve each against the machine-readable manifest at /api/v1/capabilities for the endpoint, auth mode, and tier.

  • company.obligations
  • actions.execute_dry_run
  • auth.approval_token

Related MCP tools

Registered tools on the Apier MCP server.

  • get_company_obligations
  • validate_action
  • submit_vat_return
  • explain_compliance_error