Revoke a fullmakt: retire a delegation and flip its agent principal to revoked
The revocation leg of the Fullmakt Rails. Given an agent principal the calling consumer owns, Apier revokes the delegation bound to that principal's systembruker and flips the principal to terminal 'revoked' (a revoked principal is never resurrected — create a new principal to act again). The delegations store is append-only, so revocation is REVOKE-BY-INSERT: a new status='revoked' marker row supersedes the original, and every Apier read and enforcement surface (GET /v1/auth/permissions/{org}, GET /v1/fullmakt/{org}, POST /v1/actions/execute, and the NAV/Skatteetaten delegation gates) honours the marker immediately — the delegation confers no authority anywhere in Apier after this call returns. The caller supplies ONLY agent_principal_id: the systembruker is resolved from the principal's write-once binding and the org from the delegation row itself, so a request body can never redirect the revoke at another delegation. Idempotent by design: revoking an already-revoked principal or delegation is a 200 no-op, so blind retries are safe (and Idempotency-Key is additionally supported). Ordering contract: the delegation marker is inserted FIRST, then the principal is flipped — if the flip fails after the marker landed, the response is still 200 with principal_revoke_failed in data.warnings (the delegation IS revoked; reconcile the principal, never assume full success). Altinn-side revocation is NOT yet propagated upstream: the upstream flow is a documented not-implemented stub pending live partner validation, surfaced honestly as upstream_revoke_unconfirmed — LOCAL revocation takes effect in Apier's own local check (Apier's recorded state, not a confirmation from Altinn). Recorded in the append-only audit log as fullmakt.revoke.
Request
- Base URL: https://www.apier.no
- URL: https://www.apier.no/api/v1/fullmakt/revoke
- Auth: HTTP bearer
Headers
Optional client-chosen key that makes this write safely retriable. When the same key is presented on a subsequent request with the same body, the gateway returns the original response (with Idempotent-Replay: true) instead of re-executing the write. Reservation is scoped to (consumer, endpoint, key) so the same key on different endpoints or different consumers does not collide. TTL: 24 hours. The key must be 1–255 printable ASCII characters — a v4 UUID or ULID is the recommended format. Keys are SHA-256 hashed before storage so they may safely carry client-internal identifiers.
OPTIONAL forensic-only attestation: the agent vendor / framework that issued this request (e.g. anthropic, openai, langchain). Persisted to audit_log.agent_vendor and mcp_query_log.agent_vendor; never used for authorization, scope, rate-limit, or idempotency decisioning. The server strips ASCII control chars (0x00–0x1F + 0x7F), Unicode NEL / line / paragraph separators, and BOM before persistence; values exceeding 64 UTF-8 BYTES are byte-boundary clamped (a non-ASCII string declared at 64 chars may exceed the 64-byte ceiling and be clamped further). NEVER echoed in any response body, response header, _meta block, error message, or Sentry payload — one-way capture. Omitting this header writes SQL NULL to the persisted columns. The MCP transport equivalent is clientInfo.attestation.vendor.
OPTIONAL forensic-only attestation: the agent model id (e.g. claude-opus-4-7, gpt-4o-mini-2024-07-18). Persisted to audit_log.agent_model and mcp_query_log.agent_model; identical sanitisation + clamp + non-echo rules as X-Agent-Vendor (control-char strip, 128-UTF-8-BYTE ceiling, never visible on any response). Forensic-only: never used for authorization, scope, rate-limit, or idempotency decisioning.
OPTIONAL forensic-only attestation: an opaque agent-side run / trace identifier (e.g. a LangSmith run id, a vendor-specific session id). Persisted to audit_log.agent_run_id and mcp_query_log.agent_run_id; identical sanitisation + clamp + non-echo rules as X-Agent-Vendor (control-char strip, 256-UTF-8-BYTE ceiling, never visible on any response). Forensic-only: never used for authorization, scope, rate-limit, or idempotency decisioning.
Request body
Example request
{
"agent_principal_id": "11111111-1111-4111-8111-111111111111",
"reason": "Agent access no longer required"
}Response
The delegation-revocation outcome is authoritative — including the idempotent no-op where the principal/delegation was ALREADY revoked (a blind retry never errors). The PRINCIPAL flip may still have degraded: inspect data.warnings. An empty array is the clean path (both legs landed); a non-empty array carries NAMED outcome tokens with distinct meanings — principal_revoke_failed is a genuine local degradation (the delegation is revoked but the principal is still in its prior state; reconcile and retry), while delegation_not_found (unbound principal — the principal revocation itself proceeded) and upstream_revoke_unconfirmed (best-effort Altinn-side propagation returned no ack; expected while the upstream flow is a documented stub) are expected outcomes, not local failures. Read the specific token.
Example response
{
"data": {
"signed_receipt": {
"signature": "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef"
}
},
"_meta": {
"rulebook_version": "v1.0.0",
"source": "apier.no",
"data_source": "Brønnøysund Enhetsregisteret + Apier Universal Rulebook",
"schema_version": "1.0.0",
"legal_basis": "NLOD — public registry reuse",
"response_timestamp": "2026-04-24T12:00:00.000Z",
"response_hash": "sha256:0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef",
"source_snapshot_id": "brreg-2026-04-24T02:00:00.000Z",
"cost_nok": 0.5,
"wallet_remaining_nok": 9.5,
"spend_cap_remaining_nok": 12.5
}
}Changes
No recorded changes to this operation across all 1 revision of this API.