Skip to content

How do I query compliance obligations for Skatteetaten via API?

By , founder of Apier

Obligation lookups need no delegation and no key: ask /api/v1/public/obligations for an entity type and you get the template set back, and the deadline calendar answers the same way. Anything scoped to a named company needs an API key; the company-private tier of facts is not served today, because the Altinn delegation it was gated on is no longer brokered. One thing surprises most integrators: there is no Skatteetaten scope on an Apier key. Apier-key scopes name the data source rather than the agency the filing reaches, so obligations and deadlines come under read:brreg. Agency-named Maskinporten scopes are a separate layer, and only a direct integration handles them.

Two lanes. The upper lane, labelled no key and no delegation, runs from your app to a query by entity type with no company named, and returns the obligation template describing what an AS or an ENK must file. The lower lane, labelled API key and a delegation for the private tier, runs from your app to a query by organisation number for one named company, and returns that company's obligations with a data tier on the answer.No key, no delegationYour appAsk by entity typeno company namedThe obligation templatewhat an AS or an ENK must fileAPI key, and a delegation for the private tierYour appAsk by organisation numberone named companyThat company's obligationswith data_tier on the answer
The upper lane is where most integrations should start, because it answers the design question without anyone signing anything. The lower lane is where a named customer enters the picture.

What can I check without a delegation?

More than enough to design against. The zero-auth obligations endpoint takes an entity type and returns the template set for it, with each entry carrying its legal reference as a field. The zero-auth deadline endpoint takes an optional year and returns the recurring calendar, with the timezone, the entity types each entry applies to, and any weekend or holiday adjustment already applied. Neither call names a company, so neither needs anyone's permission.

That combination answers the question most projects actually start with. Before you know which customers you will have, you want to know what a Norwegian limited company owes, how a sole proprietorship differs, and what the reporting rhythm looks like across a year. You can build and test the whole shape of your product against those two endpoints and add company-specific behaviour later.

What you cannot get without a key is anything about a specific organisation, and that is a deliberate line rather than a pricing one. Company data touches board members, signing authority and filing behaviour, which is why it sits behind an identified caller even on the free tier. The compliance automation guide covers which facts are derivable from the open record and which are not.

Which Skatteetaten scopes exist on an Apier key, and what do they cover?

None, and the reason is worth understanding because it will save you a support ticket. Scopes on an Apier key name the data source the call reads, not the agency the resulting filing eventually goes to. So there is no read:skatteetaten to request, and asking for one gets you nothing.

Keep that qualifier in mind if you have read Digdir's documentation, because it is the source of most of the confusion here. Maskinporten has its own agency-named scopes, granted to a registered client and presented on the wire to the agency itself. Those are real, and they are a different layer from the scopes on an Apier key. If you integrate directly you deal with both; a call to Apier carries only the Apier key, because what Apier answers needs no agency scope at all.

What you actually need depends on which endpoint you are calling. Obligations, deadlines and company context read registry facts, so they sit under read:brreg. Filing history and the dry-run validation surface were withdrawn on 2026-10-21 together with the Altinn based tools and the MVA line; their routes answer 410 CAPABILITY_WITHDRAWN whatever scope the key carries. The audit trail has its own scope, read:audit, so an operator can grant company-data reads without also exposing the forensic log.

The write-side prefixes exist in the vocabulary but are not assignable to any key. That means a scope list is a factual record of which sources an integration touched rather than a statement of how much it was trusted, which is the property you want when someone asks what your system had access to.

How do I tell whether a filing has already been submitted?

Not through Apier. The filing history read depended on Altinn instance data behind a customer delegation, and it was withdrawn on 2026-10-21 together with the other Altinn based tools; its route answers 410 CAPABILITY_WITHDRAWN. Your database knows what your product submitted; it does not know what the customer's accountant submitted from somewhere else last Friday, and the place that does is Altinn itself, or the filing channel you use.

Treat a filed period as a stop condition before you act, not as a reconciliation step afterwards. An agent that checks history before proposing a filing avoids the single worst failure mode in this domain, which is a duplicate submission that then has to be corrected through a process much slower than the one that created it. Combining a history check in your own channel with the obligation and deadline reads gives you both halves: whether it has been done, and whether it was due at all.

Where a period genuinely has to be re-sent, the idempotency key is the safety net rather than your own retry logic. A key makes a repeated call replay the stored response instead of executing twice, which turns an ambiguous network timeout from a decision you have to make into a call you can simply repeat. Build that in before you need it, because the moment you need it is the moment you least want to be reasoning about it.

Make the first call

The first request needs nothing and returns what a sole proprietorship must file. The second is the company-scoped history read, which needs a key and the customer's delegation.

# Zero-auth: what a Norwegian sole proprietorship must file.
curl -s "https://www.apier.no/api/v1/public/obligations?entity_type=ENK"
// Has this period already been filed? Read the history.
// Replace {org} with a real organisasjonsnummer; 999999999 exists only in the sandbox.
const res = await fetch(
  "https://www.apier.no/api/v1/company/{org}/filing-history?limit=20",
  { headers: { Authorization: `Bearer ${process.env.APIER_API_KEY}` } },
);

const { data, _meta } = await res.json();
console.log(data.filings, _meta.data_freshness);

Frequently asked questions

Is there a Skatteetaten scope I should ask for on my Apier key?
Not on an Apier key, and this surprises people. Apier-key scopes name the data source rather than the agency a filing eventually reaches. Obligations and deadlines are reached with read:brreg because their inputs are registry facts. There is no read:skatteetaten to request, and the filing history and dry-run routes that used other scopes were withdrawn on 2026-10-21. Agency-named Maskinporten scopes are a separate layer that only a direct integration deals with.
What can I query without any delegation at all?
The obligation template for an entity type, and the recurring deadline calendar. Both are zero-auth: no key, no delegation, no company named. That covers the question most integrations actually start with, which is what a Norwegian limited company or sole proprietorship has to file and roughly when.
What does a delegation add?
Nothing through Apier today. Every company-scoped response carries a data_tier field: tier_1 means open registry facts, and tier_2, the company-private tier, was gated on an Altinn delegation that Apier no longer brokers or reads since 2026-10-21, so it self-describes as unavailable. A tier_1 answer is complete over its narrower inputs rather than truncated, and the response says which rules it could not reach.
How do I check whether a filing has already been submitted?
Not through Apier any more. The filing history read depended on Altinn instance data behind a customer delegation, and it was withdrawn on 2026-10-21; its route answers 410 CAPABILITY_WITHDRAWN. Check your own filing channel or Altinn directly. What Apier answers is whether the obligation applies and by when it is due.
Can I submit to Skatteetaten through this API?
No. Apier offers neither submission nor validation for submission: the MVA line was parked on 2026-10-21 and the filing routes answer 410 CAPABILITY_WITHDRAWN. The API answers what must be filed, by when and who may sign, and the submission happens in your own filing channel.