---
title: "Sandbox mirror: acting capacity for a person on behalf of an organisation"
method: POST
path: "/api/v1/sandbox/altinn/list-acting-capacity"
tags: ["Sandbox"]
---

# Sandbox mirror: acting capacity for a person on behalf of an organisation

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

## Request

- Base URL: `https://www.apier.no`
- URL: `https://www.apier.no/api/v1/sandbox/altinn/list-acting-capacity`
- Auth: one of:
  - HTTP bearer
  - HTTP bearer

Fixture-backed mirror of `POST /api/v1/altinn/list-acting-capacity`: the same request body and the same flat response data under the sandbox envelope (`_meta.is_sandbox: true`). Answers from the four Altinn sandbox scenario organisations: 999111114 (an active daglig leder role), 999222226 (no roles), 999333338 (an accountant role that has expired) and 999444008 (an unrecognised organisation, answered with no roles). Any 11-digit `fnr` is accepted; only its HMAC (`actor.fnr_hmac`, under the sandbox key) is returned, and the raw value is never stored or echoed. Role validity is judged at the fixed sandbox clock, so every call returns the same roles and derived actions; only `correlation_id` varies. No call to Altinn or Maskinporten is made and nothing is written. `on_behalf_of.name` is always null (the scenario set carries no names). Any other organisation returns 400 SANDBOX_ORG_NOT_IN_FIXTURE_SET listing the scenario organisations, without echoing the input. Accepts a real key or the synthetic `apier_sandbox_test_<suffix>` bearer; the MCP tool `list_acting_capacity` is routed here under the sandbox bearer.

## Request body

- object
  - `fnr` string, required: 11-digit Norwegian fødselsnummer or D-nummer. HMAC-SHA-256 hashed at the boundary; never persisted in plaintext.
  - `org_number` string, required: 9-digit Norwegian organisasjonsnummer the actor wishes to represent.

## Response `200`

Acting capacity resolved from the sandbox scenario set.

- object: Sandbox 2xx success envelope BASE shape. Top-level keys mirror the production envelope (`success`, `_meta`) so SDK clients consuming sandbox responses see identical shapes. The `data` field is intentionally omitted from the base — per-operation envelopes (`SandboxContextEnvelope`, `SandboxObligationsEnvelope`, ...) `allOf` this base and pin `data` to the operation's typed payload, so generated clients keep the mirror typing for each route.
  - `success` true, required
  - `_meta` SandboxMeta, required: Sandbox `_meta` block. NOT a drop-in for production's `TrustMetadata`; clients must branch on `is_sandbox` before assuming any sandbox/production field equivalence. Differences from production: 1. `is_sandbox: true` — load-bearing detection signal; `body._meta.is_sandbox === true` is a single property assertion agents use to verify they're talking to the sandbox. Production omits this key entirely. 2. `rulebook_version` is the literal string `"sandbox"` — production carries the actual Rulebook version (e.g. `"v1.0.0"`). Sandbox responses are not Rulebook-evaluated. 3. `data_freshness` and `last_verified` are pinned constants (2026-01-01T00:00:00+01:00) — production reflects actual cache / fetch state. 4. `response_timestamp` is RFC 3339 with explicit Europe/Oslo offset (`+01:00` CET / `+02:00` CEST, DST-aware) — production's `response_timestamp` carries a UTC `Z` suffix. 5. `response_hash` and `source_snapshot_id` are OMITTED — sandbox writes ZERO provenance_log rows, so a hash without a matching forensic row would be misleading. Only `source` (`"apier.no"`) and `schema_version` semantics are shared with production.
    - `rulebook_version` 'sandbox', required: Always literal `sandbox` — sandbox responses are not Rulebook-evaluated.
    - `data_freshness` '2026-01-01T00:00:00+01:00', date-time, required: Pinned constant (2026-01-01T00:00:00+01:00) for determinism — same value on every call. Schema-locked via `enum` so spec-based drift checks catch any deviation.
    - `last_verified` '2026-01-01T00:00:00+01:00', date-time, required: Pinned constant — equal to data_freshness. Schema-locked via `enum` for the same drift-detection reason.
    - `source` 'apier.no', required: Response origin. Always `apier.no`. Preserves `_meta.source` parity with production `TrustMetadata.source` so clients can reuse `_meta` parsing across both surfaces. Provenance-specific fields (`response_hash`, `source_snapshot_id`) are omitted by design.
    - `schema_version` string, required: OpenAPI document version — mirrors the top-level `info.version` field. Distinct from `/api/v1/capabilities._meta.schema_version` and `/workflows.json.schema_version`, which version the capabilities-discovery and workflows-discovery surfaces respectively. Equality with `info.version` is enforced at CI time.
    - `is_sandbox` true, required: Load-bearing sandbox-detection signal. Always `true`.
    - `response_timestamp` string, date-time, required: RFC 3339 timestamp with explicit Europe/Oslo offset — runtime emits via `formatInTimeZone(now, 'Europe/Oslo', "yyyy-MM-dd'T'HH:mm:ssXXX")` so the offset is DST-aware (`+01:00` in CET / `+02:00` in CEST). The ONLY non-deterministic field permitted on sandbox responses (excluded from determinism comparisons).
    - `sandbox_notice` string, required: Human-readable mock-vs-government honesty signal (item 5). Constant prose: a passing sandbox run is an Apier internal mock (not Altinn TT02 / Skatteetaten test) and does not guarantee real government acceptance. `is_sandbox` is the machine-readable twin; this is the prose an agent or a human reading a logged response sees. Plain ASCII so it never trips the docs bokmål canary.
    - `cost_nok` 0: Always `0`. A sandbox call never debits anything — there is no ledger write and no government upstream. Same field name and rendering as production's `TrustMetadata.cost_nok`, so a client that reads the cost off `_meta` works unchanged against both surfaces. Emitted on every sandbox response. Declared optional in this schema only so the many older sandbox examples in this document stay valid; the runtime builder emits it on every response.
    - `wallet_remaining_nok` unknown
    - `as_of` string: Present ONLY when `?as_of=` Rulebook time travel is active on /deadlines or /obligations. Echoes the agent's exact YYYY-MM-DD input so a transcript is self-describing about which reference date the deadline / obligation statuses were derived against. Absent on every other sandbox response.
    - `simulated` true: Present + `true` ONLY on an `X-Apier-Simulate` injected failure response. The load-bearing signal that a 500 / 504 / 429 is a deliberately-simulated infrastructure failure, not a real one. Absent on every real sandbox response.
    - `session_merged` true: Present + `true` ONLY when this response merged per-suffix session state (mock filings recorded by a prior POST /api/v1/sandbox/actions/execute under the SAME sandbox-bearer suffix) over the static fixture, on the three opted-in reads (/audit, /obligations, /summary). The honesty marker distinguishing fixture state from session state. Absent on every fresh-suffix response, which stays byte-deterministic.
    - `session_merged_rows` integer: Count of response items the merged session state changed (obligation/deadline statuses overridden plus audit rows prepended). Present ONLY alongside `session_merged: true`, always >= 1.
  - `data` object, required: Flat data shape. The MCP executor extracts this verbatim and wraps it in the agent envelope on its side; returning a pre-wrapped `{ result, justification, metadata }` here would double-wrap on the MCP path.
    - `actor` object, required
      - `fnr_hmac` string, required: 64-char lowercase hex HMAC-SHA-256 of the input fnr. PSEUDONYMOUS — NOT anonymous: the hash is stable per (raw fnr, server pepper) pair, so two requests for the same actor produce the same `fnr_hmac` and a third party who later learns the pepper could re-identify. Treat as personal-data-adjacent: store only when necessary (audit chains, forensic joins), never log to a third-party telemetry service, prefer correlation_id for client-side tracing.
    - `on_behalf_of` object, required
      - `org_number` string, required
      - `name` string, nullable, required
    - `roles` object[], required
      - `code` string, required
      - `label_nb` string, required
      - `valid_from` string, date-time, required
      - `valid_to` string, date-time, nullable, required
    - `derived_actions` object[], required
      - `action` string, required
      - `via_role_code` string, required
      - `legal_reference` string, required: Lovdata.no citation. Every production row carries a verified citation as of (2026-05-16). The TBD-VERIFY-LOVDATA literal is retained as a runtime sentinel for any future un-verified seed (defense-in-depth) — when `verification_pending` is true the value is the sentinel literal, but no production row currently triggers this.
      - `verification_pending` boolean, required: True when `legal_reference` is the TBD placeholder. Agents should treat the legal citation as provisional in that case.
    - `source_snapshot_id` string, required: Opaque upstream snapshot identifier — propagated into actor_delegations.source_snapshot_id.
    - `role_count` integer, required
    - `fetched_at` string, date-time, required
    - `cached` boolean, required: True when the answer came from resolved_permissions cache; false for cold misses.
    - `correlation_id` string, uuid, required: Echoes the request's correlation_id; same value appears on the X-Correlation-ID response header.

## Other responses

- `400`: Sandbox 4xx / 5xx error from a write-side endpoint (`/api/v1/sandbox/auth/approval-token`, `/api/v1/sandbox/actions/plan`). Body shape mirrors `SandboxError` (the read-side error envelope) but the response carries the write-side CORS contract that `applySandboxWriteSideCorsHeaders` stamps on every error path: `Access-Control-Allow-Methods: POST, OPTIONS`, `Access-Control-Allow-Credentials: false`, and the write-side `Access-Control-Allow-Headers` safe list. Introduced so the published contract for approval-token + plan errors stops drifting from the runtime — they previously reused `SandboxError` which advertises the read-side `GET, OPTIONS` Allow-Methods and omits the explicit `Allow-Credentials: false` write-side guarantee. The execute route uses `SandboxExecuteError` instead because it ships reliability fields (`execution_guarantee` + `outcome`) that approval-token + plan do NOT emit.
- `401`: Sandbox 4xx / 5xx error from a write-side endpoint (`/api/v1/sandbox/auth/approval-token`, `/api/v1/sandbox/actions/plan`). Body shape mirrors `SandboxError` (the read-side error envelope) but the response carries the write-side CORS contract that `applySandboxWriteSideCorsHeaders` stamps on every error path: `Access-Control-Allow-Methods: POST, OPTIONS`, `Access-Control-Allow-Credentials: false`, and the write-side `Access-Control-Allow-Headers` safe list. Introduced so the published contract for approval-token + plan errors stops drifting from the runtime — they previously reused `SandboxError` which advertises the read-side `GET, OPTIONS` Allow-Methods and omits the explicit `Allow-Credentials: false` write-side guarantee. The execute route uses `SandboxExecuteError` instead because it ships reliability fields (`execution_guarantee` + `outcome`) that approval-token + plan do NOT emit.
- `413`: Sandbox 4xx / 5xx error from a write-side endpoint (`/api/v1/sandbox/auth/approval-token`, `/api/v1/sandbox/actions/plan`). Body shape mirrors `SandboxError` (the read-side error envelope) but the response carries the write-side CORS contract that `applySandboxWriteSideCorsHeaders` stamps on every error path: `Access-Control-Allow-Methods: POST, OPTIONS`, `Access-Control-Allow-Credentials: false`, and the write-side `Access-Control-Allow-Headers` safe list. Introduced so the published contract for approval-token + plan errors stops drifting from the runtime — they previously reused `SandboxError` which advertises the read-side `GET, OPTIONS` Allow-Methods and omits the explicit `Allow-Credentials: false` write-side guarantee. The execute route uses `SandboxExecuteError` instead because it ships reliability fields (`execution_guarantee` + `outcome`) that approval-token + plan do NOT emit.
- `500`: Sandbox 4xx / 5xx error from a write-side endpoint (`/api/v1/sandbox/auth/approval-token`, `/api/v1/sandbox/actions/plan`). Body shape mirrors `SandboxError` (the read-side error envelope) but the response carries the write-side CORS contract that `applySandboxWriteSideCorsHeaders` stamps on every error path: `Access-Control-Allow-Methods: POST, OPTIONS`, `Access-Control-Allow-Credentials: false`, and the write-side `Access-Control-Allow-Headers` safe list. Introduced so the published contract for approval-token + plan errors stops drifting from the runtime — they previously reused `SandboxError` which advertises the read-side `GET, OPTIONS` Allow-Methods and omits the explicit `Allow-Credentials: false` write-side guarantee. The execute route uses `SandboxExecuteError` instead because it ships reliability fields (`execution_guarantee` + `outcome`) that approval-token + plan do NOT emit.

---

[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)
