---
title: "Check which of your agent principals hold fullmakt for an organisation"
method: GET
path: "/api/v1/fullmakt/{org}"
tags: ["Fullmakt"]
---

# Check which of your agent principals hold fullmakt for an organisation

`GET /api/v1/fullmakt/{org}`

## Request

- Base URL: `https://www.apier.no`
- URL: `https://www.apier.no/api/v1/fullmakt/{org}`
- Auth: HTTP bearer

Read-side of the Fullmakt Rails, and the natural follow-up to POST /v1/fullmakt/request. Answers, for one customer organisation: which of YOUR OWN agent principals currently hold delegated authority, which scopes are live, which are missing relative to your tier's baseline, and what to do about it. Each entry is the join of an agent principal to the delegation brokered for its write-once `system_user_id` binding, so an agent can decide whether it may act before attempting an action.

The response always uses HTTP 200 on the happy path — the verdict lives in `data.overall_status` (`full`/`partial`/`none`). `none` is a VALID state, not an error: a consumer with no agent principals, or none holding a live delegation for this organisation, receives a 200 with an empty `data.principals` and `data.fix_steps` pointing at POST /v1/fullmakt/request. This endpoint NEVER returns 404 for 'no fullmakt yet'. Only transport-level problems (malformed org_number, missing API key, insufficient scope, internal failure) produce non-200 responses.

Data source and its limits: the verdict is computed from the delegation state Apier RECORDED locally when it brokered the fullmakt, joined to your agent principals. It is NOT a live Altinn PDP (Policy Decision Point) decision — no such call exists at v1 — so the local record and Altinn's live decision can diverge if a delegation is revoked upstream without Apier observing it. Verified against Apier's own delegation records as of `data.last_checked`; no legal guarantee is asserted.

Expiry semantics match the enforcement path exactly: a delegation is live iff `valid_until` is null or strictly in the future, so a delegation POST /v1/actions/execute would refuse is never reported here as authority.

## Path parameters

- `org` string, required

## Response `200`

Fullmakt state for the requested organisation. `data.overall_status` carries the verdict; callers MUST branch on it rather than on the HTTP status, which is 200 for `full`, `partial` AND `none` alike.

- object
  - `success` true, required
  - `data` object, required
    - `org_number` string, required: Echoed 9-digit Norwegian organisation number the state applies to.
    - `overall_status` 'full' | 'partial' | 'none', required: Aggregate verdict across every agent principal you own. `full` — at least one of your principals is itself `active` AND holds an `active` delegation covering every scope your tier requires; you can act now. Both halves are required: a delegation is authority the COMPANY granted, an active principal is authority Apier will honour, and a suspended principal holding a perfect delegation still cannot act (POST /v1/fullmakt/request rejects `suspended`/`revoked` principals outright). `partial` — at least one principal holds a live delegation, but none clears every bar: scopes are missing, the delegation is still `pending` the company's signing authority, or the principal itself is not `active`. `partial` ALWAYS carries at least one `fix_steps` entry naming the specific blocker — never a bare verdict. `none` — no principal of yours holds a live delegation for this organisation (including the case where you own no principals at all); this is a valid answer, not an error.
    - `principals` object[], required: One entry per agent principal of yours that holds a live delegation for this organisation, ordered deterministically (principal created_at ascending). A principal with no live delegation here is OMITTED rather than listed with a null verdict — so an empty array is exactly the `none` case. Principals belonging to other consumers are structurally unreachable: the join runs against your own principals only.
      - `agent_principal_id` string, uuid, required: The agent principal this entry describes. Pass this id to POST /v1/fullmakt/request to extend or re-broker its delegation.
      - `display_name` string, required: Consumer-supplied label for the principal, echoed so a dashboard can render the entry without a second lookup.
      - `principal_status` 'pending' | 'active' | 'suspended' | 'revoked', required: Lifecycle status of the agent principal itself, independent of the delegation — and a gate on the verdict in its own right. Only an `active` principal can contribute to `overall_status: full`: a principal can hold a perfectly valid, approved delegation while being `suspended`, `revoked` or not yet activated, and in every one of those cases it still cannot act, so the verdict degrades to `partial` with a `fix_steps` entry naming the lifecycle blocker.
      - `system_user_id` string, required: The Altinn systembruker this principal is bound to (write-once). This is the join key between the principal and the delegation, and is never null on an entry: an entry only exists because this binding resolved to a live delegation.
      - `delegation_status` 'active' | 'pending', required: State of the underlying delegation. `active` — approved and usable. `pending` — brokered but still awaiting approval from the company's signing authority via the delegation_url (see `fix_steps`); it grants no authority yet. `expired`/`revoked` delegations never appear — they are not live, so the principal is omitted entirely.
      - `active_scopes` string[], required: Scopes the delegation actually carries, as recorded when it was brokered.
      - `missing_scopes` string[], required: Scopes your tier's baseline requires that this delegation does NOT carry. Empty means the delegation is scope-complete for your tier — which is necessary but not sufficient for `full`, since a pending delegation is still unusable.
      - `valid_until` string, date-time, nullable, required: RFC 3339 expiry of the delegation, or null when it does not expire. Always strictly in the future on a returned entry — an elapsed delegation is not live and its principal is omitted.
    - `fix_steps` string[], required: Compliance Explainer remediation steps in Norwegian (bokmål), deduplicated and deterministically ordered. Empty when `overall_status` is `full` — there is nothing to fix. Otherwise: which endpoint to call to broker a fullmakt, which delegation_url the company's signing authority must approve, or which scope to add to an existing delegation. Describes Apier's own process only; asserts no legal claim.
    - `last_checked` string, date-time, required: RFC 3339 UTC instant the state was computed. Mirrors `_meta.last_verified` and `_meta.data_freshness` within the same response, and is the single clock instant the liveness comparison used — so the verdict cannot race the valid_until boundary mid-request.
  - `_meta` TrustMetadata, required: Metadata included in every response for trust and verifiability.
    - `rulebook_version` string, required: Current Rulebook version. Internal rule-version records carry structured origin metadata (`initial_seed` | `human_review` | `lovdata_drift_response` | `audit_finding` | `customer_question` | `legal_correction`) for operator forensics, but that attribution is deliberately NOT exposed on public responses to avoid leaking operational signal.
    - `data_freshness` string, date-time, required: When this data was last fetched (ISO 8601 UTC).
    - `last_verified` string, date-time, required: When this data was last verified against source (ISO 8601 UTC).
    - `source` string, required: Origin of this data. Defaults to `apier.no`. The agent-readiness probe (`GET /api/v1/health/agent-readiness`) is the one surface that may instead emit `apier.no telemetry` — it does so when at least one of its endpoint rates came from measured live telemetry, and falls back to `apier.no` when every rate is a static default; all other endpoints always emit `apier.no`.
    - `data_source` string: Authoritative origin of the underlying data (listed alongside rulebook_version, data_freshness, last_verified, legal_basis for Rulebook-influenced endpoints). Distinct from `source` (the response origin): `data_source` identifies the authoritative data publisher — e.g. 'Brønnøysund Enhetsregisteret + Apier Universal Rulebook'. Present on registry-backed endpoints.
    - `served_from` 'cache' | 'live' | 'static': Cache-aware endpoints only — 'cache' when the response was served from the local copy, 'live' when the gateway just refreshed from the upstream, 'static' when the payload was computed deterministically from pure code with no DB or upstream read (e.g. /v1/public/deadlines). Absent on endpoints that don't carry this semantic.
    - `stale` boolean: Cache-aware endpoints only — true when the upstream was unreachable and a within-limit cached row was served as a fallback. Absent on normal responses.
    - `schema_version` string, required: OpenAPI contract version at the time of the response; matches `info.version`. Always present on every `/v1/*` response so a future schema break can be traced to the exact rows / audit events that predate / postdate it. Agent-facing machine interfaces (v1/capabilities, workflows.json) may override with their own narrower surface version; all other endpoints inherit the manifest-level version.
    - `legal_basis` string: Legal basis under which the response data is reused. Present on Rulebook-influenced endpoints (v1/company/{org}/obligations, /v1/company/{org}/deadlines). Common value: 'NLOD — public registry reuse'.
    - `rule_count` integer: Rule-evaluation count — total rules evaluated for this request. Present on endpoints that invoke the Rulebook evaluator (v1/company/{org}/obligations).
    - `applicable_count` integer: Count of rules whose evaluation_result is 'applicable'. Present on evaluator endpoints.
    - `not_applicable_count` integer: Count of rules whose evaluation_result is 'not_applicable'. Present on evaluator endpoints.
    - `insufficient_data_count` integer: Count of rules whose evaluation_result is 'insufficient_data' (Tier 2 gated). Present on evaluator endpoints. rule_count = applicable_count + not_applicable_count + insufficient_data_count.
    - `cache_age_ms` integer, nullable: Cache layer: milliseconds since the cached row was computed, or null on a cache miss (served_from === 'live'). Agents use it alongside data_freshness as a staleness signal. Present on endpoints wired to the cache (v1/company/{org}/obligations, /deadlines, /summary, /v1/public/obligations, /v1/public/deadlines).
    - `response_time_ms` integer: Speed signal: total server-side processing time in milliseconds, measured via performance.now() at the route boundary. Mirrored on the `X-Apier-Response-Time-Ms` header so agents can key on it without parsing the body. Present on every endpoint.
    - `response_timestamp` string, date-time: RFC 3339 / ISO 8601 UTC timestamp stamped by the response builder at wire-exit. Mirrored on the `provenance_log.response_timestamp` column by a fire-and-forget writer. Distinct from `data_freshness` (when upstream data was fetched) and `last_verified` (when the citation was verified); this is the moment the envelope left the server. Always populated at runtime — deliberately left out of the `required` list to avoid a cascading contract change that would invalidate every pre-existing example envelope in this spec (append-only response contracts). A future revision may promote it into the `required` list alongside a bulk example refresh.
    - `response_hash` string: SHA-256 hash of the canonical-JSON form of the envelope with `_meta` stripped before hashing, prefixed with `sha256:`. Mirrored on `provenance_log.response_hash` so a consumer can independently re-hash the bytes they received and compare against what we persisted (integrity receipt). Stripping `_meta` is load-bearing: volatile fields (response_time_ms, cache_age_ms, served_from) and the hash itself would otherwise feed into the digest and break the cache-hit-bytewise-identical invariant.
    - `source_snapshot_id` string: Optional free-text pointer into an upstream sync snapshot the response derives from — e.g. a Brreg sync's `brreg-<ISO>` snapshot id. Absent when the response is not tied to a specific upstream snapshot (capabilities, tools, static deadlines).
    - `is_sandbox` true: Present and `true` only when the response was generated from sandbox fixture data (currently `ALTINN_MODE=sandbox` on `/api/v1/altinn/list-acting-capacity`). Absent (NOT `false`) on every other response — the absent-vs-false distinction is deliberate so downstream agents branching on `if (response._meta.is_sandbox)` cannot be misled into treating non-sandbox responses as positively-confirmed-not-sandbox. Distinct from the `/v1/sandbox/*` `is_sandbox: true` literal in `SandboxMeta` (which carries the sandbox surface tag); this flag rides through the production `/api/v1/altinn/*` surface to forensically tag a sandbox-mode response that an OEM evaluator received.
    - `cost_nok` number: What this call debited from the caller's prepaid credit balance, in NOK, rendered from the integer-øre ledger (50 øre → 0.5; the ledger itself never leaves whole øre and no float arithmetic touches a balance). Present on the 2xx body of every metered company-data read — the same debit that sets the `X-Credits-Cost-Ore` header, so the two never disagree. `0` when nothing was charged: credit enforcement running dark (the response then also carries `X-Credit-Check: shadow`) or the sandbox surface. Absent on unmetered endpoints and on error envelopes — a refunded 5xx/403/404 claims no cost rather than a wrong one. Lives under `_meta`, which `response_hash` excludes, so the provenance receipt is unaffected; the route's ETag is computed before the credit wrapper stamps it, so a conditional request can still short-circuit to 304. Append-only addition.
    - `wallet_remaining_nok` number, nullable: The prepaid credit balance remaining AFTER this call's debit, in NOK (same rendering as `cost_nok`; mirrors the `X-Credits-Balance-Ore` header). `null` when no balance was read: credit enforcement running dark, or the sandbox surface. Present wherever `cost_nok` is. An agent planning a sequence of metered calls can divide this by the per-call price from GET /api/v1/pricing to know how many reads remain before a 402 INSUFFICIENT_CREDITS. Append-only addition.
    - `spend_cap_remaining_nok` number: What the calling key may still spend under its tighter spend cap (Europe/Oslo calendar day or month) AFTER this call's debit, in NOK (same rendering as `cost_nok`; never below 0). Present on the 2xx body of a metered read only when credit enforcement is live AND the key has a daily or monthly cap (set with PATCH /api/v1/account/keys/{id}); absent otherwise. When it reaches 0 the next metered call on this key returns 402 SPEND_CAP_REACHED until the cap resets. Append-only addition.

## Other responses

- `400`: The org path parameter is not exactly 9 digits (error_code=VALIDATION_FAILED). Validation runs before the fullmakt-state lookup, but AFTER authentication and the scope check — so a malformed org_number on an unauthenticated or under-scoped request surfaces as 401/403 first.
- `401`: Authentication failed — missing, malformed, invalid, or revoked API key.
- `403`: The API key lacks the read:altinn scope (error_code=SCOPE_INSUFFICIENT). This is a plain read of your own delegation state and grants no authority, so it is servable by any key granted read:altinn or the read:* wildcard — it is NOT reserved-scope-gated like /v1/auth/system-user/delegate.
- `429`: Rate limit reached on at least one of TWO independent dimensions running in parallel: per-(api_key, endpoint) per-minute (the established per-tier scaling — Free / Starter / Professional / Enterprise unlimited) AND per-(api_key, org_number) per-day (bounds runaway-agent failure modes per client org so one org's traffic cannot starve siblings sharing the same key; daily bucket window is one calendar day in Europe/Oslo, DST-aware). The `X-RateLimit-Dimension` header identifies which bucket tripped: `per_key`, `per_org`, or `both` (when the same request exceeds both — the binding Retry-After is the per-org value because the per-org window is hours/days vs the per-minute window). The `Retry-After` header indicates how many seconds to wait before the binding window resets; `X-RateLimit-Limit` / `X-RateLimit-Remaining` / `X-RateLimit-Reset` describe the per-minute bucket state. The per-day per-org limits per tier (sized at ~100× typical daily volume — the dimension exists to bound failure modes, not to monetize) are: Free 1000/org/day, Starter 5000, Professional 25000, Enterprise unlimited. On rare infrastructure-side failures the gateway fails OPEN and passes the request through with `X-RateLimit-Check: skipped` on the response — clients can treat that as a transient signal that quota enforcement was briefly degraded.
- `500`: Unexpected failure computing fullmakt state (typically a database read failure). A read failure is surfaced as an error rather than degraded into a false `none` verdict. Internal details are never leaked in the response body.

---

[API](https://skmtc.dev/apier/apis/apier-no-api.md) · [All operations](https://skmtc.dev/apier/apis/apier-no-api/llms.txt) · [OpenAPI document](https://skmtc.dev/apier/apis/apier-no-api/revisions/9ec19bc87311?raw)
